OmniAICreator/Qiita-1.07M huggingface dataset:
HTTP通信とソケット通信の違い

## IOSエンジニアからインフラエンジニアに転身した僕の備忘録ネットワーク編

約一年半とある自社開発会社でiosエンジニアとして働いていましたが、最近インフラチームへ移動になりそこで学習したhttp通信とソケット通信の違いについて簡単にまとめてみようと思います！
初めてのQiita投稿のため温かい目で読んで頂けると幸いです！

## HTTP通信
特徴
クライアントとサーバー間で通信が行われる
接続は短命でリクエスト完了後に接続が終了する
ポート番号は80番(https通信は443番)

使用例：webページの表示、スマホアプリとサーバー間の通信

## ソケット通信
特徴
常時接続が可能
TCPまたはUPDを使って通信する
通信はバイト単位でやり取りされる
リアルタイム性が高い
チャット機能にはwebSocketがよく使われる

使用例：チャットアプリのチャット機能、オンラインゲーム

## HTTP通信とソケット通信の使い分け
データの正確性が求められる→HTTP通信
リアルタイム性が必要な場合→ ソケット通信

## まとめ・感想
元々iOSエンジニアとして仕事をしていた時もなんとなく認識していたhttp通信とソケット通信の違いについて改て調べて記事にまとめてみると、面白いなと実感しました！
今後も学習した内容を積極的に記事にしていきたいと思いました！！

間違いなどはぜひともコメントにて教えて頂けると幸いです！
またお会いしましょう！！
iPhoneのSafariで開いているページのデベロッパーツールをPCで開く方法

iPhoneとMacを使用して、「iPhoneのSafariで開いているページのデベロッパーツールをMacで開く方法」をご紹介します。

1. MacでSafariを起動します

2. iPhoneとMacをケーブルで接続します

3. iPhoneのSafariを再起動します

4. iPhoneのSafariで、デベロッパーツールを使用したいページを開きます

5. MacのSafariのメニューバーの「開発」をクリックします

6. 以下のような表示になっているはずなので、iPhoneにカーソルを乗せます

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2382613/6260ae4f-306a-409f-9bfb-46f4b59079f2.png)

7. デベロッパーツールを使用したいページ(タブ)をクリックします

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2382613/9cc1d39f-aa18-4347-b2b7-fa9589a8598d.png)

8. iPhoneのSafariで開いているページのデベロッパーツールが起動します！

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2382613/342dd2ab-8efe-43fb-bf55-adbc679e948a.png)
【完全ガイド】DatabuttonでUserGuardを設定する方法

# 【完全ガイド】DatabuttonでUserGuardを設定する方法

DatabuttonでWebアプリを開発していると、「このページにはログインユーザーだけアクセスさせたい！」という場面が出てきますよね。  
この記事では、Databuttonで`UserGuard`を設定する方法を初心者にもわかりやすく、ステップバイステップで解説します。

---

## ✅ UserGuardとは？

`UserGuard`とは、**認証されたユーザーだけに特定のページを表示する仕組み**のことです。  
Databuttonでは、各ページごとにこの設定が可能で、UI上から簡単に制御できます。

---

## 🚀 事前準備

以下の前提で進めます：

- Databuttonでアプリを作成済み
- Firebase認証 or Databutton標準の認証機能を有効化済み
- 認証が必要なページをすでに作成済み（例：`Dashboard.tsx`）

---

## 🛠️ UserGuardを有効化する手順

### 1. 対象ページを開く

Databuttonのエディタ左メニューから  
**`Pages` → `対象ページ（例: Dashboard）`** をクリック。

---

### 2. 🔐 シールドアイコンを探す

ページ名の横にある **盾（🛡️）のアイコン**を確認します。  
これは**UserGuardの設定アイコン**です。

---

### 3. 認証を有効にする

盾アイコンのメニューをクリックし、  
**「Enable auth（またはDisable authをOFFに）」** を選択します。

✅ これでこのページはログインしていないとアクセスできなくなります。

---

## 🔓 特定ページだけ認証を無効にする方法

一部のページ（例：`/public-dashboard`）を**誰でも見られるようにしたい場合**は、以下のように設定します：

1. 同様にページ名横の盾アイコンをクリック  
2. メニューから **`Disable auth`** を選択  
3. 認証なしでそのページがアクセス可能になります

---

## 🧪 動作確認

1. アプリをプレビュー
2. ログアウト状態で `/dashboard` にアクセスすると `/login` にリダイレクトされる
3. ログインすると `Dashboard` にアクセス可能になる

---

## 📝 補足：ログイン後にリダイレクトさせるには？

`UserGuard`は自動的にログイン後、元のページに戻してくれるように  
`/login?next=/目的のパス` を使っています。

ログインページの処理で `next` を読み取り、遷移するようにしましょう。

---

## ✅ まとめ

| 機能 | 設定方法 |
|------|----------|
| ページに認証をかける | 盾アイコン → Enable Auth |
| 誰でも見られるページにする | 盾アイコン → Disable Auth |
| ログイン後に戻る設定 | 自動で `next` パラメータがつく仕組み |

---

## 🧠 おまけ：UserGuardなしでも制御したいときは？

もしカスタムの認証ロジックを使いたいなら、`useCurrentUser()` や `AuthStatusProvider` を使って  
`user === null` のときに `<Navigate to="/login" />` などで制御することも可能です。

---

以上、DatabuttonでUserGuardを設定する方法の完全ガイドでした！  
認証管理はアプリの信頼性にも関わる大切なポイントなので、しっかり設定していきましょう。

## 🔗 関連リンク

- [Databutton公式サイト](https://databutton.com?via=takahiro19)
- https://ronbun-ai.org
【macOSトラブルシュート】Automator アプリが Bluetooth 接続できない時に確認すべき設定

- [0. はじめに](#0-はじめに)
- [1. エラーメッセージ](#1-エラーメッセージ)
- [2. 解決](#2-解決)
- [3. Bluetooth のアクセスを許可](#3-bluetooth-のアクセスを許可)
- [n. おわりに](#n-おわりに)

# 0. はじめに

自分で作った blueutil 経由のオートメーションアプリがエラーを起こしていたのを解決しました。

環境

> プロセッサ: 2.3 GHz クアッドコアIntel Core i5
> maOS: Sequoia バージョン15.3.2（24D81）

# 1. エラーメッセージ

<!-- スクリーンショット 2025-04-15 17.06.52 -->
![スクリーンショット 2025-04-15 17.06.52.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/844184/6853a5c7-76b5-4ff1-a2b6-50b394061183.jpeg)


自分で作ったのは WH-1000XM5 に Bluetooth 接続するアプリです。コマンドは

```
/usr/local/bin/blueutil --connect ac-80-0a-94-1a-14
```


純正の Automator と blueutil [^blueutil-git] があれば誰でもどんな Bluetooth 機器にも応用できます。

[^blueutil-git]: toy/blueutil: CLI for bluetooth on OSX: power, discoverable state, list, inquire devices, connect, info, … https://github.com/toy/blueutil 

名前は `/Applications/ConnectWH-1000XM5.app` です。Automator からは実行できるにもかかわらずアプリ単体で実行することができませんでした。

```
アクション“シェルスクリプトを実行”でエラーが起きました: “”
```

# 2. 解決

質問の回答メッセージから解決策を思いついて解決できました。

> autometorのシェルスクリプトで起動したい  
> https://teratail.com/questions/343599 

設定アプリの許可設定が OS アップデートで複雑になったなあぐらいのことは覚えていたのですが、どこで何をセキュリティ許可すればいいのか分からなかったのです。

初めはプライバシーとセキュリティのブロック設定（野良アプリが弾かれる時のあれ）を見たり、フルディスクアクセスを見たりしていたのですが、最終的には設定から Bluetooth アクセスを許可することでアプリが動くようになりました。

# 3. Bluetooth のアクセスを許可

<!-- スクリーンショット 2025-04-15 17.08.11 -->

![スクリーンショット 2025-04-15 17.08.11.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/844184/ed5eb462-dd15-4796-a6d2-e397aaffef25.jpeg)


Bluetooth のアクセスを見ると以前作ったオートメーションアプリにも許可を与えていました。

プラスボタンからアプリを追加してアクセス要件を満たすようにすると、アプリが実行できるようになりました。

Alfred で `wh -> Enter` と入力しただけでヘッドホンに接続されます。

# n. おわりに

今回は自作のオートメーションアプリ ConnectWH-1000XM5.app のデバッグをしました。

複雑化した設定アプリで Bluetooth 設定を ON にすることで解決しました。

余談ですが、ヘッドホンは rentio でレンタルしたものなのでそろそろ返却して新しいのを代わりに買おうかと思っています。

(2025-05-29 追記)

タグ付けまとめのページを参考に タグから # 記号を削除しました。

[https://qiita.com/nkay/items/29f12050fd5229dd913c](https://qiita.com/nkay/items/29f12050fd5229dd913c)
VSCodeでeditorとターミナルを行き来するショートカットの設定

## 手順

### editor→terminal
- VSCodeでキーボードショートカットの設定画面を開く（ `ctrl + k` → `ctrl + s` )
- コマンド：`ターミナル: ターミナルにフォーカス`　をダブルクリック
- 好きなコマンドを入力（例 `Ctrl + :` ）
- コマンド：`ターミナル: ターミナルにフォーカス`　を右クリックして `When式 を変更` をクリック
- `editorTextFocus` を入力

### terminal→editor
- （VSCodeでキーボードショートカットの設定画面を開く（ `ctrl + k` → `ctrl + s` )）
- コマンド：`表示: 最初のエディターグループにフォーカス`　をダブルクリック
- 好きなコマンドを入力（例 `Ctrl + :` ）
- コマンド：`表示: 最初のエディターグループにフォーカス`　を右クリックして `When式 を変更` をクリック
- `terminalFocus` を入力
HTML学習メモ１

これは、個人的備忘録です
## 例えば次のようなコードがあったとき
```html
 <!DOCTYPE html>
 <html>
 <head>
 <title>Page Title</title>
 </head>
 <body>
 
 <h1>My First Heading</h1>
 <p>My first paragraph.</p>
 
 </body>
 </html>
```
・`<!DOCTYPE html>`要素はドキュメントをHTML5のドキュメントとして定義する。
・`<html>`要素はHTMLページ全体を構成するための土台のようなもの。（ルート要素）
・`<head>`要素はHTMLページに関するメタ情報を含むもの
・`<title>`はHTMLページのタイトルを決めるもの
・`<body>`はドキュメントのbodyを定義するもので、すべての目に見えるコンテンツのコンテナである
・`<h1>`は大見出しを定義するものである
・`<p>`は改行定義するものである
第2回 SQL勉強日記 問題解答 難易度★★★☆☆ 内容：WHERE, JOIN, GROUP BY

### こんにちは！
元気よく挨拶したところで早速前回紹介しましたサイトにて
クエリをガンガン書いていきます！

ちなみに第1回はこちらです！
↓
https://qiita.com/shomacchi98/items/cba4e2e706b82be72062

私の4月から始まった研修はデータベース関連と
SQLが一旦落ち着きまして
TableauというBIツールの研修に入りました
私的にはこのTableauの方がつらいのですが
SQLとDB関連の知識が薄まらないようにしたいので
自主学習はSQLを書いていきます～

## SQL練習問題-問2
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4053502/9ffc457c-0a2d-4f1c-91f6-2165804bea19.png)
問題はこちらです。
全然いけそうですね～

想定される出力はこちら！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4053502/ee55d81f-43c7-42c5-aa2a-7bba8b2103d1.png)

【私の答え】
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4053502/7b5f7d54-f8f1-43bf-a678-28aee28e2b58.png)
【出力結果】
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4053502/c131e2bf-4334-4164-827d-532ed7e9f666.png)

### 完璧です！次！


## SQL練習問題-問3
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4053502/3eddc78f-7bb1-4a1e-9b1d-ad04f6ffa460.png)
問題はこちら！
ここでテーブルを見て気が付きます
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4053502/b08a1a71-8d47-40e3-97e6-69568e4ae3cf.png)
身長データがあるテーブルに国名がねぇ...
これは3問目にして早くもJOINの登場ですね！
JOINはテーブルを結合できる優れもの！
早速クエリを書いていきます！
【想定出力結果】
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4053502/8d79c22d-a759-4e34-8ceb-2f9aa30f1fd4.png)


