OmniAICreator/Qiita-1.07M huggingface dataset:
BigQuery データセット レプリケーションでデータセットのロケーションを変更する

[mediba Advent カレンダー 21日目](<https://qiita.com/advent-calendar/2023>) ということで、左海からは「BigQuery データセット レプリケーションを利用してBigQueryデータセットのロケーションを変更する」お話についてです。

## はじめに

最近アサインされた案件にて、外部のGCPプロジェクトにあるBigQueryのGA4データセットを弊社管理のGCPに連携するには、弊社管理のGCP内のGA4データセットのロケーションを連携元に揃える必要がありました。

ゆえに、BigQueryのデータセットのロケーション変更を行うため、[データセット レプリケーション](<https://cloud.google.com/bigquery/docs/data-replication?hl=ja>)を試してみることにしました。

他に[Copy tables across regions](<https://dev.classmethod.jp/articles/bigquery-copy-tables-across-regions/>)で、移行先のデータセット配下に移行元のテーブルをコピーする方法もありましたが、時間と手間がかかるためデータセット レプリケーションを選びました。

:::note warn
データセット レプリケーションは2023/12/17時点でプレビュー版であるため、商用環境での利用にはご注意ください。
:::

## BigQuery データセット レプリケーションとは

データセット レプリケーションとは既存のデータセットとは異なるリージョンで、データセットのレプリカ（複製）を作成する機能になります。

以下の図の場合、`US`リージョンの`analytics_123`というデータセット（プライマリ レプリカ）のレプリカ（セカンダリ レプリカ）が`asia-northeast1`リージョンとして作成されています。

![replica.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2290540/f07a9739-ab10-432e-3358-29e4dbbc3ac0.png)

セカンダリレプリカには、プライマリレプリカのデータが非同期的に複製され続けます。

## BigQuery データセットのロケーション変更

では、実際に以下の手順で`US`マルチリージョンのデータセット`hoge`を`asia-northeast1`リージョンに移行します。

1. `asia-northeast1`リージョンとしてレプリカを作成する
2. セカンダリレプリカをプライマリレプリカに昇格させる
3. レプリカを削除する

### レプリカを作成する

データセット名`hoge`のレプリカ`hoge_tokyo`を`asia-northeast1`リージョンとして作成するため、以下のクエリを実行します。

``` sql:
ALTER SCHEMA hoge
ADD REPLICA `hoge_tokyo`
OPTIONS(location='asia-northeast1');
```

以下のクエリを実行すれば、レプリカが作成されたか/後述のセカンダリレプリカがプライマリレプリカに昇格したかクエリの実行結果で確認することができます。

``` sql:
SELECT
  *
FROM
  `region-us`.INFORMATION_SCHEMA.SCHEMATA_REPLICAS;
```

### セカンダリレプリカをプライマリレプリカに昇格させる

以下クエリで、作成したレプリカ`hoge_tokyo`をプライマリレプリカに昇格させることで`asia-northeast1`がプライマリリージョンとなり、ロケーション変更が完了します。

この時、`US`マルチリージョンのレプリカはセカンダリレプリカに降格し、セカンダリリージョンとなります。

``` sql:
ALTER SCHEMA hoge SET OPTIONS(primary_replica = 'hoge_tokyo')
```

上記クエリ実行時に、以下のエラーが表示されるのですが、クエリの設定でジョブのロケーションをセカンダリ リージョン（`asia-northeast1`）に明示的に設定する必要があるようです。

> The primary replica can only be assigned from the replica region: asia-northeast1.

添付画像の通り、無事にデータのロケーションが`US`から`asia-northeast1`に変更されました。

![dataset_hoge.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2290540/4ce92bf8-0584-5ce9-b4cf-b2d01392d25a.png)

参考までに、GA4データセットのロケーションを変更する際は、セカンダリレプリカを昇格させた後にGA4プロパティ側で、既存のBQエクスポートを削除し、新たに移行先のリージョンとしてBQエクスポートを開始する必要があります。

### レプリカを削除する

最後に、不要なレプリカ（`US`マルチリージョン）を削除します。


``` sql:
ALTER SCHEMA hoge
DROP REPLICA IF EXISTS us;
```

この手順は必須ではないのですが、GCPの費用レポートで以下の費用が計上されていたのでコスト削減のためにも不要なレプリカは削除した方がよいでしょう。

> Replication Networking Traffic for Google Cloud Cross Region/Inter Region between NorthAmerica and Asia

## おわりに

データセット レプリケーションを試してみたのですが、SQLを数回実行するだけでロケーションを変更できるのはかなり便利でした。

ただ、懸念としてロケーション変更前のデータセットに対して、BigQueryやLooke Studioで以下の機能を利用している場合には、機能ごとにも移行先のロケーションとして再登録、再接続が必要です。※あくまで一部です。

- BigQuery
    - スケジュールクエリ
    - BigQuery Editionのスロットの予約
- Looker Studio
    - Looker Studioのデータソース（BigQueryテーブル/カスタムクエリ）

対応を忘れてしまうと、スケジュールクエリが停止したり、Looker Studioでグラフが閲覧できなくなったりするので、注意しておきたいです。

どなたかの参考になれば、幸いです。
クラス図の概要

<h2>UMLクラス図とは</h2>
クラス、プロパティ、メソッドやオブジェクト間の関係性を図にまとめたものです。<br>
UMLは、オブジェクト指向のプログラミングのアプローチを記述するためのモデルとして考案されたものです。<br>

<h2>属性と操作</h2>
「クラス」には「属性」と「操作」がついてきます。<br>
「属性」はクラスが保有する要素を意味します。<br>
「操作」ではそのクラスで実行可能な内容が記述されます。<br>
以下のクラス図を例にすると、「バスケットボール選手」というクラスの中には「選手名」「背番号」という「属性」があり<br>「ドリブル」「パス」「シュート」「リバウンド」「ブロック」という「操作」があると言えます。<br>
また「属性」は「クラス」の下に、「操作」は「属性」の下に記載します。<br>

![スクリーンショット 2023-11-26 14.37.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3628257/b6de2c16-3497-67e8-779c-3a7783335599.png)

画像には「属性」と「操作」の左に「＋」と「−」がありますが、これはそのシステムにアクセスできる範囲はどこまでかを設定しています。
クラス図で可視性を表現する場合、要素名や操作の左側に記号で可視性が記入されます。
可視性を表現する記号は以下の４種類です。

「＋」・・・すべてのクラスからアクセス可能
「−」・・・自クラスのみアクセス可能
「＃」・・・自クラス及び継承されているクラスからアクセス可能
「~」・・・同一パッケージ内のクラスからアクセス可能

<h2>集約</h2>
クラス同士の関係が「全体と一部」であるとき「集約」として表現されます。<br>
バスケットボールチームを例に例えると、［バスケットボールチーム］クラスという全体の中の一部として「監督」「バスケットボール選手」クラスがあるイメージです。


![スクリーンショット 2023-11-25 16.14.05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3628257/25176405-a5e3-c93c-9244-7d80324e6124.png)


<h2>依存</h2>
クラスの間に「使用する」関係があることを表します。<br>
呼び出し元の操作の中でパラメータが依存先のクラスで使用されます。<br>
以下のクラス図を例にすると「監督」や「バスケットボール選手」がなんらかの違反を犯すと「審判」がペナルティを課すイメージです。

![スクリーンショット 2023-11-25 17.08.21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3628257/f43e64c2-3b1a-ed63-7aa6-6d4bc743e091.png)


<h2>汎化</h2>
汎化関係とは、あるモデル要素（子）が他のモデル要素（親）に基づいて作成される関係です。<br>
汎化関係を開発に利用すると「バスケットボール選手」クラスに分類される「シューター」クラスを開発するときは<br>「バスケットボール選手」の属性と操作を引き継いで、差分である「3Pシュートを決める」操作だけ開発すれば良くなります。

![スクリーンショット 2023-11-25 17.33.59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3628257/1a949bbe-8fdc-d58f-212f-7a0945cb8c44.png)



<h2>最後に</h2>
今回は、以前に作成した以下のクラス図を基に概要をまとめました。

![スクリーンショット 2023-11-26 15.16.04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3628257/dc3ed5a0-e99e-abd3-b4b7-d7b68ee64653.png)


VSCodeにDraw.ioをインストールして作成しました。
https://blog.serverworks.co.jp/vscode-drawio-setup

何か誤り等があればご指摘いただけると助かります。
簡単に明日から読みやすいコードを書くコツを考えてみた

# はじめに
現在プログラミングスクール`RUNTEQ`に通っています。

久々に**リーダブルコード**を読んだので、改めて**読みやすいコード**を書くためにはどう意識すればよいか少しまとめていきます。


# 名前に情報を詰め込む
変数は**名前に情報を詰め込む**必要があります。

例えば、2時間後に締め切りによって条件分岐させるプログラムを考えるとします。

```ruby:アンチパターン
# 現在時刻を取得
now = Time.now

# 2時間後を計算
two_hours_later = now + (60 * 60 * 2)

# 締め切りが2時間後かどうかを判断
if now < two_hours_later
  puts "まだ締め切りまで時間があります。"
else
  puts "締め切り時間を過ぎています。"
end
```
上記ですが、2時間後を`two_hours_later`という変数に代入していますが、これは意味がありません。

この`now + (60 * 60 * 2)`を**どんな目的で用いるのか**を考える必要があります。
```ruby
# 現在時刻を取得
now = Time.now

# 締め切りを設定（現在時刻から2時間後）
study_deadline = Time.now + (60 * 60 * 2)

# 締め切りが2時間後かどうかを判断
if study_deadline > now
  puts "まだ締め切りまで時間があります。"
else
  puts "締め切り時間を過ぎています。"
end
```
今回は2時間後が**勉強の締め切り**だったので、`study_deadline`という変数名にする事でより文脈が分かりやすくなります。


# 要約する
例えば、こんなコードがあるとします。

```ruby
if request.user.id == document.owner_id
  # ドキュメントを編集できる
end
```
この例だと、簡単に読めそうですが**変数を5つ**使って条件を判定しています。
`request`の`user`の`id`と`document`の`owner_id`が一致している時、という分岐から、「これは何を意味してるんだ、、？」と少し考えるのに時間がかかります。

この分岐は何を意味しているかというと、`自分のドキュメントかどうか`ということを意味しているので、一度要約変数に代入することで、**読み手の負荷を下げる**ことにも繋がります。

```ruby
user_owns_document = (request.user.id == document.owner_id)
if user_owns_document
  # ドキュメントを編集できる
end
```

# 条件分岐の並び順
条件分岐は**単純な条件、かつ肯定形から分岐をさせていく**事が良いです。

```ruby:アンチパターン
if a != b 
 #aとbが「合致しない時」の処理
else
 #aとbが「合致する時」の処理
end
```

```ruby
if a = b 
 #aとbが「合致する時」の処理
else
 #aとbが「合致しない時」の処理
end
```
一致してない場合の条件分岐を書く場合はRubyでは`unless`を用いる事が良さそうです。

```ruby
print "数値を入力してください: "
num = gets.to_i
puts "#{num}は負の数です。" unless num >= 0
```

# 無関係の下位問題を抽出する
コードには`単一責任の原則`という原則があり、クラスや関数への責任は一つにしましょうという原則です。

例えば、ユーザーの年齢を計算し、その結果に基づいてメッセージを出力するメソッドがあるとします。

```ruby
def calculate_age_and_display_name(birth_year, name)
  current_year = Time.now.year
  age = current_year - birth_year

  if age >= 20
    puts "#{name}さん、あなたは成人です。"
  else
    puts "#{name}さん、あなたは未成年です。"
  end

  puts "あなたの名前は#{name}です。"
end

calculate_age_and_display_name(2000, 'Yamada')
```
このプログラムでは、`年齢の計算`と`名前の表示`という2つの`責任(役割)`を持っています。
`責任(役割)`が増えるごとに見通しが悪くなり、思わぬバグを生み出す温床になります。
また、関数名と実際の処理の内容が乖離してしまうことも考えられるので、`責任(役割)`事にメソッドに切り出す事が良いでしょう。

```ruby
def calculate_age(birth_year)
  current_year = Time.now.year
  age = current_year - birth_year
end

def display_message(age, name)
  if age >= 20
    puts "#{name}さん、あなたは成人です。"
  else
    puts "#{name}さん、あなたは未成年です。"
  end

  puts "あなたの名前は#{name}です。"
end

age = calculate_age(2000)
display_message(age, 'Yamada')
```
slow queryをインフラ視点から調査する

この記事は[検索エンジンプロダクトを一緒に開発してた同窓会 Advent Calendar 2023](https://qiita.com/advent-calendar/2023/alumni)の20日目の記事です。

### はじめに
slow queryの調査と聞くと、slow query logの調査が一番に頭に浮かぶのではないでしょうか?

しかし、その隠れた前提としてインフラは問題ないということがあると思います。今回はインフラ視点から原因を調査していきます。

### 前提
- Amazon RDS for MySQL 8.0.20(他のdbでも同じようなことができると思いますので、参考にしてください)

### 手っ取り早く解決するには?
slow queryになるSQLを実行したあとに、
```
SHOW WARNINGS;
```
をして、出てきたwarningを片っ端から調べて修正していく方法があります。

こちら解決までは速いですが、あくまでpatch的なやり方になるので、後の作業者が困る可能性が高くなります。設定の見直しをしたほうが後々を考えると安心です。

### インフラ視点から調査する
mysqlのサーバーシステムの変数がいくつあるかご存知でしょうか?250個以上あります。InnoDBのパラメータを含めると、さらに増え500を超えていきます。
https://dev.mysql.com/doc/refman/8.0/en/server-system-variables.html
https://dev.mysql.com/doc/refman/8.0/ja/innodb-parameters.html

数が多いですよね、1つ1つの変数の意味を理解して設定できる人はどのくらいいるのでしょうか?versionがあがるたびに変数が増えたり減ったりするので、理解するのは難しいです。またdefault値も変わるので、versionがあがるたびに変数の設定を見直す必要があります。

途中参加したプロダクトだと、mysqlのサーバーシステムの変数が初期から変わっていなく、古のファイルとして受け継げれていることがままあります。最初に設定した人がきっとカリカリにチューニングしてくれたのでしょう。しかし、defaultの変数はversionがあがるたびに変わるので、最新のdefault値のほうが良いということはあります。

一番良いのは、あまり設定しないことです。

日本語対応や、監視用の設定、サーバーの設定など最低限必要な設定はあるのですが、それ以外はdefault値のままで良いと思います。
特にRDSの場合は、インスタンスサイズに合わせて変動する値もあったりするので(例: innodb_buffer_pool_size {DBInstanceClassMemory*3/4})

設定が終わったら
slow queryになるSQLを実行したあとに、
```
SHOW WARNINGS;
```
をして何も問題がないか確認しましょう。または`--show-warnings`をオプションにつけて起動してください。

メモリがそもそも足りなくて、swapが発生しているとかがあった場合は、メモリを増やすなどのインフラの対応が必要になります。

### 最後に
上記が終了したあとに、slow query logを調査をすると良いと思います。
以上、インフラ視点でslow queryを調査する方法でした。参考になれば幸いです。
基本情報技術者試験に合格しました

# はじめに
誰かの参考になればとやったことを簡単にまとめておきます。

筆者のスペック
* プログラミング歴3か月
* 現場経験無し

勉強時間、内容
* 3週間
* 参考書
* 午前問題過去問7回分(基本情報4回、応用情報3回)
* 新制度サンプル問題

正式な合格発表は1か月後ですが科目A 855/1000、科目B 1000/1000でした。旧制度に比べて易化したといわれる基本情報技術者試験ですが科目A(午前問題)については問題数が減っただけで難易度自体は変わっていないような気がします。

# 勉強法
### 科目A
無難に参考書と過去問をやっていきます。どちらかというと論理より知識が重要な試験ですし参考書は何を使っても平気だと思います。私は将来受験することを見据えて応用情報技術者の参考書を使いました。過去問はやはり過去問道場がおすすめです。

https://gihyo.jp/book/2022/978-4-297-13158-6

https://www.fe-siken.com/fekakomon.php

なるべく早く過去問に触れてみるのが重要ではありますが、最低限何が問われているのかを理解できるようになるためにもIT系初学者の方は駆け足でいいので参考書を一周読んでみるといいかもしれません。
それ以降はひたすら過去問を解いて解説を読んでいき、全体的に知識が足りてないと感じる分野は参考書で体系立てて学び直すといった流れです。
基本的に出る問題はある程度パターン化されているので過去問で75%以上正解できるようになれば合格自体はまず問題ないと思います。ただ実際の試験では過去問でも参考書でも見たことがない用語についての説明を求められる問題もあったので高得点を狙うのは結構難しいかもといった印象です。

### 科目B
問題の8割が擬似言語を使ったアルゴリズムの問題、2割がセキュリティの問題になります。こちらは過去問に相当するものがIPAが公開しているサンプル問題しかないです。
セキュリティは科目Aの勉強をちゃんとしてあれば解けるような問題ばかりです。これといった対策は必要ないと感じました。
アルゴリズムの対策ですが21問のサンプル問題でとにかく出題形式慣れましょう。特に疑似言語での記法に慣れておくといいです。実際の試験ではサンプルとほとんど同じ内容のものが数値や表現が若干変わりながら出るのでサンプルを何も見ずに理解しながら解答できるようになってれば大丈夫でしょう。
# 当日の流れ
CBTテストセンターでパソコンを用いての受験となります。当日は受付で本人確認後パソコンの操作確認をしたら順次試験開始となります。試験時間は科目A90分、休憩10分、科目B100分です。一度試験を始めたら休憩まで退室できないのでトイレは先に済ませておきましょう。試験室には私物を持ち込めず、メモなどには会場から貸し出されるボールペンと紙を使います。試験終了は受験生の裁量で行えるので科目Aを早めに切り上げて科目Bに移ることも可能です。

# 最後に
ここまで読んでいただきありがとうございました。
情報技術者の勉強はただ漠然とプログラミングをしているだけでは学べないことも多く学べたので良かったです。
応用情報技術者試験も頑張ろうと思います。
メリットだらけの趣味「プログラミング」を始めよう

#### 初めに
自分の所属する企業はIT企業じゃないので、IT関連の部署にはIT未経験の人が多くいます。そんな彼ら/彼女らも基本情報技術者試験の勉強などでQiitaに触れることが多いみたいです。
そこで、本記事では偶然Qiitaを訪れたIT未経験者向けに、昔何かで書いた「趣味としてのプログラミング」を布教する文章を掲載します。

### 趣味「プログラミング」という選択肢
　世の中の大人たちの中には趣味がなくて困っているという人が多い。実際、私の会社の自己紹介でも自分には趣味がないという人が多くいた。趣味がないことは悪いことではない。しかし、趣味を持っていないという人に話を聞いてみると、多くの人が趣味を見つけたがっているということがわかった。
　新しい趣味を始めようにも、どんな趣味を始めるべきかわからない。どうせなら、得られるメリットが大きい趣味を始めたいという人は多いのではないだろうか。社会人は日々仕事に追われていて、趣味に使える時間は少ない。そんな少ない時間を割いて行う趣味は、ただ楽しいということの他にも、多くのものが得られる物であってほしいと思うのは当然のことである。そこで私は、「プログラミング」という趣味をおすすめする。趣味としてのプログラミングは、楽しいだけでなく様々なスキルを身につけることができる非常に実用的な趣味であるため、趣味にも実用性を追い求める人におすすめの趣味である。本記事では、趣味としてのプログラミングの素晴らしさを解説していく。

### 趣味「プログラミング」によって得られるスキル
　現代において、プログラミングスキルは非常に重要なスキルである。プログラミングのスキルを持った人を求めている企業は山ほど存在する。ITエンジニアの求人倍率は2023年8月の段階で10倍以上である。こうした状況を受け、数年前から日本では義務教育の中にプログラミングが取り入れられるようになった。数年後には若者全員が当たり前のようにプログラミングスキルを持っている世界になる。
　プログラミングを趣味とすることで、エンジニアにならなくてもプログラミングスキルを身につけることができる。もちろん、「プログラミングスキル」と一口に言っても、その種類は様々である。スマホスキルを開発するスキル、webサイトを開発するスキル、競技プログラミングに代表されるようなアルゴリズムのスキルなど、様々なスキルがあるが、どれも多くの場で必要とされているスキルである。
　こうした引く手数多のスキルを身につけることは安心感に繋がる。未経験OKのエンジニア系の転職サイトに登録しポートフォリオを公開していると、毎日のようにスカウトが来るようになる。それだけ多くの企業がエンジニアを欲しているということだが、このように多くの企業に求められるスキルを持っていると、（自惚ではあるが）最悪いつでも転職できるという安心感を持つことができる。そうすれば、現在のお仕事にも落ち着いて向き合うことができ、今まで以上の成果を出せるようになるのではないだろうか。

### 趣味「プログラミング」は他人にアピールすることができる
　プログラミングを趣味にしている人は割と少ない。エンジニアが周りにあまりいない環境であれば、多くの人はプログラミングと無縁の生活を送っている。あなたは休日に「スマホアプリの開発」や「競技プログラミング」を行っているという人をどれだけ見たことがあるだろうか。私は自分以外にこうしたことを趣味としている人を聞いたことがない。少なくとも私の周りでは、「プログラミング」は大変珍しい趣味であるといえる。
　また、プログラミングは非常に実用的な趣味である。上記で示したように、プログラミングは趣味を通して実用的なスキルを鍛えることができる。これだけでも十分にプログラミングは実用的な趣味であるといえるが、さらにプログラミングを趣味とすることで本業とは別の収入を得ることを目指すこともできる。スマホアプリやwebサイトなどの開発ができれば、それを利用した何らかのビジネスを始めることができる。難易度はもちろん高いが、多くの趣味に比べてプログラミングは趣味で副収入を得るハードルは低いように思われる。
　このように、趣味「プログラミング」は非常に珍しく且つ実用的な趣味であるため、自己紹介の際などに少しだけアピールすることのできる趣味である。いつも自己紹介時に「少しでも他の人の記憶に残るような自己紹介がしたい」「自分のことを目立たせたい」と思う人は、ぜひ趣味「プログラミング」を始めてみてほしい。私の感覚としては、趣味としてプログラミングを行っていると話せば９割以上の人が食いついてくる。

### プログラミングはハマればとにかく楽しい
　どんな趣味にも言えることだが、プログラミングは一度ハマってしまえば楽しくて仕方がない趣味である。プログラミングの楽しさにはいくつか種類があるが、ここでは「論理的に物事を組み立てる楽しさ」と「自分のアイディアを形にする楽しさ」を紹介する。
　「論理的に物事を組み立てる楽しさ」とは、「正解を見つける楽しさ」にとても似ている。私たちが日々生活している社会は、大抵の場合明確な「正解」が存在しない。白黒はっきりつけられない問題にぶつかり、モヤモヤしながら結論を出すということを繰り返している。一方でプログラミングにはほぼ常に明確な「正解」が存在する。論理的に合っていれば思ったものが作れるし、想像通りにいかない場合は論理的にどこか間違っているということになる。絶対にどこかにある「正解」を見つけようとする行動は、時には大変なこともあるが、その「正解」を見つけられた時には大きな達成感を味わうことができる。
　「自分のアイディアを形にする楽しさ」は、「こうあったらいいな」を実現するところから生まれる。毎日いろいろなスマホアプリやwebサイトを使っていて、「こんな機能があったらいいのに」と思ったことはないだろうか。プログラミングはその思いを実現することのできる活動である。自分の中にあるアイディアや「こんなアプリが欲しい」という思いをプログラミングは現実のものにしてくれる。自分の理想が実現した際の喜びはえも言われぬものであるが、これはぜひプログラミングを始めて味わってみてほしい。

#### 終わりに
偶然Qiitaを訪れたIT未経験の方が、この記事を見て少しでもプログラミングに興味をもってくれると幸いです。「面白そう」と思ったなら、udemyで「プログラミング」って調べてみると、わかりやすい学習講座がたくさん出てくるので、是非初めてみてください。

汚い文章でしたが、最後まで読んでいただきありがとうございました。
【メモ】Web関連用語

## はじめに
[『プロになるためのWeb技術入門』――なぜ，あなたはWebシステムを開発できないのか](https://www.amazon.co.jp/%E3%80%8E%E3%83%97%E3%83%AD%E3%81%AB%E3%81%AA%E3%82%8B%E3%81%9F%E3%82%81%E3%81%AEWeb%E6%8A%80%E8%A1%93%E5%85%A5%E9%96%80%E3%80%8F%E2%80%95%E2%80%95%E3%81%AA%E3%81%9C%EF%BC%8C%E3%81%82%E3%81%AA%E3%81%9F%E3%81%AFWeb%E3%82%B7%E3%82%B9%E3%83%86%E3%83%A0%E3%82%92%E9%96%8B%E7%99%BA%E3%81%A7%E3%81%8D%E3%81%AA%E3%81%84%E3%81%AE%E3%81%8B-%E5%B0%8F%E6%A3%AE-%E8%A3%95%E4%BB%8B-ebook/dp/B09MVGM99L/ref=sr_1_1?crid=2RUFI5FRBVD4D&keywords=web%E6%8A%80%E8%A1%93%E5%85%A5%E9%96%80&qid=1645489804&sprefix=web%E6%8A%80%E8%A1%93%2Caps%2C205&sr=8-1) 

を読んで、個人的にWeb開発を行う上で整理しておきたい以下の用語についてまとめておきます。

- Stateful / Stateless
- Request / Responce
- Cookie
- Protocol
- Port

## Stateful / Stateless

Webの世界では、しばしば「セッション情報を保持する」プロトコルと表現する際に「ステートフル」という形容詞を用いる。
※ステートフルの対義語は「ステートレス」である。

FTPなどは、FTPサーバと前後の通信の内容を保持しながら通信するため、ステートフル・プロトコルと呼ばれる。

一方、HTTPはサーバとの通信が1度で終了し、前後の通信の内容を保持しないため、ステートレス・プロトコルと呼ばれる。

## Request / Response

クライアントがWebサーバに必要な情報を要求することをリクエスト、サーバがそのリクエストに応じた情報を返すことをレスポンスと呼ぶ。

スマホのブラウザでWebサイトにアクセスすると、ブラウザがWebサーバに対して「HTMLをください！」と依頼する、これはリクエストにあたる。

リクエストに対して、Webサーバがスマホに対して「ほらよ！」とHTMLファイルを返す、これはレスポンスにあたる。

## Cookie

HTTPなどのステートレスな通信において、ステートフルに通信するための技術をCookieと呼ぶ。

具体的には、WebサーバからクライアントへHTTPレスポンスのヘッダを利用して、「名前 = 値」の組み合わせで情報を送信することである。

クライアントは、次回同じWebサーバにアクセスする際に、一度発行したCookieをそのままHTTPリクエストのヘッダに入れて送信する。Webサーバ側は、Cookieを利用してアクセスしてきた相手がどのような人物か判断する。

ゆえに、Cookieを使用するとステートレスなHTTP通信でステートフルに通信することが可能となる。

## Protocol
ネットワークに接続された通信機器がデータを送受信する際に、定められている約束事のようなもの。

現在、HTMLの転送に適したプロトコルとして「HTTP（Hyper Text Transfer Protocol）」が幅広く利用されている。

## Port
クライアントがアクセスする際のWebサイトのURLには、ポート番号が省略されている。なお、使用頻度の高いプロトコルには標準でポート番号が決まっている（well-known ports）。

これは、Webサイトアクセス時、TCP/IPによってWebサーバ側でパケット受信した際に、パケットがどのようなプロトコルのものであるか、どのようなアプリケーションで処理すべき分からないため、必ず「待ち受けポート」を決めてリクエストを待つ仕様となっている。
はじめてのNode-RED-MCUは電動自転車に乗った時のようなラクちんさ

# はじめに

こちらはNode-REDのカレンダー | Advent Calendar 2023 - Qiita、22日目の記事です。
@mshioji さんからご紹介いただき、初心者ですが、記事を書かせていただいております。
Qiitaでの投稿も初めてとなります。読みにくい点もあろうかとは思いますがどうぞご容赦くださいませ。

2023年の大きな収穫のきっかけとなったのは、4月に参加したMaker Faire Kyoto 2023に参加したことです。ここで@mshioji さんとの出会いがあり、クラフトルームを使わせていただくようになりました。
当初はレーザー加工機をお借りして、ミニ百葉箱のキットを作成していました。

https://note.com/bbd/n/nb9b468a5887e

その時々でNode-RED-MCUのチャレンジはしていたのですが、まだ本腰が入っていませんでした。
なんとなく、今シーズンが終わった11月、新たなチャレンジをはじめました。

まずは、Raspberry Piを用意し、その上で、Node-REDを動かし、さらにMCU Editionまで動かす。というものです。

# 環境の設定

https://note.com/bbd/n/na539d06e659e

数回にわたるリセマラを乗り切り、ようやく環境を手に入れました。Raspberry Piも初めてで、Node-RED-MCUも初めて。
Node-REDはinject-debugを試したぐらい。
ここからのスタートです。

# モックアップの作成

https://note.com/bbd/n/n96608e655e47

とにかく何かをしなければと思い、実現できそうなものというより、できればいいなと思うものを作ってみることにしました。
自動水やり装置の焼き直しですが、仕組みを理解しているので、実装はとても簡単でした。
ここで、Node-REDを少し理解できた気がします。

# 実際の装置作り

https://note.com/bbd/n/n4b715d8b6578

モックアップから実際の装置つくりまで数回コケましたがそれでも、今までの装置作りと比べると断然ラクです。

こちらが今回作成した機器の構成図になります。
![SALZ mini MQTT111.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/604159/641b9d82-2b9f-fa13-ef8e-f94ad9d4519e.png)

これから長期の稼働テストを行っていきたいと思います。

# 何がよかったのか？

少し冷静になって振り返ってみます。
思う所は３つあります。

## Node-RED-dashboardが秀逸

私が今まで経験したプログラミング言語の考え方では、UIのオブジェクトを設計し、そこにイベントハンドラをぶら下げておいて、実際にイベントが流れてくるのを待ち構えています。

イベントの通り道を予測して、形つくっておくイメージです。

Node-RED-dashboardでは、基本的なオブジェクトをノードとして混ぜ込んでおいて、それぞれのフローを考えながら流れを変えていくことができます。

砂場で山の上から水を流して、その流れを見ながら、仕掛けを変えていくことができるようなイメージです。

## メッセージの流れを意識するだけでよい

以前作ったSALZ mini 2022では同時に様々な割り込みに対応し複雑なアクションをこなすため、状態遷移表を作成し作りこみました。

https://note.com/bbd/n/n46ceb7d10638

これはこれでやり切った感はありましたが、もうこれ以上手を入れることができません。メインテナンス性が著しく悪いです。

Node-REDではメッセージの流れを意識するだけでよく、プログラムの可読性も非常に良いです。

## Node-RED-MCUのデバッグ環境が秀逸

neopixelsのサンプルを試していて、injectのボタンを押すと、MCUのLEDが点灯する仕掛けが理解できませんでした。

![2023-12-18 23_18_04-Node-RED _ Examples_Neopixels.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/604159/5a965c3d-5d8b-0e1e-494b-00ca59249c47.png)
「はじめてのNode-RED MCU Edition」より引用

それ程よくできているな、と思います。

# おわりに

タイトルにも書かせていただきましたが、はじめてのNode-RED-MCUは電動自転車に乗った時のようなラクちんさで、このような楽しい体験は久しぶりです。
Node-RED-MCUの環境構築が難解でしたが、そこさえ乗り切れれば、これは素晴らしいツールだと思いました。
これからも、少しずつですが、盆栽向けの装置作りをこのNode-RED-MCUを使って進めて行こうと思います。
生成aiの代表的な論文に自作のGPTsで簡易化して見る。

About GPTs

使ったのは、Visually Engagement COです。
GPTs Storeなどで利用可能です。

Find the best GPTs & Plugin List of ChatGPT | GPTStore.AI
Discover the best ChatGPT GPTs & plugins for AI at GPTSto
gptstore.ai
https://gptstore.ai/

prompt
Reconstructure attached thesis about generative ai to be readable easily due to the visually tecnique.

Result
The thesis you've provided, titled "Attention Is All You Need," is a comprehensive paper on the Transformer model, a significant advancement in the field of generative AI. To restructure it for easy readability using a visually engaging technique, I will provide a simplified and structured summary with key points and visual markers.

🔍 Abstract & Introduction

Key Idea: Introduces the Transformer model, which relies solely on attention mechanisms, eliminating the need for recurrent or convolutional layers.

Advantages: Demonstrates superior performance in machine translation tasks, being both more parallelizable and efficient in training.

📐 Model Architecture

Encoder-Decoder Structure: Follows this conventional structure but uses self-attention and point-wise, fully connected layers.

Innovations: Incorporates multi-head attention, allowing the model to process different parts of the sentence simultaneously.

🔬 Attention Mechanism

Scaled Dot-Product Attention: Central to the model, it computes the attention function on a set of queries simultaneously.

Multi-Head Attention: Uses several attention mechanisms in parallel to capture different context aspects.

🚀 Training & Results

Datasets: Trained on WMT 2014 English-German and English-French translation tasks.

Performance: Achieves state-of-the-art results, outperforming previous models with less training time.

🎯 Conclusion

Significance: Marks a shift towards attention-based models in natural language processing.

Future Work: Suggests potential applications beyond text, like images, audio, and video.
今年もお世話になったジェネレーターやプラグインたち

こんにちは、中村です。
18日に書いたばかりですがまたお邪魔します。

今年もあとわずかですね。
今年はとにかく忙しくて、あっという間に過ぎてしまいました。
乗り越えてこられたのは、さまざまなジェネレーターやプラグインたちのおかげだなぁと思ったので、感謝を込めてご紹介します。
昔から使っているものも多いので定番のラインナップになりそうですが、気になるものがあればぜひお試しください。

## CSS

Figmaを使っているといらなくなるかも知れませんが、いざという時の強い味方です。

### Layoutit Grid

https://grid.layoutit.com/

いきなりド定番ですね、いいかげん自分で書けるようにならなきゃな、と思いつつ、あれこれ書かないといけないものは頼ってしまいます。

### Clippy
https://bennettfeely.com/clippy/

clip-pathのジェネレーターです。
吹き出しのしっぽなどはもうborderは使わないでclip-pathで作ります。角度が少し変わった形も簡単です。

### cssgradient

https://cssgradient.io/

グラデーションのジェネレーターです。簡単で助かります。


## JavaScript
### Swiper
https://swiperjs.com/

カルーセルの定番プラグインですね。
イベントも充実しているのでこの後紹介するアニメーション用のプラグインと組み合わせると表現の幅が広がります。

### Shuffle.js
https://vestride.github.io/Shuffle/

ソートやフィルター機能を実装できるプラグインです。
使い方は以前記事を書いたので弊社のブログをお読みください。

https://tech.arms-soft.co.jp/entry/2020/09/16/090000

### ScrollHint
https://appleple.github.io/scroll-hint/

横にはみ出す要素を横スクロールできるようにしてくれます。
何が入ってくるかわからない、CMS管理の記事詳細などに使っています。



## アニメーション
### GSAP
https://gsap.com/resources/get-started/

これも定番のプラグインなんじゃないかと思います。
スクロールアニメーションなどはCSSでもできるようになっていきますが、
タイムラインを活用すると細かいアニメーションや用意したタイムラインアニメーションを任意のタイミングで実行できるのが素晴らしく便利です。
先ほど紹介したSwiperと組み合わせると、スライドを変えたタイミングでアニメーションを実行、などということもできます。
最近リバースできることも知りました。開閉時のアニメーションなんかも作れてしまいます。
すごいです。

すごいけれど色々出来すぎてとっつきにくいです。
自分のメモがわりにブログを書いていますのでよかったらどうぞ。

https://tech.arms-soft.co.jp/archive/category/GSAP

チートシートもあります。

https://greensock.com/cheatsheet/


## これからお世話になりたいプラグイン
https://markuplint.dev/ja/

先日の朝までマークアップで知りました。
マークアップのチェックをしてくれます。VSCodeのプラグインです。
自宅のPCには入れて試して、これは入れるべきだ・・と実感したので実務にも導入していきます。


## 最後に
来年もお世話になります。いつもありがとう。
Pythonで「リストに指定した値と同じ要素が含まれているか確認する」の動作を確認してみた

# 概要

Pythonで「リストに指定した値と同じ要素が含まれているか確認する」の動作を確認してみました。以下のページを参考にしました。

https://www.javadrive.jp/python/list/index10.html

# 実装

以下のファイルを作成しました。
```sample.py
mylist = ["A", "B", "C", "D", "E"]
print("B" in mylist)
print("G" in mylist)

mylist = ["A", "B", "A", "A", "C"]
print(mylist.count("A"))
print(mylist.count("B"))
print(mylist.count("D"))

mylist = ["A", "B", "A", "A", "C"]
print(mylist.index("A"))
print(mylist.index("B"))
print(mylist.index("C"))
#print(mylist.index("D"))
```

以下のコマンドを実行しました。
```
$ python3 sample.py 
True
False
3
1
0
0
1
4
```

# まとめ

何かの役に立てばと。
AlmaLinux9環境にSSH公開鍵認証接続する

## はじめに
CentOS7系の運用環境をAlmaLinux9に更新したのに併せてAlmaLinux9の個人用開発環境をビルドした際に得た知見を備忘のため記します。

## 環境
* 仮想環境
* AlmaLinux 9.3
* openssh 8.7p1

## 接続用ユーザーの作成と公開鍵の配置
作業用のユーザーを作成し、公開鍵を配置します。鍵ペアは以前から使用しているもののため作成済みです。
```
# useradd -u 1001 -G wheel uta
# mkdir /home/uta/.ssh
# echo 'ssh-rsa 【公開鍵のテキスト】' > /home/uta/.ssh/authorized_keys
# chown uta.uta /home/uta/.ssh
# chmod 700 /home/uta/.ssh
# chmod 400 /home/uta/.ssh/authorized_keys
```

## 接続テスト
コンソール接続を試みたところ、公開鍵認証に失敗しました。
```
Using username "uta".
Server refused our key
uta@192.168.xx.xx's password:
```

調べてみたところ、openssh 8.8 から RSA署名での鍵ペアによる公開鍵認証をデフォルト拒否する [^1] ようになったようです。

## ED25519署名の鍵ペアを作成
新規の個人用環境のため、新たな鍵ペアを作成することにしました。
```
# su - uta
$ ssh-keygen -t ed25519
$ cat .ssh/id_ed25519.pub >> .ssh/authorized_keys
```

## 接続テスト2
作成された秘密鍵をホストOS側に移して、改めてコンソール接続を試みたところ、無事に接続できました。
```
Using username "uta".
Authenticating with public key "ed25519-key-20231217"
$ 
```

[^1]: 厳密にはopensshが拒否するのはSHA-1アルゴリズムを用いたRSA署名だけですが、現状では全てのRSA署名の鍵ペアで接続ができないようです。
参考: https://nulab.com/ja/blog/backlog/disables-rsa-sig-using-the-sha-1-in-openssh/
カレンダーの日付を取得

## はじめに
学習の備忘録として残します。ご指摘等がございましたら教えていただけますと嬉しいです。
現在Googleカレンダーを作成しています。
使用したライブラリはdayjsです。

## 実装
### 前月の日付の計算
```js
import dayjs, {Dayjs} from "dayjs";
import ja from "dayjs/locale/ja"
dayjs.locale(ja);

const Calendar = {
  // 今日の日付を取得
  const today = dayjs();

  // 前月の日付を取得
  const startDay: number = today.startOf("month").day();

  const lastDayOfLastMonth: number = today
    .subtract(1, "month")
    .endOf("month")
    .date();

  const daysFromPreviousMonth: Dayjs[] = Array(startDay)
    .fill(null)
    .map((_, index) => {
      return dayjs(
        new Date(
          today.year(),
          today.month() - 1,
          lastDayOfLastMonth - startDay + index + 1
        )
      );
    });
  return <div></div>
};
```
前月の日付の取得のところを詳しく説明していく
```js
  const daysFromPreviousMonth: Dayjs[] = Array(startDay)
    .fill(null)
    .map((_, index) => {
      return dayjs(
        new Date(
          today.year(),
          today.month() - 1,
          lastDayOfLastMonth - startDay + index + 1
        )
      );
    });
```
ここでは新しくdayjsのオブジェクトを作っている。
例えば、前月が30日（火）だとした場合
水曜日は日曜日を０だとした場合は３であるから
・日曜日の日付：30 - 3 + 0 + 1 = 28
・月曜日の日付：30 - 3 + 1 + 1 = 29
・火曜日の日付：30 - 3 + 2 + 1 = 30

### 現在の日付の実装
```js
  const nowMonth = dayjs().daysInMonth();
  const daysFromNowMonth: Dayjs[] = Array(nowMonth)
    .fill(null)
    .map((_) => {
      return dayjs(new Date(today.year(), today.month(), index + 1));
    });
```
現在の日付の日数を取得する。そして前月と同じようにデータをまとめる。
### 来月の日付の実装
```js
  const nowMonthFinish: number = today.endOf("month").day();
  const nextMonthLengh: number = 6 - nowMonthFinish;
  const daysFromNextMonth: Dayjs[] = Array(nextMonthLengh)
    .fill(null)
    .map((_, index) => {
      return dayjs(new Date(today.year(), today.month() + 1, index + 1));
    });
```
現在の月の終わりが何曜日か取得する。
そしてmap関数で来月の曜日を入れていく。

### 最後に全ての日付を配列に入れる
```js
  const calendarArray: Dayjs[] = [
    ...daysFromPreviousMonth,
    ...daysFromNowMonth,
    ...daysFromNextMonth,
  ];
```
## おわりに
ロジックを考えることに慣れていないので練習として丁寧にやっていきました。
関数名も適当になってしまっているので今後改善していくようにします。
pydubで音声再生するときの「Permission denied」【解決】

# `pip install simpleaudio`すれば治る！
[こちらの記事](https://wpchiraura.xyz/python_how-to-solve-when-permissionerror-errno-13/)にある解決方法そのままですが、これで解決するのが衝撃的過ぎて、備忘録を兼ねて記事にしました。
自己流エクセルでのVLOOKUP関数を使ったカレンダー作成

# 背景
何かとエクセルでカレンダーっぽいもの作りたくなる時ってあると思います。
作り方をググってみるといくらでも出てきますが、主要な手段は特定のセルに作成したい月の月初日を入力し、数式で＋１していくような作りが殆どなんじゃないかと思います。
ですがこの作り方だと「隔週でこういう処理を入れたい」という時、if文を使いすぎて一つのセル内の数式がくどく成りがちでした。
なので、私はROW()とCOLUMN()とVLOOKUP()を使ったカレンダーを用いています。
ググっても同じような奇行を取っている変態がいなかったので投稿してみることにしました。

# カレンダー関連の関数整理
日曜日を週の初めとします。
以下に記載する関数がカレンダー記述の基準となる関数です。
重要なのは`=WEEKDAY(A2)`と`=WEEKNUM($A2)-(WEEKNUM($A$2)-1)`です。
覚書ついでによく使う関数をいくつか記載しています。
（A2に日付が入力されているものとします。）

| 関数 | 目的 |
| - | - |
|`=TEXT(2023/12/1,"yyyy/mm/dd")`　※A2 | 入力した日付を指定の書式に変える |
|`=TEXT(A2+1,"yyyy/mm/dd")`　※A3～ | 基準日から月末までの日付 |
|`=TEXT(A2,"aaa")` | 日付に対して曜日を返す |
|`=WEEKDAY(A2)` | 曜日を数字に置き換えたもの<br>オプションで週の初めの曜日も指定できる |
|`=COUNTIF($C$2:C2,C2)` | その月での何番目の曜日かを返す<br>第１日曜日、第２日曜日・・・ |
|`=WEEKNUM($A2)-(WEEKNUM($A$2)-1)` | その月での何番目の週かを返す<br>第１週、第２週・・・  |
|`=TEXT(EOMONTH(A2,0),"m/d")` | その月の末日を返す |
|`=TEXT(A2+7-WEEKDAY(A2,1)+IF(WEEKDAY(A2,1)<=1,-6,1),"m/d")` | 指定日付から見た次の日曜日 |

# カレンダー作成開始

上記の関数にて以下の表を作成。これを**表１**とします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/394613/fd65b0eb-9486-9088-4888-7cb1992c8ba7.png)

上記の表のE列とC列を`=E2*10+C2`という式で結合します。これを番地と呼ぶことにします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/394613/9a218312-2dc3-ae51-7bd6-a4190b1c5a0d.png)

次にROW()とCOLUMN()を使って以下のような表を作成します。**表２**とします。
今回はB2を基準に`=ROW()-1&COLUMN()-1`を入れています。
これをB2～H7までコピーして、同じ数式が入った状態にします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/394613/fc9a06f8-a70f-503f-5239-09a80a285569.png)

この上表で出力された２桁の数字ですが、この数字を番地と見立てます。
ここでVLOOKUP()を使って、番地を検索値として目的の値を持ってきます。
VLOOKUP()で呼び出す値を表１に作成します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/394613/b31436af-f5f4-13f4-658b-3edc9e739a50.png)

表２の数式を変更します。
`ROW()-1&COLUMN()-1`は素の状態だと文字列として処理されるので`VALUE(ROW()-1&COLUMN()-1)`とし、
`=VLOOKUP(VALUE(ROW()-1&COLUMN()-1),表１!$F:$G,2,FALSE)`という数式を入力します。
同じ数式でいいのでコピペが楽ちんです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/394613/9888cd1d-1927-4a63-2ae7-23f6365ca6ee.png)

エラーが気になるので、`=IFERROR(VLOOKUP(VALUE(ROW()-1&COLUMN()-1),表１!$F:$G,2,FALSE),"")`にします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/394613/794a1a1f-56e7-d1ad-0898-857d4f4f638a.png)


