OmniAICreator/Qiita-1.07M huggingface dataset:
Git bashでtreeコマンドを使いたい

<h1>はじめに</h1>
学習している中で、<br>・教本等の教材でよく見る<b>ディレクトリ構造の平面図</b>を出したい。<br>・qiitaに示す時に<b>コピペ</b>で済ませたい。<br>と、思い使用している環境でにインストールしたいと思い試しました。

<h1>環境</h1>
Windows11<br>
コマンドプロンプト(Gitbash)

<h1>インストール手順</h1>
実行ファイルのダウンロードとインストールが必要なので、それぞれ以下で解説します。<br>
<h3>（１）tree.exeのダウンロード</h3>
<a href="https://gnuwin32.sourceforge.net/packages/tree.htm">Tree for Windows</a>で以下キャプチャのファイルをZipリンクよりダウンロードします。<br>

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/754176/05d36ef7-13ff-2aa7-d362-8fdc0497e5f0.png)

押下と同時に以下の画面に飛ばされますが、数秒待つと自動的にダウンロードが開始されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/754176/8698dbc1-1dad-9e3e-0a3d-d9b9d7912032.png)

ダウンロード用フォルダにzipファイルが確認できれば完了です。

<h3>（２）使用環境へのインストール</h3>
ダウンロードが環境したzipファイルを解凍します。<br>
解答し展開されたディレクトリを確認すると、tree-1.5.2.2-bin/bin/tree.exe というファイルが確認できるかと思います。
<br>
コマンド実行時に走るファイルがtree.exeになるので、使用環境のbinディレクトリ配下へコピーします。
<br>
私の場合は/usr/binなので以下の様にコピーを実行しました。
<br>

```bash
cp ~/Downloads/tree-1.5.2.2-bin/bin/tree.exe /usr/bin
```
完了後、任意のフォルダで動作を確認します。

```bash
tgr@DESKTOP ~/Downloads/tree-1.5.2.2-bin
$ tree
.
|-- bin
|                   `-- tree.exe
|-- contrib
|                   `-- tree
|                   `-- 1.5.2.2
|           |       `-- tree-1.5.2.2
|           |       `-- tree-1.5.2.2-GnuWin32.README
|                   `-- tree-1.5.2.2-src
|               |   `-- CHANGES
|               |   `-- INSTALL
|               |   `-- LICENSE
|                   `-- README
|-- man
|   `-- cat1
|       `-- tree.1.txt
`-- manifest
    |-- tree-1.5.2.2-bin.mft
    `-- tree-1.5.2.2-bin.ver

9 directories, 9 files
```
よく見る平面図でのディレクトリ構造が表示されれば完了です。
<h1>おわりに</h1>

学習だけではなく、業務中も使える場面が多く重宝しているのでお勧めです。
特にエラーもなく実行できましたが、環境等により本記事の内容ではエラーが出るなどの場合はコメントください！
SQLの行集約方法【PostgreSQL】

## 説明

1. MAX 関数を利用して複数の行を1つに集約し、値がある場合はその値を、値がない場合は NULL を設定します。
2. MAX は NULL 値を無視し、値が存在する場合にはその値を取得します。

```sql
-- SQL
SELECT
    MAX(column1) AS column1
    , MAX(column2) AS column2
    , MAX(column3) AS column3
FROM
    my_table;
```

 元データ
column1 | column2 | column3
--------|---------|--------
 null   |  TEST2  |  null
 TEST1  |  null   |  TEST3

実行結果
column1 | column2 | column3
--------|---------|--------
 TEST1  |  TEST2  |  TEST3
Python 3.13.0 でvenvを使うと plt.plot() できないバグがあるらしい

タイトル通りの問題が発生中とのこと．
以下のエラー文が表示されます．
tkinter関連のバグみたいです．
```
_tkinter.TclError: Can't find a usable init.tcl in the following directories:
```

対処法は2つです．
1. Python 3.12 を使う
2. Python 3.13.1 が出るのを待つ．