【私の答え】
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4053502/80d433d0-3a1b-4e92-9a7f-08bec7938ba9.png)
【出力結果】
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4053502/7317b81f-7841-46a6-9d50-0f4dc7b54cb0.png)
### なんか違くねぇか！？
国名と平均身長はなんとなく出ているので
順番を変える箇所が問題ありと思ったので...

【私の答え2】
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4053502/6fbc9242-76d4-4a4f-8d17-5c09e1f53283.png)

あくまで練習用ということで名前を一文字にして
すぐ書き直せるように調整...笑
ちょっと細かく説明すると今回欲しいデータは
とりあえず国名と平均身長なわけです
それでASで名前付けをします
問題文にFROMはcountriesでと
しっかり指定がありますのでそれに従い
FROMを埋めていきます！
そこにplayersテーブルをJOINします
今回はcountriesテーブルのidと
playersテーブルのcountry_idをもとに
JOINしています
GROUP BYでグループ化をします
今回はc.idとc.nameの2カラムでやってます
理由としてはc.idのみでグループ化を行うと
SELECT句でc.nameが使用できないからです。
(ここはSQLの実行順序について勉強してください)
c.nameのみでもいいですが、
c.nameにかぶりが無いとも言い切れないので
一旦両方でグループ化しています

【出力結果】
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4053502/33243645-4b61-4644-ad1d-df1b7a4901b9.png)

ちゃんと出てきましたね～
一回やらかしましたね...お恥ずかしい

## まとめ
今回は割と簡単かつ重要なポイントを
おさらいすることができました！
ナメてかかったので普通に間違えました笑
修正できれば問題なし！
それではまた次回！
Firebase Studioで日本語を使わないほうがいい

TODOアプリを作ろうとしたところ、日本語で指示するとエラーばかりです。

# 日本語を使用した場合

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

# 英語を使用した場合
<iframe width="560" height="400" src="https://www.youtube.com/embed/nup7CBh2pRk?si=wnAhfyF-eJFHA47o" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>
CORSエラーとは？ブラウザとサーバーの役割について

## はじめに

Web開発をしていると、ある日突然コンソールに赤字で表示される「CORSエラー」。
このエラーに遭遇すると、多くの開発者が頭を抱えることでしょう。
「なんだかよくわからないけど、サーバー側で設定を追加したら直った」という経験はありませんか？

本記事では、CORSエラーの正体、発生する理由、そして解決方法について、わかりやすく解説します。

## CORSとは何か？登場人物で理解する

CORSを理解するために、関係者を登場人物に例えてみましょう。

- **ブラウザくん**: ユーザーの代理人。Webサイトを表示したり、データを取得したりする働き者
- **フロントエンドさん**: ブラウザくんの中で動いているWebアプリ。外部のサーバーからデータを取得したい
- **APIサーバーさん**: データや機能を提供するサーバー。フロントエンドさんのリクエストに応える
- **オリジン警備員**: ブラウザくんの中にいるセキュリティ担当。怪しい通信がないか見張っている

### オリジンとは？

オリジンとは、Webサイトやサーバーの「住所」のようなものです。

- **プロトコル** (例: `https://`)
- **ドメイン** (例: `example.com`)
- **ポート番号** (例: `:443` - デフォルトは省略されることが多い)

この3つの組み合わせがオリジンです。一つでも違えば「別のオリジン」とみなされます。

## CORSエラーが発生する仕組み

### なぜCORSエラーは起きるのか？

1. **フロントエンドさんのお願い**: 
   フロントエンドさん (例: `https://app.example.com`) が、APIサーバーさん (例: `https://api.example.com`) にデータをリクエストします

2. **オリジン警備員のチェック**: 
   ブラウザくんの中のオリジン警備員が「このリクエストは違うオリジン宛だな。安全か確認しないと！」とチェックします

3. **許可証の確認**: 
   オリジン警備員は、APIサーバーさんからの応答に「許可証 (CORSヘッダー)」が付いているか確認します

4. **ブロック！ (CORSエラー)**: 
   もし許可証がなければ、オリジン警備員は「通せん！」と、データの受け取りをブロックします。これがCORSエラーです

## 誰がブロックしているのか？

**アクセスをブロックしているのは「ブラウザ内のオリジン警備員」です。**

「サーバー側が許可していないなら、サーバーがエラーを返せばそれで済むのでは？」と思うかもしれません。しかし、実際にブロックしているのはブラウザなのです。

### なぜブラウザがブロックする必要があるのか？

- **ユーザーを守るため**: 
  悪意のあるWebサイトが、ユーザーがログイン中の別のサービスのAPIを勝手に呼び出すのを防ぎます

- **サーバーは普通に応答する**: 
  サーバー自体は、どのオリジンからのリクエストにも普通に応答します。curlなどで直接リクエストすれば、CORSエラーは起きません

- **ブラウザの役割**: 
  ブラウザは、CORSヘッダーをチェックし、「許可がない」と判断したら、応答データをJavaScriptに渡さないようにブロックします

## CORSエラーの解決方法

CORSエラーを解決するには、**APIサーバー側**に「このオリジンからのリクエストは許可します」という**許可証 (CORSヘッダー)** を発行してもらう必要があります。

### サーバー側の設定方法

- **`Access-Control-Allow-Origin`ヘッダーを設定する**: 
  これが最も重要です。ここに許可するフロントエンドのオリジンを指定します。
  ```http
  Access-Control-Allow-Origin: https://app.example.com
  ```
  
  安易に `*` (ワイルドカード) を指定すると、どのサイトからでもアクセスできてしまい、セキュリティリスクが高まります。**信頼できるオリジンだけを指定**しましょう。

- **必要に応じて他のヘッダーも設定する**:
  - `Access-Control-Allow-Methods`: 許可するHTTPメソッド
  - `Access-Control-Allow-Headers`: 許可するリクエストヘッダー
  - `Access-Control-Allow-Credentials`: 認証情報を伴うリクエストを許可する場合に設定

## よくある疑問と回答

### 疑問1: 悪意のあるサーバーが許可証をばら撒いたら危険では？

「もし悪いサーバーが『誰でもアクセスOK！』という許可証を出していたら危険では？」

- **CORSの役割**: CORSは「サーバーのデータを誰に渡すか」を決めるものです。サーバーが「誰にでもデータを渡す」と決めた場合、CORSはその決定を尊重します
- **アクセスの判断**: 悪意のあるサーバーにアクセスするかどうかは、最終的にはWebアプリの開発者やユーザーが判断することです

CORSは「サーバーの守衛さん」であり、「ユーザーを守る警察」ではないのです。

### 疑問2: サーバーがエラー時に何も返さなければ、ブラウザのブロックは不要？

「サーバー側でエラーを返すときに、重要な情報を含めなければ、ブラウザがブロックしなくても問題ないのでは？」

- **サーバー側の努力**: サーバーは、エラー発生時に詳細な内部情報を含めるべきではありません。これは基本的なセキュリティ対策です
- **CORSブロックの役割**: たとえサーバーが安全なエラー応答を返しても、ブラウザのCORSブロックは「Webページ上のJavaScriptによる意図しない情報利用」を防ぐための追加の防御策として重要です

