OmniAICreator/Qiita-1.07M huggingface dataset:
ブラウザ拡張機能で履歴を表示する

# 概要

これは[初心者のブラウザ拡張機能 Advent Calendar 2024](https://qiita.com/advent-calendar/2024/browser-extension)の21日目の記事です。

ブラウザの履歴を拡張機能で表示してみます。

# やること

右クリックでコンテキストメニューから新しいウィンドウを呼び出します。
そのなかでボタンを押すと直近24時間の履歴が表示されるようにします。

# 出力イメージ

![拡張機能画面イメージ](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/302006/e494e0bd-d315-470e-8673-50baef644606.png)

![拡張機能画面イメージ](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/302006/dbbec9b2-fa9d-f508-c5e0-dc293289e00b.png)

# 具体的なソースコード

```json:manifest.json
{
    "browser_specific_settings": {
        "gecko": {
          "id": "the-town-sample-history@example.com"
        }
    },
    "manifest_version": 3,
    "name": "init-extention",
    "version": "0.1",
  
    "description": "履歴サンプル",
  
    "icons": {
      "48": "icons/icon-48.png"
    },

    "background": {
        "scripts": ["background.js"]
      },
  
      "permissions": [
        "menus",
        "history"
      ]
}
```

履歴へアクセスするために`permissions`に`history`を追加します。


```background.js
browser.menus.create(
  {
    id: "sample",
    title: "sample menu",
    contexts: ["page"],
  }
);


function createPage() {
  let createData = {
      type: "popup",
      url: "page.html",
      width: 500,
      height: 300,
    };
    let creating = browser.windows.create(createData);      
}


browser.menus.onClicked.addListener((info, tab) => {
  console.log("clicked");
  if (info.menuItemId === "sample") {
      createPage();
  }
});
```

こちらはコンテキストメニューを追加しています。新しいウィンドウを開く処理です。


```javascript:history.js
const logElem = document.getElementById("log");
console.log = (msg) => (logElem.textContent = `${logElem.textContent}\n${msg}`);

function onGot(historyItems) {
    for (const item of historyItems) {
        console.log(item.url);
        console.log(new Date(item.lastVisitTime));
    }
}

function onClick(e) {
    e.preventDefault();
    browser.history.search({ text: "" }).then(onGot);
}

document.querySelector("form").addEventListener("submit", onClick);
```

履歴へアクセスするために`browser.history.search`を使います。表示したいだけなので詳細は触れませんが、特に指定しなければ24時間前のものが出力されます。

[history.search()](https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/history/search#examples)

```html:page.html
<!DOCTYPE html>

<html>
  <head>
    <meta charset="utf-8">
    <meta name="color-scheme" content="dark light">
  </head>

<body>
    <h1>拡張機能ページ</h1>
    <p>これはサンプルページです</p>
      
    <form>
      <button type="submit">履歴表示</button>
    </form>
    <pre id="log""></pre>
    <script src="history.js"></script>
</body>

</html>
```

履歴を表示する画面です。



# 参考

[history.search()](https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/history/search#examples)

[【JavaScript】event.preventDefault()が何をするのか](https://qiita.com/yokoto/items/27c56ebc4b818167ef9e)
LINEアプリの日程調整機能をデータベース設計してみた


## 概要
LINEアプリの日程調整機能をデータベース設計してみました。
実際にスマホ画面でLINEアプリをポチポチ操作しながら、LINEアプリの日程調整機能の仕様を分析しました。
その成果物として、LINEアプリの日程調整機能のER図を作成しています。

また、本記事は自身のバックエンドスキルを証明する一つの材料として執筆しております。

:::note warn
本記事は下記のサービスにて公開しております。公開日時：2024年12月21日
複数のプラットフォームで発信することで、多くの方にご覧いただき、少しでも参考になれば幸いです。
- Zenn
- Qiita
- Twitter
- LinkedIn
- Findy
- Forkwell
- LAPRAS
- 職務経歴書のレジュメ
- etc
:::

## 詳細
2つ成果物を作成しております。
1. LINE日程調整機能_画面フロー図
2. LINE日程調整機能_ER図

### 1.LINE日程調整機能_画面フロー図
LINE日程調整機能の概要については、[LINE公式日程調整機能ドキュメント](https://line-ja.officialblog.jp/archives/17582540.html)をご参照ください。

![line-schedule-flow.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3967556/bda1d000-5b86-6402-5ed7-c1a1c43f48e6.png)

### 2. LINE日程調整機能_ER図

LINE日程調整機能に焦点を当ててテーブル設計を行い、ER図を作成しました。

![line-schedule-er-design.drawio.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3967556/3a6f8616-e87e-f647-1665-f6b43c2d8657.png)

#### データベース設計の要所解説

- 第3正規化を徹底する
  - 理由
    - データ保持効率が高い
    - RDS/Aurora は高性能であるため、非正規化を行わなくても十分にパフォーマンスを確保できる
- 招待テーブルは、ポリモーフィックリレーションで表現する
  - 理由
    - RDS/Aurora は高性能であるため、複雑な構成を避け、シンプルさを優先した設計を優先する
- ステータスを管理するカラムは、0始まりの数値で管理する
  - 理由
    - boolean (true/false) では拡張性が低く、将来的なステータス追加が難しい
    - 数値にすることで、0（偽）と1（真）のような二値管理からステータスといった用途に対応できる
【簡素な表付き】久しぶりにFavicon設定をするとよく分からなくなったので、調べる

みなさんはFaviconについてしっかり説明できますか？サイトやアプリにおいておまけ程度の認識でいないですか？（昨日までの私...）

業務においても、個人開発においても、そう何度も作成・設定するものではないので、久しぶりに扱うとよくわからなくなりました。

そのため改めて調べてまとめようと思います。

同じ境遇の方、ぜひ読んでいただけると嬉しいです。

## faviconとは

### faviconの歴史や概要
faviconとは、Webサイトのブラウザタブのタイトルやブックマークに表示される小さなアイコンです。（以下添付画像左部分のアイコン）
このアイコンは、1999年にInternet Explorer 5で初めて対応しました。小さなグラフィックでありながらも、ブランディングにおける重要な要素の一つとして活用されています。

![スクリーンショット 2024-12-22 13.02.34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3624902/3ea021ee-2669-6fca-b1e1-0149f99c1230.png)


### faviconの役割と重要性
faviconはユーザーがタブを記憶したり、サイトの認識を高めるために重要な存在です。その作成は、ブランドイメージを確立し、ブラウザのユーザー体験を向上させるために必要です。

確かにもしアイコンがない場合を考えると、サイトをどのタブで開いたか認識しづらいです気がしますよね。また、Wordpressなどのデフォルトのアイコンを使用する場合も同様に他サイトとの違いを認識しづらいかもしれません。

私たち意外にこのちっこいアイコン見てるんですよね...:rolling_eyes:

## faviconに使用できるフォーマットと比較

### faviconに使用可能なフォーマット

- **ICO**
    - favicon用に最も普通に使用されるフォーマット。複数のアイコンサイズを内包できるのがメリット。
- **SVG**
    - ベクトルデータのため、スケーラビリティーに優れる。高解像度で設定できる。
- **PNG**
    - 高解像度なビットマップファイル。しばしばサブオプションとして使用される。
- **JPEG**
    - コンプレッションがかかるが、普及したフォーマット。透過できない為、注意。
- **GIF**
    - すべてのブラウザでサポートされていますが、アニメーションが必要な場合に限る。
- **WebP**
    - 高品質でファイルサイズが小さい。使用可能なブラウザーが限る。

:::note
icoフォーマットの「複数のアイコンサイズを内包できる」というのは、例えば青リンゴのfaviconを設定したい場合に、①（16px × 16px）②（32px × 32px）③（48px × 48px）という3つのサイズパターンを用意したら、専用のツールやプラグインで1つの.ico形式の画像に変換できます。

その為、サイトの表示環境を側っても内包しているサイズパターンの分だけ解像度を保つことができるというわけです。
:::

### フォーマットの比較

| フォーマット | 解像度 | サポート性 | ファイルサイズ | ブラウザサポート |
|---------|--------|-------------|------------|----------------|
| ICO     | 高い | 複数アイコン対応 | 大きい | 高い         |
| SVG     | 最高 | スケーラブル | 小さい | 高い         |
| PNG     | 高い | 限定的   | 中くらい | 高い         |
| JPG     | 低い | 限定的   | 小さい | 高い         |
| WebP    | 高い | 限定的   | 最小     | 低い         |

:::note
フォーマットとしてはicoの使用率が高い気もしますが、昨今のブラウザ状況（IE終了）等を考えるにSVGやPNGでも正直問題ないと思います。大きい画像の場合SVGだと重くなりますが、faviconに設定する画像はそもそも小さいことが多いので、SVGで問題ない気がします。
:::

## どのディレクトリに配置すべきか

faviconは、一般的にWebサイトの格設ファイル「rootディレクトリ」に配置されます。これは、多くのブラウザーが自動的に「/favicon.ico」を検索するためです。しかし、HTMLヘッダの`<link rel="icon" href="URL">`タグを使用することで、別のディレクトリやファイルを指定できます。

また、最近でいくとフロントエンドはJSフレームワークの使用が常態化しているかもしれません。各フレームワーク・ツールでは公式ドキュメントにfaviconについて記載されていると思うので、ご使用になられるフレームワークのドキュメントを読むのをオススメします！

いくつかドキュメント添付します。

**Nuxt.js**
https://nuxt.com/docs/guide/directory-structure/public

**Next.js**
https://nextjs.org/docs/app/api-reference/file-conventions/metadata/app-icons

**Astro**
https://docs.astro.build/en/basics/project-structure/#example-project-tree

他フレームワークは分かりませんが、基本的にfavicon画像の配置場所はお馴染みの`public`ディレクトリ直下かつindex.htmlと同じ階層に置くのが通例っぽいです。

ちなみに最近React + Viteでプロジェクト立ち上げたときには、favicon画像のみ`public`内に配置しindex.htmlはルート直下に配置しましたが、build時に自動でfavicon画像が`public`からルート直下に移動するので、無事描画されました。

## まとめ

faviconは、Webサイトのアイデンティティを高め、ユーザー体験を向上させる重要な要素です。使用するフォーマットを選ぶときは、サイトの要件に合わせて選定しましょう。また、ファイルの配置場所にも注意し、しっかり描画できるように設定を行いましょう〜:middle_finger:

本記事を読んでいただきありがとうございました！:bow_tone1:
ForbiddenAttributesError

#### 禁じられた属性のエラー
>Active Model ForbiddenAttributesError

#### マスアサインメントに使われた禁じられた属性のとき例外が起きる
>Raised when forbidden attributes are used for mass assignment.

```rb
class Person < ActiveRecord::Base
end

params = 

ActionController::Parameters.new(name: 'Bob')
Person.new(params)
# => ActiveModel::ForbiddenAttributesError

params.permit!
Person.new(params)
# => #<Person id: nil, name: "Bob"
```

https://api.rubyonrails.org/classes/ActiveModel/ForbiddenAttributesError.html#:~:text=Active%20Model%20ForbiddenAttributesError,nil%2C%20name%3A%20%22Bob%22
【自習】AWS DynamoDB

PMする上で必要になってきたのでおさらい

https://docs.aws.amazon.com/dynamodb/?icmpid=docs_homepage_databases

## **AWS DynamoDBとは？**

AWSが提供する**スケーラブルなフルマネージド型NoSQLデータベースサービス**。 高い可用性、低レイテンシ、スケーラビリティを備えており、リアルタイムアプリケーションに最適。

## **DynamoDBの特徴**

1. **サーバーレス**
   - インフラ管理が不要。必要に応じて自動スケール。
   - プロビジョニング（リソース確保）やパッチ適用が不要。

2. **スケーラブル**
   - 数バイトのデータから数テラバイト規模まで自動スケール。
   - スループット（読み取り/書き込み性能）を動的に調整可能。

3. **高速なパフォーマンス**
   - ミリ秒単位の低レイテンシでデータを処理。
   - リアルタイムのレスポンスが必要なアプリケーションに適している。

4. **データモデルの柔軟性**
   - キー/値ストア型とドキュメント型の両方に対応。
   - JSONや属性を持つ複雑なデータも扱える。

5. **フルマネージド**
   - 高可用性（マルチAZ配置）とデータの耐障害性を自動で提供。

6. **イベント駆動**
   - DynamoDB Streamsを使ってデータの変更をトリガーとして他のサービス（例: Lambda）を実行可能。

## **DynamoDBの基本構造**

#### **1. テーブル**
- データを格納する基本単位。
- 各テーブルには**プライマリキー**が設定される。

#### **2. アイテム**
- テーブル内のデータの1つの単位（行に相当）。
- アイテムは**属性**を持つ（列に相当）。

#### **3. 属性**
- アイテムを構成するデータフィールド（値）。
- **型**: 文字列（String）、数値（Number）、ブール値（Boolean）、マップ（Map）、リスト（List）など。

#### **4. プライマリキー**
- 各アイテムを一意に識別するキー。
  - **パーティションキー**: 単一キーでアイテムを識別。
  - **パーティションキー＋ソートキー**: 複数属性を組み合わせて識別。

## **DynamoDBの主なユースケース**

#### **1. セッションデータの管理**
- **シナリオ**: ユーザーのログインセッション情報を保存。
- **理由**:
  - 高速なデータ読み書き。
  - セッションデータは軽量でスケールが必要。

#### **2. リアルタイムアプリケーション**
- **シナリオ**: チャットアプリ、IoTデバイスのデータ管理。
- **理由**:
  - ミリ秒単位のレスポンス。
  - DynamoDB Streamsでリアルタイム処理。

#### **3. ショッピングカートや在庫管理**
- **シナリオ**: Eコマースサイトでのショッピングカートデータ。
- **理由**:
  - 柔軟なデータモデル。
  - 高可用性でスケール可能。

#### **4. ゲームのリーダーボード**
- **シナリオ**: スコアランキングやプレイヤーデータの管理。
- **理由**:
  - ソートキーを使った効率的なスコアランキングの取得。

#### **5. データキャッシュ**
- **シナリオ**: 頻繁にアクセスされるデータの保存。
- **理由**:
  - 高速で低レイテンシの読み取り。

## **DynamoDBの料金体系**

DynamoDBの料金は、以下の項目に基づいて課金されます：

1. **プロビジョンドスループット**
   - **読み取りキャパシティユニット（RCU）**:
     - 1秒間に1つのデータ（最大4KB）を強力整合性で読み取れる単位。
   - **書き込みキャパシティユニット（WCU）**:
     - 1秒間に1つのデータ（最大1KB）を書き込める単位。

2. **オンデマンドモード**
   - データ読み書きのリクエスト数に基づく課金（使用量が不規則な場合に適）。

3. **ストレージ**
   - 保存されるデータの量に応じて課金（$0.25/GB/月）。

4. **DynamoDB Streams**
   - データ変更イベントを使用する場合、ストリームの利用料金が発生。

5. **バックアップとリストア**
   - 自動バックアップ: 無料。
   - オンデマンドバックアップ: 保存容量に応じて課金。

## **DynamoDBの導入手順**

#### **1. テーブルの作成**
1. AWSコンソールで「DynamoDB」を開く。
2. 「テーブルを作成」をクリック。
3. テーブル名とプライマリキーを指定。
   - 例: パーティションキー = `UserID`。

#### **2. データの挿入**
- コンソールからデータを直接入力。
- または、AWS SDKやCLIを使ってデータを挿入。

#### **3. データの取得**
- プライマリキーでアイテムをクエリ。
- ソートキーを使った範囲検索も可能。

#### **4. DynamoDB Streamsの設定（オプション）**
- ストリームを有効にしてデータ変更イベントを処理。

## **DynamoDBのメリットとデメリット**

#### **メリット**
1. **スケーラビリティ**
   - 自動スケールで、大量のトラフィックにも対応。
2. **高可用性**
   - マルチAZ配置で耐障害性を確保。
3. **サーバーレス**
   - インフラ管理が不要で、アプリケーション開発に集中できる。

#### **デメリット**
1. **複雑なクエリには不向き**
   - SQLのようなJOIN操作がないため、リレーショナルデータベースが必要な場合は適さない。
2. **設計が重要**
   - プライマリキーやアクセスパターンを適切に設計しないと、パフォーマンスが低下。

## **DynamoDBのベストプラクティス**

1. **適切なプライマリキー設計**
   - 頻繁にアクセスするデータを効率的に取得できるキーを設定。

2. **オンデマンドモードの活用**
   - 使用量が不規則な場合は、オンデマンドモードでコスト最適化。

3. **DynamoDB Streamsの活用**
   - データの変更をリアルタイムでトリガーに利用。

4. **データモデリングの計画**
   - アクセスパターンを事前に設計してパフォーマンスを最大化。

## 感想
NoSQLとRDBの使い分けについて、詳しく理解していないと選定が難しい。その辺りは実際に触ってみないとわからない気がする。
新卒2年目エンジニアの学習記録：学習10カ月目

# はじめに
新卒2年目エンジニアのA.Kと申します。
**1月から社内開発のフルスタックエンジニアとして転職予定のため、今月はまるまるお休み**をいただいています。
**ただ、細長く学習は続けていた**のでその様子を振り返っていきます。

https://qiita.com/AK_React/items/044499668cc635f90160

# 学習10カ月目にやったこと

### <font color="Red">**Railsチュートリアル完走**</font>

**転職先で使われているため、一足早くRailsデビュー**しました。
やはり手を動かすのがいいということで、**アプリケーションを作成しながら学んでいくタイプの教材**を選択しています。かなりボリュームのある内容で、1周で理解しきることは難しいと感じました。

https://railstutorial.jp/webtext

Railsを学んでみた所感としては、「**記法がシンプルなので直感的に内容を理解できる。だがその分、MVCを用いた処理の流れや、メソッドの理解といった基礎基本をより意識させられる。**」といったところでしょうか。。
恥ずかしながら、**私はそういった土台を固めないまま現場に出て、手を動かしてきた人間**です。
従って、**プログラミングの基本やお作法をしっかりと身に着けることの重要性を痛感**させられました。（上記のチュートリアルでは基本概念から丁重に解説してくれています。）
***

### <font color="Red">**オブジェクト指向に関する本を読む**</font>

とある方のLT会で取り上げられていた「**ちょうぜつソフトウェア設計入門**」という本を読んでいます。これまで**アウトプット学習に身を捧げてきた自分にとって、こうした専門書を読むのは初めてですし、その割にかなり背伸びしたチョイスだなとも思いつつ（笑）**
ちなみにまだ3分の1も読めていません、めちゃくちゃ内容が濃いので全集中して読んでいます。

そもそも**この本を手に取った背景としては、LTで面白そうな本の紹介をしてる！→ 確かに「オブジェクト指向とは何ぞや？良い設計とは何ぞや？」→ せっかく時間があるから読んでみよう**！といった流れです。

所感としては、もちろん簡単に理解できる内容ではないものの、文章に技術書特有の無骨さがないので読み進められています。
「**設計にはこういう原則があって、だから良い設計とはこういうことを指すんだよ**」みたいな。**言及しているテーマは難しいものの、話の流れは簡潔で分かり易い印象**を受けました。
年末年始に読み切りたいなあ。

https://www.amazon.co.jp/%E3%81%A1%E3%82%87%E3%81%86%E3%81%9C%E3%81%A4%E3%82%BD%E3%83%95%E3%83%88%E3%82%A6%E3%82%A7%E3%82%A2%E8%A8%AD%E8%A8%88%E5%85%A5%E9%96%80%E2%80%95%E2%80%95PHP%E3%81%A7%E7%90%86%E8%A7%A3%E3%81%99%E3%82%8B%E3%82%AA%E3%83%96%E3%82%B8%E3%82%A7%E3%82%AF%E3%83%88%E6%8C%87%E5%90%91%E3%81%AE%E6%B4%BB%E7%94%A8-%E7%94%B0%E4%B8%AD-%E3%81%B2%E3%81%95%E3%81%A6%E3%82%8B/dp/4297132346

### <font color="Red">**ITイベントに参加してミドル層と交流する**</font>

**先月もイベントには積極的に参加していましたが、ついつい同世代と絡みがちでした**。楽しいし居心地が良いんですよね～
もちろん同世代の仲間たちも大好きなのですが、最近はPMやマネジメント関連の役職に就かれている方と多く交流させてもらっています。
理由としては、**自分の今後のキャリアの方向性に迷いがある＆マネジメント職への興味がある**、といったところです。
先輩方とお話しするのは敷居が高いようにも思えますが、実際お話ししてみるとすごく気さくで温かい方ばかりです。そしてたくさんの世界を知っているし、一つ一つの言葉に重みがあって、、私は数年後こうなれているのだろうか（笑）

キャリアの相談に乗ってもらう中で、**自分の描くキャリア像がいかに漠然としているか・なるべく早い段階で方向性を決めることの重要性**を強く感じました。
実際に「**せっかくバイタリティがあるんだから、目的地が決まれば強いじゃん！**」と言ってもらって、その通りだなと。。

なので、**この期間に「自分は何のために働いているのか・これからどうなりたいのか」をしっかり考えて、先輩方を頼らせてもらいながら走っていきたいと思います。**
# おまけ
先月ボディメイクの大会に初出場してきました。
結果は入賞ならずと悔しい終わり方になってしまいましたが、何一つ悔いはないです。
出場を決断した自分、ナイス。一回り強くなれました。
応援してくれた方、本当にありがとうございました。
今はたくさん食べてガンガン高重量扱ってめちゃくちゃ元気です！


# おわり
以上が10カ月目の振り返りでした！
自分の中で学習をやめるという選択肢はありません。波はあるにせよ、その時の状況に合わせて柔軟に継続していきたいと思います。
Android RoomDB備忘録

### RoomDB導入
```
build.gradle（Project）

plugins {
    // 2024年12月22現在
    id("com.google.devtools.ksp") version "2.0.21-1.0.26" apply false
}
```
```
build.gradle（Module）

plugins {
    id("com.google.devtools.ksp")
}

...

dependencies {
    // Room
    implementation("androidx.room:room-runtime:2.6.1")
    ksp("androidx.room:room-compiler:2.6.1")
    implementation("androidx.room:room-ktx:2.6.1")
}
```
Elixirチートシートを作ろう、番外編その３　解説の文中のサンプルの話



# 1. OverView

どもども、うん、アドベントカレンダーの完走賞狙いなんだ、すまない。
チートシート１９日分書いたから、あとはこつこつ書くだけだね。

解説の文中のサンプルの話をしたいと思います…もっともこれ、結論がないのです。

# 2. 本文

Elixir Schoolの記事、一文にすっごく味があって、俺なりにコピペで「こう解釈したのだ」と書き飛ばして
見たのだけど、当初の不満は、「作例に見たこともない機能が出てくること」

これ、最初は学習順を整理すれば、何とかなると思ってたんだよね。でも、そこで起こるのは苦痛なだけなんですわ。
今回、最後にシジルを持ってきたのだけど、そこまでの例でも使ってる、でも、シジルがないと、以下の様に一般的ではない書き方となる。

```
iex(11)> ~s/hello #{greeting_target}/
"hello world"
iex(12)> "hello " <> greeting_target
"hello world
```

うーん、文字列の結合を最初に説明しているとは言え、後者が連発して例として読みやすいか？
Elixir Schoolのサンプルの様に「説明していない機能でも、Elixirの書き方に沿った例に入れる」方が結果的に
よくないか？と言う結論に至りました。

# 3 蛇足
世間で言うラムダ式が複雑だから、レビューが通らない、と言う誤解も、ここら辺から来ると思うなぁ。

ElixirでEnum.mapのサンプルとなります。

```
iex(23)> Enum.map([0, 1, 2, 3], fn(x) -> x * 5 end)
[0, 5, 10, 15]
iex(24)>  Enum.map([0, 1, 2, 3], &(&1 * 5))
[0, 5, 10, 15]
iex(25)>
```

気を付けるべき点は「関数を引数に取る」「無名関数がその場で定義する」なんだよね。
これ、他の言語に書き直してみましょうか？…うん、Ｃ言語にlistないから、許して。
```
for( i = 0,  ; i < 4; i ++) {
        x = i * 5;
        pos = strlen(newlist);
        sprintf(newlist[pos], "%d,", x)
}
```
動くかな…心配になって来たｗまぁこれ、Cのプログラマなら反射で書けるわ。

肝は、フローチャートのレベルで書けば普通の処理なのに、なぜかEnum.map([0, 1, 2, 3], fn(x) -> x * 5 end)を
特別なものの様に説明してしまった間違いだと思うんだよね。

説明としては、
LISTの各要素を５倍したい。
各要素に対して処理を行うEnum.mapは、引数に取り出した各要素を処理する関数をとる。今回は処理が簡潔であり、再利用しない
ため、引数は通常の変数は定義せずに、無名関数fn(x) -> x * 5 endを定義した。

…とでも説明すれば、レビューが可能に思うなぁ。
数度説明すれば、以降は同じ、で済むでしょう。

どうだろ？SIerでレビューを担当する同志諸君？納得してくれそう？
あ、大河大長編無名関数とか書く阿呆は…ドツケｗ
UTF-8 with BOMを処理した話[Go]

Goでcsvをデコードしようとしたら`UTF-8 with BOM`になっていて、base64にデコードして文字列にしようとするとエラーが出て困ったことがあるので、その対処法を記載したいと思います。

# utf-8 with BOMとは

`UTF-8`は、Unicode用の符号化形式の1つです。

`Unicode`は、符号化文字集合と呼ばれ、世界で使用されている文字に対して、番号が振られたものです。

例えば、`あ`には<font color="red">12354</font>という数字が振られています。

その数字を文字に変換するときのルールを符号化形式と呼び、`UTF-8`では<font color="red">0xe3 0x81 0x82</font>と表されています。

:::note
### どうして符号化形式が存在するのか
Unicodeは2バイトで1文字を表現します。
しかし、世界には約7000語ほど言語があると言われているらしく、それを２バイトで表現するのは難しかったそうです。
それを解決するために`UTF-8`や`UTF-16`という変換形式が生まれたそうです。
:::

`UTF-8 with BOM`は、UTF-8で書かれていることを示すために、Unicodeの先頭に`0xEF 0xBB 0xBF`がついたものを指します。

:::note
### BOMとは
`Byte Order Mark`のことで、unicodeの符号化方式を識別するために先頭に付与される数バイトのデータのことを言います。
:::


# 対処方法

例えばcsvがbase64エンコードされていたとします。
下のようにcsvをbase64デコードすると、`utf-8`と認識できずBOM付きの場合エラーを吐きます。

```go:go
decodedCSVBytes, err := base64.StdEncoding.DecodeString(csv)

decodeCSVString := string(decodedCSVBytes)

if !utf8.ValidString(decodeCSVString) {
		if err != nil {
			return nil, err
	}
}
```

:::note
### base64とは
文字列を64進数でエンコードします。
エンコードされた文字列はアルファベット(a~z, A~z)と数字(0~9)、一部の記号(+,/)の64文字を使って表されます。(正確には=を使うので65文字らしいです)
:::

この場合は、文字列に変える前に`UTF-8 with BOM`の先頭の３バイトで識別して下のコードを挿入します。
こうすることでBOMを弾いた内容をデコードすることができます。

```go:go
	if len(decodedCSVBytes) >= 3 && decodedCSVBytes[0] == 0xEF && decodedCSVBytes[1] == 0xBB && decodedCSVBytes[2] == 0xBF {
		decodedCSVBytes = decodedCSVBytes[3:]
	}
```


# utf-8 with BOMを確認する方法
txtファイルであればfileコマンドでfileの形式を確認できます。
```:zsh
file test.txt
```

しかし、csvファイルだと確認できないため、下のコマンドで確認します。
```:zsh
file -e encoding test.csv
```

BOM付きの場合、下のように表示されます。
```:zsh
test.csv: Unicode text, UTF-8 (with BOM) text
```

# UTF-8 with BOMを作成する方法
テストでUTF-8 with BOMを作成する必要がある場合は、`nkf`コマンドを使います。

nfkは「Network Kanji Filter」の略で、文字コードを変換することができ、異なるOS間でのファイル共有を可能にするコマンドです。

:::note
nkfコマンドは最初から入っているものではないのでインストールしてください。
- windows
`nkf.exe`をインストールしてパスを通してください。

- Mac
homebrewでのインストール
```:zsh
brew install nkf
```
> 参考:https://neos21.net/blog/2018/04/10-01.html#windows-%E3%81%AE%E5%A0%B4%E5%90%88
:::

下のコマンドを使うことでUTF-8 with BOMに変換することが可能です。
```:zsh
nkf --overwrite --oc=UTF-8-BOM test.csv
```
Human Interface Guidelines「Right to left」のまとめ

## これは何
`Human Interface Guidelines>Foundations>Right to left`を読んだまとめ・感想

https://developer.apple.com/design/human-interface-guidelines/right-to-left

## アラビア語に変えてみたプチ話
実際にアラビア語で変えてスマホを操作してみましたが、設定から日本語に戻すのに苦労しました:dash:

普段慣れで操作してる部分が結構あるんだなと別の気づきを得ました。

例えば、だいたい「戻るボタンは左/完了ボタンは右」にあるよな〜と思って英語のサイトでも操作できたりとか。アラビア語にすると全てが逆なので、アイコンで設定できるものがわかっても操作に時間がかかります:cold_sweat:

ぜひ、アラビア語設定に変えて困ってみてください:tea:

## 書いてあったこと
### Right to left概要
スクリプトの読み取り方向に合わせて、インターフェースを反転することで、アラビア語やヘブライ語など右から左に記述する言語をサポートする


### テキストの配置
- 段落は言語に合わせて配置する
    - 1,2行程度なら、現在のコンテキストに合わせる
    - それ以上なら、文章の言語に基づいて配置する
        - （例）アラビア語で見ていても、5行程度の英語のテキストがある場合は左揃えにする

 >![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3632482/4b3746f7-440d-ee09-499d-083fcaef5b68.png)



### 数字と文字
- Right to left（RTL）言語でも異なる数値体系が使用されてることがある
    - 数値中心のトピックを扱うサービスの場合はそれぞれの地域に対して適切な表現を特定する
    - 数値関連のトピックがメインじゃない場合はシステムが提供する数値表現に依存で:ok:
- 特定の番号の数字の順序は逆にしない
    - ex.電話番号、クレジットカードの番号
- 進行状況やカウントする場合は数字の順序を逆にする
    - 数字だけでなく、それに伴うスライダーや評価のアイコンも逆にする
        - （例）評価の:star:が右から5

 ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3632482/bb95ac59-d9b4-b165-0a8c-1d8bd487216a.png)


### コントロール
- ある値から別の値への進行状況を示すコントロールを反転します
    - 進行状況を示すスライダー
    - 固定された順序でナビゲートするもの
        - 戻るボタン・進むボタンなど
- 実際の方向を参照するものはコントロールの方向のままにする
    - ゲームアプリとかで右に移動する場合は、>を押せばそのまま右に移動するようにする、みたいなこと？
- 必要に応じてラテン文字とRTLの視覚的なバランスを調整する
    - そのままだとRTL言語は小さく見える
    - 2pt大きくすると効果的
    - :memo:日本語と英語でも調整が必要な部分はありそう

>![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3632482/20e00a34-6c36-fb6e-75a7-a8a55a2e7d16.png)


### 画像
- 写真やイラストなど反転すると意味が変わるものは反転しない
:::note warn
反転してしまうと著作権違反になる場合もあるので注意
:::
- 画像の順序も意味がある場合、逆にする

>![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3632482/8c39405b-97dd-a686-a4a3-fb20298aa897.png)


### インターフェースアイコン
- Appleが提供しているSFシンボルはRTL言語に対応している

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3632482/f3b39b71-8b65-e80a-e69c-1f33db853ff8.png)

- テキストが含まれるアイコンではRTL言語版の作成を検討する
    - 文章の方向
    - 文章を補足する要素の位置
        - （例）エラーを示す:x:を左ではなく右に位置させる
- ロゴやユニバーサルサイン・マークは反転させない
    - :memo:世界で普遍的なマークを調べたけどうまく探せなかった
    - チェックマークは例として挙げられていた
- 現実世界のオブジェクトを表すものは反転しない
    - （例）時計、ペン、ゲーム機など
- アイコンを反転させる際は、意味合いやバランスを検討する
    - スラッシュで否定を意味する場合、LTRでもRTLでも同じバックスラッシュを使用することで意味の一貫性を持たせる
        - >![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3632482/be1c6cfd-97fb-de29-356c-5135fa9cdce1.png)
    - アイコンに+バッジがついてたりする場合はバッジも反転させる
        - >![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3632482/aeb11204-f626-fcf0-1ea0-2223fe58335f.png)

### その他の参考
https://note.com/sakinotomiura/n/n240b39b7f08f

この記事には反転されてるアイコンがまとめられていたりして、RTL言語にした時の違いがわかりやすいです:memo:
【数式】期日までの営業日ベースの残り日数計算

# 概要
期日 (DueDate__c) に設定された日付までの残り営業日（土日を除く平日の日数）を計算する。  

# 数式
```
IF(
    DueDate__c < TODAY(),
    "期日超過",
    TEXT(
        DueDate__c - TODAY() - 
        FLOOR((DueDate__c - TODAY() + WEEKDAY(TODAY()) - 1) / 7) * 2 - 
        IF(MOD(WEEKDAY(TODAY()) + DueDate__c - TODAY() - 1, 7) = 6, 1, 0) - 
        IF(MOD(WEEKDAY(TODAY()) + DueDate__c - TODAY() - 1, 7) = 0, 1, 0)
    )
)
```
[VS Code] GitHub Copilotログインできない

# はじめに
青色のログインボタンを押してもなにも表示されなかった人向けの記事です。VScodeで「Github Copilot」にログインできない！
<img width="150" alt="githubcopilot.PNG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3743053/7bfb307d-edbf-36ca-fe9b-3fdf0395cc31.png">👈これ
## 拡張機能の認証機能が有効になっていない
私は過去にGithubの認証まわりを触ってしまったことが原因でログインできませんでした。以下有効にする手順です。
### ①ファイルからユーザー設定のプロファイル
 ファイル→ユーザー設定→プロファイルをクリックします。
 その後拡張機能のGithub認証を探してクリックします。
<img width="150" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3743053/cecf61b0-6d04-7ab2-7f3c-ed522f9fb550.png"><img width="350" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3743053/ce1189f6-9e92-4067-d437-da86d43b73df.png">

### ②Github認証を有効にする
以下の画像のように有効にします
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3743053/c311d712-cc24-d5c8-4072-775545b4db5b.png)
その後青色のログインボタンを押してください！
これでみんなもcopilotエンジニア！✊
M2でUnrealEngine5.2を構築する

# えっ、私がエンジニア…！？　そんなの絶対無理ぃ！
ひょんなことからUnrealEngineでゲームを作ることになった私
プログラムなんて、言葉すらまともに聞いたことなかったのに・・・

一体私、どうなっちゃうの〜！？！？

### 環境
- MacBook Air(Apple M2 Pro)
- macOS Sonoma 14.7.1（23H222）
- Unreal Engine 5.2（最新）
- Xcode 16.1
- Android Studio Flamingo

ゲームの実行環境
- Metaquest2


# 構築手順

## UnrealEndgineのインストール
 公式ページの手順に沿ってUE５.2をインストールする
 https://www.unrealengine.com/ja/download
 - Epicのアカウント登録が必要
 - 公式の手順が最強すぎてここで語ることがない

## Xcodeのインストール
 言わずもがなAppStoreからインストールする
 - 最新版を入れるためにMacOSをアップデート必要があって面倒だった
     - この時点で、その日中に構築が終わらないことを悟る
     - かわいそうだね

## SDK・NDKのインストール
AndroidStudioを利用するので、公式ページの手順を参照すると良い
https://dev.epicgames.com/documentation/ja-jp/unreal-engine/how-to-set-up-android-sdk-and-ndk-for-your-unreal-engine-development-environment?application_version=5.3

- バージョンはFlamingo
    - https://developer.android.com/studio/archive
    - この時のパスは後で使うので覚えておくと良い

![image-2024-11-19_18-22-39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3967203/4800ac65-d73b-a45e-0a9c-59d50f1abe3b.png)
![image-2024-11-19_18-27-33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3967203/ad0d9f2b-3e9a-f23b-5aec-376d394e0f23.png)

設定は以下の通り
 - SDK Platform: Android 12L (Sv2)
 - NDK: 25.1.xxx(最新版)
 - SDK Build-Tools: 32.0.0, 30.0.3
 - SDK Command-line-tool: 8.0
 - Android Emulator: 35.2.10
 - Android SDK Platform-Tools: 35.0.2

## JDKのインストール
Oracle公式からJava SE Development Kit 8u301をインストールする
 - Oracleのアカウントを作成する必要がある
 - macOS x64 DMG Installer

# 動作確認
UnrealEngineを起動し、ゲーム＞バーチャルリアリティを選択して作成
![スクリーンショット 2024-12-21 17.49.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3967203/0e6da557-e837-b3f7-6c71-0eef58274ae7.png)


これで完了！！
・・・と思いきや？

![image-2024-11-14_20-5-43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3967203/f78278d9-33ec-ba88-e674-977742e34b7b.png)


ぎぃいいいええぇぇぇえええええええ！？！？！？！？
アイエエエエ! クラッシュ!? クラッシュナンデ!?

スナップからお察しですが、MyProjectを何回作っても100％再現する模様

``
An Unreal process has crashed
``

## 解決編
どうやらデフォルト設定ではうまく動かないらしい
https://forums.unrealengine.com/t/unreal-engine-5-1-vr-project-crashes-while-being-creates/718702

作成したProjectをFinderで開き、config＞DefaultEngine.iniの中身を以下に変更する
```
vr.InstancedStereo=False
```

ホッ・・・
![スクリーンショット 2024-12-22 12.06.12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3967203/9e0216d1-7822-46ec-a3a5-7a2c1bebf5c0.png)


## UnrealEngine側での設定
下記サイトを参考にSDK、NDK、JDKを設定すれば良さげ
https://www.isoroot.jp/blog/6348/

JDKとかどこに入ってるんだっけ？となったので備忘録
あくまで自分はここにあったよ〜というやつ

```
# SDK
/Users/{ユーザ名}/Library/Android/sdk
 
# NDK
/Users/{ユーザ名}/Library/Android/sdk/ndk/25.1.8937393
 
# JDK
/Library/Java/JavaVirtualMachines/jdk1.8.0_301.jdk/Contents/Home
```
※NDKはSDK配下という罠があるので注意。許さない。


## Metaquestとの接続
~~正直ウイニングランなのであえて記載しなくてもいい気がする~~

下記サイトを参考にMetaquest側の設定を行う
https://yoshikawastudio.com/unreal-engine-5-vr01/

設定完了後、PCとM2を直接接続する
 - PCにMetaquestを接続すると通知が出るので許可をする
 - M2側でも通知が出るので許可

先ほど起動確認したプロジェクトのプラットフォームタブを開き
「Quest2」が表示されていれば認識OK

ビルドにはかなり時間がかかるので、紅茶でも淹れて優雅なティータイムにしましょう！
（自分は体感1時間以上ありました）

# 終わり
良いゲームライフを！！！！
（Qiita記事でよくあるやつ、一度言ってみたかった）
Next.js15のparamsの処理(サーバーコンポーネント側)

# Next.js15に変更した後のparamsのコード
vercelを使用しようとしたら次のようなエラーが出た
## エラー内容

```bash
Type error: Type '{ __tag__: "GET"; __param_position__: "second"; __param_type__: { params: Record<string, string | string[]>; }; }' does not satisfy the constraint 'ParamCheck<RouteContext>'.
  The types of '__param_type__.params' are incompatible between these types.
    Type 'Record<string, string | string[]>' is missing the following properties from type 'Promise<any>': then, catch, finally, [Symbol.toStringTag]

```

ここではparamsの型がPromise型にしないといけないというエラーが出ている

## userIdを取得する例

```

```sample.tsx
export async function GET(
  req: Request,
  { params }: { params: Promise<Record<string, string>> }
) {
  const resolvedParams = await params; 
  const userId = resolvedParams.userId;

  <!-- 他の処理 -->

}
```
記憶装置について

あなたは、どこまで記憶装置について、知っているだろうか。
ふと思ったことで、記憶装置はどこまで進化したのか、気になった。
ますは、大きさについてみていこう。フロッピーは8インチ・5インチ・3.5インチに分けることができる。光ディスクの直径は12cmが一般的だ。8㎝についてはぐぐr
まずは、容量についてだ。フロッピーでは3.5インチのが1.44MBなのが一般的だ。
光ディスクではcd・dvd・bdに分けられる。cdでは700MBくらい。dvdは5～15GBくらい。bdは25～100GBくらい。
一般的にフロッピーは書き換えられるが、光ディスクではできない。
USBメモリは基本的に光ディスクと同じ。大きさはさまざま。
後書きハードディスクは
【ヒヤリ・ハット事例】クラウド環境における危機一髪なセキュリティ体験談

## はじめに

こんにちは！
今回はセキュリティに関する記事を書きました。
どなたかの役に立てばと思います！

---

さて、クラウドサービスの普及に伴い、多くの企業がその恩恵を受けていますね。
実際、クラウドサービスは簡単に利用できるので、エンジニアとしても利便性を感じます。
しかし、利便性の裏にはセキュリティリスクが潜んでおり、これらを軽視すると重大なインシデントを招く可能性があります。

私の会社では、クラウド基盤を活用したシステムの開発や運用を行う中で、いくつかの「ヒヤリとした」体験を共有する機会がありました。
これらは大事に至る前に対応できたものの、日々の運用で**見落としがちなポイント**が原因でした。

この記事では、実際に経験したクラウドセキュリティの「ヒヤリ・ハット」事例を3つご紹介します。
同じような状況に遭遇する前に、あなたのシステムで必要な対策を検討するきっかけになれば幸いです。

## ヒヤリ・ハットとは

「ヒヤリ・ハット」とは、<font color="red">大きな事故や問題には至らなかったものの、「ひやり」としたり「はっと」した経験</font>のことを指します。
この言葉は、主に医療や製造業で使われてきました。
近年ではIT業界でもリスク管理の観点から注目されているようです。

こういった事例は、重大な問題を引き起こす「予兆」として捉えることができます。
そのため、早期に対応することで大きな被害を防ぐことが可能です。

つまり、「ヒヤリ・ハット」を見逃さずに改善につなげることが、リスク管理の第一歩です。

## 体験談：ヒヤリ・ハット事例3選

### 1. ベンダのアカウントが残っている😱

あるプロジェクトで、外部ベンダにシステムの開発を依頼しました。
ベンダ専用のアカウントを作成し、開発期間中は適切に運用されていました。
しかし、開発完了後もそのアカウントが削除されずに残っていたのです。

数カ月後、検証アカウントの整理を行った際、そのアカウントがパスワード変更されることなくそのまま残っていることが発覚しました。
アクセスログを確認したところ、幸い、悪用された様子はありませんでした。
しかしこれが、仮に不正アクセスが発生していたら大きな被害につながっていた可能性があります。

#### 対策
**アカウントの定期棚卸し**を実施することにしました。
特にそれぞれのアカウントを人に紐づけるようにし、その人がプロジェクトにいるかいないかでアカウントの要否を判断するように管理しました。
これにより、使用が終了したアカウントは即時削除されるようにすることができました。
また、アカウントの利用状況を監視し、**異常があればSlackに通知する仕組み**を導入しました。

### 2. AWSサーバの踏み台ポートがベンダの固定IPに対して開きっぱなし😱😱

開発中のAWS環境で、外部ベンダの固定IPに対して踏み台サーバのSSHポートが開かれたままになっていました。
本番リリース後もこの設定が残っていたことに気づいたのは、他の作業中に偶然設定を確認したときです。

さらに問題だったのは、この踏み台サーバが本番環境と検証環境の両方に接続可能で、アプリケーションサーバやバッチサーバにもアクセスできる状態だったこと。万が一、固定IPからのアクセスが不正に使われた場合、全環境に被害が広がる危険がありました。

#### 対策

まず、不要なポートは閉じ、ネットワーク制限を厳格化しました。
AWSはこの辺りの設定もコンソールから簡単に行えるので、なぜ構築を担当したインフラエンジニアはその考慮ができていなかったのか...
と愚痴を言い始めると止まらなくなってしまします。

また、ゼロトラストモデルを採用し、環境ごとにアクセス経路を分離しました。
当社の他PJでは、踏み台サーバを環境で分離させているケースが多いので、そのようにすることも考えたのですが、
そもそも環境ごとにAWSアカウントを分離し、踏み台経由ではなく、SessionManager経由でアプリサーバへアクセスできるようにしました。
一方、DBは、開発者各自慣れたGUIツールがあると思うので、こちらだけ踏み台経由としましたが、そもそもAWSアカウントを切り離したため、踏み台サーバも自ずと分離する形になりました。

### 3. 全ての権限が付与されたDBアカウントが存在する😱😱😱

ある日、開発チームから「一部のデータベース操作に権限不足エラーが発生している」との報告がありました。
これは、案件にジョインしてまもないチームメンバーが、データを書き換える際、リードオンリーユーザでログインしていたためでした。
ただ、この調査の過程で、特定のDBアカウントが全ての権限を保持していることが判明しました。
このアカウントは本来、データ解析用に作成されたものでしたが、開発時の利便性を優先して設定が甘くなっていました。

内部関係者が悪用する可能性や、万が一このアカウントが漏洩した場合のリスクを考えると、非常に危険な状態でした。
すぐにこのアカウントの権限を最低限に抑える対応を行いましたが、問題発覚の遅れがインシデントを引き起こしかねない状況でした。

#### 対策

最小権限の原則を厳守し、不要な権限は付与しないというルールを徹底しました。
新規ユーザー追加時には、権限設定をレビューし、不適切な設定を早期に修正するという対策も取り入れました。
また、もし万が一があった時のためにアカウントごとの操作ログを詳細に記録し、異常を検知できる仕組みも構築しました。


## 結論

クラウドセキュリティの運用においては、ついつい見落としてしまいがちな部分にリスクが潜んでいます。
今回紹介した事例からも、些細な手順の見逃しや設定ミスが重大な問題に発展する可能性があることがわかります。
ヒヤリ・ハット体験を通じて、システムや運用フローを見直し、日々の管理に対する意識を高めることが、未然にリスクを防ぐ鍵となります。
今後もセキュリティ対策を強化し、問題が発生する前に対策を講じることが大切です。

皆さんも、自社のクラウド環境を定期的に振り返り、より堅牢なセキュリティ基盤を築いていきましょう！！！😄
Crystalのshardsのドキュメントはcrystaldoc.infoで閲覧できる

## はじめに

ライブラリを見つけた時に、コード全体を読む前にドキュメントを生成して全体を把握することがよくありますよね。Rubyの場合であれば、[rubydoc.info](https://rubydoc.info/) にアクセスすればオンラインですべてのgemのドキュメントを閲覧することができます。Crystalではどうでしょうか？

## CrystalDoc.info

実は rubydoc.info に似たサイトが提供されています。その名も「crystaldoc.info」。Rubyと同じですね。

https://crystaldoc.info/

ソースコード [GitHub - CrystalDoc](https://github.com/nobodywasishere/crystaldoc.info)

管理人は [@nobodywasishere](https://github.com/nobodywasishere) さん。

ありがたい！
Udemyでの模擬試験が1問1答に対応したよ！

# はじめに
私はAWS認定の合格対策として、Udemyで模擬試験問題を購入して勉強しています。

AWS認定の合格対策については、Udemy以外にもCloudLicenseやCloudTechなどの模擬試験サイトが有名です。
ただしこれらのサイトは**サブスク型料金プラン**のため、最小の出費で合格するためには短期間で勉強に集中する必要があります。

一方でUdemyはサブスクプランもあるものの[^1]、基本的にはコンテンツごとを買い切り型です。
しかし、Udemyの模擬試験コンテンツは<font color="red"><b>全問解き終わらないと回答と解説が見られない</b></font>という重大な欠点がありました。

今回は、Udemyの模擬試験が**1問1答**に対応したので、ご紹介いたします。

[^1]:企業などの比較的加入人数が必要ですが、Udemy Businessというサブスクプランもあります。https://ufb.benesse.co.jp/


# 1問1答（演習モード）の説明
模擬問題を購入していると、テスト開始時に以下のように**演習モードと試験モード**が選択できます。
今回ご紹介する1問1答は<font color="red">**演習モード[^2]**</font>ですので、こちらを選んでください。

![スクリーンショット 2024-12-22 112732.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3706974/43d2c6fc-2cd6-590d-be8b-ff74af98a5ed.png)

[^2]:演習モードはβ版のため、今後大きく変更される可能性もあります。


演習モードの画面です。
ここの問題は従来の試験モードと変わりません。

![スクリーンショット 2024-12-22 112937.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3706974/de2c130a-3648-27d4-c692-25b404a17e5b.png)


解答を選択したら、<b>「解答を確認する」</b>ボタンを押すと、以下画面となります。
こんな感じで、すぐに解答と解説が確認できます。

![スクリーンショット 2024-12-22 113036.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3706974/579e8013-5fde-ad52-4935-dd8a0f783a3b.png)

全ての問題を解き終わった場合も試験モードと変わらず、全ての問題で間違った問題、マークした問題を振り返ることができます。
違いとしては、**演習モードのマーク**がされており、**合格/不合格が表示されない**くらいです。

![スクリーンショット 2024-12-22 121026.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3706974/6ef7f7e0-393d-6069-d816-55e444034961.png)


# 使ってみての感想
圧倒的に演習モードの方が使いやすいです！
時間制限が厳しい試験以外は、**演習モードで実施した方が学習効率ははるかに高い**です！

## 演習モードによる実績
演習モードがいつから実装されたか分かりませんが、私は2024年12月のAWS認定試験対策から利用しました。
演習モードによりDEA(Data Engineer Associate)とSAP(Solution Architect Professional)に、今までよりも少ない勉強時間で合格できました。

演習モードはすぐに解答が確認できるので、移動や休憩などの隙間時間で学習でき、分からなかった用語などをすぐに調べて知識を定着しやすくなりました。


# まとめ
Udemy模擬試験で1問1答の演習モードが登場したことで、各種ベンダーの認定試験対策としてUdemyが筆頭候補に挙がったと思います！
過去購入した問題も対応していますので、学習を休んでいた方も是非冬休みに取り組んでみましょう！
VoIPとSIPを通じてRustを勉強する：音声認識

前回はIP電話で音声認識を使うケースを書きました。
今回は自然言語処理のケースを書いてみようと思います。

# コールセンターの高度な高度な顧客応答
NLPを活用して顧客の意図を理解し適切な対応を提供する。

# リアルタイムの感情分析
通話中に顧客の感情をリアルタイムで分析

# 自動議事録の作成と要約
通話内容を自動で文字起こしし、要約。

# 音声ボットによる自然な会話応答
NLPを組み込んだ音声ボットが、　IP電話で顧客と会話

# 詐欺電話防止
話している内容から詐欺の検知

# おわりに
IP電話でも音声認識、自然言語処理が導入されています。
今後のIP電話の発展、面白そうですね。
【アクセシビリティ】テキスト表記で気をつけること

## はじめに
テキスト（Altやボタンのラベル、サイト内の文章など）をWebサービス・アプリで表示させるときに、アクセシビリティ観点で気をつけることを学びました:memo:

## テキスト表記で気をつけること
### 特定の感覚に依存しない表現を意識する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3632482/d7192df2-8fa4-b23a-be26-b65decd3aedd.png)

例：色に依存したテキスト

:::note alert
- 「緑のアイコン」だと色弱のユーザーは他のアイコンと区別できない
- スクリーンリーダーのユーザーには色では伝わらない
:::

:::note info
- 形/色/場所/音など感覚的に依存しない
- アイコンにテキストラベルを与えるなど、いくつか情報を提示する
- 左右で場所を伝えない（上下はOK✅）
    - 左右だとレイアウトが変わった時に伝わらない
    - 上下は該当箇所の前後として捉えられるためOK
:::

### 単語にスペースや改行を入れない
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3632482/160b19d4-d1b3-70db-912c-ac6aee3f74c9.png)

:::note alert
- スペースや改行を入れると正しくスクリーンリーダーで読み取れない可能性がある
:::

:::note info
- 余白を設けたい場合、スペースや改行ではなく`letter-spacing`や`margin`を用いてCSSで調整する
:::

色々試してみたメモ:memo:
- 英語は単語一文字ごとにスペースを入れると、文字単体として読まれる
- 日本語はスペースを間に挟んでいても、単語として認識してくれることが多い
    - ひらがなは一文字ずつ読まれても意味が通じる
    - 漢字の単語は文字間にスペースが入っていても、だいたい単語として読み上げてくれる
        - 単語として不自然なものは、一文字で読まれる
        - 例：「絵　文　字」は「えもじ」と読まれる
            - 「絵　文」は「え　ぶん」と読まれる
- 英語の読み上げ方は言語設定が日本語だから？:thinking:



### 記号や省略表記、絵文字の使い方に注意する
以下のように、記号によって意味が伝わらないものがある:memo:
また、絵文字を使いすぎると文章が伝わりにくくなるため注意！
以下の説明で「」内は読み上げ時のテキストです。

#### 記号の持つ意味が伝わるもの
- <b>`¥`「えん」</b>
    - ¥5000「5000円」
- <b>`$`「どる」</b>
    - $5000「5000ドル」
- <b>`〒`「ゆうびんばんごう」</b>
- <b>`@`「あっとまーく」</b>
- <b>`%`「ぱーせんと」</b>
- <b>`〜`「から」</b>
    - 半角だと`~`「ちるだ」
    - 14:00〜15:00「じゅうよじからじゅうごじ」
    - 14:00-15:00「じゅうよじじゅうごじ」伝わる？:thinking:
#### 記号の持つ意味が伝わらない場合があるもの
- <b>`*`「ほし」</b>
    - 「*こちらの項目は必須です」と注意の意味で`*`が使われていても伝わらない
- <b>`※`「れふぁれんすまーく」単体だと「こめじるし」</b>
    - `*`と同じく注意の意図が伝わりにくい
- <b>`/`「すらっしゅ」</b>
    - 1/2「いちすらっしゅに」
        - 「2分の1」分数の意図で使っても伝わらない場合がある
    - 2024/12/22「にせんにじゅうよんすらっしゅじゅうにすらっしゅにじゅうに」
        - 日付の意図で使っても、伝わらない場合がある
        - `2024-12-22`や`2024.12.22`は伝わる
        - `2024年12月22日`と明示するのがベター
- <b>`()`「みぎまるかっこ」</b>
    - 22日（土）「にじゅうににちつち」
        - 曜日の表記に使いがちだけど、伝わりにくいかも
        - `22日土曜日`が本来わかりやすいはず

:::note alert
- 記号を使うと、伝わりにくい可能性がある
:::

:::note info
- 記号を使う時にはスクリーンリーダーで読み上げて、意図が伝わるか確認する
- 正しく意味が伝わる読み上げになるように、`aria-label`やその他の方法を検討する
:::

`aria-label`が使えないpタグで正しい読み上げになるように実装している記事

https://qiita.com/gilly/items/18456a7812691c9491ad#aria-label-%E3%81%8C%E4%BD%BF%E3%81%88%E3%81%AA%E3%81%84p-%E3%82%BF%E3%82%B0%E3%81%A7%E5%AE%9F%E8%A3%85%E3%81%97%E3%81%A6%E3%81%BF%E3%81%9F%E3%81%93%E3%81%A8

## まとめ
テキスト表記は理解できる糸口をいくつか用意しておく必要があるとわかりました:memo:

他にも、テキストの可読性や簡潔な文章か意識できると、誰でもわかる文章に近づけるはず！

最後までお読みいただきありがとうございます:santa_tone1:

## 参考

https://a11y-guidelines.freee.co.jp/explanations/text-wording.html

https://zenn.dev/kagan/books/easy-japanese-wcag/viewer/principle-1#%E9%81%94%E6%88%90%E5%9F%BA%E6%BA%96-1.3.3-%E6%84%9F%E8%A6%9A%E7%9A%84%E3%81%AA%E7%89%B9%E5%BE%B4-(%E3%83%AC%E3%83%99%E3%83%AB-a)

https://waic.jp/translations/WCAG-TECHS/F32.html


https://www.soumu.go.jp/soutsu/tokai/siensaku/accessibility/L4_text2.html
Ubuntu24.04 × XWiimote 環境構築

[kstm Advent Calender 2024](https://qiita.com/advent-calendar/2024/kstm) 22日目の記事です．

https://qiita.com/advent-calendar/2024/kstm

# はじめに
[XWiimote](https://xwiimote.github.io/xwiimote/)とは，WiiリモコンなどをLinuxにBluetoothで接続して使用できるようにするデバイスドライバーです．センサーの値を取得して利用するプログラムをC言語で作ることができるようになります．

![xwiishow.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3627615/eb008438-d7c6-400d-7f9a-59775f406e59.png)
画像はXWiimoteに含まれるテストアプリxwiishowでセンサーの値を取得する様子

この記事では，VirtualBoxにインストールしたUbuntuでXWiimoteの環境を構築した手順を紹介します．

# 事前準備，検証環境
- wiiリモコン
BluetoothでNintendo RVL-CNT-01と表示される型のWiiリモコンプラスを使用しました．Nintendo RVL-CNT-01-TRと表示される型もあり，こちらも動作を確認しました．
- VirtualBox7.0.14 上の Ubuntu24.04.1 LTS
こちらの記事を参考に構築しました．

https://auroralights.jp/entry/2024/06/08/172908

- Bluetoothドングル
VirtualBox上のUbuntuでBluetoothを使用するために，TP-Link UB500を使用しました．もしかしたらPCに標準搭載されているBluetoothアダプターを使用することもできるかも知れませんが，私にはわかりませんでした．

# 環境構築
:::note warn
追記
今から説明する以下のステップを踏まずとも，`sudo apt install xwiimote`でインストールできました．

https://packages.ubuntu.com/source/jammy/xwiimote

:::
1. システム更新
    パッケージを最新の状態にします．
    ```bash
    sudo apt update
    sudo apt upgrade
    ```
    <br>
1. 必要なパッケージのインストール
    XWiimoteのビルドに必要な開発ツールやライブラリをインストールします．
    ```bash
    sudo apt install libudev-dev libncurses-dev git autoconf libtool pkg-config make
    ```
    <br>
1. XWiimoteのソースコードを取得
    Gitを使用して[XWiimoteのリポジトリ](https://github.com/xwiimote/xwiimote)からソースコードをクローンします．私はホームディレクトリで実行しました．
    ```bash
    git clone https://github.com/xwiimote/xwiimote.git
    ```
    <br>
1. ソースコードのビルドとインストール
    クローンしたディレクトリに移動し，ビルドとインストールをします．ライブラリlibxwiimote.so.2を認識させるためにldconfigを実行しています．
    ```bash
    cd xwiimote
    ./autogen.sh
    make
    sudo make install
    sudo ldconfig
    ```
    <br>
これで環境構築は終了です．

# 使用できるか確認
1. WiiリモコンをBluetoothで接続
    VirtualBox上のUbuntuでBluetoothドングルを認識させ，UbuntuでBluetoothを使用できるようにします．Wiiリモコンの裏にある赤いSyncボタンを押すとUbuntu側でBluetooth機器として「Nintendo RVL-CNT-01」が見つかるので接続します．成功すると1PのLEDが点灯します．
    ![bluetooth.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3627615/205e9472-40a7-a958-4e06-1b7f3deafadc.png)

    windowsPCのVirtualBoxでBluetoothドングルを使用するやり方の参考記事
    https://askubuntu.com/questions/1378461/virtualbox-bluetooth
    <br>
1. xwiishow
    xwiishowを実行すると接続しているwiiリモコンをテストすることができます．
    ```bash
    xwiishow list       # 認識されているWiiリモコン一覧を表示
    xwiishow 1          # 一覧に表示されたリモコンの内，番号'1'のリモコンをテスト 
    ```
    ![xwiishow.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3627615/eb008438-d7c6-400d-7f9a-59775f406e59.png)
    実行した様子

以上

# リンク集
XWiimoteについて（公式）

https://xwiimote.github.io/xwiimote/

XWiimoteについて（ArchWiki）

https://wiki.archlinux.jp/index.php/XWiimote

XWiimoteのリファレンス

https://xwiimote.github.io/xwiimote/api/index.html

XWiimoteのリポジトリ

https://github.com/xwiimote/xwiimote

XWiimoteを利用したC++プログラムの参考

https://shikky-lab.hatenablog.com/entry/2020/10/06/014515

Wiiリモコンが使えるようになるライブラリ一覧

https://wiibrew.org/wiki/Wiimote/Library

Wiiリモコンについて

https://wiibrew.org/wiki/Wiimote
レビュー時にDBのDockerコンテナを切り替える

# はじめに

コードレビューをする時に、PCのローカル環境でそのコードの動作の確認を行うことがあります。しかし、もしDBのスキーマに変更が入っていたら、動作確認をするためにはそのマイグレーションを適用しないといけません。もしかしたらその変更には、カラムやテーブルのDROPのような不可逆な変更が含まれているかもしれません。自分が開発でも使っているローカルのDBのデータに、レビューのための変更を加えたくはないけど、動作確認はしたい。そんな需要を満たす方法を紹介します。

# 前提

- ローカル環境にMySQLのdockerを利用している
  - MySQL以外でもvolumeのあるコンテナだったらいける気はしているが、動作未検証
- docker composeを利用する

# 方法

dockerが提供する[`COMPOSE_PROJECT_NAME`](https://docs.docker.jp/compose/reference/envvars.html#compose-project-name)という環境変数を利用します。この変数名（プロジェクト名）を変えると、コンテナ名をデフォルトのものから変更することができます。

たとえば、もともとは`myapp-mysql-1`というコンテナ名だったのが、`COMPOSE_PROJECT_NAME=my2ndapp docker compose up`とすることで、`my2ndapp-mysql-1`という名前のコンテナとして起動することが可能です。名前が変わるということは、その`my2ndapp-mysql-1`は、元の`myapp-mysql-1`とは別物として認識されるということです。つまり、レビュー時にコンテナ名を変更して起動することで、別のコンテナ、別のDBを使うことができるということです。

# 注意点

重要なのは、**匿名volumeを使う必要がある**ことです。

もし名前付きvolumeを使っていたり、ローカルの特定のディレクトリをmysqlの`/var/lib/mysql`にマウントしていたりすると、コンテナ名を変更してもデータを共有してしまうので、別コンテナで別データを持たせることができません。

以下のような状態であれば問題ありません。この状態だと、[匿名volumeが自動でマウント](https://github.com/docker-library/mysql/blob/090eb25ac69bca920fc5320484bc35aac92a8143/8.0/Dockerfile.debian#L91)されます。匿名volumeは異なるコンテナ名でコンテナを生成したら、自動的に別のvolumeが作られます。

```yml:docker-compose.yml
services:
  mysql:
    image: mysql:8.0
    volumes:
      - ./local/my.cnf:/usr/etc/my.cnf
    ports:
      - "3306:3306"
    environment:
      MYSQL_ROOT_PASSWORD: root
```

# ダメな例

以下のように名前付きvolumeを使うと**ダメ**です。別のコンテナで同じデータが使われます。

```diff:docker-compose.yml
  services:
    mysql:
      image: mysql:8.0
      volumes:
        - ./local/my.cnf:/usr/etc/my.cnf
+       - db-store:/var/lib/mysql
      ports:
        - "3306:3306"
      environment:
        MYSQL_ROOT_PASSWORD: root

+ volumes:
+   db-store:
```

MySQLではやってる人はいないかもしれませんが、以下のようにローカルのディレクトリをマウントする（バインドマウント）のもダメです。

```diff:docker-compose.yml
  services:
    mysql:
      image: mysql:8.0
      volumes:
        - ./local/my.cnf:/usr/etc/my.cnf
+       - ./local/data:/var/lib/mysql
      ports:
        - "3306:3306"
      environment:
        MYSQL_ROOT_PASSWORD: root
```

# 補足

匿名ボリュームの公式の説明は[こちら](https://matsuand.github.io/docs.docker.jp.onthefly/storage/#more-details-about-mount-types)です。
VoIPとSIPを通じてRustを勉強する：音声認識

IP電話で音声認識に関連のある項目を書いてみました

# IVR
音声認識を利用したインタラクティブボイスレスポンスシステムで、お客がボタンを押す代わりに音声で操作できる。
ちょっと前まではコールセンターにつなぐのにボタンを押していた代わりに音声認識を使うという形ですね。

# 自動通話内容の文字起こし
通話中の会話内容をリアルタイムまたは後で文字起こしする。

# 通話の感情分析
音声認識と感情分析で通話中のお客の感情をリアルタイムに把握。

# 声で操作する電話サービス
ユーザーが電話の操作を会話で実行する方法です。
最近はよく導入されています。
URLから直接アクセスされたときも権限判定を行いたい

# はじめに
システムをリリースした後の追加要望で、権限の追加を依頼されたときの画面制御時に実装したものです。
当時のレビューで直接アクセス時も制御するよう指摘されたので教訓として残しておこうと思います。


# コード例

```jsx
import { useEffect } from 'react';
import { useRouter } from 'next/router';
import toast from 'react-toastify';
import UseAxios from 'your-axios-hook';

const MyComponent = () => {
  const router = useRouter();

  const fetchUserInfo = async () => {
    try {
      const res = await UseAxios('get', 'hoge');
      if (res && res.status === 200 && res.data) {
        const hoge = res.data.hoge;
        return hoge.is_user;
      }
    } catch (error) {
      console.error('Error fetching user info:', error);
      return false;
    }
  };

  useEffect(() => {
    const checkPermissions = async () => {
      const is_user = await fetchUserInfo();
      
      if (!is_user) {
        toast.error('アクセス権限がありません。トップページへリダイレクトします。', {
          position: 'top-right',
          autoClose: 3000,
          hideProgressBar: true,
          closeOnClick: true,
          pauseOnHover: true,
          draggable: true,
          progress: undefined,
          theme: 'colored',
        });
        router.push('/');
      } else {
        getDatas();
      }
    };

    checkPermissions();
  }, [router]);

  return (
    <div>
    </div>
  );
};

export default MyComponent;

  ```

# おわりに
直接アクセスされた際は上記のuseEffectで権限判定を行い、判定によってリダイレクト有無が発生します。
権限なくても直接アクセスなどの裏技っぽいことは他にも学んでいきたいです。（対策できるように）
Rを学びたい Step23 帰無仮説と対立仮説

## はじめに
Rを学びたい Step23です。今回は帰無仮説と対立仮説に関して学びます。
帰無仮説と対立仮説は、何かを調べたり確かめたりするときに使う「考え方」です。

## 帰無仮説とは
「何も特別なことは起きていない」という前提のことです。
一旦、「特に変わったことはない」と考えて、それが本当に正しいのかを調べます。

例：お菓子の袋に入っている数
	•	あなたは、「このお菓子の袋には10個のお菓子が入っている」と信じています。
	•	帰無仮説（何も特別なことはない）：
	•	「袋には10個のお菓子が入っている」と仮定します。

### 1. 帰無仮説 ( H_0 ) の数学的定義

•	定義：
帰無仮説  H_0  は、「特に変わったことがない」という仮定や主張を表します。検定ではまずこの仮説を正しいと仮定して検証します。

数学的な形式
	•	母集団のパラメータに関する主張として書かれる：
```math
H_0: \theta = \theta_0
```

```math
\
\begin{align}
&\theta ：母集団のパラメータ（例：平均、分散など）\\
&\theta_0 ：特定の値（帰無仮説で仮定される値）\\
\end{align}
\
```

 ## 対立仮説
 「帰無仮説が間違っているかもしれない」という考え方です。
「何か特別なことが起きている」と言えるかを確認します。

例：お菓子の袋に入っている数（続き）
	•	対立仮説（帰無仮説が間違っているかも）：
	•	「袋には10個ではない数のお菓子が入っているかもしれない」と考えます。

```math
H_1: \theta \neq \theta_0
```
```math
\
\begin{align}
&\theta ：母集団のパラメータ（例：平均、分散など）\\
&\theta_0 ：特定の値（帰無仮説で仮定される値）\\
&H_1 ：\theta \text{が } \theta_0 \text{ と異なる場合（両側検定）} \\
\end{align}
\
```




## 帰無仮説と対立仮説の使い方
1.	まずは帰無仮説を信じる：
 •「特に変わったことはない」と仮定して調査を始めます。
2.調査や実験をする：
 •	実際にお菓子の袋を開けて中身を数えてみます。
3.	結果から判断する：
 •	お菓子が10個入っていれば、「帰無仮説は正しそう」と考えます。
 •	もし9個や11個だったら、「帰無仮説は間違っているかも」と判断します。

## 例題で理解する：コインを投げる場合

問題：コインが公平（表も裏も同じ確率で出る）か調べたい
	•	帰無仮説：
	•	「このコインは公平で、表と裏が出る確率は同じ。」
→ つまり、特に変わったことはないと考えます。
	•	対立仮説：
	•	「このコインは公平じゃないかもしれない。」
→ つまり、表や裏が出る確率が偏っているかもと疑います。

調査方法：
	•	コインを10回投げて、表と裏の回数を調べます。
	•	もし表が10回連続で出たら、「このコインは公平じゃないかも」と考えます（帰無仮説を疑う）。
	•	もし表が5回、裏が5回だったら、「このコインは公平かもしれない」と考えます（帰無仮説を受け入れる）。

## Rでまなぶ
例題：学生のテスト平均点が75点かどうかを検証
	•	帰無仮説 ( H_0 ): 学生のテストの平均点は75点である。
	•	対立仮説 ( H_1 ): 学生のテストの平均点は75点ではない。

```r
# サンプルデータ生成（学生のテスト点数）
set.seed(123)  # 再現性のため
sample_scores <- rnorm(30, mean = 78, sd = 10)  # 平均78、標準偏差10のデータを30個生成

# データの要約
summary(sample_scores)
hist(sample_scores, breaks = 10, col = "skyblue", 
     main = "Histogram of Test Scores",
     xlab = "Scores")

# 仮説検定
# 帰無仮説: 平均点 = 75
# 対立仮説: 平均点 ≠ 75（両側検定）
t_test_result <- t.test(sample_scores, mu = 75)

# 結果を出力
print(t_test_result)

# 結果の解釈
if (t_test_result$p.value < 0.05) {
  cat("帰無仮説を棄却します。平均点は75ではありません。\n")
} else {
  cat("帰無仮説を棄却できません。平均点は75と考えられます。\n")
}
```

```shell:実行結果
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
  58.33   71.29   77.26   77.53   82.89   95.87 

        One Sample t-test

data:  sample_scores
t = 1.412, df = 29, p-value = 0.1686
alternative hypothesis: true mean is not equal to 75
95 percent confidence interval:
 73.86573 81.19219
sample estimates:
mean of x 
 77.52896 

帰無仮説を棄却できません。平均点は75と考えられます。
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/599049/a1a187ac-9d1a-1237-03b9-0e2f83bf11c8.png)
アドベントカレンダーを25記事書いてみて

# マジでできると思っていなかった
以下の企画として、アドベントカレンダー2024を一人で完走してみました。
※**Qiitaくんのぬいぐるみ欲しさ**というのが一番のモチベというのは、一旦隠しておきます。

https://qiita.com/tatataichi/private/56936a028e625e62af8e

この企画は、「**chat GPTに任せっぱなしにしていたらコントロールできなくなった**」というガチヤバ状態だったのを脱するために、「**コーディングする能力をゼロから取り戻す**」ために行いました。

正直に言うと、普段の業務もほどほどに忙しいし、土日に時間を取って勉強するという習慣もなかったので「**どこかで挫折するかも**」と思っていました。

そんな中でも、今回は一応ちゃんと完走することができたので、色々まとめていこうと思います。

# 完走するためにやったこと
完走するためにやったことはめちゃくちゃシンプルですが、以下の通りです。

**1. 朝の1時間を必ず記事を作成することにした**
**2. 桜井さんの動画を観てモチベを上げた（上がった）**
**3. 記事のテンプレを用意して、最初の一筆のハードルを下げた**

一個ずつざっくり語ります。

## **1. 朝の1時間を必ず記事を作成することにした**
結局コレです。
一番大事なのは時間の確保でした。夜は経験的に絶対にやれない（披露＋仕事の終わる時間が一定じゃない）とわかっていたので、朝の時間を使うことにしました。

具体的には7時〜8時の間は「本を読む」+「執筆」を必ず行うようにしました。
1時間で収まりそうな範囲を見極めて、それぞれの分量を調整しました。

僕の場合、記事にするには大体20-30分くらい必要なので、30-40分くらいインプットをするって具合です。

## **2. 桜井さんの動画を観てモチベを上げた（上がった）**
なんのこっちゃって感じかもですが、**有限会社Soraの桜井政博さん**（スマブラ作った　で有名ですよね）の以下動画が、めちゃくちゃモチベになりました。

https://youtu.be/JV3KOJ_Z4Vs?si=-wEPXVI2hrDQC2O0

僕も「〇〇だからできないかも…」「〇〇ってやり意味あるかな」みたいにごちゃごちゃ考えてしまうタイプなので、自分に対して **「うるせーだまってさっさとやれ！！！」** を言い続けましたw

**やる以外に進む道はなく、ここで逃げたら今後の人生で何も継続しない**と思って、とにかくやりました。
結果的にちゃんと完走できたので、これは本当に自信に繋がっています。
「**自分は一ヶ月くらいならちゃんと継続できる**」という成功体験をアラサーになって積み上げられたのは貴重だったと思います。

## **3. 記事のテンプレを用意して、最初の一筆のハードルを下げた**
「とにかくやる」ために必要なのは「第一歩目のハードルをいかに下げるか」だと思います。
これは「企画を始める」という意味での第一歩ではなく、「毎日記事を書く」ということへの第一歩の意味です。

継続しないときは「あぁ、やっぱめんどいな」という気持ちに負けてしまうからだと思いますので、明日の自分のために「ここまではやっておいたよ！」お膳立てしてやるわけです。

それでも「やりたくねぇ」となってしまうこともあると思います。そのときは桜井さんの「**とにかくやれ**」を思い出しますw
結局は気持ちの問題ですが、その気持を少しでも前に向けてやるためにもお膳立ては必要だと思います。

前置きが長くなりましたが、そのためにやったことが「**記事冒頭のテンプレを用意した**」ということです。

具体的には以下ですね。

```terminal:例
※以下の企画です

https://qiita.com/tatataichi/private/56936a028e625e62af8e

前回に続いてゼロつくを進めていきます。  
今回は「」の内容に入ります。  

それでは頑張ります〜

# 章のタイトル
## 中項目
```

たった数行ですが、「冒頭の一筆をなんて書き出そう」という思考時間がなくなるので、スッと書き始められます。
この文章＋タイトルを下書きとして保存しておけば、翌日は下書き一覧から引っ張ってくるだけで書き始められます。

こんな感じで色々工夫して、自分を鼓舞しながら書き進めました。


# 結果何が得られたか
乾燥した結果として何が得られたのかもまとめていきます。
大きく分けると以下の二点です。

**1. コーディングが楽しくなった**
**2. 継続の成功体験を得られた**

それぞれちょっと深掘ります。

## **1. コーディングが楽しくなった**
**chat GPTに頼らずにコーディングをゼロから行うことの楽しさ**を改めて感じられました。
特に「Pythonチュートリアル」は普段使っている言語の細かい仕様やテクニックを改めて学ぶことができ、少しずつ実行しながら結果を見るという懐かしい体験をすることができました。

「今までなんとなく使っていたもの」の解像度も上がったので、GPTが出力してきたコードの内容を見直して理解を深めたり、自分で書き直してみたりということを積極的に行えました。

何より、GPTとの付き合い方が上手くなった気がします。
まずは自分でコードの骨組みを、自分の理解できるアルゴリズムやフローで記述して、GPTにリファクタリングやレビューをお願いする。この流れができたことで、ペアプログラミングをしているような楽しさを見出すことができました。

エンジニア（と名乗るのもおこがましいですが）として死んでいた自分に、改めて新卒エンジニアくらいには戻れたと思います。

**プログラミングたのしー！！！！！！！！！！！！！！**

## **2. 継続の成功体験を得られた**
副産物的に得られたのが「**継続の成功体験**」　です。
アラサーになってからは「自分のあらゆる考えや行動、生き方」みたいなものが凝り固まり始めているのを感じていたので、「**自分にはこれ以上できない**」みたいな勝手なブレーキを無意識に掛けてしまっていたと思います。

そんな中で、改めて自分の腐った性根にムチを打ち、「とにかくやる」という姿勢を貫くことで、25日間継続して目標を達成した（しかも誰にも強いられていないのに）という成功体験はデカかったです。

**ちゃんとやればできる。**
**やる方法がある**

と思えたことで、「chatGPTに殺される…僕は駄目な子だ…」から「次は何に挑戦しようかな」というマインドに切り替わりましたw

**※毎日やったぜみたいな雰囲気出していますが、翌日分をストックできた日もあったのはココだけの話**

# まとめ
**まじでめちゃくちゃ良かった！！！！！！**
**自分を変えられた！！！！！！**
**Qiita最高！！！！！**

**次は統計検定とるぞーーー！！！！！！！！！！！！！**

**メリークリスマス！！！！！！！！！！！！！！！！！！！！！！！！！！！！！！！！！！！！１**
【Java】Stream APIをざっくり

## Stream APIとは
配列やコレクションに対して、値の集計や変換などの処理ができるAPIのこと。主に以下の3つのステージで構成される。

1. 生成(streamの生成)
2. 中間操作(要素に対する処理)
3. 終端操作(結果を出力)

## ストリームの生成
### コレクションから生成
```
List<String> list = Arrays.asList("A", "B", "C");
Stream<String> stream = list.stream();
```

### 配列から生成
```
Stream<Integer> arrayStream = Arrays.stream(new Integer[]{1, 2, 3});
```

### 静的メソッドを使用
```
Stream<String> generatedStream = Stream.of("X", "Y", "Z");
```

## 中間操作
中間操作はストリームを加工・変換するための操作で、これらは終端操作が呼ばれるまで実行されない。主なメソッドは以下。

### filter
条件に合う要素だけを残す。
```
stream.filter(s -> s.startsWith("A"))
```

### map
各要素を別の要素に変換

```
stream.map(String::toUpperCase)
```

### flatMap
ネストしたストリームを平坦化

```
stream.flatMap(List::stream)
```

### distinct
重複を排除
```
stream.distinct()
```

### sorted
ソートされたストリームを生成
```
stream.sorted()
```

### limit
指定した数までの要素を取得
```
stream.limit(5)
```

### skip
指定した数だけスキップ
```
stream.skip(3)
```

### 終端操作
ストリームを閉じ、結果を生成する。

### collect
結果をコレクションや文字列に変換

```
stream.collect(Collectors.toList())
```

### forEach
各要素に対して処理を実行
```
stream.forEach(System.out::println)
```

### reduce
要素を1つの値に畳み込む
```
stream.reduce(0,Integer::sum)
```

### count
要素数をカウント
```
stream.count()
```

### anyMatch
条件を満たす要素が存在するかチェック
```
stream.anyMatch(s -> s.contains("A"))
```

### noneMatch
条件を満たす要素が1つもないかチェック
```
stream.noneMatch(s -> s.isEmpty())
```

### findFirst
最初の要素を取得
```
stream.findFirst()
```

### findAny
任意の要素を取得
```
stream.findAny()
```

## ストリームAPIの特性
1. **遅延評価**
中間操作は終端操作が呼び出されるまで評価されない。これにより、効率的な処理が可能。

2. **無変更性**
ストリームは元のデータを変更しない。

3. **一度限りの使用**
ストリームは一度消費されると再利用できない。


## 注意点
1. **並列ストリーム**
**parallelStream**を使うと並列処理が可能になるが、データサイズや特性に応じて慎重に選択する必要がある。

   ```
    list.parallelStream().forEach(System.out::println); 
   ```
2. **状態を持たない操作**
中間操作は状態を持たないことが推奨される。

3. **終端操作の結果**
終端操作の結果がvoidなのか、値を返すのか意識しておくこと。

4. **ストリームと例外**
ラムダ式で例外を扱う場合、エラーハンドリングの実装について意識しておくこと。