[githubでの議論](https://github.com/python/cpython/issues/125235)を見ると，Python 3.13.1 では治るらしいのでしばらく待ちましょう．

## 参考文献
* https://github.com/python/cpython/issues/125235
新卒が配属1ヵ月間を通して感じたこと

## はじめに
現場に配属されてから1ヶ月が経過しました。
なのでこの1ヶ月間で感じたことについてまとめてみました。

## １. 専門用語の多さ
専門用語が多く、会話についていくのが大変でした。
調べたり、聞いたりして徐々に理解できるようになってきましたが、まだ力不足を感じています。
スキマ時間等を有効に活用したいと思います。

## ２. 報告のタイミング
50％ほど作業が終わったタイミングで報告するのは遅かったです。
20～30％の段階で早めに報告することで、手戻りを少なくし、自分にも相手にも良い結果を生むことがわかりました。
まずは報・連・相をしっかり行えるようになる必要があると思ったので改善していきます。
とはいえ、理想を言えば、手戻りが発生する必要のない理解力を身につけたいです。

## ３. 認識合わせの重要性
この1ヶ月で最も重要だと感じたのは **「認識合わせ」** です。
特に未熟なうちは、認識合わせをすると高確率で間違いが見つかると思います。
作業に取りかかる前に認識を合わせておくことが、時間短縮に繋がると強く感じました。

## ４. 要点を抑えたメモの重要性
「メモを取れ」とはよく言われますが、ただ取るだけでは意味がないことに気づきました。
私のメモには、以下のような課題がありました。

・省略しすぎて後から見ても内容がわからない
・日付を書いていないため、いつのメモかわからない
・情報の取捨選択ができておらず、整理されていない
・メモが詰め込みすぎで見づらい

要点を押さえたメモを取る力があれば、自分の作業をスムーズに進められる他、報告や設計書作成にも役立てることができると思います。社会人としての必須スキルだと感じたので日頃から意識をしていきたいです。

## ５. リモートワークにおけるレスポンスの早さ
リモートワークの課題の一つは、コミュニケーションの遅さだと感じました。
レスポンスが早ければ、現場にいるようなスピード感で仕事を進めることができると思います。技術力が未熟な新卒にとって、こうした基本的な面での努力は重要だと思います。
また、リモートワークに限らず、レスポンスの早さは大切だと思います。

## さいごに
この1ヶ月で、仕事をする大変さを改めて実感しました。
こうしたスキルを身につけることで、やっと半人前なのかなとも感じました。
これからも日々の業務を通じて成長していきたいと思います。
複数あるフラグメント遷移の仕方

立ち上げるフラグメントが複数ある時に、whenを使用した分岐方法をメモする。

```kotlin
val intent = Intent(activity, Workctivity::class.java).apply {
putExtra("workFragment", Workctivity.WorkFragments.WorkA.ordinal)
}
startActivity(intent)
```
```kotlin
val intent = Intent(activity, Workctivity::class.java).apply {
putExtra("workFragment", Workctivity.WorkFragments.WorkB.ordinal)
}
startActivity(intent)
```
```kotlin
enum class WorkFragments {
    WorkA,
    WorkB
}


val fragmentType = intent.getSerializableExtra("workFragment")

val fragment = when (fragmentType) {
    0 -> {
        WorkAFragment()
    }
    1 -> {
        WorkBFragment()
    }
}

supportFragmentManager
    .beginTransaction()
    .add(R.id.work_container, fragment, Fragment::class.java.name)
    .setTransition(TRANSIT_FRAGMENT_OPEN).commit()
}
```

enumで定義した値をordinalで渡し、when文で分岐させる。値に応じてフラグメントを切り替える。


#### 参考

https://qiita.com/watanabeyt06-w/items/385bac8a5d80074f9621
Xcode　Swiftファイルの過去コミットを確認する方法

普段あまり使わない機能だと忘れやすくなってしまいます。

今回確認しようと思い、直ぐに思い出せなかったので、残しておこうと思います。

画像のような一番右上をクリックして開いて、時計マークをクリックすると、過去コミットを確認できます。

![スクリーンショット 2024-09-30 18.12.24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/274615/8364dfcd-3d75-efe7-3163-4ad88697e477.png)

簡単なことですが、普段使わないと忘れますね。
MacでいらないソフトウェアをLaunchpadから非表示にする方法

MacをしようするとLaunchpadを使うことがよくあると思うのだが、必要ないソフトウェアは表示したくないというシーンは多くあると思う。
例えば「株価」や「天気」など、知りたい情報ではあるがもっと専門的なサイトを見たりする人の方が多いだろう。
ただしアプリ自体を削除してしまうと不具合が起こったりする可能性や、ウィジェットのみしようしたい場合もあるのでLaunchpadから非表示にするだけでアプリは削除せずに運用するといった方法を取るのがベストだろう。
以下のコマンドでLaunchpadから不要なアプリを非表示にすることができる。
```
// sqliteデータベースに入る。
$ sqlite3 ${TMPDIR}../0/com.apple.dock.launchpad/db/db

// アプリケーションのリストを表示する。
＞select * from apps;

// 株価アプリを非表示にする
＞delete from apps where title="株価";
```
上記コマンドで非表示に設定後、control + Dでsqliteから抜ける。
```
// カーネルを再起動する(このコマンド実行後に非表示が反映される)。
killall Dock
```
以上でLaunchpadから不要アプリが非表示になる。
注意点としてはLaunchpadのアプリの並び順が崩れることがあるのであらかじめアプリの配列を覚えておくか新たに自分好みに設定し直す必要がある。
【Apex】脱初心者: SOQLは一度使うだけのベストプラクティス

# はじめに 

SalesforceではSOQLを使ってデータを取得できる便利な特性がある反面、SOQLクエリには1つのトランザクションでの使用回数のガバナ制限があり大規模な組織では工夫をしないと引っかかってしまうことも多々あります。
Apexでは、参照関係を持つオブジェクトを扱う際に、特定の親オブジェクトを子オブジェクトのリストから取得するためにSOQLを用います。Apexを始めたばかりの方は、次のようにfor文の中でSOQLを繰り返し実行することが多いです。
今回は、Apex初心者の方のためにListだけに頼らない、SetとMapを使ったオブジェクト取得のベストプラクティスを紹介することを目的としています。

```apex
for (Child child : childList) {
    Parent parent = [SELECT Id, Name FROM Parent WHERE Id = :child.parentRef];
}
```
この方法は、処理件数が少ない場合には特に問題はありませんが、件数が多くなるとガバナ制限（SOQLクエリ制限）に引っかかりやすくなり、パフォーマンスも低下してしまいます。

# SOQLをfor文の前で実行し、Mapを活用するベストプラクティス
ガバナ制限に引っかからず、効率的にデータを取得するために、for文の前にSOQLを一度だけ実行し、結果をMapに格納することでfor文の中で繰り返し検索することができます。これにより、SOQLの実行回数を最小限に抑えることが可能です。

以下がMapを使用したベストプラクティスの例です。
```apex
Set<Id> parentIdSet = new Set<Id>();
for (Child child : childList) {
    parentIdSet.add(child.parentRef);
}

Map<Id, Parent> parentMap = new Map<Id, Parent>(
    [SELECT Id, Name FROM Parent WHERE Id IN :parentIdSet]
);

for (Child child : childList) {
    Parent parent = parentMap.get(child.parentRef);
    // 必要な処理をここに記述
}
```
この方法では、まず parentIdSet に子オブジェクトの参照先IDをすべて追加し、次にそのIDリストを用いてSOQLを一度だけ実行します。取得した親オブジェクトは Map<Id, Parent> に格納されるため、for文の中で Map.get() メソッドを使って各親オブジェクトを効率よく取得できます。

# まとめ
リストを操作する際には、SOQLクエリをfor文内で繰り返さないようにすることが重要です。Mapを活用して一度のクエリでデータを取得することで、ガバナ制限を意識しつつ、パフォーマンスの良いコードを書くことが可能です。ぜひ、この方法を参考にしてApexのコーディングスキルを向上させてください！
マルチディスプレイのSystem.Windows.Forms.Screen.AllScreens。DPI絡み（未解決）

マルチディスプレイで開発していてSystem.Windows.Forms.Screen.AllScreensを使ったときの話。
ディスプレイごとのDPIを元にScreen情報が取得できると当たり前のように思っていたけどどうもそうではないらしい。

すべてのモニタのScreen情報はメインモニタのDPIを使って計算されている模様。

### 目先の解決
app.manifestに下記追加で解決。ちゃんとそれぞれのモニタのDPIで計算されて値が設定されていた。
```xaml:app.manifest
<application xmlns="urn:schemas-microsoft-com:asm.v3">
  <windowsSettings>
    <dpiAware xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">True/PM</dpiAware>
  </windowsSettings>
</application>
```
🤖　AIを主軸にアプリ開発した話

# 前置き
(ChatGPT3.5が出てちょっとした時にやって以来だったので、最近のツール使ってやってみたかったので今更感には目を瞑って下さいmm)
AIをフル活用してアプリの開発からデプロイまでを実験的に行ってみました。
**無料枠のみ**で行なっています。(ゲームも開発もなるべく無料でやりたい勢です。)
1.5日くらいで作ったものなので作りが甘い部分やまだまだガバガバな部分が多いです。
そこはご了承ください🙇

# 結論
- 開発効率爆上がり！
  (こんなに楽をして良いのだろうか...と思ってしまうほどには)
- 機能の大枠から詳細、UIと大体なんでも作成できて嬉しい！
- 色々なAIツールを触ってみて、特性を掴むのが大切なのかなと思いました。

# 今回利用したAIサービス
ご存知の通り、各AIツールには得意・不得意があります。
今回の企画で複数ツール使いながら開発することでより感じることができ、得意な分野を任せることでより良い開発体験をすることができました！

## 1. ChatGPT
他ツールの無料回数制限が来た時の心強い最後の砦。
汎用性が高いのでエラー内容丸投げなど、機能やUI生成とは別用途で主に活躍してもらいました。

## 2. Claude Sonnet 3.5
裏側のロジックなどのアプリの機能面の生成を主に担当してもらいました。
(回数制限がすぐ来ちゃうので質問を投げる時は少し慎重になっちゃいますよね😓)
また、Marpでのスライド作成でも活躍してもらいました。
(アーティファクトでプレビュー見れるの大助かりです！)

## 3. Vercel V0
主にUI作成に大きく貢献してもらいました！
Shadcn/ui、TailwindCSSをベースにコンポーネントからページ全体、デザインまでUI周りを作成してもらいました！
個人的な感覚ですが、UIの生成に関しては扱いやすさ、精度的にも他のツールより高精度な気がします。
(割と雑に投げても良い精度のものを出してくれる)

## 4. Perplexity
AIはすごい！！
それでもやはり時々、怪しい回答があります...
そんな時はこの子です！
リアルタイムでスクレイピングし、エビデンスを示してくれ、怪しい回答の真偽をはかるのに役立ちます🔍
(エラーの検索などでも活躍してもらいました。)

# 今回採用した技術スタック
## 1. Nextjs
後述しますが、Vercelのホスティングサービスを利用するため、相性が良いこともあり、こちらを採用。

## 2. React
Nextjsと相性が良いため採用。
Svelteなどでもよかったですが、自分が慣れているのとウェブにも文献が多いことからAIとも相性が良さそうだったので。

## 3. Prisma (ORM)
Vercelのアドオン(Postgres)が公式リファレンスを出していること、記述量が少なく楽に開発ができるため採用。

## 4. NextAuth
こちらで自前で認証を実装したくない、ユーザーの認証情報を持ちたくないという意思、前に使ったことから採用。
全て紹介するとキリがなくなっちゃうので他は割愛...

# 実際に開発したもの
良ければアクセスしてみて下さい🙇
(URL: https://worth-it-psi.vercel.app/)
![](https://storage.googleapis.com/zenn-user-upload/4440e4e537e2-20241027.png)
# 今回の一番の驚き
今回の企画をやる上で一番個人的に驚きだったのはVercelのV0でした。
皆さんはCSSだったりと、スタイル周りは得意・お好きですか？
僕はUIを使ったり、見るのは好きですが、自分でいじるのは苦手です😓

そんな中、V0を用いることでモーションもついたオシャレ(主観)なUIができたことにワクワクでした！
イメージを文章にして伝えることである程度汲み取り、UIを作成してくれます。
その他にもイメージ画像などを入れてもその画像に似たUIが生成できたり、コンポーネント別に出力することなどもでき、僕的にはかなりすごいなという感想でした。
(個人的にはローディング画面がお気に入りですw)
![](https://storage.googleapis.com/zenn-user-upload/190e7c647a4f-20241027.gif)


# 使っていく中での感じた注意点
世間的にも言われていますがただ作らせて切りするだけは流石にきつそうです。
(プロンプトを使いこなせるとまた変わってくるかも知れませんが...)

やはりある程度、使用する技術に対しての知見や使用経験は必要だと感じました。
実際にNextAuthを使用する際に、かなり沼りました...
割と新しく、破壊的変更が入ったことがあることもあり前の情報だったりをもとに出力されることが多く、結局公式のリファレンスを参照しにいき、解決しました😓
僕はやりがちなのですが、何でもかんでも聞く。
実際に調べにいく方が早いこともあります。ここは気をつけたいです。
便利すぎて僕はよくやっちゃいます。
(別の解決策や僕の使い方が甘いのかもしれませんが。)

ずっと同じスレッドで会話をしていくうちに間違った方向に進み、変にバイアスがかかる時があります。
その時は新しくスレッドを立てて利用した方が良い回答を得られることが今回は多かったです。

- **無料のみやる場合**
なるべく一回の質問で複数の回答が得れるようにすることや、なるべく複数個解決できるように質問する。調べてある程度わかることはなるべく質問しないなどに気をつけないと高精度のツールはすぐ使えなくなるので気をつけたいポイントですね...


# まとめ
- AIを用いて開発効率アップ！
- AIにも適材適所がある
- 各ツールの特性をつかむ
- 自身の知識も大事

やっぱり技術って面白いですね。
よければ、先日のAmazonプライム感謝祭で買ってよかったものを投稿してみて下さい🙇
(いいなと思ったもの買います...)

# おまけ (今回のプロンプトと生成の一部)
Vercel V0がある程度適当だったり、だいぶ抽象的にプロンプト投げても(自分主観で)イカしたUIつくってくれてワクワクしました。

![](https://storage.googleapis.com/zenn-user-upload/c2c287b2f81e-20241027.png)
![](https://storage.googleapis.com/zenn-user-upload/911744db5a60-20241027.png)
![](https://storage.googleapis.com/zenn-user-upload/f4e838d2833b-20241027.png)
SSH接続エラー「接続を確立できません」の対処

DBサーバを終了したのち、新しく別のサーバーを同じIPアドレスで立て、VSCodeで踏み台からDBサーバにアクセスしようとしたところ、
> "DB-server"は接続を確立できません

とのエラーがでました。
その対処を備忘録として残します。

# 背景とエラー内容

VSCodeだとエラーが見づらいので、PowerShellから`ssh <DBサーバー>`をすると以下のようなエラーを見ることができます。


```
PS C:\Users\koin3z> ssh <DBサーバー>
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@    WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED!     @
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
IT IS POSSIBLE THAT SOMEONE IS DOING SOMETHING NASTY!
Someone could be eavesdropping on you right now (man-in-the-middle attack)!
It is also possible that a host key has just been changed.
The fingerprint for the ED25519 key sent by the remote host is
SHA256:6xq+etv23U6j5IS6rhEWI0ZaPSeo4DiMPlAjryxzOeELk.
Please contact your system administrator.
Add correct host key in C:\\Users\\koin3z/.ssh/known_hosts to get rid of this message.
Offending ECDSA key in C:\\Users\\koin3z/.ssh/known_hosts:15
Host key for YYY.YYY.YYY.YYY has changed and you have requested strict checking.
Host key verification failed.
```

# 解決
DBサーバーのホストキーが以前と違うために、セキュリティ上の懸念からSSHが接続を拒否しているようです。
どうやら、新しいインスタンスを再作成したときやIPアドレスの変更した際によく見られるエラーなんだとか。

そのため、ローカルの`known_hosts`ファイルに保存されている古いホストキーを以下コマンドで削除します

```: コマンドプロンプトやPowerShellで
ssh-keygen -R <hostname>
```

```: 該当するホストキーを削除
PS C:\Users\koin3z> ssh-keygen -R YYY.YYY.YYY.YYY
# Host YYY.YYY.YYY.YYY found: line 13
# Host YYY.YYY.YYY.YYY found: line 14
# Host YYY.YYY.YYY.YYY found: line 15
C:\Users\koin3z/.ssh/known_hosts updated.
Original contents retained as C:\Users\koin3z/.ssh/known_hosts.old
```

その後、SSHすると無事繋がります。

```:無事つながった
PS C:\Users\koin3z> ssh <DBサーバー>
The authenticity of host 'YYY.YYY.YYY.YYY (<no hostip for proxy command>)' can't be established.
ED25519 key fingerprint is SHA256:6xq+etv23U6j5IS6rhEWI0ZaPSeo4DiMPlAjryxzOeELk.
This key is not known by any other names.
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Warning: Permanently added 'YYY.YYY.YYY.YYY' (ED25519) to the list of known hosts.
Activate the web console with: systemctl enable --now cockpit.socket
```

てっきりネットワークやホスト側の設定ミスかと思っていましたが、クライアントの方だとは思いませんでした。おわり。
AWSのデプロイサービスを使いこなそう！効率的なアプリケーションデプロイの実現方法

# AWSのデプロイサービスを使いこなそう！効率的なアプリケーションデプロイの実現方法

こんにちは！インフラ寄りの業務に携わっている関係でアプリ周りの理解が乏しいことから、AWSのデプロイサービスについて調べたものをまとめなおしてみました。

## なぜCI/CDサービスを使うべきなのか

一般的な話題として、手動デプロイ運用に対する辛さがあるように見受けられました。例えば、チーム内でデプロイ手順の認識違いがあったり、本番作業のデプロイ時にミスをしたり...。そういったツライ経験は、CI/CDサービスを導入すると、すっきり改善できそうです。どのように改善できるかという観点では、具体的には以下のようなメリットがあります。

**開発効率が劇的に向上**
- 面倒なデプロイ作業が自動化され、コードを書くことに集中できる
- テストも自動化されるので、早期にバグを発見できる
- テスト環境だけでなく本番環境のデプロイ時でもミスの心配が少ない

**デプロイの信頼性が格段にアップ**
- 手作業によるミスがなくなる
- いつも同じ手順でデプロイされるので安心
- 問題が起きてもすぐにロールバックできる

## AWSのデプロイサービスだったら、どれを選べばいいの？

AWSには主に3つのデプロイサービスがあります。それぞれのサービスにおける特徴について見ていきましょう。

### AWS CodeDeploy
EC2やLambda、ECSなど、様々なプラットフォームに対応していて、特にブルー/グリーンデプロイが便利です。本番環境で新バージョンのテストができるので、安全にデプロイすることができます。

### AWS Elastic Beanstalk
Elastic Beanstalkは「とにかく簡単にデプロイしたい！」という方におすすめ。インフラの細かい設定を意識せずに、アプリケーションのデプロイができます。

### AWS CloudFormation
インフラをコードで管理したい場合はこちら。一度テンプレートを作ってしまえば、環境の複製が簡単にできて便利です。

## AWS CodeDeployで実現できること

CodeDeployの良いところは、デプロイタイプを柔軟に選べることです。

**インプレースデプロイ**
これは既存のサーバーに直接デプロイする方式です。シンプルで分かりやすいのですが、デプロイ中にサービスが停止する可能性があるので注意が必要です。

**ブルー/グリーンデプロイ**
新環境を作ってからトラフィック切り替えるので、ダウンタイムがほとんどありません。ただし、新旧の両環境を一時的に立ち上げておく必要があるため、コストは若干高くなります。

## Elastic Beanstalkのデプロイポリシーを使いこなす

Elastic Beanstalkには5つのデプロイポリシーがあります。

**All at once**
一度に全環境を更新する方式です。コストメリットがあるため、開発環境に向いていますが、本番環境では避けた方が無難です。

**Rolling**
コストと安定運用のバランスが良いパターンです。バッチ単位で更新（１インスタンス毎の更新）していくので、サービスを止めることなくデプロイできます。

**Rolling with additional batch**
Rollingの改良版で、追加容量を確保しながら更新するので、より安全に更新ができます。ただし、その分コストは上がります。

**Immutable**
新しい環境を作って切り替える方式です。安全性は高いのですが、デプロイに時間がかかることやその分コストがかかります。

**Traffic splitting**
段階的にトラフィックを移行できるので、新バージョンの問題を早期に発見できます。

## CloudFormationでインフラをコード化する

CloudFormationはアプリとインフラをセットにデプロイせず、インフラ環境を中心にデプロイする場合に優位性があります。

例えば、以下のようなYAMLテンプレートで、EC2インスタンスを作成することができます。

```yaml
Resources:
  # EC2 インスタンス
  MyEC2Instance:
    Type: "AWS::EC2::Instance"
    Properties:
      InstanceType: "t2.micro"  # インスタンスタイプを指定
      ImageId: "ami-0123456789abcdef0"  # AMIのIDを指定
      SecurityGroupIds:
        - !Ref MySecurityGroup  # セキュリティグループの参照
      SubnetId: "subnet-0123456789abcdef"  # VPC内のサブネットIDを指定
      Tags:
        - Key: Name
          Value: MyInstance

  # セキュリティグループ
  MySecurityGroup:
    Type: "AWS::EC2::SecurityGroup"
    Properties:
      GroupDescription: "Enable SSH access"
      VpcId: "vpc-0123456789abcdef"  # 使用するVPC IDを指定
      SecurityGroupIngress:
        - IpProtocol: "tcp"
          FromPort: "22"  # SSH用
          ToPort: "22"
          # グローバルアクセス（セキュリティ上の理由で本番環境では制限することを推奨）
          CidrIp: "0.0.0.0/0"

Outputs:
  InstanceId:
    Description: "The Instance ID of the EC2 instance"
    Value: !Ref MyEC2Instance
```

## まとめ

AWSのデプロイサービスは選択肢が多くて戸惑いやすいですが、それぞれの特徴を生かして利用することでよりアプリケーションコードに集中して開発ができるものと推測しています。

この記事がどなたかのお役に立てれば幸いです。
L1ノルムとL2ノルム

## L1ノルム

- 定義: ベクトルの各要素の絶対値の和
- 数式: ||x||₁ = Σ|xᵢ|
- 別名: マンハッタンノルム
- 特徴:
  - **スパースな解**を生成しやすい
  - **特徴選択**に有効　→高次元の入力データを扱う際に特に有用
  - 外れ値に対してロバスト　→異常検知タスクに有用
- ML, DLにおける利用例:
  - 過学習抑制：L1正則化
  - 生成モデル：鮮明な画像生成・・・生成画像と真の画像間の絶対誤差を最小化

## L2ノルム

- 定義: ベクトルの各要素の二乗和の平方根
- 数式: ||x||₂ = √(Σxᵢ²)
- 別名: ユークリッドノルム
- 特徴:
  - 解析的な解が存在する
  - 計算効率が良い
  - 多くの場合、より**安定した解**を生成
- ML, DLにおける利用例:
  - 過学習抑制：Weight decay・・・正則化手法
  - RNN：勾配クリッピング・・・勾配爆発対策

## 主な違い

1. スパース性:
   - L1ノルムは疎な解(多くの要素が0)を生成しやすい
   - L2ノルムは密な解を生成する傾向がある

2. 特徴選択:
   - L1ノルムは自動的に特徴選択を行う
   - L2ノルムは全ての特徴を保持する

3. 外れ値への感度:
   - L1ノルムは外れ値の影響を受けにくい
   - L2ノルムは外れ値に敏感

4. 解の一意性:
   - L1ノルムは必ずしも一意の解を持たない
   - L2ノルムは通常一意の解を持つ

5. 計算効率:
   - L1ノルムは解析的な解が存在しないため、計算が複雑になることがある
   - L2ノルムは解析的な解が存在し、効率的に計算できる


目的に応じてL1ノルムまたはL2ノルムが選択される。
例えば、**特徴選択が重要な場合はL1正則化、モデルの安定性が重要な場合はL2正則化**が用いられることが多い。
科学、学問とは何なのか?我が父の言葉より

科学や学問とは何であるのか?
我が父である故萩行正憲の蔵書に示唆深い書き込みがされていたので紹介したい。
肝心の蔵書のタイトルを記録し忘れたので、そこは後日補完したい。

その書き込みは統計力学の本に記載されており、本の出版年数的に父が学部時代に記述したものと思われる。

まずは該当部分の本の記述を紹介する。

>現在のわれわれは、この中にただ哲学するためだけの思想が、いかに無為無益であるかを知るのみなのであるが、当時Ostwaldは力学的自然観に立つBoltzmannとの華々しい論争においても破れることはなかった。

背景としては、統計力学の歴史において、Ostwaldらがエネルゲティークという概念を提唱していたが、Boltzmannらとの論争の結果、現在においてはエネルギティークはほぼ否定されている、とうことがある。

この一文に対して、父の書き込みが2つされてる。

> Mach、Ostwaldらにとっては決してそうではない。本来学問とは、何かを発展させることに源を発するのではなくて、その人自身の世界観、たとえそれが、無為無益に見えようとも、をつくりだすためのものなのである。アインシュタインの晩年の仕事も、彼の世界観の統一として彼には必要だったのだ!

> このイミではOstwald自身の世界観は完全にイジされたのでアル。たとえ 現在 Bolztman流の考えが風ビしておろうとも、エネルゲティークが復活する日がくるかもしれぬということは頭の中にいれておくべきだ。
> 科学がいかにたくみに自然を表現しようとも、人の心の中までは潤すわけにはゆかない。いろいろ考えること自体が科学であるという立場を僕はとりたい。


科学や学問とはどうあるべきなのか?人によって考えはあると思うが、私自身はこの父の考えを大切にしたい。

最後に父の座右の銘を紹介しておきたい
> 世の中は皆さんが思っているより深くて不思議で面白い
Visual Studio Coce メソッドの簡単作成方法

Visual Studio Codeでメソッド化する場面に使える便利なショートカットです


メソッド化したいものを囲み電球マークをクリック→メソッドを抽出する
![スクリーンショット 2024-10-27 12.21.06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3893700/e05b0b60-cb66-16d0-66ea-68607a7172c0.png)
BFFにおけるFIDO認証の認証登録と認証の流れ

## はじめに
FIDO認証の認証登録と認証の流れを整理する

## 前提
- 登場人物はフロントエンド（アプリ・InAppブラウザ）、BFF、バックエンド、認証サーバ
- 異常系は考えない
- Attestation（※１）は使用しない

※１ 認証情報の証明で、セキュリティと信頼性を向上させるため使用される

## FIDO認証の登録の流れ

|フロントエンド（アプリ）|フロントエンド（InAppブラウザ）|BFF|バックエンド|認証サーバ|
|:----|:----|:----|:----|:----|
|１．InAppブラウザでFIDO認証をサポートするウェブサイトにアクセス（デバイス登録の開始）| | | | |
| |２．BFFにデバイス登録のリクエスト送信（フロントエンドからのPOST①）| | | |
| | |３．バックエンドにリクエスト送信（BFFからのPOST②)| | |
| | | |４．認証サーバにリクエスト送信（バックエンドからのPOST③）| |
| | | | |５．認証サーバがチャレンジコード（※１）を作成|
| | | |６．認証サーバからレスポンス（チャレンジコード）受信（POST③のレスポンス）| |
| | |７．バックエンドからレスポンス（チャレンジコード）受信（POST②のレスポンス）| | |
| |８．BFFからレスポンス（チャレンジコード）受信（POST①のレスポンス）| | | |
|９．In-Appブラウザが受信したレスポンスを受取る| | | | |
|１０．生体認証を実施| | | | |
|１１．公開鍵と秘密鍵のペアを作成| | | | |
|１２．秘密鍵を保存| | | | |
|１３．チャレンジコードを署名（秘密鍵で署名）| | | | |
|１４．InAppブラウザに公開鍵と署名を渡す| | | | |
| |１５．BFFに公開鍵と署名を送信（フロントエンドからのPOST④）| | | |
| | |１６．バックエンドに公開鍵と署名を送信（BFFからのPOST⑤）| | |
| | | |１７．認証サーバに公開鍵と署名を送信（バックエンドからのPOST⑥）| |
| | | | |１８．署名を検証（公開鍵で署名を検証）しチャレンジコードを取得|
| | | |１９．認証サーバからレスポンス（検証結果）受信（POST⑥のレスポンス）| |
| | |２０．バックエンドからレスポンス（検証結果）受信（POST⑤のレスポンス）| | |
| |２１．BFFからレスポンス（登録成否）受信（POST④のレスポンス）| | | |
|２２．処理を完了（デバイス登録の完了）| | | | |

※１ 認証プロセスの一部として利用されるサーバーがユーザに対して送るランダムな文字列、チャレンジと表現することが多い

## FIDO認証の流れ

|フロントエンド|InAppブラウザ|BFF|バックエンド|認証サーバ|
|:----|:----|:----|:----|:----|
|１．InAppブラウザでFIDO認証をサポートするウェブサイトにアクセス（認証の開始）| | | | |
| |２．BFFに認証リクエストを送信（フロントエンドからのPOST①）| | | |
| | |３．バックエンドにリクエスト送信（BFFからのPOST②）| | |
| | | |４．認証サーバにリクエスト送信（バックエンドからのPOST③）| |
| | | | |５．チャレンジコードを作成|
| | | |６．認証サーバからレスポンス（チャレンジコード）受信（POST③のレスポンス）| |
| | |７．バックエンドからレスポンス（チャレンジコード）受信（POST②のレスポンス）| | |
| |８．BFFからレスポンス（チャレンジコード）受信（POST①のレスポンス）| | | |
|９．In-Appブラウザが受信したレスポンスを受取る| | | | |
|１０．生体認証を実施| | | | |
|１１．チャレンジコードを署名（秘密鍵で署名）| | | | |
|１２．InAppブラウザに署名を渡す| | | | |
| |１３．BFFに署名を送信（フロントエンドからのPOST④）| | | |
| | |１４．バックエンドに署名を送信（BFFからのPOST⑤）| | |
| | | |１５．認証サーバに署名を送信（バックエンドからのPOST⑥）| |
| | | | |１６．認証サーバが署名を検証（公開鍵で署名を検証）しチャレンジコードを取得|
| | | |１７．認証サーバからレスポンス（認証結果）受信（POST⑥のレスポンス）| |
| | |１８．バックエンドからレスポンス（認証結果）受信（POST⑤のレスポンス）| | |
| |１９．BFFからレスポンス（認証成否）受信（POST④のレスポンス）| | | |
|２０．認証を完了（認証の完了）| | | | |

## 認証登録と認証の違い
- 認証登録のみ、秘密鍵と公開鍵を生成
- 認証登録のみ、公開鍵を認証サーバに送信

## まとめ
（実際に実装するのは難しいだろうが、）
整理すると公開鍵暗号方式にフロントエンドの認証（例では生体認証）が組み込まれているだけでそこまで複雑ではない
【ABC377】AtCoder Beginner Contest 377【C++】

### コンテスト名
トヨタシステムズプログラミングコンテスト2024（AtCoder Beginner Contest 377)

### コンテストURL
https://atcoder.jp/contests/abc377

### 開催日
2024/10/26 21:00-22:40

---

## [A: Rearranging ABC](https://atcoder.jp/contests/abc377/tasks/abc377_a)
**解法**
- 文字列を昇順にソートして `ABC` と一致するか判定する
```cpp:ABC377A.cpp
#include <iostream>
#include <string>
#include <algorithm>
using namespace std;

int main(){
    string s;
    cin >> s;
    
    sort(s.begin(), s.end());

    if(s=="ABC"){
        cout << "Yes" << endl;
    }else{
        cout << "No" << endl;
    }

    return 0;
}
```

## [B: Avoid Rook Attack](https://atcoder.jp/contests/abc377/tasks/abc377_b)
**解法**
- コマが一つも置かれていない列数と行数の積が求める答えである
```cpp:ABC377B.cpp
#include <iostream>
#include <vector>
#include <string>
using namespace std;

int main(){
    vector<string> G(8);
    for(int i=0; i<8; i++){
        cin >> G[i];
    }

    int cnt1 = 0, cnt2 = 0;
    for(int i=0; i<8; i++){
        bool flag1 = true, flag2 = true;
        for(int j=0; j<8; j++){
            if(G[i][j]=='#'){
                flag1 = false;
            }
            if(G[j][i]=='#'){
                flag2 = false;
            }
        }
        if(flag1){
            cnt1++;
        }
        if(flag2){
            cnt2++;
        }
    }

    cout << cnt1 * cnt2 << endl;

    return 0;
}
```

## [C: Avoid Knight Attack](https://atcoder.jp/contests/abc377/tasks/abc377_c)
**解法**
- コマが置かれているマスとコマが移動できるマスを `set<pair<int, int>>` に記録する
- マス数 $N^2$ からコマが置かれているマスとコマが移動できるマスの合計を引いた数が求める答えである
```cpp:ABC377C.cpp
#include <iostream>
#include <set>
#include <cmath>
using namespace std;

int main(){
    long long int n;
    int m;
    cin >> n >> m;

    set<pair<int, int>> S;
    int a, b;
    int cnt = 0;
    for(int i=0; i<m; i++){
        cin >> a >> b;
        S.insert({a, b});

        for(int j=-2; j<=2; j++){
            for(int k=-2; k<=2; k++){
                if(j==0 || k==0 || abs(j)==abs(k)){
                    continue;
                }
                if(abs(j)==abs(k)){
                    continue;
                }
                if(a+j<1 || a+j>n || b+k<1 || b+k>n){
                    continue;
                }

                S.insert({a+j, b+k});
            }
        }
    }

    
    cout << n*n - S.size() << endl;

    return 0;
}
```

## [D: Many Segments 2](https://atcoder.jp/contests/abc377/tasks/abc377_d)
**解法**
- 区間の右端を固定して条件を満たす左端の個数を数える
- 各右端について、最も大きい左端を `vector<int>` に記録しておく
```cpp:ABC377D.cpp
#include <iostream>
#include <vector>
using namespace std;

int main(){
    int n, m;
    cin >> n >> m;

    vector<int> V(m+1);
    int l, r;
    for(int i=0; i<n; i++){
        cin >> l >> r;
        if(V[r]<l){
            V[r] = l;
        }
    }

    for(int i=1; i<=m; i++){
        if(V[i]<V[i-1]){
            V[i] = V[i-1];
        }
    }

    long long int cnt = 0;
    for(int i=1; i<=m; i++){
        cnt += i - V[i];
    }

    cout << cnt << endl;

    return 0;
}
```
【合格体験記】Python3 エンジニア認定基礎試験

こんにちは。今回はOdysseyの[Python3 エンジニア認定基礎試験](https://cbt.odyssey-com.co.jp/pythonic-exam/python3basic.html)を受験し、無事に合格することができたので学習方法や試験を受けての所感をまとめたいと思います。
![スクリーンショット 2024-10-27 10.48.41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3853136/1f136512-0f1e-a365-34a8-3e3e6fa2c09c.png)

## 1. 背景
私は今年からIT系の会社に新卒入社し、エンジニアとして業務を行っています。業務ではクラウド（主にAWS）によるシステム構築を行っていますが、Pythonを用いてコーディングを行うこともあります。
入社前は大学・大学院でバイオインフォマティクス研究室に所属しており、Pythonのコーディングは5年ほど使用経験がありましたが、業務で扱う上では標準的な知識が足りていないなと感じたため受験をすることにしました。

## 2. 勉強方法
上述の通り元々5年ほどPython経験はあったため、知識面のインプットに絞り１週間の学習期間で行いました。具体的な教材、内容は以下の通りです。（Python初学者というよりは、少し触ったことがあり資格取得も考えているという方の参考になるかと思います。）

① **[徹底攻略Python 3 エンジニア認定［基礎試験］問題集](https://aoten.jp/store/detail.html?c1=%E8%B3%87%E6%A0%BC%E5%AF%BE%E7%AD%96%E6%95%99%E6%9D%90&c2=Python%E3%82%A8%E3%83%B3%E3%82%B8%E3%83%8B%E3%82%A2%E8%AA%8D%E5%AE%9A%E8%A9%A6%E9%A8%93&no=a2400i_y230309)**
まず本書で分野別に問題を解き、知識が不足している点を特定しました。問題数も12分野×10問程度と取り掛かりやすく、公式問題集なので網羅性も高いため実際の問題のレベル感を知る上でも役に立ちました。最後の1回分の模擬試験も含め「3日で1週を2セット」繰り返しました。

② **[ExamApp](https://python-basic.com/)・[PRIME STUDY](https://study.prime-strategy.co.jp/)**
①を1セット終えた後は、これらのサイトの模擬試験を行いました。各サイト3回分（ExamAppは初級〜上級のレベル別）あり、1日に複数回取り組む日もあり「計6回を2セット」繰り返しました。複数の模擬試験に取り組むことで、正答以外の選択肢からもより細かな知識をインプットできたり、同じ事象・概念の異なる説明のされ方を押さえることができました。

③ **[Pythonエンジニア育成推進協会監修 Python実践レシピ](https://www.amazon.co.jp/dp/4297125765)**
後続の[Python3 エンジニア認定実践試験](https://cbt.odyssey-com.co.jp/pythonic-exam/python3cpe.html)も受験を予定しているため購入していました。①②で知識が不足していると感じた点は、まず本書で該当項目を辞書的に使用してインプットしました。また、if文やfor文の挙動などはネットでの検索、[Google Colaboratory](https://colab.research.google.com/)を用いた簡単な動作確認も行いました。（やはり実際にコーディングして動きを確かめることが一番手っ取り早いです！）

## 3. 所感
1週間という短期間ではありましたが、上記の学習を通して満点で合格することができました。学習の中でPythonの標準的な記述方法や文法事項、標準モジュールの使い方など知らなかった知識を体系的に整理することができ、受験を通じた目的は達成できたかなと感じています。今までコーディング経験はありましたが都度調べながら場当たり的に知識が増えていたこともあり、今回の機会は個人的にかなり有意義なものだったと感じています。
もっと早く受けておけば良かったと思う反面、元々の経験値があったからこそ早く正確に理解を進められたのかなとも思います（卵が先か鶏が先かの話ですが...）
この後は引き続き実践試験も受験を予定しています。また今回の学習を通じて、データ分析試験も取りたいなと思い始めました（NumPyやPandasも経験的な知識しかないので...）

[2024/11/26　追記]
実践試験の体験記を投稿しました↓

https://qiita.com/rizumu620/items/48da84417bad528d9e70

##
今回は以上です。ご覧いただきありがとうございました！
BootloaderアンロックしたXQ-BT44を元に戻す

# 概要

これを元に戻す。

https://qiita.com/g3TXQMKpO1uZyRa8IleF/items/44d69029f723bed210bd

## 前提

以下が残っていること
* boot.img
* tadump_2.ta

fastboot と flashmode のドライバがインストールされていること。
* Flashtool-drivers.exe を使えばインストールできる。
* Windowsのドライバの署名強制を無効化する必要あり。

## 手順

* ボリューム↑を押しながらPCとUSB接続を行い、以下のコマンドでデバイスを確認する。
```
> fastboot devices
XXXXXXXXXX       fastboot
```
* boot.imgを書き込む。
```
> fastboot flash boot boot.img
Sending 'boot_a' (98304 KB)                        OKAY [  0.397s]
Writing 'boot_a'                                   OKAY [  0.646s]
Finished. Total time: 1.089s
```
* Bootloaderをロックする
```
> fastboot oem lock
OKAY [ 32.853s]
Finished. Total time: 32.855s
```
* 一度XQ-BT44を起動し、「erasing」と表示→起動したらシャットダウンする。
* tadumpフォルダ内の`tadump_2.ta`に`newflasher.exe`をコピーする。
* ボリューム↓を押しながらPCとUSB接続後、newflasherを起動する。
* n > s > n でリストア開始(ここに別の.taファイルがあったりするとそれも書き込まれるため注意)
* 再起動
Chatter Free Userプロファイルなど、プロファイルの編集画面からデフォルトのレコードタイプを変更できない場合

### 一部プロファイル画面にはレコードタイプが表示されないため、変更できない。
プロファイル
Chatter External User

レコードタイプのセクションがなし：
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3894299/a748e75b-5b6f-e5d6-2029-13eb1389b279.png)

### 変更手順

No1. プロファイル画面にアクセスし、URLをCopy

httpｓ://xxxxx.lightning.force.com/lightning/setup/EnhancedProfiles/page?address=%2F**00e5h000000Qt7t**

「00e」で始まる 15 文字の ID は、プロファイルの ID

No2. 画面右上のプロフィールから [Salesforce Classic に切り替え]をクリック


No3. [設定] | [ユーザの管理] | [プロファイル] をクリックし、**標準のシステム管理者** プロファイルをクリックし、[レコードタイプの設定] までスクロールして、無効化 / 削除するレコードタイプを含むオブジェクトの横にある [編集] リンクをクリック

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3894299/35b5acb3-f400-9fe6-c37f-4eb51452c022.png)

URLをコピー
httpｓ://xxxxx.my.salesforce.com/setup/ui/profilerecordtypeedit.jsp?id=**00e5h000002YBcS**&tid=Event&pn=%25E3%2582%25B7%25E3%2582%25B9%25E3%2583%2586%25E3%2583%25A0%25E7%25AE%25A1%25E7%2590%2586%25E8%2580%2585&retURL=%2F00e5h000002YBcS

No4. No1で取得したIDをNo3のURLのid=00e部分を書き換える

No5. No4のURLにアクセスすると、レコードタイプ編集画面が表示されるので、他のプロファイルと同じ操作をする
無線LANのアクセス制御

有線のアクセス制御は調べたので、無線の方も調べる

>無線LANは、CSMA/CA方式によって通信を制御しています。CSMA/CD方式に似ているところが異なりますが、`「衝突検出」の部分が「衝突回避」になっている`ところが異なります。
　無線LANは、物理層媒体として`電波を使うため、衝突の検出ができません`。そこで、衝突を検出するのではなく、回避しようというのがCSMA/CA方式です。

衝突を回避する

# 特徴
>* 送信を行うノードは、`利用したい周波数帯が使われていないかを確認`後、`必ずランダムな時間だけ待って`から送信を開始する。この`待ち時間をバックオフ制御時間`という。
>* 衝突が発生し、フレームが壊れてしまってもそれを検出できないため、データを受け取ったノードは`ACKを応答することがデータを正常に受け取ったことを検知`する。
>* 送信側ノードは、設定時間内に`ACKを受信できなければ、干渉が発生したと判断して一定時間後に再度送信`する。

ACKを受信しない限り再度送信する
### ACK(アック）
>ACKnowledgementの略。データ通信において｀受信側から送信側に送られる`、データを`正常に受信したことを示す信号`。ACKが届かない場合には送信側は同じデータを再送する。低速回線では遅延の原因にもなる。

https://cn.teldevice.co.jp/glossary/11921/


# RTS/CTS
>無線LANでは、通信するノード間の`距離が離れすぎていたり、ノード間に障害物がある`場合は、お互いに他のノードがデータ送信していることを検知できないため衝突が生じます。これを`隠れ端末問題`といい、これを回避するための方式にRTS/CTS方式があります。
　無線LANノードは、データを`送信する前にRTS（送信リクエスト）をアクセスポイントに送信`し、これを`受理したアクセスポイントがCTS（送信OK）を返信`したらデータ送信を開始します。CTSには、他のノードに対する`送信抑制時間が記載されていて、衝突を抑制`します。
 なお、データ送信を開始する前に、データ送信のネゴシエーションとしてRTS/CTS方式を用いた`CSMA/CAをCSMA/CA with RTS/CTS`といいます。

https://gihyo.jp/book/2023/978-4-297-13865-3

 # 感想
 疑問が出ていないことがまずいと思う。
 どこかでまたつまづくだろう

https://www.global.toshiba/content/dam/toshiba/migration/corp/techReviewAssets/tech/review/2015/01/70_01pdf/f02.pdf
資料作成が嫌いな自分へ

「●●の資料を作って」と言われたら、いきなりパワポ、エクセルを起動していませんか。最近経験の浅いメンバーの作業を見る機会があり、なんか混乱しているなぁと思うことが多かったので、少しまとめてみます。

# 作業に取り掛かる前にまずは考える
仕事の早い人を見ていると、実際にパワポを開く、コードを書きだすまでの時間が長いです。それまでに何をしているかというと、図を書いたり、何か調べたり、作業の前準備をしている時間が長いです。そのうえで、いざコードを書きだすとガーッと数時間で終わっていました。

# 資料大枠を考えよう
4W1Hで考えます。（Whichは考えても出ませんでした。。）

- Why: なんのための資料か
    - 資料はどう利用されるのか？
    - その資料をベースに次のStepは何があるのでしょうか。それを踏まえて、今の資料ではどこまでの詳細度に落とすべきですか。
　
- What: 何を決めたいのか
    - 資料で決めたい、話したい内容はなんですか？
    - 確認ポイントはまずは一覧化しましょう。
　
- How: どうやって作るか ＝ 何をInputにするべきなのか？
    - 一般的な情報でしょうか？その場合何か業界のベストプラクティス的な使える情報はありますか？
    - 考慮すべきお客さんの社内ルールとか、過去のプロジェクトの情報とかはありますか？
　
- Who: 誰が読み手なのか
    - 誰にこの資料を見せるべきでしょうか？
    - お客さんはあなたが作った資料をどうレビューするのか？いきなり詳細データの一覧を見せてもお客さんは面食らうでしょう。
    - 前提として、例えばAzureのアーキテクチャの資料なのであれば、お客さんはAzureを知っているのか？もしかしたらAzureの基礎的な部分も説明した方がよいのでは？ZoneやRegionと言ってお客さんに通じるのか？
　
- When: いつまでに作るべきか？
    - それにより、求められる資料の完成レベルが異なります。明日までにであれば、まずは議論のたたき台となるものを早めに提供すべきでしょう。（どんな複雑な資料でも、1日くらいで中間成果物を誰かに見せてもいいと思いますが。まずは図とかは後回しにして、文字だけでもいいでしょう。）
　

これらのことはOneNoteとかに自分用にまとめるのがおすすめです。
または、今作る資料をもとに、今後さらなる作業が予定されている場合、お客さん向けに今後の作業流れをまとめたスライドを1枚頭に載せてもいいでしょう。

# フレームワークで考える
適当にブラウジングして得た情報で作成した資料だと網羅感に不安が残ります。

既存のフレームワークやベストプラクティスを積極的に利用しましょう。フレームワークでMECEに考えることでぐっと説得力が増すし、お客さんもレビューしやすくなります。第一自分も考えるのが楽です。

[IPAの非機能要件グレード](https://www.ipa.go.jp/archive/digital/iot-en-ci/jyouryuu/hikinou/ent03-b.html)

[IPAの各種ドキュメントテンプレート](https://www.ipa.go.jp/archive/digital/tools/ep/ep2.html)

[Azure Architecture Center](https://learn.microsoft.com/ja-jp/azure/architecture/)

[ゼロトラストによるセキュリティ](https://learn.microsoft.com/ja-jp/training/modules/introduction-zero-trust-best-practice-frameworks/)

[UML](https://www.cybermedian.com/ja/a-comprehensive-guide-to-14-types-of-uml-diagram/#UMLsabeino_zhuang_taitoha_hedesuka)

[Amazonのいろんな設計書のテンプレートをまとめた本](https://www.amazon.co.jp/%E3%82%A8%E3%83%B3%E3%82%B8%E3%83%8B%E3%82%A2%E3%81%AA%E3%82%89%E7%9F%A5%E3%81%A3%E3%81%A6%E3%81%8A%E3%81%8D%E3%81%9F%E3%81%84-%E3%82%B7%E3%82%B9%E3%83%86%E3%83%A0%E8%A8%AD%E8%A8%88%E3%81%A8%E3%83%89%E3%82%AD%E3%83%A5%E3%83%A1%E3%83%B3%E3%83%88-%E6%A2%85%E7%94%B0%E5%BC%98%E4%B9%8B/dp/4295013145#customerReviews)

等など

# 基礎知識を身に着ける

ちゃんと基礎知識を身に着けて資料を作りましょう。いろんな個人Webサイトを読んでみてもツギハギ感がぬぐえません。ただ、いきなり長大な公式ドキュメントを読むのはつらいということもあると思います。

そんな場合、Microsoft技術であれば、以下のページのTraining Catalogからクイックに特定領域について学ぶことができます。以下はTrainingを脅威モデリングについてLearning Pathで絞った例。

https://learn.microsoft.com/ja-jp/training/browse/?terms=%E8%84%85%E5%A8%81%E3%83%A2%E3%83%87%E3%83%AA%E3%83%B3%E3%82%B0&resource_type=learning%20path

個人的にですが、Microsoftのドキュメントは複雑で読む気をなくしますが、Trainingの資料はかなりわかりやすく概念から説明してくれている印象です。いたずらにいろんなページに飛びまくらないのが良い。
SQLについて（超初心者の覚書）

データベースとSQLについて学んでいます。

SQL、プログラミングを学び始めてよく聞くけど何のことだろうと思っていました。
データベースを操作するための言語がSQLということを初めて知りました。
（Structuresd　Query Language、略してSQL、なるほど）
データベースを作ったり呼び出したり命令が必要で、そのためにSQLがあるんですね。

さらにSQLにも３種類の命令文（言葉）があります。
１．データ定義言語（Data Definition Language。略してDDL）
２．データ操作言語（Data Manipulation Language。略してDML）
３．データ制御言語(Data Control Language。略してDCL)

何の違いがあるのやら？と思ったので、簡単に説明します。

１．データ定義言語（DDL）
Definitionは「定義」です。なので、データを定義（データの入ってる「テーブル」の作成、変更、削除）するための命令と思えばよさそうです。

２．データ操作言語（DML）
Manipulationは「操作」です。データを操作する（データそのものを検索、追加、削除）するための命令と思えばよさそうです。
DDLとの違いはデータの入っている入れ物（テーブル）に関する命令なのか、それともデータそれ自体に対する命令なのか、と分けて考えたら違いがわかりやすそうです。

３．データ制御言語(DCL)
Controlは「制御」です。データベースに対するユーザーへの権限付与や剥奪に使うようです。

自分がこれからSQLでいろいろ操作していくなら、DDLとDMLの勉強を進めていけばいいなと方針が定まってきました。
まだまだ勉強したてでわからないことが多いですが、学んだことがあれば記事にしていきます。
よく見かけるクラスからnewしたオブジェクトについて

# 概要
クラスからnewしたオブジェクトが戻り値として帰ってきた場合、以下のような表記を見ることが多いと思います。
```rb
class Test

end
```


```rb
(ruby) t = Test.new
#<Test:0x000000010c4f4130>
(ruby) t.class
Test
```

クラス自身の戻り値は、クラス自身が返ってきます
```rb
(ruby) Test
Test
```

クラスからnewしたオブジェクトをto_sすると、Stringクラスのオブジェクトになります。
```rb
(ruby) t.to_s
"#<Test:0x000000010c4f4130>"
(ruby) t.to_s.class
String
```

# まとめ

個人的に
```rb
#<Test:0x000000010c4f4130>
```
こういう表記を見た時に「これはnewされたインスタンス自身である」という事を意識できないことがあり、記事を書きました。

単純ではありますが、パッと見た時にこれがなんであるのか、気づけるようになりたいと思います。

ログなどで大量に出力されている時やデバッカーで確かめている際に、これが何なのか即知りたい需要があり書いた
ruby Array#permutation メソッド

# Array#permutationとは

### 1.配列の順列を全て返す

```ruby
arr = [1,4,6]
pp arr.permutation.to_a
```
```terminal:結果
[[1, 4, 6], [1, 6, 4], [4, 1, 6], [4, 6, 1], [6, 1, 4], [6, 4, 1]]
```

引数に数字を渡すと、その長さの順列を返してくれます。

```ruby
arr = [1,4,6]
pp arr.permutation(2).to_a
```
```terminal:結果
[[1, 4], [1, 6], [4, 1], [4, 6], [6, 1], [6, 4]]
```

※範囲以上の数字を渡すとnilです。
```ruby
arr = [1,4,6]
pp arr.permutation(4).to_a
```
```terminal:結果
[]
```

また、返り値はArrayではなくEnumeratorが返るので、配列として取得してしまいたい場合はto_aが必要になります。

https://docs.ruby-lang.org/ja/latest/class/Enumerator.html

### 2.ブロックを渡す
ブロックを渡した場合、その場で結果を利用するのでto_aは必要ありません。
（Enumeratorは遅延評価で必要な時に結果を生成する）
渡された処理を結果配列の各要素に実行してくれます。

```ruby
arr = [1, 4, 6]
result = []
arr.permutation(2) {|e| result << e}
pp result
```
```console:結果
[[1, 4], [1, 6], [4, 1], [4, 6], [6, 1], [6, 4]]
```

競プロで、値が小さい全探索に利用できそうです。
[tips][cpp] std:: priority_queue

# 優先度付きキュー

処理順番を指定してデータを溜めておける。

優先順位はデフォルトでは、[less](https://cpprefjp.github.io/reference/functional/less.html)が指定されていて、データは大きい順に並ぶ。このため、`top()`や`pop()`で先頭要素を参照したり、先頭要素を削除したりする。結果、降順に処理される。

[greater](https://cpprefjp.github.io/reference/functional/greater.html)を指定すれば、データが小さい順に並ぶので、昇順に処理される。

※追記
[`pop()`](https://cpprefjp.github.io/reference/queue/queue/pop.html)では、`front()`が呼び出され、先頭要素を削除する。


テンプレート第三引数について

- less: 
降順処理
イメージ
$x_1 > x_2 > x_3 > ... > x_n$ で`top()`/`pop()`で参照/削除するのは$x_1$


- greater: 
昇順処理
イメージ
$x_1 < x_2 < x_3 < ... < x_n$ で`top()`/`pop()`で参照/削除するのは$x_1$




Containerはデフォルトではvector。[deque](https://cpprefjp.github.io/reference/deque/deque.html)も使用できる。

ランダムアクセスイテレータもち、次のメンバを実装すれば、独自のコンテナを使用できる。

- `front()` 
- `push_back()` 
- `pop_back()` 
- `emplace_back()`

リファレンスにある例に追加します。

```cpp
#include <iostream>
#include <queue>
using namespace std;
int main()
{
  // 昇順に処理する
  {
    priority_queue<
        pair<int, string>,              // 要素の型はpair<int, string>
        vector<pair<int, string>>, // 内部コンテナはstd::vector
                                        // (デフォルトのまま)
        greater<pair<int, string>> // 昇順 (デフォルトはstd::less<T>)
        >
        que;

    que.push({10, "foo"});
    que.push({20, "bar"});
    que.push({30, "baz"});

    while (!que.empty()) {
      cout << "first: " << que.top().first << ","
                << "second: " << que.top().second << endl;
      que.pop();
    }
  }
  return 0;
}
```

output
```cpp
first: 10, second: foo
first: 20, second: bar
first: 30, second: baz
```


# 参考

https://cpprefjp.github.io/reference/queue/priority_queue.html
https://atcoder.jp/contests/tessoku-book/tasks/tessoku_book_ba
Dartにおける変数の修飾子

# Dartの主な修飾子
Dartで扱うことのできる変数宣言時の修飾子は主に以下の5つ
- var
- final
- const
- late

それぞれの特徴と制約を覚えて効率よく変数を扱えるようになりたい！

ということでまとめていきます。

## var
`var`は動的型付けで、初期値から自動的に型を決定します。
割り当てられた初期値の型が変数の型となります。

```dart
var count = 0; // int型と推論される
count = 'Hello!'; // エラー
```
変数宣言時に初期化をしなくてもエラーにはなりませんが、その場合dynamic型かつnullable型として扱われ、静的型付けが可能なDartの利点が失われます。

また、初期化をされてない変数を利用することは予期せぬバグの原因に繋がるため、宣言時と同時に初期化をする利用方法が推奨されます。

## final
`final`は一度だけ値を設定可能であり、設定後は値の変更ができません。実行時に値が決定されます。

また、初期化前に変数を利用しようとするとエラーになります。

```dart
final int MAX_COUNT = 10;
MAX_COUNT = 100; // エラー

final int count;
count++; // エラー
```
## const
`const`はコンパイル時定数です。
宣言時の値を設定することが必須で、実行中に値を変更できません。

```dart
const String GREETING = 'Hello!';
GREETING = 'Have a Nice Day!'; // エラー

const MORNING_GREETING; // エラー（初期値なしの宣言はできない）
```
## late
`late`は遅延初期化を可能にします。
宣言時に初期化をする必要がなく、後で値を設定できます。
`var`と異なり、明示的に型を指定する必要があります。

こちらも初期化前に変数を利用しようとするとエラーになります。

```dart
late String greeting;

print(greeting); // エラー

greeting = 'Hello!'; // 後で初期化ができる
```

# まとめ
| 修飾子 | 再代入 | 初期化タイミング | 代入(初期化)可能な値の種類 |
|:-:|:-:|:-:|:-:|
| var  |  可能 | 宣言時  | 任意  |
| final  | 不可  | 実行時  | 任意  |
| const  | 不可  | コンパイル時  | 定数のみ  |
| late  | 可能  | 遅延（初回参照時）  | 任意  |
【CTF/Crypto】RSAの復号手順メモ

Crypto問のRSAの簡単な復号手順、参考になるサイトをメモ。

## RSA暗号
<dl>
  <dt>■ 与えられるもの</dt>
  <dd>公開鍵：$n, e$</dd>
  <dd>暗号文：$c$  </dd> 
  <dt>■ 導くもの</dt>
  <dd>秘密鍵：$d$</dd>
  <dd>平文：$m$ </dd> 
</dl>

■ **暗号化**
```math
c \equiv m^e  \pmod n
```
■ **復号化**
```math
m \equiv c^d  \pmod n
```
■ **式関係**
```math
\begin{gather}
n = p*q \\
\varphi(n): (p-1)*(q-1) \\
d*e \equiv 1 \pmod {\varphi(n) }
\end{gather}

```
※途中計算
```math
\begin{gather}
c^d \equiv (m^e)^d \equiv m \pmod n
\end{gather}
```
## 手順
### (1) nを素因数分解

ここが肝。これがクリアできれば解ける。
$n$を素因数分解し、$p$と$q$を求める。

以下のサイトでペアが見つかれば嬉しい。（誰かが素因数分解のペアを登録していないと見つからないらしい）

https://factordb.com/index.php

見つからなかった場合は、与えられた情報に素因数分解するためのヒントがあるはず。

### (2) 秘密鍵dを計算
復号化の式から$d$が求まれば$m$が分かる。次の計算で$e$の逆元$d$を求める。

```math
\begin{gather}
\varphi(n): (p-1)*(q-1) \\
d \equiv e^{-1} \pmod {\varphi(n) }
\end{gather}
```


### (3) 復号化
次の計算で$m$を求める。
```math
\begin{gather}
m \equiv c^d  \pmod n
\end{gather}
```
最後に$m$を文字列に変換する。



### プログラム

pythonでは次のように求められる。 
pycryptodomeをインストール
`pip install pycryptodome`
```python
from Crypto.Util.number import *

phi = (p-1)*(q-1)
d = pow(e, -1, phi)
m = pow(c, d, n)
print(long_to_bytes(m).decode())
```
:::note warn
pycryptodome関連のエラーが出た場合
:::
pip  installはできているが、下記のようなエラーが出たため、次のサイトを参考に対処した。（uninstall→installも試したが変わらず）
`ModuleNotFoundError: No module named 'Crypto'`

https://zenn.dev/shiraccc/articles/f527bafcf80794

pycryptodomeが上手くいかなくても次のように16進数から2桁ごとに区切って10進数の変換を行い、対応する文字に変換すれば良い。
```python
number = 123456
decoded_string = bytes.fromhex(hex(number)[2:]).decode('ascii')
print(decoded_string)
```



## 参考

https://scrapbox.io/soraie-other/%5BCTF%5D_RSA%E6%9A%97%E5%8F%B7%E3%81%AE%E3%81%BE%E3%81%A8%E3%82%81

https://qiita.com/orangehouse/items/78454a71cb40b00c4f47
分散処理システムについて

自分用の備忘録として記しています。
色々と詳細が不足していて申し訳ないです。


# 分散(処理)システム
　データや機能を各コンピュータに分散させ、利用者がネットワークを通してすべてのシステム資源を共有しながら効率よく処理できるように構築されたシステム。

### メリット
・局所的な機能追加や変更が比較的容易
・障害発生時も影響が局所化できる

### デメリット
・管理が煩雑
・セキュリティ対策がしづらい

### 代表例
・クライアントサーバシステム



# 集中処理システム
情報処理やシステムを一箇所に集中させたシステム。

### メリット
・管理しやすい
・セキュリティ対策がしやすい

### デメリット
・機能追加や変更に比較的対応しづらい
・一部の障害がシステム全体に影響する

### 代表例
・VDI(Virtual desktop infrastructure)
【データサイエンス】データサイエンスの実践について

## はじめに
　データサイエンスは、単に分析を行うだけではなく、ビジネス戦略を進化させ、経営判断に深いインパクトをもたらす手法です。しかし、正しく理解し活用するには、仮説構築の重要性を認識し、ビジネス視点を持った学びが欠かせません。本記事では、データサイエンスの本質を捉え、活用力を身につけるためのステップを紹介します。

## 第1章: データサイエンスの本質は「仮説」にあり
　データサイエンスの基本は「仮説構築」にあります。なぜそのデータが必要なのか、どのようにビジネスの成果につながるかをまず考えることが不可欠です。この段階を飛ばしてデータ分析を始めると、結果として「何のための分析だったのか」が不明瞭になり、無駄な投資と時間を浪費しかねません。常に「なぜなぜ分析」を行い、業務の背後にあるロジックを明確にし、実際の事業成果に直結する仮説を作り上げていきましょう。
### データサイエンスの8ステップ
- 目的設定
    プロジェクトの目的や達成目標を明確にする
- 課題の特定
    達成を妨げる問題点や課題を洗い出す
- 仮説構築
    問題解決に必要な仮説を立てる
- データ収集
    仮説検証に必要なデータを集める
- データ分析
    収集したデータを使い、分析を行う
- 解釈
    分析結果をビジネス上の成果に結びつける
- 巻き込み
    組織全体で理解し、実行に移すための行動計画を共有
- 実行と評価
    解釈に基づき改善点を反映し、評価を行う

## 第2章: 初級者向けデータサイエンスの学び方
　データサイエンスを初めて学ぶ方には、ビジネス事例から理解を深めることが効果的です。おすすめ書籍としては、『マネーボール』や『統計学が最強の学問である』など、具体的なビジネスの成功事例が挙げられます。これらの書籍では、データを駆使して成果を出した事例が紹介されており、データサイエンスが実際にどのように企業の利益向上に寄与するかが明確に理解できます。

## 第3章: データサイエンスの中級者向け学習と実務応用
　データサイエンスの基礎を学んだ後は、より実践的なスキルを身につけるため、分析手法やデータドリブンマーケティングに焦点を当てた中級書籍を取り入れるとよいでしょう。例えば『エクセルでできるデータドリブンマーケティング』や『完全特集統計学入門』などが挙げられ、これらは実務に役立つ実践的な手法や、データサイエンスの具体的な応用を学ぶための良い指針となります。

## 第4章: RやPythonによる高度なデータサイエンスの道
　本格的なデータサイエンティストを目指すためには、プログラミングスキルが不可欠です。RやPythonといった分析ツールを使いこなせることが、より高度なデータ解析やモデル構築の基礎となります。こうしたスキルを持つことで、データを用いた予測やパターン認識といった、ビジネスに革新をもたらすアプローチが可能になります。

## 第5章: データサイエンティストのキャリア形成とビジネス理解
データサイエンティストとしての成功には、ビジネスへの深い理解と現場での仮説構築・検証のスキルが求められます。
　キャリアの初期段階から企業のデータ部門で実務を積むか、**理系出身のエンジニア**としての経験を活かしてキャリアチェンジするルートが推奨されます。グローバルでも需要が高まり続けているため、ビジネスの課題を理解し、データ分析を通じて価値を生み出せる人材は非常に貴重な存在です。

## まとめ
　データサイエンスは、データを分析すること自体が目的ではなく、ビジネス価値を最大化するための「仮説構築と検証」に真の意義があります。そのため、データサイエンティストにとっては、分析技術以上にビジネスへの深い理解と現場の課題に基づいた視点が重要です。今後も需要が高まるこの分野で活躍するために、ビジネス課題の把握、仮説構築の力、そして分析技術をバランスよく磨き続けましょう。
基本設計を基本からまとめてみた【要求定義・要件定義】

## 要求定義とは？

- 基本的にはお客様が行う作業でシステムに求める仕様を定義したものを指す

## 要件定義とは？

- システムを開発する工程の中では『上流工程』と呼ばれるシステムの開発や導入前の一番最初に行うステップ

- 幅広いIT知識やノウハウが問われる上、お客様とのコミュニケーション及び折衝スキルが求められる

- 要件定義の段階でお客様が何を求めているかしっかりと吸い上げてこれから作るシステムの具体的な仕様や方向性、開発プロジェクトの進め方を決めていく

- お客様の要求に対して、できるできないを判断、代替案を提示、後継フェースに回したりを判断する

- 多くはPMが中心なり、要件定義書を作る
※ 要件定義工程の成果物が要件定義書

## 要件定義とは？

- 発注するお客様側へプロジェクト内容を説明することがメインの目的

- 要件定義の最終的な成果物は『要件定義書』と呼ばれるドキュメント

## 要件定義書とは？

- システム開発において開発会社側が作成するお客様側の具体的な要件や要望をシステムの専門家の立場からまとめた文書

- 『要件定義書』を作成する目的は、お客様側と開発側の認識合わせ目的を確実に達成できるシステムを開発すること

## 要件定義の具体的な内容

(1)システムの概要（目的・背景・課題・解決策）

(2)現状の業務要件(業務フロー・システム要件・システムフロー・システム導入後の業務フロー)

(3)現状の機能要件（必要な機能）

(4)非機能要件(セキュリティー・性能・運用)

(5)実行計画

## (1)システムの概要（目的・背景・業務課題・解決策）

- お客様と開発会社の認識あわせをするために目的、背景、業務課題を明記

- 業務課題に対し、システムの専門の立場からソリューションを検討し、アプローチ案を検討

## (2)現状の業務要件

- 業務要件とは、システムかの対象となる業務の定義のこと

- プロジェクトが進むにつれて業務フローを変更したり、増減などがあるので現状がどのようになっているか視覚手にわかるように記録をしておく

## (3)現状の機能要件

- 機能要件とは、システムに備える必要がある機能のこと

- どのプロセスに位置する機能か大中小に分けて管理を行い、各種機能の詳細をまとめる 

## (4)非機能要件

- 非機能要件とは、機能意外の要件のことを指す

①セキュリティ

- 実際に書く内容はシステムのセキュリティレベルデータの暗号化方法、アクセス制御の仕組み、セキュリティポリシーなど

- 目的と意図はデータの保護とシステムの安全性を確保するため

②性能・品質・パフォーマンス

- 実際に書く内容は、処理速度・応答時間・同時アクセス数・システムの安定性

- 目的と意図はユーザーの満足度を保証し、スムーズで快適な操作感を提供するために必要な項目

③保守・運用

- 実際に書く内容はシステムのメンテナンス計画・運用体制・バージョンアップの方針・障害対応プロセスなど

-　目的と意図はシステムの長期的な安定稼働を保証して将来的なトラブルやニーズの変化に柔軟に対応するために必要

④拡張性

- 実際に書く内容はシステムのスケーラビリティモジュール性・将来的な機能追加や拡張の容易さに関する方針について記載

-　目的と意図はビジネスの成長性や変化に伴うシステムの変更や拡張をスムーズに行えるようにするため

⑤実行計画

- 要件定義以降の開発を進める計画の事を指す

- スケジュール・予算・人員・使用する機器

## 要件定義書を作成する

①現状を把握分析する

- お客様と情報共有を入念に行い現状を把握分析する
- お客様にヒアリング
- お客様から提案依頼書や要求仕様書を受け取る

②課題の解決策を検討する

- 考えられた方法で本当に課題を解決できるのかを検討する 

③システム化対象のものを要件化する

- 解決策の中からシステム化の対象になるものを要件化する
- どの業務をシステム化するのか、どんな条件のシステムが必要なのかを定義する

④要件定義書の構成を決める

- 要件をわかりやすく伝えられるよう要件定義書の構成を決める

- 大項目 ⇨ 小項目など階層を立てることでわかりやすい構成になる

⑤項目ごとにわかりやすくまとめる

- 誰が見ても理解しやすい内容にする





## 参考サイト
[【システム・アプリ開発会社の選び方】要求定義・要件定義とは？要求定義書作成までの流れを説明します！おすすめする確認ポイントや観点を５つ のステップで解説☆約20分！#003](https://www.youtube.com/watch?v=WCDAoftSVNw)

[【システム・アプリ開発会社へ外注！】基礎解説！設計フェーズ・基本設計のプロセスや流れを説明します！13分で解説☆(株式会社GeNEE)](https://www.youtube.com/watch?v=2xCKvkPhUo4)
Elixir 二重リストのEnum／内部Enum操作

こんにちは！
プログラミング未経験文系出身、Elixirの国に迷い込んだ？！見習いアルケミストのaliceと申します。
今回は二重リストのEnum／内部Enum操作について学んだことをまとめます。

# 目的
二重リストのデータに対してEnum／内部Enum操作ができるようになる

## 実行環境
Windows 11 ＋ WSL2 ＋ Ubuntu 22.04
Elixir v1.17.0
Erlang v27.0


# 前提
- あらかじめ下記で二重リストの変数を定義しておきます
```diff_elixir:iex
list_of_lists = [[1, 2, 3], [4, 5, 6]]
```
- なお、本記事では
` [[1, 2, 3], [4, 5, 6]]`を「外側のリスト」
外側のリストより1階層深い`[1, 2, 3]`および`[4, 5, 6]`を「内側のリスト」と呼称しています


# やったこと
`Enum.with_index`と`Enum.map`でlist_of_listsを下記に更新したいとします
```diff_elixir:iex
updated_list_of_lists = [[1, 12, 3], [4, 5, 6]]
```

操作をまとめると下記の通りです
```diff_elixir:iex
updated_list_of_lists =
  list_of_lists
    |> Enum.with_index()
    |> Enum.map(fn
      {list, 0} ->
        list
        |> Enum.with_index()
        |> Enum.map(fn
          {value, 1} -> 12
          {value, _} -> value
        end)

      {list, _} ->
        list
    end)
```
以下に順を追って手順を解説します

## 1.Enum.with_indexでリストにインデックスを振る
```diff_elixir:iex
 updated_list_of_lists =
   list_of_lists
+    |> Enum.with_index()
```
この時点での断面です。
内側のリストにインデックスが付与されました
```
[{[1, 2, 3], 0}, {[4, 5, 6], 1}]
```

## 2.Enum.mapで操作対象のリストだけに絞り込む
1.のうちインデックスが0のものだけを操作したいので、Enum.mapで絞り込みます
```diff_elixir:iex
 updated_list_of_lists =
   list_of_lists
     |> Enum.with_index()
+    |> Enum.map(fn
+      {list, 0} ->
+        list
+ 
+      {list, _} ->
+        list
+    end)
```
この時点での断面です。
Enum.map内の分岐が書けました。
分岐後の処理はまだ書いていないので出力値は入力値から変わっていません
```
[[1, 2, 3], [4, 5, 6]]
```

## 3.2.で絞り込んだ後のリストにインデックスを振る
操作したい要素を含むリストを対象に、さらにその中の各要素にインデックスを振ります。
今回は内側のリストのうちインデックスが0のリストが対象ですので、`{list, 0}`の分岐後にインデックスを振ります
```diff_elixir:iex
 updated_list_of_lists =
   list_of_lists
     |> Enum.with_index()
     |> Enum.map(fn
       {list, 0} ->
         list
+        |> Enum.with_index()
 
       {list, _} ->
         list
     end)
```
この時点での断面です。
内側のリストのうち、インデックスが0のリストの各要素に内側のリストにのみインデックスが付与されました
```
[[{1, 0}, {2, 1}, {3, 2}], [4, 5, 6]]
```

## 4.Enum.mapで操作対象の要素だけを更新する
```diff_elixir:iex
 updated_list_of_lists =
   list_of_lists
     |> Enum.with_index()
     |> Enum.map(fn
       {list, 0} ->
         list
         |> Enum.with_index()
+        |> Enum.map(fn
+          {value, 1} -> 12
+          {value, _} -> value
+        end)
 
       {list, _} ->
         list
     end)
```
この時点での断面です。
欲しい出力を得られました
```
[[1, 12, 3], [4, 5, 6]]
```


# 余談
今回はEnum.with_indexとEnum.mapによる二重リストのEnum／内部Enum操作ができることを確認しましたが、もっと効率の良い手順が存在する気がします。
新しく学びを得たらまた記事化していきたいと思います


# ～Elixirの国のご案内～
↓Elixirって何ぞや？と思ったらこちらもどぞ。Elixirは先端のアレコレをだいたい全部できちゃいます:laughing::sparkles::sparkles:

https://qiita.com/piacerex/items/09876caa1e17169ec5e1

↓ゼロからElixirを始めるなら「エリクサーチ」がおすすめ！私もエンジニア未経験から学習中です。

https://elixir-lang.info/topics/entry_column


↓[We Are The Alchemists, my friends!:bouquet:](https://qiita.com/torifukukaiou/items/6bcd5bbb80df9e594e9e "Awesome-san's Awesome article")[^10]
Elixirコミュニティは本当に優しくて温かい人たちばかり！
私が挫折せずにいられるのもこの恵まれた環境のおかげです。
まずは気軽にコミュニティを訪れてみてください。[^11]


https://speakerdeck.com/elijo/elixirkomiyunitei-falsebu-kifang-guo-nei-onrainbian




[^10]: @torifukukaiouさんのAwesomeな名言をお借りしました。Elixirコミュニティを一言で表すと、これに尽きます。


[^11]: @kn339264さんの素敵なスライドをお借りしました。Elixirコミュニティはいろんな形で活動中！
とにかく優しいジャイアンを作った話

お疲れ様ですmczkです。
先日の休みに「ひたすら甘やかされてえな」と思い、
どんな言葉にも優しく返答してくれるジャイアンを作りました。

<br>
【使用したサービス】

・LINE Developers
・GAS
・Dify

<br><br>
最近流行ってるやつですね。
LINEからメッセージを送るとGASを挟んでDify呼び出して生成AIが返答してくれる仕組み。
<br><br>
完成！！！

質問①：自炊あきらめてもいいかな？
![IMG_4978.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2466674/344ac90f-2380-b253-4605-3fc1ce9a1dd5.jpeg)
<br>
質問②：仕事でうまくいかないときは？
![IMG_4977.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2466674/b14dc59c-5bff-c171-a65f-5162607c26fa.jpeg)






よろしければ友だち追加お願いします！！
ひたすら優しいジャイアンBot 

https://lin.ee/aXJxfCX



<br>
作り方だったりの詳細を知りたい人はXで@stifle904へDMくださいまし～。
Difyが便利すぎてLINEのアカウント量産しちゃいそう。
paizaラーニング問題集「【配列 2】立体で計算」を解いてみた

https://paiza.jp/works/mondai/b_rank_new_level_up_problems/b_rank_new_level_up_problems__calculate_in_three_dimensions

▼考え方

N=3(3×3×3)の三次元配列が与えられたことを想定し、3要素からなる縦列・横列・斜め列の和のうち最大値を求めるという前提で、説明します。

[概要]
3×3×3の立方体を考えます。要素は1～27の数字とします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3881331/65822ebc-e854-2d8b-ae24-ecc9ba5c9ccc.png)

[処理1]
x,z軸における縦列・横列・斜め列の和を計算します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3881331/42d41475-abfa-9366-aaee-752ad95dc79b.png)

[処理2]
y,z軸における縦列・横列・斜め列の和を計算します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3881331/3a6383d6-de0c-da4c-7587-8f13f9be9cca.png)

[処理3]
x,y軸における斜め列の和の計算を計算します。縦列・横列は処理1,2で計算済みです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3881331/0bdb3836-527c-abaa-d154-60d90bd3fb37.png)

[処理4]
x,y,z軸における斜め列の和の計算を計算します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3881331/516b14a7-6f54-017a-c006-0460ba07b151.png)

[処理5]
処理1～4で求めた列の和の最大値の計算をします。

▼コード
```py
########## 処理0(準備) インプット,リスト定義 ###########

N = int(input())

A = []

########## 処理1 x,z軸における縦列・横列・斜め列の和の計算 ###########

# xz: 縦列の和の計算用のリスト
xz = []

# xz_naname: 斜め列の和の計算用のリスト
xz_naname = [0]*2*N

# xz_tmp: 3×3の入力ごとに計算するためのリスト
xz_tmp = [[0]*N]*N

for i in range(N):

    for j in range(N):
        xz_tmp[j] = list(map(int,input().split()))
        A.append(xz_tmp[j])

    for j in range(N):
        xz.append(sum(xz_tmp[j]))
        xz_naname[2*i] += xz_tmp[j][N-1-j]

        for k in range(N):
            if j == 0:
                xz.append(sum(xz_tmp_r[k] for xz_tmp_r in xz_tmp))
            if j == k:
                xz_naname[2*i+1] += xz_tmp[j][k]

    xz_tmp = [[0]*N]*N

########## 処理2 y,z軸における縦列・横列・斜め列の和の計算 ###########

# yz: 縦列の和の計算用のリスト
yz = [0]*(N**2)

# yz_naname: 斜め列の和の計算用のリスト
yz_naname = [0]*2*(N**2)

s = 0
for j in range(N):
    for i in range(N):
        yz_naname[2*j] += A[(N-1)+(N-1)*i][j]
        yz_naname[2*j+1] += A[0+(N+1)*i][j]
        
        for k in range(N):
            yz[s] += A[j+N*k][i]
        s += 1

########## 処理3 x,y軸における斜め列の和の計算 ###########
########## ※縦列・横列は処理1,2で計算済み ###########

# xy_naname: 斜め列の和の計算用のリスト
xy_naname = [0]*2*(N**2)

for j in range(N):
    for i in range(N):
        xy_naname[2*j] += A[j+N*i][i]
        xy_naname[2*j+1] += A[j+N*i][(N-1)-i]

########## 処理4 x,y,z軸における斜め列の和の計算 ###########

# xyz_naname: 斜め列の和の計算用のリスト
xyz_naname = [0]*4

for j in range(N):
    xyz_naname[0] += A[(N-1)+(N-1)*j][0+j]
    xyz_naname[1] += A[(N-1)+(N-1)*j][(N-1)-j]
    xyz_naname[2] += A[(N*N-1)-(N+1)*j][0+j]
    xyz_naname[3] += A[(N*N-1)-(N+1)*j][(N-1)-j]

########## 処理5 処理1～4で求めた列の和の最大値の計算 ###########

print(max(xz + xz_naname + yz + yz_naname + xy_naname + xyz_naname))

```