**結論**: サーバー側で「余計な情報を返さない」努力と、ブラウザ側のCORSブロックの両方が連携することで、Webはより安全になります。

## まとめ

CORSエラーは、Webのセキュリティを守るための重要な仕組みです。

- CORSエラーは、**ブラウザ**が異なるオリジン間の通信を制限することで発生します
- 解決するには、**サーバー側**で適切な**CORSヘッダー**を設定し、信頼できるオリジンからのアクセスを許可する必要があります
- CORSは、Webアプリケーションとユーザーを保護するための重要なセキュリティ機能です

CORSエラーに遭遇したら、「どのオリジンからどのオリジンへアクセスしようとしているのか」「サーバー側で許可設定はされているか」を確認しましょう。この仕組みを理解すれば、もうCORSエラーは怖くありません。
DBeaverで複数クエリまとめて実行するとエラーになる場合の解消法

DBeaverを使っていて1つ1つのSQLは問題なく実行できるが複数選択してまとめて実行しようとするとエラーになる場合がある。

```:エラーメッセージの例
SQLエラー [1064] [42000]: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'select * from xxxxx ...
```

SQLの末尾にセミコロンを付け忘れていなければ、あとはデータベースの種類によっては複数クエリの実行がデフォルトで禁止されている場合がある(MySQLなど)。

# MySQLの場合の解消法
- DBeaverのデータベースナビゲーターで対象のDB接続を右クリックして **[編集 接続]** を選択
- **[接続設定]** で **[ドライバのプロパティ]タブ** を選択
- プロパティの中の`allowMultiQueries`の値が`False`になっているので`True`に変更して **[OK]** を押す
- 再接続するかのダイアログが表示されるので **[はい]** を押す
- 再度SQLを実行してみると今度はまとめて実行ができるようになる
【ソケット通信の仕組みとTCP/UDPの違い】実装して感じた違和感と学び

## はじめに

以前、Pythonでサーバーを自作していたときに、こんな疑問が浮かびました。

> 「recv(1024)って指定しても、TCPだと全部届かないときあるのに、UDPは一発で届く…なんで？」
> 

それまではなんとなく「TCPは信頼性があってUDPは速いけど雑」くらいの認識だったけど、この**リアルな違和感**から調べた結果、ソケットの仕組みやTCP/UDPの本質がストンと腹落ちしました。

この記事では、そのときの疑問→調査→理解をベースに、**ソケット通信の本質とプロトコルの違い**を整理します。

以下は、Pythonで開発した TCP/UDP ソケットを用いて独自のサーバーとプロトコルを実装したシンプルなチャットメッセンジャーアプリです。
https://github.com/ga-techcraft/Online-Chat-Messenger

---

## そもそもソケット通信ってどこに保存されてるの？

### パイプの理解をベースにすると

- パイプは**カーネルのリングバッファ**（メモリ）に一時的に保存
- アプリは**ファイルディスクリプタ**を通じてバッファに読み書き

### ソケットも同じ

**ソケットも、カーネルの送信バッファ・受信バッファに保存されている！**

```
アプリ → write() → カーネルの送信バッファ → ネットワークへ
アプリ ← read()  ← カーネルの受信バッファ ← ネットワークから
```

TCPやUDPは、その送受信の過程で**データの整形や再構築**をしている

---

## TCPとUDPの違いって何？

| 特徴 | TCP | UDP |
| --- | --- | --- |
| データ構造 | バイトストリーム〜流れる水 | メッセージ〜1通ずつ |
| 分割・再構築 | プロトコルが自動で分割 / 復元 | 1パケット = 1通 |
| 境界 | なし（アプリが分ける必要あり） | あり（1送信 = 1受信） |
| 信頼性 | 高い〜再送、順序保証あり | なし（失われることも） |

---

## `recv(1024)` で感じた違和感と答え

### TCP の場合

```python
conn.sendall(b"HELLO")
conn.sendall(b"WORLD")

data = conn.recv(1024)
```

→ `data == b"HELLOWORLD"`になることもあるし，分割されてることもある

> 理由：TCPは流れだから。どこまでが1通かは自分で判断する必要がある
> 

### UDP の場合

```python
sock.sendto(b"HELLO", addr)
sock.sendto(b"WORLD", addr)

data, _ = sock.recvfrom(1024)
```

→ `data == b"HELLO"` （2回目の`recvfrom()`で`b"WORLD"`が来る）

> 理由：UDPは「メッセージ」だから。送信 = 受信が保証されている
> 

---

## まとめ

| ポイント | 理解 |
| --- | --- |
| 保存元 | カーネルの送受信バッファ（RAM上） |
| TCP | 流れのデータ。区切りなし。自分で分ける必要あり |
| UDP | 送信 = 受信の1通単体。一発で取得。 |
Amazon S3 Glacier Deep Archiveと復元

# Archive
次のリンクのチュートリアルを行うと大まかには理解できます。

https://aws.amazon.com/jp/getting-started/hands-on/getting-started-using-amazon-s3-glacier-storage-classes/

1. バケット作成※バージョニング・オブジェクトロックは有効
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3518951/8256f220-ba4e-4a75-ad91-633b58cfbe2d.png)
ガバナンスモードを追加設定してみます。
勝手に消すなよ設定です。（既に環境は無いので安心してください。）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3518951/f6f26277-3b7e-4b70-b52f-5597cb71eacc.png)


2. ファイルをアップロードします。
この際、アップロードの工程においてストレージクラスを選択できますね。
べんり。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3518951/a221f522-9977-4c67-bfe0-36d270961964.png)
OK！
次にAWS CLIでやりくり。
```:cmd
aws configure list
```
S3の一覧表示
```
aws s3 ls
```

Glacier Deep Archiveを保存先として指定する場合。
```
aws s3 cp "C:\Users\{ユーザー名}\Desktop\{ファイル名}" s3://{バケット名}/path/{ファイル名} --storage-class DEEP_ARCHIVE --region us-east-1
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3518951/ddd2093c-7fbb-4b9a-8adc-511612fd408b.png)



参考:
フォルダをアップロードしたい場合。
```
aws s3 cp "C:\Users\{ユーザー名}\Desktop\{フォルダ名}" s3://{バケット名}/path/ --recursive --storage-class DEEP_ARCHIVE --region us-east-1
```



# 復元
1. コンソール上で解凍します。※これは標準取り出しなので12時間
該当のオブジェクトをクリックし、ポップアップに従って復元します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3518951/e2db60f1-fe97-40ee-ae3e-c8b496625906.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3518951/1fac0ed5-61e6-442b-a85b-694c7ceb2887.png)
復元されているコピーは、期間を指定して自動削除してくれるようです。

復元後の表示→
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3518951/9b20d89d-b47f-46b1-bcc8-f7f3fa5bb881.png)
実際にファイルをダウンロードすることができました。




2.コマンドでもやってみます。※これは一括取得なので48時間
```
aws s3api restore-object --bucket {バケット名} --key "{ファイル名}" --restore-request "{\"Days\":2,\"GlacierJobParameters\":{\"Tier\":\"Bulk\"}}" --region us-east-1
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3518951/ce0c3eaf-cf22-417e-8a88-8cb74e37c2bd.png)
ファイルサイズは関係ないようです。.txtファイルで内容未記載のデータでしたが、復旧時間は平気で24時間を超えてきました。
しかし、表示にあるとおり、時短をすることが可能なようです。「取得時間をアップグレード」というボタンから短縮できるようです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3518951/e5ad1aad-37a5-4d38-b436-99b2fb809519.png)
実際にファイルをダウンロードすることができました。
DevContainerを利用したVSCodeでClineがコマンドの実行結果を参照出来るようにする

# はじめに

Clineはタスクの中でVSCodeのターミナルでのコマンドの実行・結果の参照が出来ます。
これをDocker+DevContainerを利用したVSCode上で試したところ失敗してしまったので、成功するまでの手順を記載します。

# 失敗原因

失敗原因はClineも教えてくれており、PowerShellを利用する必要があるためでした。
対象のDevContainerはAlpine Linuxであるため、デフォルトではPowershellは入っていません。