という具合でカレンダーを作成していきます。

サンプルとして第何曜日を表示させます。
今回はCHAR(10)を使って改行させて、`=G2&CHAR(10)&H2`を戻り値にします。
表１
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/394613/4a6968c7-ce13-239a-fa6f-2f968f25d63d.png)

表２
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/394613/5431bb41-38f8-f3e0-e69c-d4ad9eca953e.png)

# おわり
以上です。小ネタでした。
圧力容器の直径の変化量 第10章 薄肉圧力容器 基本例題10.04 p338「材料力学演習(20221021)」をsympyでやってみたい。(英:thin wall structure）

# オリジナル
[基本例題10.04 p338](http://zairikiweb.starfree.jp/zai_enshuh/zai_enshuh_ver.3.3.pdf#page=343)＜[「材料力学演習(20221021)一括(ver.3.3)」を勉強したい。#sympy](https://qiita.com/mrrclb48z/items/c3274daf5f7a99cfe027#%E4%BD%9C%E6%A5%AD%E4%B8%AD%E7%A7%81%E3%81%AE%E8%A7%A3%E7%AD%94sympy)
　　　　　　　　　　？？？タブレット等で、pdfを開く事ができないかも。？？？　
[←基本例題10.01 p335](https://qiita.com/mrrclb48z/items/cf778b34a610e44b9edb)

# sympyで
```python
from sympy import *

var('εt,D,ΔD'      ,real=True)
var('σt,σx,v,E,p,t',real=True)
def myEq_RepLR(eq):
     return {eq.lhs:eq.rhs}
eq1=Eq(εt,(pi*(D+ΔD)-pi*D)/(pi*D))           ;print("#",eq1)
eq1=Eq(eq1.lhs,eq1.rhs.simplify())           ;print("#",eq1);print()
# 
eq2=Eq(εt,σt/E-v*σt/E)                       ;print("#",eq2)
rep=myEq_RepLR( Eq(σt,D*p/(2*t)))           #;print(rep)
eq2=Eq(eq2.lhs,eq2.rhs.subs(rep).factor())   ;print("#",eq2);print()
# 
ans=solve(eq1,ΔD)[0]                         ;print("#",ans)
eq3=Eq(ΔD,ans)                               ;print("#",eq3)
rep=myEq_RepLR(eq2)                         #;print(rep)
eq3=eq3.subs(rep)                            ;print("#",eq3)
# Eq(εt, (-pi*D + pi*(D + ΔD))/(pi*D))
# Eq(εt, ΔD/D)

# Eq(εt, -v*σt/E + σt/E)
# Eq(εt, -D*p*v/(2*E*t) + D*p/(2*E*t))
# Eq(εt, -D*p*(v - 1)/(2*E*t))

# D*εt
# Eq(ΔD, D*εt)
# Eq(ΔD, -D**2*p*(v - 1)/(2*E*t))
```
# いつもの? sympyの実行環境と 参考のおすすめです。
(テンプレート)

https://qiita.com/mrrclb48z/items/00dd08b0317069be9342
基盤地図情報の DEM1A を Windows の 3D ビューアーで覗いてみた

# はじめに

今年の10月末に国土地理院から [基盤地図情報（数値標高モデル）１ｍメッシュ（標高）の提供開始](https://www.gsi.go.jp/gazochosa/gazochosa61002.html) が予告され、11月末から[基盤地図情報ダウンロードサービス](https://fgd.gsi.go.jp/download/mapGis.php?tab=dem) を通じて **DEM1A** として提供が開始されました。せっかくなので Windows にデフォルトでインストールされている 3D ビューアーで簡単にプレビューしてみましょう。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/82494/7cc6c577-6254-f8bf-3456-4c5f541c2451.png)

※ 本記事の執筆時点では **東北地方太平洋沿岸部** が公開対象となっています

# できあがり

以下のような3次メッシュコード **57414044** の領域を

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/82494/6029c15e-f254-e7ff-bf89-b2a44a82e5b9.png)

このようにプレビューできました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/82494/39aa600a-8761-953a-3e35-7e32ffe03858.png)

実際の段取りは以下の通りです。

1. [基盤地図情報ダウンロードサービス](https://fgd.gsi.go.jp/download/mapGis.php?tab=dem) から 1m メッシュのオプションを選択してメッシュコード **574140** をえらんでダウンロード (要ログイン・アンケート)
2. **FG-GML-5741-40-DEM1A.zip** のような zip がダウンロードされるので展開
3. **FG-GML-5741-40-44-DEM1A-20230929.xml** のようなファイル名の XML が収録されていることを確認
4. <https://frogcat.github.io/dem1a-to-3mf/> をブラウザで開き、ファイルアップロードボタンを押して **FG-GML-5741-40-44-DEM1A-20230929.xml** を選択
5. 20秒程度待つと **FG-GML-5741-40-44-DEM1A-20230929.3mf** がダウンロードされる
6. 同ファイルを Windows の **3Dビューアー** で開く

# 解説

## DEM_1A

基盤地図情報ダウンロードサービスからは 3次メッシュコード(だいたい1km四方) 単位で整備された XML/GML として DEM_1A のデータが入手可能です。
基盤地図情報の仕様は [基盤地図情報ダウンロードサービス>各種資料](https://fgd.gsi.go.jp/download/documents.html) の中の **基盤地図情報ダウンロードデータファイル仕様書5.0** に定義されています。2023/11/30 に更新されていて、DEM1A に関する情報も追加されています。

ただ DEM_1A といっても仕様上は大きな差異はありません。[基盤地図情報～数値標高モデルを利用する](https://qiita.com/tobira-code/items/43a23362f356198adce2) の情報などを参考に、DEM5 や DEM10 と同様に取り扱えるかと思います。

※ もしかすると従来の各種変換ツールやプラグイン等で DEM_1A の XML をそのまま利用できる可能性も

## 3MF

[Windows の 3D ビューアー](https://apps.microsoft.com/detail/9NBLGGH42THS?rtc=1&activetab=pivot%3Aoverviewtab&hl=ja-jp&gl=JP) が対応するフォーマットは以下の通りです。

> 一般的な種類の 3D ファイル (FBX、STL、OBJ、GLB、GLTF、PLY、3MF) を高品質なステージングで表示できます。

この中で最も後発の [3MF](https://ja.wikipedia.org/wiki/3MF) は以下のような特徴があります

- Zipped XML(s)
- 色や素材の表現に対応
- STL などと比べて軽量

とりあえず XML をいくつか作って zip できれば作れそう、という気軽さです。

## DEM_1A to 3MF 変換

前述の通り XML(GML) を読んで XML(3MF) を生成して zip に圧縮できさえすれば、どんなプラットフォーム・言語でも問題なく実装できそうです。

上の手順では、ブラウザの JavaScript だけで動く変換の実装を用意しています。詳細が気になる方は <https://github.com/frogcat/dem1a-to-3mf>  をご覧ください。200行足らずの単ページ HTML+JS です。

※ ちなみに所要時間が長いのはブラウザの zip 圧縮が遅いせいです

# まとめ

基盤地図情報 DEM_1A の簡単なプレビューでした。
今後提供エリアの拡大や標高タイルの提供なども期待できそうですね！
会社の生成AI普及コミュニティを紹介します

# はじめに
私は、神戸のとある診断薬を製造している工場に勤務している平社員です。データサイエンスは未経験です。普段は、ExcelのVBAを色々いじって業務効率化をやっています。データラーニングギルドには、昨年からひっそりと加入させていただいておりました。訳あって、データラーニングギルドのコミュニティマネジメント研修に参加させていただき、今回初めてアドベントカレンダーにも参加させていただくことになりました。
私自身はデータサイエンスや生成AIにはあまり詳しくなく、何を記事にすればと迷いに迷いました。会社に Generative AI　普及コミュニティがあるのですが、今回はこちらの活動内容を紹介しようと思います。私自身は、途中からこちらのコミュニティに参加させていただき、メインで活動されている運営メンバーのお手伝いを微力ですがさせていただいております。

# 本記事のアウトライン
記事の内容は、以下の順番となっております。
1. コミュニティ活動のまとめ
1. Generative AI 普及コミュニティの活動内容（5月発足〜8月）
1. Generative AI 普及コミュニティの活動内容（9月〜現在）
1. 今後の活動

# コミュニティの活動のまとめ
今回紹介するコミュニティには、「社内のChatGPT（もしくは生成AI）の活用を推進したい」、「（生成）AIに強い人材を増やしたい」と言う目標があります。様々な活動を行ってきましたが、単なる呼びかけ「生成AIはこんなことが出来ますよ」「こんなセミナーありますよ」では、関心は持ってセミナーにも参加してくれますが、それ以降に繋がらないです。それ以降というのは、実際に自分で生成AIを使ってくれる人が増えない、セミナーに参加していない人に波及していかない、です。その為、途中からAIコンサルの活動を進めて行ったのですが、こちらの方が、自分の業務に直結して考えやすいのか、自分で実際に使ってくれる人が増えてくれました。
今後も、社内へのAI普及を続けていく予定です。ただ、現時点では人手不足でもあり、今後は、AI普及の協力者をどうあつめるか、も考えていくつもりです。

# Generative AI 普及コミュニティ発足 〜　8月まで

### 活動内容
Generative AI 普及コミュニティは、社内のデータサイエンティストや生成AIに詳しい人が有志で集まって、今年の5月に立ち上げました。私はただ何となく興味があってコミュニティに加入し、ROM専をしていたのですが、7月から運営のサポートメンバーとしても参加しました。以下はコミュニティの8月までの社内向けの活動内容です。

- 日本Microsoft社 を招いてのAzure Open AI セミナー（6月）
- ChatGPTによる新規事業創出ワークショップ（7月）
- STORIA社 柿沼先生を招いての AI法律相談会（7月）
- GitHub社を招いてのGithub Copilotのセミナー（8月）
- Generative AI 普及コミュニティ運営メンバーによる初心者向けワークショップ（月1の頻度）

上記にあるように、5月に発足して以来、セミナーを沢山開催しました。ChatGPTが世間で話題になって皆の関心を惹きやすい今を逃すまい、と短期間で実施しました。また、大手の会社を招くことで、"聞いたことあるなあるな"という感じで社内の生成AIへの関心・興味を引くことを目指しました。

### 活動した結果
8月までで、セミナー参加者が結構いたので、皆の興味を引くことが出来たかなって感じでした。ただ、いざ、実際に使用している人は何人ぐらいになるだろう？ってなると、そこまで使っている人はいないようにみられました。聞き取り調査を行うと、「実際に使うとなると、どこでどのように活用できるのか分からない。アイディア出し、ぐらい？ネットで調べるのと変わらないのでは？」って意見が多かったです。（本当に、一度も使ったことがない人が多かったです。セミナーには参加するのですが。。）

# 9月〜現在
### 活動内容
9月からは、趣向を変えて、社内での生成AI活用コンサルを行いました。生成AI活用コンサルを始めた目的は、まずは8月までの活動で生成AIに興味を持ってくれた人を対象に、実際に業務で使えるようなるまでをサポートし、社内での生成AI活用事例を増やすことです。社内での生成AI活用事例を増やすことで、元々関心のない人にも興味を普及させることを狙っています。他の活動は、社外向けのイベントを開催しました。
※私は詳しくないので、議事録作成だったり、初心者向けワークショップのチョイ講師役をしたりしかしてないです。

- 社外向けChatGPTオフラインイベント（9月）
- 生成AI活用コンサル（相談があったら随時）
- 社外向けChatGPTオフラインイベント（12月）
- Generative AI 普及コミュニティ運営メンバーによる初心者向けワークショップ（月1の頻度）

### 活動した結果
徐々にですが、実際に業務で使えたよ〜って事例が増えてきました。

# 今後の活動
社内AI活用コンサルをコミュニティの運営メンバーだけで回すのは限度があるので、コミュニティの運営メンバーの募集や、社内の各部署にAIに精通しAIを業務で使える人を増やすための活動を行おうと色々考案中です。運営メンバーの募集に関しては、「どんな人をコミュニティの運営メンバーとして選定するか（登壇するのが好きな人？社内のお偉い人に根回しするのが得意な人？最新技術情報をキャッチアップするのが好きな人？）」というのが現時点で悩んでいるところです。他の施策は、AI教育資料を作成したり、ChatGPT以外に、AIソフト（異常検知のための画像分析、時系列分析だったり）のハンズオンセミナーを開催予定です。
Copilot Chatでよく使う文言をショートカットキー登録したい（VSCode）

## 前提
VSCodeで[GitHub Copilot Chat](https://marketplace.visualstudio.com/items?itemName=GitHub.copilot-chat)の拡張を利用している方

## よく使う文言をVSCodeのキーショートカットに登録したい
オフィシャルで用意されていそうですが、設定方法をうまく見つけられませんでした。

非正規な方法だと思いますが、下記コマンドの引数でショートカットキー登録はできました
（2023/12/19時点では動く）

```json:VSCodeのkeybindings.json
[
    {
      "key": "cmd+l", // 任意のキー
      "command": "workbench.action.openQuickChat.copilot",
      "args": "@workspace 選択範囲のコードを保守性の観点で評価してください"
    }
]
```

---
この記事はAll About Group（株式会社オールアバウト） Advent Calendar 2023の19日目の投稿です。

https://qiita.com/advent-calendar/2023/allabout
MySQLクエリの結果を外部ファイルへ出力するシェルスクリプトを作った

##  はじめに

以下のコマンドを毎回手で打つのが面倒だったので、シェルスクリプトを作りました。

```shell
mysql -u user_name -p -h db_host_name db_name < fugafuga.sql 1> fugafuga.output 2> fugafuga.error
```

## 仕様

- 引数で**sqlのファイル名**を受け取る
  - sqlファイル名・標準出力ファイル名・標準エラー出力ファイル名は、`.拡張子` 以外は同一とする
- パスワードはファイルに書かず、別途手で入力する

## 作成したシェルスクリプト

```shell:execute_sql.sh
#!/bin/bash

if [ "$#" -ne 1 ]; then
        echo "Usage: $0 needs a sql file name (example: fugafuga.sql)"
    exit 1
fi

BASENAME="${1%.sql}"
DB_USER="user_name"
DB_HOST="db_host_name"
DB_NAME="db_name"

read -s -p "Enter MySQL password for user $DB_USER: " DB_PASSWORD
echo

mysql -u $DB_USER -p$DB_PASSWORD -h $DB_HOST $DB_NAME < "${BASENAME}.sql" > "${BASENAME}.output" 2> "${BASENAME}.error"
```

## 解説

### コマンドライン引数の数が1でなかったらエラーを出す

- `$#` が引数の数

    ```shell
    if [ "$#" -ne 1 ]; then
            echo "Usage: $0 needs a sql file name (example: fugafuga.sql)"
        exit 1
    fi
    ```

### 受け取ったファイル名から「.sql」を削除

- `${word%suffix}` で、wordからsuffixを削除
- `$1` は引数

    ```shell
    BASENAME="${1%.sql}"
    ```

### readコマンドでキーボードからの入力を受け取る

- `-s` は読み込んだ文字を画面に表示しない
- `-p` は読み込み前に文字列を表示
- 入力された文字列を`DB_PASSWORD`に代入

    ```shell
    read -s -p "Enter MySQL password for user $DB_USER: " DB_PASSWORD
    ```

### mysqlコマンドを実行

- `"${BASENAME}.sql"` のようにダブルクォーテーションで囲む
  - ファイル名に空白があったとしても1つのファイル名として正しく変数展開される

    ```shell
    mysql -u $DB_USER -p$DB_PASSWORD -h $DB_HOST $DB_NAME < "${BASENAME}.sql" > "${BASENAME}.output" 2> "${BASENAME}.error"
    ```

## 実行

```shell
$ ./execute_sql.sh fugafuga.sql
```

## おわりに

シェルスクリプト作成にかえって時間がかかった気がしなくもないですが、勉強になりました。

## 参考

https://qiita.com/yuyuchu3333/items/8d043d781bc8b343e108

https://atmarkit.itmedia.co.jp/ait/articles/1811/28/news003.html
AWS Cloud Quest-CloudPractitioner- 日本語版をやってみた

## はじめに
こんにちは！◤●ㅅ●◥ﾉ

上司の方からゲーム形式でAWSが学べるものがあると紹介してもらいました！
その名は **AWS Cloud Quest** 
今回はCloud Questの日本語版があるとのことで気になったのでやってみました！

ちなみにAWSの知識自体はどんなサービスがあるのか動画などで軽く知っている程度です

### AWS Cloud Questとは
Amazon Web Servicesが2022年3月に公開したオンラインロールプレイングゲーム
プレイヤーはクラウド技術者となり街の課題をAWSを駆使して解決し街を発展させる
本物のAWSを動かして課題をクリアするため、ゲームを通して学べることが特徴です

#### CloudPractitionerで学べること
AWS Cloud Questではさまざまなロールで学んでいくことができる
その中でCloudPractitionerでは12個の課題を解きながら9つのサービスを学ぶことができます

↓CloudPractitionerで学べる９つのサービス↓
Amazon S3, Amazon EC2, AWS Pricing Calculator, Amazon VPC, Amazon DynamoDB, 
Amazon Relational Database Service, AWS Identity and Access Management, 
Amazon Elastic File System, Elastic Load Balancing

#### 解決パートの流れ

解決パートでは実際にソリューションを作っていきます
1.Learn、2.Plan、3.Practice、4.DIYのステップで構築します
構築するソリューションについて学び、構築の計画を立て、実践し、
最後に自分で変更を加えるという流れで構築を行います

#### ボリューム
１つ当たり大体30分~1時間でした
少し難しい課題に関しては2時間くらいかかリました

全体的な時間だと約11時間くらいかかりました

## できるようになったこと
EC2インスタンスの起動、インスタンスタイプの変更
Amazon RDSインスタンスの起動、バックアップを設定
リードレプリカの作成
Amazon EC2インスタンスAutoScalingグループの作成
AutoScalingポリシーの設定　
などなど...

## 感想
AWSを知識としてしか知らなかったのが、実際にソリューションを作る経験ができたことで
EC2やS3などの実際のサービスを動かせるようになったのはもちろんですが、
それ以上にAWSを動かすことに対するハードルが自分の中でかなり低くなったと感じます。

ゲーム内では街の人の課題解決のみならず、
街にいる動物をクイズをすることでペットにできるなどいろいろ楽しむ要素があるので
ぜひ興味を持った方は遊んでみてください！

![CloudQuest.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3336192/fe49b6d8-ae72-f62a-2690-1db16ea50eac.png)

ここまで読んでいただき、ありがとうございました！
ではまた〜　◤●ㅅ●◥ﾉ"
第一回　ゲームプログラム初心者がDirectXに手を出してみた

## 雑談
皆様初めまして、ネットではシロクマさんという名前で生活をしている者です。

今回は入社させていただいた会社の方でqiitaのイベントに参加するとのことでしたので、自分の方でも参加させていただきました。
ブログ的な物はやりたいと思っていたのですが、まさか初ブログが技術系のブログになろうとは、、、
まったり雑談交じりの雰囲気でやっていきますので、
少し時間がある時に暇つぶし感覚で読んでいってもらえると嬉しいです。

## 記事の内容
タイトルにもある通り、自分のブログではDirectXをちまちま扱っていこうと思います。
専門学校でゲーム開発の勉強をしていた時はDirectXをがっつり触ることは無かったのでちょっと楽しみだったり、、、
参考書を見ながら勉強しているので、書いてあるコードを載せるより、不明な部分を抜粋して、半備忘録的な感じになります。


勉強に使っていく参考書は↓
https://amzn.asia/d/c5WxIuS

ﾊｲ、魔導書です。めちゃめちゃ分厚いです。
終わるまで何年かかるかわかりませんが、まったりやっていきましょう。

## 使用する知識
ご存じの方も多いと思いますが、DirectXで3Dのプログラムをする場合数学的な知識がかなり必要とされます。

本書の記載だと
- 三角関数
- n次方程式
- 数列
- 図形問題
- 指数対数
- 微積分
- ベクトル
- 行列
を使うらしいです。
数2Bで挫折した自分としては大分ハードルが高いですね、、、、

## 本題

### DIrectX初期化

魔導書を進めて行くとまずここで詰まりました。

DirectXの機能を使うにあたって、
以下のオブジェクトを初期化（生成）する必要があるらしいです

- D3D12Device
- DXGIFactory
- DXGISwapchain

そもそもこいつらは一体何者なのかとなるので、調べてみます

#### D3D12Device

実際に生成しているクラスはID3D12Device

主な機能
1. リソースの作成と管理:
    - バッファやテクスチャなどのグラフィックスリソースを作成するためのメソッドを提供している。これにより、アプリケーションはGPUメモリ内に配置されたリソースを作成および管理できる。
2. パイプラインステートの作成
3. コマンドキューの作成
4. デスクリプタヒープの作成
5. GPUとのやり取り
6. フィーチャーサポートの取得

#### DXGIFactory

実際に生成しているクラスはIDXGIFactory6

主な機能
1. デバイスの作成
    - IDXGIFactory6 は、CreateDevice メソッドを通じて、Direct3D 12デバイスを作成するのに使用されます。このデバイスは、Direct3D 12 APIを使用してグラフィックスリソースを作成し、描画処理を行います。
2. ハードウェアのサポート状況の取得
3. Direct3D 12およびDirect3D 11のサポート
4. DXGIオブジェクトの作成と管理
5. ハードウェアアダプターの列挙

正直難しい事ばかりでよくわからないので、まとめると
描画処理などのグラフィックスAPIの操作ができるようになる物らしいです。

#### DXGISwapchain

実際に生成しているクラスはIDXGISwapChain4

1. HDR（High Dynamic Range）サポート:
2. オーディオ出力との同期:
3. オーバーレイプレーンのサポート:
4. マルチプレゼンテーション:

アプリケーションが画面上で描画した結果をユーザに表示する際に使用されます。

画面上に実際に表示させている場所と新しく描画するものを準備しておく場所があり、その二つを切り替えたりするような機能があるイメージになります

## あとがき

第一回はいったんここまで（長すぎるとスクロールするのも大変なので、、、
第二回ではこれらをどのように使っているか等を書けたらいいなと思います。

バイバーイ:open_hands:
tsconfigのpath設定をstorybookに反映させる方法

dev環境でコンポーネントを取得するpathの書き方が
storybook上ではエラーとなっていた
原因はtsのエイリアス設定がstorybookに反映されていない為であり
.storybook/main.ts
をいじる必要がある

main.jsを修正するコードはすぐに見つかったが
main.tsを修正するコードは見つからなかったので
main.jsを参考に修正を試みたところ、どうしても動かず困り果てていたが
ふと、公式を検索すれば解決するのではと調べたところ、全く同じ[事例](https://storybook.js.org/docs/builders/webpack#typescript-modules-are-not-resolved-within-storybook)(ページ表示後に要素が挿入されて表示がずれます。スクロールして「TypeScript modules are not resolved within Storybook」の所が参照元)が載っていた
二通りやり方があるのでここに示す

## プラグインを使う方法

```.storybook/main.ts
// Replace your-framework with the framework you are using (e.g., react-webpack5, vue3-vite)
import type { StorybookConfig } from '@storybook/your-framework';

import TsconfigPathsPlugin from 'tsconfig-paths-webpack-plugin';

const config: StorybookConfig = {
  framework: '@storybook/your-framework',
  stories: ['../src/**/*.mdx', '../src/**/*.stories.@(js|jsx|mjs|ts|tsx)'],
  webpackFinal: async (config) => {
    if (config.resolve) {
      config.resolve.plugins = [
        ...(config.resolve.plugins || []),
        new TsconfigPathsPlugin({
          extensions: config.resolve.extensions,
        }),
      ];
    }
    return config;
  },
};

export default config;
```

'tsconfig-paths-webpack-plugin'
名前の通りtsconfigのpath設定を反映させてくれるのでこれがシンプルな解決策


## プラグインを使わない方法
```.storybook/main.ts
import path from 'path';
// Replace your-framework with the framework you are using (e.g., react-webpack5, vue3-vite)
import type { StorybookConfig } from '@storybook/your-framework';

const config: StorybookConfig = {
  framework: '@storybook/your-framework',
  stories: ['../src/**/*.mdx', '../src/**/*.stories.@(js|jsx|ts|tsx)'],
  webpackFinal: async (config) => {
    if (config.resolve) {
      config.resolve.alias = {
        ...config.resolve.alias,
        '@': path.resolve(__dirname, '../src'),
      };
    }
    return config;
  },
};

export default config;
```
自身で設定する

### ハマっていた内容
私が最初に試していた方法は後者の方法で

```tsconfig.json
"paths": {
      "@/*": ["./src/*"]
    }
```
tsconfigの記述に合わせるため下記のように書いていたが動かなかった

```.storybook/main.ts
config.webpackFinal = (config) => {
  config = {
    ...config,
    resolve: {
    ...config.resolve,
      alias: {
        ...config.resolve?.alias,
        "@/*": path.resolve(__dirname, "../src/*"),
      }
    }
  }
  
  return config
```

上記から末尾の/*を両方とも削除したものを貼り付けると正しく動く
*だけ削除では動かない

わざわざtsconfigの書き方と異なる記述をする気になれないのでプラグインを使う方法を採用
HP ProLiant DL380p Gen8で初期パスワードが不明なiLOを初期化する（管理ユーザーを作成する）

# これは何のメモ？
iLOの初期パスワードが記載されたタグを無くした時に，iLO RBSUから管理者ユーザーを追加する．
セキュリティ設定によってはMB上のスイッチを操作する必要は無いかも？
他のモデルも大体同じ操作で上書きできるはず．

# 環境
- HP ProLiant DL380p Gen8
- iLO4 2.70
- P70 05/24/2019

# 作業手順
まず電源を落とし，ACコードも抜く．
蓋を開け，システムボード上のセキュリティオーバーライドスイッチをonにする．
DL380pGen8の場合はここ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2353160/b5ea350e-d93f-4682-31e4-9f13bdc22e08.png)
1番をONにする．
![iloimg02.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2353160/1a471b32-0628-36f0-78a1-c87be14c64ee.jpeg)


電源を入れ，この文言が出たらF8を押してiLOの設定画面に入る．
![iloimg01.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2353160/1c722bbb-e0b1-97ae-9b3b-014f1ac99d44.jpeg)

UserウィンドウからAddかEditを選択して，お好みのパスワードを設定する．
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2353160/7201f37c-6eb7-a4be-a487-39354aea348e.png)

電源を落として，セキュリティオーバーライドスイッチをoffに戻す．
めでたく設定完了．

# 参考文献
[HP ProLiant サーバー - iLO の初期アカウント情報が記載されたタグを紛失してしまった場合の対処方法について](https://support.hpe.com/hpesc/public/docDisplay?docId=c03957453&docLocale=ja_JP)
[HPE ProLiant DL380p Generation 8 システム構成図 (おっとサーバー)](https://www.pcserver1.jp/client_info/PCSERVER1JP/view/userweb/images/Product/dl380pgen8.pdf)
Flutterのディレクトリ構成を考える

# はじめに

この記事はYUMEMI Flutter Advent Calendar 2023の18日目の記事です。

https://qiita.com/advent-calendar/2023/yumemi-flutter

# 本題

## TL;DR

```
project_name
├ assets
├ lib
│ ├ apis
│ ├ components
│ ├ configs
│ ├ features
│ │ └ feature
│ │ 　 ├ apis
│ │ 　 ├ components
│ │ 　 ├ hooks
│ │ 　 ├ models
│ │ 　 └ providers
│ ├ gen
│ ├ hooks
│ ├ l10n(or i18n)
│ ├ models
│ ├ pages
│ └ providers
└ test
```

## フロントエンドのディレクトリ構成

自分が1年ほど前までWebのフロントエンドエンジニアとして仕事をしていたため、Reactのディレクトリ構成をよく考えていました。有名なものとしては、Atomic DesignやBCD(BCCD) Design、featuresディレクトリなどです。その中でも、featuresディレクトリを用いるbulletproof-reactを元に、Flutterのディレクトリ構成を考えていきます。

https://github.com/alan2207/bulletproof-react

## features

featuresディレクトリとは、機能ベースのディレクトリとなっており、featuresディレクトリ以下には各機能の名称のディレクトリを持ちます。例えば、認証機能を提供する`auth`や、ユーザー情報を提供する`user`などです。
メリットとして、機能ごとに役割が分かれているため、テストの書きやすさにも繋がります。また、不要になった機能はディレクトリを消すだけでよくなり、依存関係を確認したりする手間も省けます。

以下は自分の考えるfeaturesディレクトリの構成になります。

```
features
└ feature
　 ├ apis
　 ├ components
　 ├ hooks
　 ├ models
　 └ providers
```

### apis

apisディレクトリではAPI通信の処理を管理します。例えば、[http](https://pub.dev/packages/http)を使用してユーザー情報の取得などを行い値を返すような関数を定義します。

### components

componentsディレクトリではその機能を満たすためのUIを管理します。例えば、ユーザープロフィールを表示する場合だと、`user_profile.dart`のようなファイルを定義します。

### hooks

hooksディレクトリではカスタムフックを管理します。例えば、[flutter_hooks](https://pub.dev/packages/flutter_hooks)の`useState`使用して、API通信中かどうかの判定を行います。

### models

modelsディレクトリではAPIのレスポンスなどのモデル（型）を管理します。例えば、[Freezed](https://pub.dev/packages/freezed)を使用して、ユーザー情報のモデルを定義します。

### providers

providersディレクトリではプロバイダを管理します。例えば、[Riverpod](https://pub.dev/packages/riverpod)を使用して、複数の画面で使用されるようなユーザーアイコンの画像を持つプロバイダを定義します。

## pages

pagesディレクトリはその名の通り、ページごとの名称のディレクトリを持ちます。例えば、ユーザープロフィールを表示する`profile`などです。featuresディレクトリで作成したコンポーネントを用いてUIを構築していきます。

また、このディレクトリで各ページのルーティングも定義します。例えば、[go_router](https://pub.dev/packages/go_router)を使用した場合、`path`などをこのディレクトリで定義し、すべてのルーティングを束ねるファイルはlib直下に`router.dart`を作成して対応します。

## その他

その他のディレクトリは共通で使用するファイルや環境変数、多言語化対応などを定義します。

以下は自分の考えるディレクトリの構成（featuresディレクトリとpagesディレクトリは省略）になります。

```
lib
├ apis ... 共通で使用するAPI通信を行うファイル群を管理
├ components ... 共通で使用するコンポーネント群を管理
├ configs ... 環境変数を管理
├ gen ... FlutterGenの出力先として画像などを管理
├ hooks ... 共通で使用するカスタムフック群を管理
├ l10n(or i18n) ... 多言語化対応のためのファイル郡を管理
├ models ... 共通で使用するモデル郡を管理
└ providers ... 共通で使用するプロバイダ群を管理
```

## まとめ

プロジェクトの直下には画像等を管理するassetsディレクトリと、テストを管理するtestディレクトリを追加し、最終的に考えたディレクトリ構成は以下のようになります（iosディレクトリやandroidディレクトリなどは省略しております）。

```
project_name
├ assets
├ lib
│ ├ apis
│ ├ components
│ ├ configs
│ ├ features
│ │ └ feature
│ │ 　 ├ apis
│ │ 　 ├ components
│ │ 　 ├ hooks
│ │ 　 ├ models
│ │ 　 └ providers
│ ├ gen
│ ├ hooks
│ ├ l10n(or i18n)
│ ├ models
│ ├ pages
│ └ providers
└ test
```

# おわりに

ディレクトリ構成はプロジェクトの規模やプロジェクトのメンバーにも左右されます。自分の紹介したディレクトリ構成もプロジェクトによっては相応しくないかもしれません。
色々なディレクトリ構成を比較する上で、ひとつの案になれれば幸いです。
リダイレクトとパイプライン

# 標準出力、標準エラー出力
標準出力をファイルにリダイレクト

~~~bash
$ ls /xxxx > list.txt
~~~

標準エラー出力をファイルにリダイレクト

~~~bash
$ ls /xxxx 2> error.txt
~~~

標準出力と標準エラー出力を、それぞれ別のファイルにリダイレクト

~~~bash
$ ls /xxxx > list.txt 2> error.txt
~~~

標準出力と標準エラー出力をひとつのファイルにリダイレクト

~~~bash
$ ls /xxxx > result.txt 2>&1
~~~

上記の意味は>で標準出力をresult.txtへリダイレクトし、標準エラー出力(2>)を、標準出力(&1)へリダイレクトしているので、結果として標準エラー出力もresult.txtへリダイレクトされる。

標準入出力の数値の意味は以下
0: 標準入力
1: 標準出力
2: 標準エラー出力

# noclobber
なおリダイレクトで出力したファイルは上書きしてしまう。重要なファイルをうっかり上書きしてしまう危険がある。常に>>を使って、追記しかしないという手もあるが、以下の設定で上書きを防止できる。

~~~bash
set -o noclobber
~~~

上記の設定により既存のファイルを上書きしようとすると以下のように表示される。

~~~bash
$ echo abc > file.txt
-bash: file.txt: 存在するファイルを上書きできません
~~~

# /dev/null

~~~bash
$ ls -l /dev/null
crw-rw-rw-. 1 root root 1, 3 12月 18 08:33 /dev/null
~~~

上記はスペシャルファイルと呼ばれる特別なファイルで、
+ 入力先に指定しても、何も内容を返さない。
+ 出力先に指定しても、どこにも保存されない。

入力をクリアしたい場合、出力をどこにもしたくない場合に使用する。例えば、本来標準エラー出力に出力されるエラーが、あらかじめわかっていて不要な場合などに使う。

~~~bash
$ 何らかのコマンド 2> /dev/null
~~~

# パイプライン
標準出力を次のコマンドに送りたい場合にはパイプラインを使う。

~~~bash
$ history | less
~~~

標準出力に加えて標準エラー出力も次のコマンドに送りたい場合は、標準エラー出力を標準出力へリダイレクトして、パイプラインを使う。

~~~bash
$ ls -l / /xxx 2>&1 | less
~~~

# フィルタ
標準入力を入力として受け取り、標準出力に出力するコマンドをフィルタと呼ぶ。

代表的なフィルタコマンド
+ cat
+ head
+ tail
+ grep
+ sort
+ uniq
+ tac
+ wc

フィルタコマンドの活用例
/binディレクトリ配下ファイルサイズが大きい上位5つを表示

~~~bash
$ du -b /bin/* | sort -n | tac | head -n 5
~~~
なんちゃって一次ローパスフィルタの周波数特性

拝啓 ChatBot様

$$
x_{n+1} = (1-\alpha)x_{n} + \alpha u_n 
$$

のフィルタ(αは[0, 1]とする)伝達関数のz変換は

$$
\frac{\alpha}{z-(1-\alpha)}
$$

で、これをTustin変換を用いて周波数 $f$ Hzで連続化したときの極は

$$
\frac{2f\alpha}{2 - \alpha}
$$

になるので次からこれで計算してください。よろしくおねがいします。
[Godot 4.2] クリップボードにコピーする

こちらのコードで可能です。

```gdscript
DisplayServer.clipboard_set("コピーしたい文字列")
```

もちろん get もできます。

## 参考文献
[DisplayServer — Godot Engine (4.x)の日本語のドキュメント](https://docs.godotengine.org/ja/4.x/classes/class_displayserver.html)