DevContainerのリポジトリに、[PowerShellをインストールするためのスクリプト](https://github.com/microsoft/vscode-dev-containers/blob/main/script-library/docs/powershell.md)があったのですが、これはDebian Linux向けでした。

今回はAlpine Linuxなので上記のスクリプトをそのまま使うことは出来ません。
そのため、今回はDockerfileにインストールコマンドを追加して自前でセットアップしていきます。

# 対応手順

### 1. PowerShellをインストールするスクリプトを作成

Debian向けの例のようにスクリプトファイルを作成し、実行する方式にすることにしました。
PowerShellのインストールスクリプトは公式に[Alpine LinuxへのPowerShellのインストール](https://learn.microsoft.com/ja-jp/powershell/scripting/install/install-alpine?view=powershell-7.5)があるため、こちらを参考にします。

```sh
# Alpine Linux への PowerShell のインストール
# https://learn.microsoft.com/ja-jp/powershell/scripting/install/install-alpine?view=powershell-7.5

# install the requirements
sudo apk add --no-cache \
    ca-certificates \
    less \
    ncurses-terminfo-base \
    krb5-libs \
    libgcc \
    libintl \
    libssl3 \
    libstdc++ \
    tzdata \
    userspace-rcu \
    zlib \
    icu-libs \
    curl

apk -X https://dl-cdn.alpinelinux.org/alpine/edge/main add --no-cache \
    lttng-ust \
    openssh-client \

# Download the powershell '.tar.gz' archive
curl -L https://github.com/PowerShell/PowerShell/releases/download/v7.5.0/powershell-7.5.0-linux-musl-x64.tar.gz -o /tmp/powershell.tar.gz

# Create the target folder where powershell will be placed
sudo mkdir -p /opt/microsoft/powershell/7

# Expand powershell to the target folder
sudo tar zxf /tmp/powershell.tar.gz -C /opt/microsoft/powershell/7

# Set execute permissions
sudo chmod +x /opt/microsoft/powershell/7/pwsh

# Create the symbolic link that points to pwsh
sudo ln -s /opt/microsoft/powershell/7/pwsh /usr/bin/pwsh

# Start PowerShell
pwsh
```

こちらをプロジェクトカレントの`.devcontainer/library-scripts`フォルダに配置しました。

### 2. Dockerfileでスクリプトを呼び出す

`1`で作成したスクリプトをDockerfileで呼び出します。

```Dockerfile
FROM node:22-alpine

COPY .devcontainer/library-scripts/install-powershell.sh /tmp/library-scripts/

RUN apk add sudo &&\
    ash /tmp/library-scripts/install-powershell.sh
```

### 3. docker-compose build

ビルドします。

### 4. docker-compose up

upします。
個人的にはここでハマってしまい、DockerDesktop上で▶を押しても反映されず、upし直す必要がありました。

### 5. VSCodeをDevContainerで開いてPowerShellを選択

VSCodeをDevContainerで開きます。
`Ctrl+Shift+P`でコマンドパレットを開き、`Select Default Profile`を選択します。
すると、`sh`や`ash`などと一緒に、`pwsh`があると思うので、`pwsh`を選択します。

### 6. 試す！

これで設定は完了です。
適当なプロンプトで実行結果の取得を試してみます。

```
`ls`コマンドを実行して、その結果を教えて。
```

ちなみに、jestやvitestなどでテスト結果を参照して欲しい時などは、Watchモードにならないように`--run`オプションを付与するなどする必要があります。

# おわりに

これで、DevContainerを利用したVSCodeでClineがコマンドの実行結果を参照出来るようになりました。
Debian向けのスクリプトやAlpineへのPowerShellインストール方法など、公式でのドキュメントがそれぞれ見つかったので助かりました。
これでCline君ともっと戯れていきたいと思います！
より良い方法などがあれば教えていただけると助かります。
ここまで見ていただきありがとうございました。
#87　「Falcon」による大規模のシステム障害について

## はじめに

一ヶ月前、全世界規模のシステム障害が発生してしまい、交通、飲食、エンタテインメントなど多くのサービスが停止せざるを得ないことになっていた。一体何が発生したのと原因や影響を分析したいと思う。

## 問題があるアップデートによる大パニック

7月19日、CrowdStrike会社のセキュリティーソフト「Falcon」の自動更新と伴い、問題がある設定ファイルの追加でWindowsの不具合が発生し、全世界多くのサービスに影響を与えた。日本の新聞によると、USJや空港なども影響されてしまい、欠航などのサービスの一時停止になった。

## 原因は一体？

原因はサイバーアタックではないが、一つの設定ファイルで全世界にもパニックになったが、現在のOSは簡単に不具合が発生しないものです。例えばWindowsシステム、Microsoftから基本正式の更新を公表する前、内部テストから開発者テストなど、多重のテストを重ねて故障原因を最低限にしてから一般ユーザーに提供する。
そして、WindowsやLinuxなど、OSによっての保護制御があり、アプリケーションに不具合が発生してもシステム自体には影響及ばない。では今回の不具合は一体何が原因でしょうか？

「Falcon」の処理はアプリ層で行うではなく、カーネル処理としてOSにで作動しているようです。セキュリティーソフトとして、即時OSの動作をモニターニングするため、多くの権限が付与されていて、カーネルにで行動分析や観察処理を行う。その観察や保護用の設定ファイルの更新でロジックエラーが発生し、BSOD、所謂青画面の不具合が発生してしまう。

## 感想

今回の大規模不具合について、ほぼ回避不可能だと考えている。セキュリティーソフトは常に最新化しないと、新しいアタックに襲う可能性もあり、自動更新を止めることはいけない。そのためソフトのテストや質をより一層確認するのが必要と思う。第三方のソフト提供者は勿論、Microsoftみたいな国際企業として、しっかり事前に各ソフト提供者とコミュニケーションをとるべきです。さもなければ又同じような不具合が発生してしまい、今回のように全世界に影響を及ぼす。
エンジニアとして、いろんなものことから勉強し、改善すべきところを考えて、自分の技術向上のためにもなるでしょう。

## 最後

すでに１ヶ月過ぎて、まだ対応していないデバイスはいないと思うため、ここでは特に説明しないようにしておく。
不具合問題に気になる方がいれば、こちらCrowdStrike会社公式のポストを参照しましょう。[こちら](https://www.crowdstrike.com/blog/falcon-update-for-windows-hosts-technical-details/)

## 参照

- <https://www.crowdstrike.com/blog/falcon-update-for-windows-hosts-technical-details/>
- <https://www3.nhk.or.jp/news/html/20240720/k10014517151000.html>
- <https://time.com/7000476/microsoft-it-outage-crowdstrike-role-what-happened-explanation/>
【Vue.js】環境によって audio が再生されない問題とその対処法（音声リソースの解放）

## 🎧 問題の概要

Vue.jsで構築したアプリケーションで、**複数の音声を再生するツール**を開発していました。


音声は以下のような仕様で再生される設計です：

- 各音声に対して「再生ボタン」が1つずつ
- 各ボタンを押すと、対応する音声ファイルを1回だけ再生

このとき、**一部の環境で音声が再生されないバグ**が発生しました。


## ❗ 発生した問題

以下のような症状が報告されました：

- **Google Chromeでは正常に動作**
- **Microsoft Edgeでは一部再生されない**
- **特定の端末で、数ページに1回の頻度で発生**
- **Console上にエラーログは出力されない**
- **キャッシュ削除後に再生できるようになる場合もある**


## 🛠️ 原因と推測

音声再生部分のロジックは**共通のAudioインスタンスを使い回す構造**で、再生終了後もオーディオリソースが残っていた可能性があります。

このため、以下のような状況で不具合が発生していたと推測されます：

- オーディオがGC（ガベージコレクション）されずに残り続ける
- ブラウザの制限により新しいAudioインスタンスの生成・再生がブロックされる
- Edgeなど、環境によってこの影響が顕著に表れる

## ✅ 解決策：音声再生完了後にリソースを明示的に解放

再生完了時点で、使用したAudioインスタンスを明示的に破棄することで、問題を解決できました。

### 1. `doneFlag` を監視して音声を解放

音声の再生が完了したことを示すフラグ `done_flag` をwatchし、`true` になったタイミングでAudioを解放します。

```js
// Vue コンポーネント内
watch: {
  nowPlay(newVal) {
    if (newVal) {
      this.releaseAudio(); // 再生完了後にAudioリソースを解放
    }
  }
}
```

### 2. releaseAudio() メソッドでインスタンスを解放
```js
methods: {
  releaseAudio() {
    if (this.audio) {
      this.audio.pause();       // 再生停止
      this.audio.src = '';      // ソースクリア
      this.audio = null;        // インスタンス解放
      console.log("release");
    }
  }
}
```

### 3. コンポーネント破棄時にも解放処理を追加
```js
beforeDestroy() {
  this.releaseAudio(); // コンポーネント破棄前に確実にAudioを解放
}
```

## 🎉 効果

この修正を加えた以降、すべての環境で音声が安定して再生されるようになりました。
特にEdgeや、キャッシュが絡んでいた端末でも、再現性のある不具合が完全に解消されました。

## 💬 補足
今回の仕様では「1回再生した音声は2回目以降再生できない」設計だったため、解放処理は特に有効でした。

同様の構成で音声プレイヤーを使う場合も、再生終了後にAudioを明示的に破棄することをおすすめします。

一見エラーが出ないために原因が特定しづらく、ブラウザごとの差異に注意が必要です。
ORマッパーって何？



## 勉強前確認

初めて聞いた単語...
DBで内部で動く処理的なやつ？

## ORマッパーとは

よく `O/Rマッパー` と記載されている。
O/Rマッピングともいわれている。

オブジェクト指向プログラミング言語のデータを関係データベースにマッピングするツールで
マッパー・マッピングは対応付ける という意味です。

ORマッパーによってリレーショナルデータベースのレコードがオブジェクトとして直感的に扱え、コードの可読性や保守性を向上させることができます。
DBのテーブルはクラスに紐づけられて、オブジェクトに対する操作をすることでデータの操作を行います。

また自動的にデータベースのスキーマを生成したり変更を追跡するなど開発効率を高める機能もあります。
ただ、パフォーマンスの問題が発生することもあるため、チューニングが必要になる可能性があります。


## ORマッパーの基本的な話

ORマッパーの概念は以下があります
- エンティティ
	- データベースのテーブルに対応するクラス
	- フィールドがテーブルのカラムにマッピングされる
- セッション
	- データベースとの通信を管理する
- トランザクション
	- データの一貫性を保つ


## どんなORマッパーがある？

主要なORマッパーは以下のようなものがあります
- Hibernate
- EclipseLink
- MyBatis


## 参照

- [Java ORM（Object-Relational Mapping）の比較と選び方](https://www.issoh.co.jp/tech/details/3301/)
- [SQLAlchemy 概要と基本の使い方](https://zenn.dev/myuki/books/02fe236c7bc377/viewer/d2422a)
- [O/Rマッパーを使う理由](https://tikasan.hatenablog.com/entry/2018/08/06/110000)
【Supabase】90日の復元期限を過ぎたプロジェクトを復元する方法（Docker + psql）

# はじめに

Project cannot be restored through the dashboard　:sob:

Supabaseの無料プランでは、プロジェクトが一時停止後、**90日間**が経過すると、管理画面上からの復元ができなくなります。

今回は、**90日の復元期限を過ぎたプロジェクトを復元**する必要があり、その際に行った対応手順を記録としてまとめました。

## 対応手順

### 1. Supabase側の対応

#### 1-1. 復帰用の新規プロジェクト作成

Supabaseの管理画面から新規プロジェクトを作成します。

#### 1-2. バックアップファイルを保存

事前にSupabaseから取得しておいた `.backup` ファイルを使用します。

:bulb: `.backup` ファイルは、Supabaseで復元対象のプロジェクトを開くと表示される「Download backups > Database backup」からダウンロード可能です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3639392/db13268a-addd-43da-b197-ac5270514e4e.png)

#### 1-3. DockerでPostgreSQLコンテナの作成・起動

ローカル環境にPostgreSQLをインストールしていないかつ、ローカルに直インストールしたくなかったので、psql実行用にDockerを作成します。

Dockerコンテナを作成したコマンド
```bash
docker run --rm -it --name pg_restore -v ${PWD}:/backup postgres:15 bash
```


#### 1-4. `psql` コマンドでSupabaseのDBをローカルから復元
事前にSupabaseから取得しておいた `.backup` ファイルから使用します。

##### :white_check_mark: 成功したコマンド

以下のコマンド（Supabaseにて作成した新規プロジェクトのTransaction poolerに記載あり）を使用して、Docker環境内で復元を実施しました。

Docker環境のターミナルで実行したpsqlコマンド
```bash
psql -h aws-0-ap-southeast-1.pooler.supabase.com -p 5432 -d postgres -U ＜ユーザー名＞ -f /backup/db_cluster-MM-DD-YYYY@xx-xx-xx.backup
```
##### :x: 失敗したコマンドとエラー内容
以下のホストを指定したコマンド（Supabaseにて作成した新規プロジェクトのDirect connectionに記載あり）は、IPv6の関係で失敗しました。
```bash
psql -h ＜ホスト名＞ -p 5432 -U postgres -d postgres -f /backup/db_cluster-MM-DD-YYYY@xx-xx-xx.backup
```
エラー内容
```sql
psql: error: connection to server at "＜ホスト名＞"......
Is the server running on that host and accepting TCP/IP connections?
```

### 2. フロントエンド側の対応
.env ファイルの以下の値を、新しいSupabaseプロジェクトのものに書き換えます。
``` env
NEXT_PUBLIC_SUPABASE_URL=＜復帰用の新規プロジェクトのURL＞
NEXT_PUBLIC_SUPABASE_ANON_KEY=＜復帰用の新規プロジェクトのキー＞
```

### 3. Netlify側の対応
Netlifyを使ってデプロイしていたため、管理画面から環境変数を修正します。
1. Site configuration にアクセス
2. 「Environment variables」を表示
3. 以下の設定値を更新
``` env
NEXT_PUBLIC_SUPABASE_URL=＜復帰用の新規プロジェクトのURL＞
NEXT_PUBLIC_SUPABASE_ANON_KEY=＜復帰用の新規プロジェクトのキー＞
```

# おわりに
今回は、Supabaseのバックアップ保持期限が過ぎた後の復元方法を記録しました。
手元に .backup ファイルさえあれば、新プロジェクト＋psql実行環境（今回はDockerコンテナ）で復旧可能です。

同じ状況で困っている方の参考になれば幸いです。
個人的備忘録：Alembicのenv.pyがうまく言語化できなかったので、まとめてみました

## はじめに

Alembicは、SQLAlchemyを使用するPythonプロジェクトでデータベースのスキーマをバージョン管理するためのマイグレーションツールです。その設定の中心となるファイルの一つが `migrations/env.py` です。

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

このファイルは、マイグレーションの実行時に使われる環境や処理を定義しており、Alembicがどのようにデータベースと接続し、どのテーブル情報を参照するかを決定します。

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

受講しているITスクールのハッカソンに参加している中で、バックエンド担当の方がこの `env.py` の処理を書いているのを見て、自分でも理解を深めたいと感じました。

https://github.com/2025SpringTeamA/backend/blob/main/migrations/env.py

今後の学習や実務にも活かせるよう、備忘録としてまとめました。

**参考文献**

https://zenn.dev/shimakaze_soft/articles/4c0784d9a87751

https://zenn.dev/shimakaze_soft/scraps/bfa75df3e51258

## `migrations/env.py` の内容とその役割

### 1. 基本設定と環境変数の読み込み
```python
load_dotenv()
database_url = os.getenv("DATABASE_URL")
```
- `.env` ファイルから `DATABASE_URL` を読み込み、Alembicの設定にセットします。
- URLが見つからない場合はエラーを出します。

### 2. ログ設定
```python
if config.config_file_name is not None:
    fileConfig(config.config_file_name)
```
- `alembic.ini` ファイルからロギング設定を読み込み、マイグレーション時のログ出力を整えます。

### 3. モデルのメタデータ設定
```python
sys.path.append(str(Path(__file__).parent.parent))
from app.models import Base
target_metadata = Base.metadata
```
- SQLAlchemyモデルの定義を読み込み、`Base.metadata` を `target_metadata` にセット。
- これにより `alembic revision --autogenerate` が有効になります。

### 4. マイグレーションの実行モードを定義

#### オフラインモード
```python
def run_migrations_offline():
```
- データベースに接続せず、SQL文をスクリプトとして出力します。
- CI環境やレビュー目的で使用されます。

#### オンラインモード
```python
def run_migrations_online():
```
- データベースに実際に接続し、マイグレーションを適用します。
- 開発環境や本番環境での適用時に使います。

### 5. 実行モードの判定と呼び出し
```python
if context.is_offline_mode():
    run_migrations_offline()
else:
    run_migrations_online()
```
- 実行モードに応じて、適切なマイグレーション処理を選択します。

## まとめ

`migrations/env.py` はAlembicのマイグレーションの土台となる重要なファイルで、環境変数の読み込み、メタデータの指定、実行モードの選択など、マイグレーション処理の基本的な流れを制御しています。

このファイルの内容を理解することで、Alembicの動作に対するカスタマイズやトラブル対応がしやすくなり、より柔軟なスキーマ管理が可能になるかと思います！
MessagingAPIのMCPサーバーってどう使えばいいの？色々考えてみた

## LINEのMessagingAPIのMCPサーバーが出たらしい

https://developers.line.biz/ja/news/2025/04/14/line-bot-mcp-server/

おー、公式のやつが出ましたか

MCPサーバーはAPIが公開されているサービスであればいくらでも自分で作れるので公式のものを待つ必要もあまりないのですが、公式が出してくれると全体的に活用法とかも出てくるので、色んなサービスに作って欲しいなーと思っています。

## 実際に使ってみたい方

始め方を書いてくださっている方がいたので実際に使ってみたい方は参考にしてやってみましょう

https://qiita.com/course_k/items/f24b28a513b2ac7eaee7

## このMCPサーバーは何ができるっていうんだい

基本的にMCPサーバーはコード側で定義されたツールというのを使って様々な動作をAIエージェントが実現しようとするのでツールを見れば大体わかるだろうということで、[README](https://github.com/line/line-bot-mcp-server) を見ていきます。

### 🔨 tool 一覧

1. push_text_message
Push a simple text message to user via LINE.
　
2. push_flex_message
Push a highly customizable flex message to user via LINE. 
　
3. get_profile
Get detailed profile information of a LINE user including display name, profile picture URL, status message and language.

### 簡単にまとめると…

1. 普通にLINEを使用するときに送るようなテキストベースのメッセージ送信が可能
　
2. FlexMessageというオシャレな感じのメッセージの送信が可能（下に画像添付）
　
3. Profile情報の取得が可能（LINEで設定している名前などですね）

##### 以前のminiアプリの検証時の画像

![IMG_5402.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3734276/8149c417-2466-4bf3-b213-8a7dfcf62b81.png)

## なるほど。出来る事はわかったけど、どう使えばいいんだ？

MessagingAPIの利用法を考える前に他のMCPサーバーをこう使っているという話を挟みます。
私は以下のようなツールを使用しています。

### GitHub

- 例えばGitHubのMCPサーバーは、開発中に後でこれやろうと思ったことをエディター上からIssue作成してもらって後で対応する
→ 一度GitHubに移動して起票して戻るというノイズをなくせますので、よく使います。
　
- 例えば、コミットメッセージ考えるのも面倒だし、コマンド叩くのも一々やるが面倒、ふわっと指示出してPR出してもらう
→ これは体験として微妙だったので私は使っていませんが、楽になりそう

### Backlog（タスク管理ツール）

公式のがなかったので、個人的に制作したこちらも、上と同じで課題を起票するときにエディター上で完結するのでよく使います。

### Playwright

これは言わずもがな、色んなところで便利な点が述べられていますが、テストは大体大変なのでAIが色々やってくれたら嬉しいので人気です。

### Messaging API

1. テキストベースのメッセージ送信
→ 仕事で関わる人とか作業している時にLINE送りたいことがあまりない

2. FlexMessageの送信
→ これは個人的に活用例あるので後で書きます。

3. Profileの情報を取得する
→ 取得してメッセージに載せるなどは開発の時に行うが、エディター触っているときに情報欲しい場面があまりない
→ 情報が欲しい場面はありますが、それはMCPサーバーを使うための環境変数を知りたい場合が多いし、一度確認できればいいので本末転倒

## 「FlexMessageの送信」これは使うかも

基本的にMCPサーバーは現状開発者向けの技術というか、一般の方が触ることはほとんどないのではないかと思っています。

ですが、YoutubeなどでMCPサーバー関連の情報を確認していると一般の方向けの情報発信も多く見かけるのでそれ前提で利用パターンを考えてみました。

### 1. 開発者以外の方がFlexMessageを作成できる

そのままですが、開発者以外の方もFlexMessageを作成できます。

ただ、おそらく私は利用したことがないので分かりませんが、世の中に多くあるLINEの運用ツール的なのはテンプレートなどはありつつもFlexMessageをサポートしている気がするので、自分でLINEアカウントの運用をしている店舗のオーナーさんなどにはあまり意味がないです（きっと）

### 2. 開発中のFlexMessageを気軽に確認できる

開発者的にはこれですねー、基本的にFlexMessageの作成手順としては
```
「FlexMessageSimulator」で作成 → リンクや画像を差し替えて完成
```
だと思います。別のプロジェクトのjsonファイルを流用する場合もあるかもしれません。

ですが、やはり結局実際の画面でどうなのかという確認を間違いなく行います。

そして、そのFlexMessageが非常に多くの工程を経て送信されるものだった場合に、微調整を何度も行うのは面倒です。

そして、色んな分岐を経て多くのFlexMessage全てを確認しなくてはいけない場合も面倒です。

そんな時に、jsonファイルを渡してMCPサーバー経由でトークルームに送信すれば、非常に多くの工程を経る画像や、FlexMessageの数が多い場合も簡単に確認ができます。

これは私も今後非常に多くのFlexMessageを使うことがあった場合に利用するかもしれません。

## 他に有用な利用方法が思いついた方がいたら

ぜひ、教えて下さい！

私は基本的にAI Editor上で利用すること前提で考えているので、日常遣いするという視点が基本的にありません。

他のMCPとの組み合わせなどもあると思いますので、イケてる利用方をしている方がいたら教えていただきたいです！

## まとめ

### FlexMessageを送信できる機能は使いそう

という感じで、上にも書きましたが基本開発ベースで考えているので正直あまり使う機会は限られそうなのですが、有効的に使える場面がないかを考え日々過ごしていこうと思います。

MCPサーバー作ってくれてありがとうございます！
【Haskell初心者向け】ラムダ式の基礎から応用、カリー化まで　たくさんの例で学ぶ

## 記事の内容

Haskellのラムダ式に慣れたい！！

ラムダ式は、さまざまなプログラミング言語に登場します。
とくに、Haskellの場合、関数を中心に構成していくので、ラムダ式はとても重要な考え方です。

この記事では、
* Haskellにおけるラムダ式の例を豊富に紹介します。
* Haskellの基礎であるカリー化についても案内します。

上記特徴を求めている人はぜひ読んでみてください。

## ラムダ式とは？
一言で表すならば、**名前の無い関数**です。

通常の関数定義：
```
add x y = x + y
```
これは次のようなラムダ式で書き換えることができます：
```
\x y -> x + y
```
この `\x y -> x + y` は、「`x`と`y`を引数に取り、`x + y`を返す関数」です。

## ラムダ式を使ってみる

### 例1
リストへのmap
```haskell
map (\x -> x * 2) [1, 2, 3]
-- => [2, 4, 6]
```
`map` はリストの各要素に関数を適用します。ここでは「2倍にする無名関数」を使っています。

### 例2
タプル `(a,b)` に対して、合計を計算する無名関数です。
```haskell
map (\(a,b) -> a + b) [(1,2), (3,4)]
-- => [3, 7]
```

### 例3
フィルタで条件を絞る
```haskell
filter (\x -> x > 10) [4, 12, 5, 18]
-- => [12, 18]
```
無名関数 `\x -> x > 10` によって、`10`より大きい要素だけを選びます。


### 例4
リスト内包表記と合わせる
```haskell
[ f x | x <- [1..5], let f = (\y -> y * y) ]
-- => [1,4,9,16,25]
```
`f` にラムダ式を入れて平方を計算します。


### 例5
`map` を使って、文字列のリストをすべて大文字に変換する。
```haskell
map (\s -> map toUpper s) ["haskell", "fun"]
-- => ["HASKELL", "FUN"]
```


### 例6
`filter` とラムダ式で、偶数だけを取り出してみる。
```haskell
filter (\x -> x `mod` 2 == 0) [1..10]
-- => [2,4,6,8,10]
```


## ラムダ式をネストする

ラムダ式は入れ子にできます。
```haskell
(\x -> (\y -> x + y)) 3 5
-- => 8
```
これは、`x` に `3` を適用し、その結果の関数に `y = 5` を適用するという意味です。

### 例1
ネストされたラムダ式で `x*y + z` を計算する関数を定義する。
```haskell
(\x -> (\y -> (\z -> x * y + z))) 2 3 4
-- => 10
```
`x = 2`
`y = 3`
`z = 4`
と順に適用され、最終的に `2 * 3 + 4 = 10` となります。

### 例2
条件に応じた分岐。引数 `x` の値によって分岐させています。
```haskell
(\x -> if x > 0 then "positive" else "non-positive") 5
-- => "positive"
```

### 例3
無名関数を関数に渡す。
```haskell
let applyTwice f x = f (f x)
applyTwice (\n -> n + 1) 5
-- => 7
```

### 例4
ネストしたラムダ式を使って、条件によって異なる関数を返す。
```haskell
(\x -> (\y -> if x > y then x else y)) 5 8
-- => 8
```


## カリー化とは？

Haskellでは、関数は1引数しかとらないのが基本です。複数の引数をとる関数は、関数を返す関数として表現されます。

たとえば：

`add x y = x + y`

これは実はこう解釈されます：

`add = \x -> (\y -> x + y)`

これがカリー化です。

カリー化とは、**カリー化とは、複数の引数をとる関数を、引数を1つずつ受け取って“関数を返す関数”の連鎖に変換すること**です。

### 部分適用の例
```haskell
add3 = add 3
add3 5
-- => 8
```
`add 3` は `\y -> 3 + y` という関数になります。

カリー化は部分適用と非常に相性が良く、柔軟な関数設計を可能にします。
XIAO ESP32C6の内部写真を撮って遊ぶ。(分解)(あっさり壊したので)


目的
----

金属カバーを半田ごてで取って内部を観察する。
故障の原因は、たぶん、3.3Vに5Vを掛けたので?
いろいろ　壊したのは、「XIAO ESP32C6+GROVE」1代目と、命名する。
いろいろ　今後は、3.3Vと信号に定電圧ダイオードを付ける。


写真
----

![image_original (94).jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/fb984589-f972-49b7-a701-e6322ecd7c84.jpeg)


![image_original (95).jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/ca34996b-4d14-4f25-a7e6-09856536a2c2.jpeg)
VSCodeで別のブランチのファイル差分だけを反映する

VSCodeで別のブランチのファイル差分だけを反映する。
コミットログは取り込まない。

`git restore --source='ブランチ名' --worktree .`

クォーテーションはｔなくてもいいけど、#とかがブランチ名に入っている場合は必要
【java】Springがチュートリアル通りでうまくいかなかったので別の方法で何とか動かした

javaの勉強を始めて、フレームワークも触ってみたいということで
Springに挑戦しました。

チュートリアル通りにやってみて、ローカルサーバーを立ち上げのところで
エラーが解消せずうまくいかなかったので、別の方法で動かせたので、参考なるか分かりませんが
メモを残します。

公式のチュートリアル
https://spring.io/quickstart


## 結論:MavenでプロジェクトをGenerateする
チュートリアルでは、Gradle - Groovyでプロジェクトをビルドする流れとなっておりますが
私はこれだとビルドとローカルサーバーの立ち上げのところでエラーが出て直りませんでした。
(javaのバージョン不一致のエラーでしたが、バージョンを合わせても解決せず)
そこで、MavenでプロジェクトをGenerateすしたところうまくいきました。

詳細な手順は、この後解説します。

## STEP1:プロジェクトをGenerate
結論で言ったように、MavenでプロジェクトをGenerateします。
以下のように設定して"Generate"ボタンを押してください。
(※私はjave version=24ですが、verは自身の環境と一致するのもにしてください)

https://start.spring.io/

![sぴりん.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3332453/b5987b8e-6e53-464e-906b-92ff1cb2b277.jpeg)


## STEP2:コード編集
ここは公式チュートリアルと全く同じでいいです。
src/main/java/com/example/demoの中のDemoApplication.javaを編集します。
```java:DemoApplication.java
package com.example.demo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

@SpringBootApplication
@RestController
public class DemoApplication {
    public static void main(String[] args) {
      SpringApplication.run(DemoApplication.class, args);
    }
    @GetMapping("/hello")
    public String hello(@RequestParam(value = "name", defaultValue = "World") String name) {
      return String.format("Hello %s!", name);
    }
}
```

## STEP3:ビルド&実行(サーバー起動)
MavenでプロジェクトをGenerateした場合、ここが公式のチュートリアルと手順が異なります。
プロジェクトの階層で、下記のコマンドを実行します。
```
./mvnw spring-boot:run --quiet
```
これで成功しました。
![ぶlるん.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3332453/dac796b6-cae6-4e71-a814-08413c0a6b6c.png)


以上です。
Spring Boot + Javaでユーザー管理APIを簡単に作ってみた（JPAなし）

## ✅ 背景と目的

Spring Boot の練習として、**JPAを使わずにメモリ上で動くユーザー管理API**を実装しました。  
主に以下の目的で設計しています：

- Java × Spring Boot の基本構造を理解
- Controller / Service / Repository の責務を整理
- CRUD API の一連の実装を体験

---

## 🧩 実装構成（JPAなし）

UserController.java ← APIの窓口
UserService.java ← ロジック（nullチェック、例外処理など）
UserRepository.java ← 仮想DB（List<User>で代用）
User.java ← エンティティ（@Entity未使用）


---

## 🛠 API仕様（REST設計）

| メソッド | エンドポイント   | 説明               |
|----------|------------------|--------------------|
| GET      | `/users`         | 全ユーザー取得     |
| GET      | `/users/{id}`    | 指定ユーザー取得   |
| POST     | `/users`         | ユーザー新規追加   |
| PUT      | `/users/{id}`    | ユーザー情報更新   |
| DELETE   | `/users/{id}`    | ユーザー削除       |

---

## 💡 技術ポイント

- `List<User>` を仮想DBとして利用（簡易的なCRUDを実現）
- `List.copyOf()` でリストを不変化 → セキュリティを意識
- `Optional` で null 安全な設計
- サービス層での `orElseThrow` による明示的な例外処理

---

## 🔍 使用技術

- Java 17  
- Spring Boot 3.x  
- Gradle  
- IntelliJ IDEA  

---

## 📌 ソースコード

GitHubリポジトリ：  
🔗 [https://github.com/hyeon-marina/LikeLion-Backend-Assignments/tree/main/Assignments/Week02](https://github.com/hyeon-marina/LikeLion-Backend-Assignments/tree/main/Assignments/Week02)

---

## 🏷 タグ
`SpringBoot` `#Java` `#RESTAPI` `#バックエンド` `#学習記録`	

---

## ✍️ 補足

次回は**JPA + MySQL連携版**にアップグレード予定です。  
Qiitaでも差分を比較できるように投稿していきます！
OCI学習#7 Run Command(Instance)#1

## 概要
インスタンスに対してOCIコンソール上からRun Commandを使用してコマンド実行を実施。
今回はテキストで直接コマンド入力、出力を行う。
下記OCIドキュメントを参照しながら設定を実施。
[インスタンスでのコマンドの実行](https://docs.oracle.com/ja-jp/iaas/Content/Compute/Tasks/runningcommands.htm?Highlight=Run%20command)

## 目的
OCI資格取得に向けた学習の一環として、単に知識を暗記するだけでなく、
実際にOCI環境に触れて実践的な経験を積むことで、将来の設計や構築の場面で
自信を持って対応できるスキルを習得する。

## OCI学習記事まとめ
Part1
1.[OCI学習#1 ネットワーク設定](https://qiita.com/nonZy/items/adbbf47646a28e59fe36)
2.[OCI学習#2 インスタンス作成、接続](https://qiita.com/nonZy/items/b821d419c03ca7c7cd7c)
3.[OCI学習#3 Block Volume追加](https://qiita.com/nonZy/items/5053c853c77cfb68bc51)
4.[OCI学習#4 Object設定、アクセス](https://qiita.com/nonZy/items/abb5717666d8f74eb690)
5.[OCI学習#5 ネットワークパスアナライザ](https://qiita.com/nonZy/items/641de2daca61af29e7df)

Part2
6.[OCI学習#6 ネットワークパスアナライザ#2](https://qiita.com/nonZy/items/a6e3a83c5d934a8877c2)
ネットワークパスアナライザの使用

## 実施手順
### インスタンス作成、設定
1.[OCI学習#2 インスタンス作成、接続](https://qiita.com/nonZy/items/b821d419c03ca7c7cd7c)を参考にインスタンスを作成する。

下記、"コンピュート・インスタンスの実行コマンド"が有効化されていることを確認する。
![71.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/510919/858bef1f-b9a2-4fc6-93e6-0215cf90aafa.png)

### 動的グループ作成
対象インスタンスが含まれる動的グループの作成を実施。
※対象インスタンスのOCIDをコピーしておくこと
1.[アイデンティティ・ドメイン]-[動的グループ]-[動的グループの作成]をクリック
```
例: Any {instance.id = 'ocid1.instance.oc1.iad..exampleuniqueid1', instance.compartment.id = 'ocid1.compartment.oc1..exampleuniqueid2'}
```
![72.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/510919/d282de83-5f52-48b4-a20d-9fa1f4ca779c.png)

### ポリシー設定
1.[アイデンティティ]-[ポリシー]-[ポリシーの作成]をクリック
動的グループに対してポリシーを設定します。
```
Allow dynamic-group RunCommandDynamicGroup to use instance-agent-command-execution-family in compartment ABC where request.instance.id=target.instance.id
```
![79.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/510919/2194c900-09f9-4361-b364-0f010c86afd8.png)


最大30分程度時間がかかることもあるみたいなので、OSで下記コマンドを実行しましょう。
```
# systemctl restart oracle-cloud-agent
```

### 実行コマンド作成、実行
1.[コンピュート]-[インスタンス]-[対象インスタンス]-[実行コマンド]をクリック
2.[コマンド作成]をクリック
![73.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/510919/bdd1252c-a497-457c-ae96-ff5617711112.png)

今回はOSのホスト名を確認するコマンドを記述。
![74.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/510919/2e06c749-4642-469f-8a23-3ae9fd2b2076.png)

### 確認
コマンド作成後。
![75.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/510919/1673c172-87ef-4712-abae-009e4656436a.png)

コマンド完了後。
![76.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/510919/dbc7b94b-4715-4dc2-a616-7f1428f4b441.png)

[コマンドの詳細の表示]をクリック
![77.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/510919/5cbf9490-1395-4e23-889f-27b8d9d14a54.png)

実行結果の詳細を確認。
![78.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/510919/5ad18202-254b-4bd0-b4ea-411cbf7f36ce.png)

## まとめ
コマンドは即時実行ではなく、一定の時間をおいてから実行されるので注意。
次はバケットにスクリプト配置して実行、ログもバケットに出力。
【Databricks API×TROCCO】TROCCOのワークフローでDatabricksのジョブを起動する

**誰でも簡単にTROCCOからDatabricksのワークフロー等を起動させることができます!!**

## 今回実行するDatabricksのワークフロー⏬️
事前に次のようなワークフローを組んでおきました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3033246/70dfa243-5260-4489-ae81-c990f6687297.png)



## 最終的にできあがるTROCCOのワークフロー⏬️

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3033246/6a45753c-4d0e-46ef-88ac-625313bc8d07.png)


1️⃣ TROCCOでSalesforceのデータをDatabricksに転送する
2️⃣ その後、Databricksのワークフローを起動する

という流れです。
これで、よくある「データが揃ってから諸々の処理を実行したい」願いが叶います。

***

TROCCOのHTTPリクエストタスクについては以下記事がとても参考になります。

https://qiita.com/hgkcho/items/27ef005401ff91f7154d

# 設定方法

## 【Databricks】 API実行権限の設定
APIを実行するには、API Keyを発行するユーザーが「Admin」または「Can Manage」権限を持っている必要があります。
管理者に依頼して付与してもらいましょう。


## 【Databricks】 アクセストークン の発行

ユーザー画面>開発者>アクセストークン の画面より、API Keyが発行可能です。コピーをしておきます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3033246/147cc307-ba61-498a-9ae6-089b4590a390.png)
この操作自体は前述の権限が無くとも可能なようです。

## 【TROCCO】ワークフロー&HTTPリクエストタスクの設定

ワークフローを作成したら、タスクを追加します。
TROCCOからAPIをキックするには、HTTPリクエストタスクを利用します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3033246/c6f43ba2-e861-49ec-b4fa-a8317d80881e.png)

リクエストを投げたいURLやパラメータ等の入力画面が表示されるので、入力してきます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3033246/e63a0884-df7b-4517-ad7a-81ea201fbee7.png)

今回の設定した内容は次の通りです。
* URL
  * `https://<your-databricks-instance>/api/2.0/jobs/run-now`
* HTTPメソッド
　* POST
* HTTPパラメータ
　* 名前
    　* `job_id`
 * 値
     *  実行したいDatabricksジョブのID※1
* HTTPヘッダ
    * キー
        * `Authorization`
    *値　
        * `Bearer <アクセストークン>`※2

※1 DatabricksジョブのIDは、画面上の「ジョブの詳細」より確認可能です⏬️
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3033246/70dfa243-5260-4489-ae81-c990f6687297.png)

※2 `Bearer `をつけ忘れるとうまく動かないので注意です。

***

今回は

1️⃣ TROCCOでSalesforceのデータをDatabricksに転送する
2️⃣ その後、Databricksのワークフローを起動する

という流れを実現したかったので、HTTPリクエストタスクの前にDatabricksワークフロー内で利用するデータを転送する転送設定をタスクとして付け加えました。


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3033246/7b2a906c-29fb-409b-902b-53d0cbce1fcf.png)

実行してみます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3033246/1fece087-386d-48c7-833a-3277c4c4297c.png)

転送設定→HTTPリクエストタスク(Databricksジョブ実行)の順でタスクが動いています。

TROCCO HTTPリクエストタスクの実行ログ⏬️

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3033246/75bffb59-008f-477d-a307-4891ac4f2e1b.png)

Databricksジョブのログ⏬️
※「手動で」と表示されていますが、これは「スケジュール起動ではないよ」ということのようです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3033246/733985e0-8aa4-4b38-a9fb-088a8d41879c.png)


# 補足と注意
TROCCOのワークフローではDatabricks APIをキックすること**しか**できません。
そのため、Databricks側の処理が終わった後、TROCCO側の別の処理を動かしたい要件の場合は別の手段を考える必要があります
（スケジュール感覚の調整、TROCCOのAPIをどこかで叩く、など）

今回はDatabricksワークフローを利用しましたがクエリ・ノートブック単体でも同様の手順で可能なようです。もしよろしければ試してみてください。
git merge --dry-run 相当？ gitで実際にマージされる内容を表示するコマンド（エイリアス）

## 概要

ローカルのgitで実際にマージされる内容をdiff表示するコマンド（エイリアス）。

## コマンド（エイリアス）

GitHubではトリプルドットdiffが使われるので、実際にマージされる内容と Files changed タブの表示内容が異なる問題は解決できない。

しかしローカルでgitに以下エイリアスを登録してコマンド実行することで、（作業コピーは更新せずに）実際にマージを実行してマージ前とマージ結果をdiffできる。これにより、実際にマージされる内容を表示することができる。

```.gitconfig
[alias]
	merge-diff = "!f() { git show $1 > /dev/null; git merge-tree HEAD $1; git diff HEAD `git merge-tree HEAD $1 | head -1`; }; f" # 最初のshowは、ブランチ名の補完が効くようにするため
	merge-df = "!f() { git show $1 > /dev/null; git merge-tree HEAD $1; git difftool -d HEAD `git merge-tree HEAD $1 | head -1`; }; f" # 最初のshowは、ブランチ名の補完が効くようにするため
```

```bash
# 使い方

# 実際にマージされる内容を、コンソールにdiff表示する
git merge-diff 《マージ先ブランチ》

# 実際にマージされる内容を、ツールを使ってdiff表示する
git merge-df 《マージ先ブランチ》
```

## 説明

以下のような処理をすることで、実際にマージを実行して、マージ前とマージ結果をdiffすることができる。
それをエイリアスとして使いやすく登録したのが上の.gitconfig内容になる。

```bash
# staging領域や作業ツリーは更新せずにマージを実行して、マージ結果のgitオブジェクトを作成する
git merge-tree HEAD 《マージ先ブランチ》

# ここに《マージ結果のgitオブジェクトID》が表示される

# マージ前の内容とマージ結果の差分を表示する
git diff HEAD 《マージ結果のgitオブジェクトID》
```

## git merge --dry-run はこれでいいのでは？

` git merge --dry-run`というオプションは存在しない。
検索すると`git merge --no-ff --no-commit`を代わりに使えという記事がひっかかるが、ドライランで行いたいことは『マージで衝突が発生するかと、マージされる内容を、ブランチを更新せずに確認したい』というものだと思うので、`--dry-run `でやりたいことは上記コマンドで実現できる気がする。
【資格試験】Python3エンジニア認定データ分析試験 合格体験記

# はじめに
2025年4月12日(土)に、Python3エンジニア認定データ分析試験を受験し、無事に合格できたので、受験当日までの過程を記録させていただきます。
なお、これから受験をされる方や受験を考えている方に向けて参考になれば幸いです。

# 試験概要
データ加工・分析をPythonで行うために必要最低限の知識が問われます。
出題範囲は全て、データ分析の実務には欠かせない専門知識だと個人的には感じています。
詳細は、下記URLの公式サイトからご確認ください。
https://cbt.odyssey-com.co.jp/pythonic-exam/python3cda.html

# 受験動機
これからデータに関係する仕事（データサイエンスやアナリストなど）をしたく、そのための基礎知識を復習しようと考え、試験に申し込みました。

# スキル
#### 試験申込時点のPythonや数学に関する知識やスキル
- Python
    - 初めてPythonに触れてから4年経過
    - アプリ開発のコーディング経験有
    - 新卒でSES企業に入社後、データ分析研修を受講し、PandasやNumpy等のライブラリの使い方を勉強
    ※その後はデータに関わる案件に配属されなかったためこれらの知識は活用できず

- 数学
    - 大学で、線形代数や確率統計を受講
    - 2021年6月に、統計検定2級を合格

# 試験勉強
#### 具体的な勉強方法や勉強時間について
- 勉強方法
    - 公式テキスト「あたらしいPythonによるデータ分析の教科書」は１周読みました。
    私は、業務でPythonを使用することがあるため、pipやパッケージの概念など基礎知識は身についていたため、概要は流し読みで試験本番に挑みました。
    しかし、Numpy、Pandas等のモジュールに関しては、具体的にどういうメソッドがあって、メソッドの使い方を理解するところまで読み込みました。
    - 模擬試験を1回受験しました。
    正直、本番の試験問題より模擬問題の方が難しいと感じました。
    模擬問題を理解して解けていれば合格できる可能性がかなり高いと思います。

- 勉強時間
    - 合計10時間(参考書読み込み8時間、模擬試験受講復習2時間)

 # 受験した感想
 私は、本試験を受験して良かったと実感しております。
 改めてデータ分析における、Pythonの基礎的なモジュールの理解やメソッドの使い方を知ることで、実務でプログラミングするときに調べなくともできるようになり、統計算出やデータ加工などの業務スピードの向上に繋がったと感じております。
 これからPythonを使ってデータ分析する知識をつけたい方におすすめの資格検定です！
1分で分かるsysの使い方

<h1>1. 始めに</h1>
今日はsysについて紹介していきます！
<br>カレンダーを作る中でsysモジュールにはすごく苦戦しました。他の関数とどう組み合わせていいか分からない、そもそも書き方あってるのかと思いながら公式ドキュメントを何周も読んでました。
<br>そんな悩みを解決するために私が１から書き方伝授します！sysは種類が多すぎるのでカレンダー作成の際に作ったものを参考に説明していきます。

それではまず私の完成のコードからご覧ください。
```python:完成形がこちら！
def main():
    parser = argparse.ArgumentParser()
    parser.add_argument('-m',   type=int, required=True)
    args = parser.parse_args()
    month = args.m
    if not 1 <= month <=12:
        print(f'{month} is neither a month number (1..12) nor a name')
        sys.exit(1)
    if __name__ == "__main__":
   main()

```

<br>これを見た時きっとあなたの頭の中には「？？？」が浮かんでいると思います。
<br>私も正直最初は「このコードはどうなっているんだ」という気持ちでいっぱいでした。
<br>このコードを噛み砕いて解いて説明していきます。

<h1>2.sysを使ったプログラムの書き方について</h1>
<h3>2-1. mainを定義する</h3>

```python:mainを定義する
def main():

if __name__ == "__main__":
   main()

```

mainを定義するのは、関数の後ろに書けるからです。変数名の衝突も防ぐことができるので定義しましょう。
<h3>2-2. parserを作る</h3>

```python:parserを作る
def main():
    parser = argparse.ArgumentParser()
```
```perser```を作ります。プログラムの説明なども（）内に書く事ができます。プログラム名や利用方法、オプションの追加など全体を定義するところになります。
<h3>2-3. parserの引数の設定をする</h3>

```python:parserの引数の設定をする
     parser.add_argument('-m',   type=int, required=True)
```
引数とはコマンドラインで使う「-〇〇」などのオプションのことです。Linuxコマンドの```ls -a```で言うところの```-a```のことです。引数を指定するには([引数],[文字型or数字型],[オプションを必須に指定])という構成で書きます。最初に作った```parser```に引数の設定を加えると```-m```が使えるようになります。
<h3>2-4. argsの引数を取得する</h3>

```python:argsの引数を取得する
     args = parser.parse_args()
```
argsはコマンドの引数を取得するために使うものです。追加した引数を使うために指定します。
<h3>2-5. argsの引数をmonthに渡す</h3>

```python:argsの引数をmonthに渡す
    month = args.m
```
```month```に```arg```で取得した```-m```の値を渡すことで指定した数字かどうかを判断します。
<h3>2-6. monthの数字が1~12か判断する</h3>

```python:monthの数字が1~12か判断する
   if not 1 <= month <=12:
        print(f'{month} is neither a month number (1..12) nor a name')
```
```-m```で指定した数字が1~12だったらカレンダーを出力してそれ以外の数字はエラーにします。
<h3>2-7. exit()で終了する</h3>

```python:exit()で終了する
        sys.exit(1)
```
```sys.exit(1)```を使うとプログラムを終了できます。
<h1>3. 最後に</h1>
このように細かく見ていくとすごく流れがよく分かりますよね。
<br>これ以外にもsysモジュールはたくさんあるので色々なモジュール使ってきたいです！
<br>他のsysモジュールも気になった人はぜひ調べてみてください！
ubuntu 24.04 リモートデスクトップ接続の小ネタ

## きっかけ
余っていた小型PCがあったので、せっかくだし使ってみよう。
wineを入れてWindowsのソフトも動かしてみたい。
CPU : Core i3-7100U
RAM : 16GiB
SSD : 128G
OS  : Ubuntu24.04 lts
ん－、ちょっと容量少ないかな。
## 昔の知識でこんにちは
チョップトップ（今はこう言わないの？検索しても出てこなかったｹﾄﾞ）で使いたいから、xrdpをインストールしてクライアントからの接続待ち状態まで設定。
昔と違ってGUIがリッチになってるなぁ、と思いながらUbuntuの設定を見てみたら「Remote Desktop」なる項目が。そっかそっかWindowsのリモートデスクトップ接続でつながるんだ。へー。
## 無限接続テスト地獄
それは便利になったもんだとUbuntuの「Remote Desktop」の設定をして、接続してみた。
ふむ。画面は出たぞ。
ユーザ名とかパスワードとか入れて、レッツゴー。
あれ？切れちゃうよ？
Ubuntu側のモニタには、「iBus通知」なるタイトルの文字が。スクショしたけど、こんなん見たことないわー。
何か設定間違えてるかなー？って「Remote Desktop」接続の設定画面を眺めていたら、一番上にある「リモートログイン」のスライドボタンがONにした後、数秒でOFFになってる。え？勝手に触ってるの誰？
何回設定しても、どこを見直してもOFFになるよぉ・・・。
## 気付きの時間
いろいろ調べていたら。
ん？
リモートデスクトップはけっこー最近のお話なんだ。ふむ。
xrdpとか古臭いこと言ってんじゃないですよもう21世紀の25年ですよ。
・・・・・・。
ひょっとして？
sudo apt remove xrdp（ッターン！！！）
Ubuntu : 終わったよー
よしわかった待ってろチョップトップ！（まだHDMIケーブルは刺さってる）
windowsのリモートデスクトップ接続アイコンぽちー
わーい
接続できたー

## まとめ
xrdpをインストールしたらWindowsのリモートデスクトップ接続アプリでつながらないよ。