OmniAICreator/Qiita-1.07M huggingface dataset:
lambda関数のレイヤー追加方法

## はじめに
python　pipで躓いたので備忘録　**in202412月**
**レイヤーの追加の方法がわからなかったので追加方法がメイン**です。
## 結論　ライブラリをzip化→Layers追加
　↓レイヤーを追加して **Layers(1)** という表記にすればおｋ
  <img width="400" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3743053/d17072d1-1fb5-6ef1-bd9a-75086b7c0036.png">

## やり方
#### 1.lambda関数と同じpythonバージョンでzip化
(やり方は下の記事みてね)
※名前はpython.zipでないとダメぽい？
zip後AWSに戻ってLambdaのホーム画面に移行する。

#### 2.その後Lambda側のホーム画面でレイヤーをクリック
awsのホーム画面の左側にある**レイヤー**に行きます。
  <img width="200" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3743053/b24a775b-0629-2f13-8c7d-01c06082b418.png">

#### 3.レイヤーの作成ボタンを押して、zipファイルをアップロードする
**レイヤー作成**で名前・アップロード・アーキテクチャ・ランタイムを記載してレイヤーを作成する
<img width="200" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3743053/5e03fa80-0893-501b-f6fb-14343d570cef.png">
 
<img width="200" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3743053/1b738a15-c2f9-dab5-b277-467812ffea60.png">

#### 4.Lambda関数のページに行き一番下のレイヤーの追加で連携完了
レイヤー作成後Lambda関数のページに行き一番下にあるレイヤー追加で先ほど作成したレイヤーを追加する。
<img width="200" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3743053/2d6a0ff4-3d44-dbb2-f565-9616e06fd8d5.png">

完了✊　lambda関数のテストでちゃんとライブラリが生きているか確認してね。

### lambdaを初めて使ってみて...
lambdaとeventbridgeはいいですね。
ある程度のスケジューラなら無料で実行できるので便利です!

### 参考にした記事たち
https://qiita.com/__DASHi__/items/268062f0dba0e93170f2

https://zenn.dev/ndjndj/articles/69a2aabb227530
C言語 Tips

# 配列とポインタは違う

> C言語では、関数に配列を渡すときに、配列はポインタとして渡されます。このため、関数内で配列のサイズ（要素数）を直接取得することはできません。配列のサイズを取得するには、配列のサイズ情報を関数の引数として明示的に渡す必要があります。
※ChatGPTより

```c
#include <stdio.h>

void func(char *p)
{
    printf("%ld\n", sizeof(p)); //★8
}

int main()
{
    char s1[100] = "This is array.";
    printf("%ld\n", sizeof(s1)); //★100
    func(s1);
    return 0;
}

```

s1は配列の先頭アドレスが実体のポインタではなく、配列全体（配列のオブジェクトとして扱う）を示す。
なので、sizeof(s1)で配列のサイズが取得できる。
式で配列オブジェクトを示す場合は、配列の先頭アドレスに変換される。
Rails system specでソート順をテストした時に学んだこと

## 読んで欲しい人
- system specでソート順をテストしたいけど、やり方わからん人
- 過去の自分

## 具体的なテストケース

例：ユーザー一覧を作成していて、表示順を生年月日(birthdate)の昇順にしているとき

### モデル
```schema.rb
  create_table "users", force: :cascade do |t|
    t.string "name", default: "", null: false
    t.date "birthdate", null: false
  end

```

### コントローラ

`order`で生年月日の昇順を指定

```users_controller.rb
class UsersController < ApplicationController

  def index
    @users = User.order(:birthdate)
  end
```

### ビュー
```erb
<table>
  <thead>
    <tr>
      <th>名前</th>
      <th>生年月日</th>
    </tr>
  </thead>
  <tbody>
    <% @users.each do |user| %>
      <tr>
        <td><%= user.name %></td>
        <td><%= user.birthdate %></td>
      </tr>
    <% end %>
  </tbody>
</table>
```

## テストコード

```books_spec.rb
  describe '一覧画面のソート順' do
    before do
      create(:user, name: '鈴木', birthdate: '2005-12-15')
      create(:user, name: '吉田', birthdate: '2000-10-15')
      create(:user, name: '佐藤', birthdate: '1990-01-15')
    end

    it '生年月日の昇順になっていること' do
      visit users_path

      within 'tbody' do
        users = all('tr').map { _1.all('td')[0].text }
        expect(users).to eq %w[佐藤 吉田 鈴木]
      end
    end
  end

```

### 期待値

佐藤 ：1990-01-15
↓
吉田 ：2000-10-15
↓
鈴木 ：2005-12-15

の順番(生年月日が古い順)で並んで欲しい

## 解説

### createの順番について

```ruby
before do
  create(:user, name: '鈴木', birthdate: '2005-12-15')
  create(:user, name: '吉田', birthdate: '2000-10-15')
  create(:user, name: '佐藤', birthdate: '1990-01-15')
end
```

最初にテストデータを作成するときに、意図的にcreateする順番を期待値通りの順番で作成しないようにしています。

期待値通りの順番で作成すると、そのソートが`order`によるものなのか判定できません

### テスト範囲を絞る
```ruby
within 'tbody' do
~~~
end
```

今回テストしたいのは、`thead` `th`ではないので`tbody`でテスト範囲を絞る

### テスト対象を取得して配列に

```ruby
users = all('tr').map { _1.all('td')[0].text }
```

`all('tr').map`で全ての`tr`タグを取得します

1つの`tr`には2つの`td`が含まれているので、それを`map`メソッドで回します。

```ruby
map { _1.all('td')[0].text }
```

`tr`の0番目の`td`要素から[textメソッド](https://rubydoc.info/github/jnicklas/capybara/Capybara%2FNode%2FElement:text)を使用して、テキストを取得します

```erb
<% @users.each do |user| %>
  <tr>
    <td><%= user.name %></td> <%# ここが0番目の要素　%>
    <td><%= user.birthdate %></td>
  </tr>
<% end %>
```

取得したテキストは`users`配列に格納します

**※`_1`とは何か**

番号指定パラメータというやつです
ここについては今回は触れませんが、下記の同様のことをしています

```ruby
map { |row| row.all('td')[0].text }
```

### expectで順番を確認

```ruby
expect(users).to eq %w[佐藤 吉田 鈴木]
```

取得した`users`の配列が `%w[佐藤 吉田 鈴木]`の順番になっているかを確認します

以上

## 感想

system specで結構リソース使うのが「この操作ってどうやってかくの？」という部分だと思いますが、こういったrubyメソッドの応用などはやっていて楽しい反面、rubyやらんとなぁと思い知らされます

## 参考

https://www.sonicgarden.jp/blog_articles/sggym_202206

https://techbookfest.org/product/50CLAnEpRNhFNKzgq1aK78?productVariantID=gmDHaevdhz4T3T4eiGjWHe
LinuxのOSを入れたMicroSDカードをWindowsで認識させてフォーマットしたい

ラズパイOS等をMicroSDカードに入れたはいいけど、Windowsだとその後MicroSDカード自体が認識されなくなったり、認識出来てもパーティションが別れていてフォーマット出来なかったりとか面倒なことが起きたりします。

そんなんLinuxで初期化すればええやん、と思うかも知れませんが、Windowsで出来るにこしたことはないわけで。

そんな貴方に朗報です。
以下、そのやり方になります。

※ この作業は 『**対象ディスクのデータを消去**』 しますので、対象ディスクを必ず選ぶようにして下さい。紛らわしいディスクは取り外すなどした方がいいです。
<br>

１．Windowsアイコンを右クリック、ターミナル（管理者）を起動させます

２．diskpart　コマンドを実行します
```
PS C:\Users\USERNAME> diskpart

Microsoft DiskPart バージョン 10.0.26100.1150

Copyright (C) Microsoft Corporation.
コンピューター: COMPUTERNAME
```
３．list disk　コマンドを実行します
　すると、下記のような表示がされます

```
DISKPART> list disk

   ディスク      状態           サイズ   空き   ダイナ GPT
  ###                                          ミック
  ------------  -------------  -------  -------  ---  ---
  ディスク 0    オンライン           476 GB      0 B        *
  ディスク 1    オンライン           931 GB      0 B        *
  ディスク 2    オンライン           238 GB      0 B
  ディスク 3    オンライン            14 GB    12 GB        *
```
※ 今回の例では ディスク３ が対象です

４．select disk 3　のコマンドを実行します
```
DISKPART> select disk 3
ディスク 3 が選択されました。
```

５．clean　コマンドを実行します
```
DISKPART> clean
DiskPart はディスクを正常にクリーンな状態にしました。
```

６．最後に次のコマンドを実行します
```
DISKPART> create partition primary
DiskPart は指定したパーティションの作成に成功しました。
```
これで、Windows上でパーティションが一つにまとまった状態で正常に認識されるようになったと思います。
(∩´∀｀)∩ ﾜｰｲ

あとは普通にフォーマットするだけです

というわけで終わりです。
(/・ω・)/ ｺﾛｺﾛｺﾛ ＝〇
GitHubに草が生えなくなった

# 発生した事象
GitHubに草が生えなくなったことに気づいた。
過去1ヶ月〜2ヶ月くらいの草が生えていなかった。

# 原因
```
git config --global user.email
```
メールアドレスを確認したら`@`の直後の文字が大文字になっていた。

# 解決策
[こちらの記事](url)を参考に、過去のログのemailアドレスの一括変更を試みてみる。

```
git filter-branch -f --env-filter "GIT_AUTHOR_NAME='GitHubのusername'; GIT_AUTHOR_EMAIL='GitHubのメールアドレス'; GIT_COMMITTER_NAME='GitHubのusername'; GIT_COMMITTER_EMAIL='GitHubのメールアドレス';" HEAD
```

ところが下記のエラーが発生する。
```
Cannot rewrite branches: You have unstaged changes.
```

`$ git status`でどのファイルがuncomittedなのか確認する

```
{PROJECT_NAME}.xcodeproj/project.xcworkspace/xcuserdata/{USER_NAME}.xcuserdatad/UserInterfaceState.xcuserstate
```

# 結論

開きっぱなしになっていたXCodeを閉じて一連の流れを再調査

```
Proceeding with filter-branch...

Rewrite 768b266bc278c46543cdcf054d6487df0804eba2 (71/74) (3 seconds passed, remaining 0 predicted)    
```

解決した。

# 参考記事

https://zenn.dev/cyaroya/articles/7e281e730791a1
2024年振り返りレポート

# 2024年を振り返る

年越す前にやるのが普通ですが、間に合いませんでした

:::note warn
警告
ゆるいです。ご了承ください。
:::

## 転職の年
2024年は、私にとって**変化の年**でした。  
10月から本格的に始めた転職活動は、翌年の3月まで続きました。  
転職活動を通じて得た学びは以下の通りです。

**転職サイトについて**  
  主に「Green」を活用しました。ただし、どの転職サイトが良いかは個人の使いやすさ次第だと思います。  
  メジャーなサイトであれば、どれでも問題ないと感じました

**転職エージェントについて**  
個人的には使わないほうが良いかなと感じました。
理由として、地方だと紹介できる企業が少ないことや、エージェントが実績の少ない人を企業に推薦しづらいという点があります(これは自分が悪い)

また、エージェントとの面談で別途日程を調整するのがスケジュール的にきついなと感じました

**大都市圏での転職活動であれば、エージェントの活用は有効**だと考えます

**応募のスタンス**  
とりあえず気になる企業にはどんどん応募する方針を取りました
**応募するだけならタダです...！！！**

**面接の心得**  
面接では、ありのままの自分を表現することを心がけました
嘘ついたり過剰に盛ったりしてもお互いに良くありません

**志望企業の絞り込みについて**  
志望先を絞りすぎず、幅広く見ることが大切だと実感しました
自分の場合は落ちることが多いと思っていたので、それに一喜一憂するのも勿体ないと思ってました

https://www.green-japan.com/

## 受託開発から自社開発へ
2024年は、受託開発から自社開発へと環境が大きく変化しました。

**受託開発と自社開発の違い**  
受託開発では、案件を受注すれば収入が確保されました。
一方で、自社開発は**売上を立てなければ給料が支払われない可能性**もある環境です

**ユーザーとの距離の近さ**  
  自社開発では、ユーザーの声を非常に近くで感じることができます
  私が所属しているチームのユーザーは社内の社員さんです
  
  * ユーザーと昼飯食べているときに
  
  ユーザー：「〇〇のここがおかしくて...？バグですかね...？:thinking:」
  
  私：「なぬ？！詳しく教えて下さい...」
  
  ユーザー：「ほげほげでふがふがで...」
  
  私：「バグですね！すいませんでした...！:innocent:」
  んで、午後はバグ改修してリリースする

* **システム障害への対応**  
  システム障害が発生した際は、慌てることもありましたが、その経験から多くを学びました

## 職場近くへの引越し
沖縄では車社会のため、朝の渋滞を避けるため職場近くに引っ越しました
バス通勤は快適です
けれど、沖縄のバスは時間通りきません

## コミュニティとの繋がり
昨年は、他社との合同イベントや自社イベントを通じて、**多くのエンジニアとの繋がり**を築きました。

* **SNSでの繋がり**  
  X（旧Twitter）でエンジニアのフォロワーが増えていくのが嬉しかったです

* **エンジニアコミュニティ**  
  コミュニティで出会うエンジニアは皆良い人ばかりでした。他社の方々との繋がりがとても大切だと改めて感じました

# 2025年の抱負
2025年は、以下の2つを目標に活動していきます。

## ユーザーにコミットする
単にコードを書くのではなく、ユーザーの**ニーズを吸い上げて形にする**ことに注力します。  
ユーザーの業務改善に貢献できるエンジニアを目指します。

## たくさんアウトプットする
技術ブログの執筆に加え、コミュニティでの登壇などを通じて、**自分の考えや技術を積極的に共有**していきます。

* **アウトプットの重要性**  
  アウトプットはキャリアアップに繋がるだけでなく、求職者が企業の「中の人」を知るための重要な情報源だと考えています。  
  自分自身がそうだったので、積極的に取り組んでいきたいです

# おわりに

昨年はお世話になりました。
今年もよろしくお願いします。
BeanとDTO、Entity、Formについて

# はじめに
どうも、稲葉です。この記事では、BeanとDTO、Entity、Formについてまとめます。
# Bean
Beanは次の要件を満たします。
1. 引数がないコンストラクタを公開すること
2. シリアライズが可能であること
3. プロパティそのものは公開せず、アクセサメソッドを定義すること
# DTO
DTO（Data Transfer Object）とは、Beanのうち、データの転送をするためのオブジェクトです。データストア・外部実体と情報の受け渡しをします。EntityやFormと命名されたクラスが使用される場合、データを転送する相手は外部システムです。DTOは責務が外部実体・データストアと情報をやり取りすることであるため、基本的にアクセサメソッド以外の処理を定義しません。
# Entity
Entityとは、DTOあるいはBeanのうち、データストア、すなわちデータベースと情報の受け渡しをするためのオブジェクトです。データモデルのエンティティないしデータベースのテーブルと対応します。よって、プロパティの型は基本的に`ResultSet`クラスのgetterの引数や`PreparedStatement`クラスのsetterの戻り値の型となります。
# Form
Formとは、DTOあるいはBeanのうち、画面によって外部実体、つまりユーザと情報の受け渡しをするためのオブジェクトです。画面の入出力項目群と対応します。よって、プロパティの型は基本的に`String`型となります。
# おまけ
データ層で使用するEntity、プレゼンテーション層で使用するFormではプロパティの型が制限されていたり、アクセサメソッド以外の処理を定義しなかったりします。そのため、オブジェクト指向プログラミングでは情報と処理をまとめたクラスを作成してアプリケーション層で使用することもあります。
# おわりに
BeanとDTO、Entity、Formの関係をまとめると次のようになります。
|Beanの種類|授受の相手|作成の単位
|:--|:--|:--|
|DTO|データストア・外部実体、とくに外部システム|任意|
|Entity|データストア|テーブル|
|Form|外部実体のうち、ユーザ|入出力項目群|
Amazon Bedrock Knowledge Bases が RetrieveAndGenerateStream API をサポート

# 内容

AWS re:Invent 2024 で発表があった Amazon Bedrock Knowledge Bases が [RetrieveAndGenerateStream API](https://docs.aws.amazon.com/bedrock/latest/APIReference/API_agent-runtime_RetrieveAndGenerateStream.html) をサポートしたことについてシンプルに纏めます。

https://aws.amazon.com/jp/about-aws/whats-new/2024/12/amazon-bedrock-knowledge-bases-streaming-retrieveandgeneratestream-api/

- Knowledge Bases を利⽤する RAG で、完全な応答を待たずに、順次応答を受け取ることができる（ストリーム）
- InvokeModelWithResponseStream の Knowledge Bases みたいな感じ？


# 対応リージョン

- Knowledge Bases を利用可能な全てのリージョン


# 設定

## 前提

ストリームができるかの確認ですので、Knowledge Bases は構築済とします。

## retrieve_and_generate_stream API の実行と結果

```python
import boto3
import json

bedrock_agent = boto3.client("bedrock-agent-runtime", region_name="us-west-2")
knowledgeBase_Id = "<ナレッジベースID>"
model_Arn = "arn:aws:bedrock:us-west-2::foundation-model/anthropic.claude-3-5-sonnet-20241022-v2:0"

prompt = ("2023年の山手線の利用者数ベスト10を教えて下さい")

response = bedrock_agent.retrieve_and_generate_stream(
    input={"text": prompt},
    retrieveAndGenerateConfiguration={
        "type": "KNOWLEDGE_BASE",
        "knowledgeBaseConfiguration": {
            "knowledgeBaseId": knowledgeBase_Id,
            "modelArn": model_Arn,
        },
    }
)
stream = response.get("stream")

if stream:
    for event in stream:
        if "output" in event:
            print(event['output']['text'], end="", flush=True)
```

![RetrieveAndGenerateStream.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/280929/5916a361-bea4-c7de-9765-608e05d8e690.gif)
Ubuntu24.04でのかな切り替えをCtrl+Spaceで行う

以下の記事が少し古くなっていて若干操作が違ったためUbuntu24.04での方法をメモ。

https://qiita.com/nabenabe0928/items/09affae67df9c150ad50#0ubuntu%E3%81%A7%E8%A8%80%E8%AA%9E%E3%81%AB%E6%97%A5%E6%9C%AC%E8%AA%9E%E3%82%92%E9%81%B8%E6%8A%9E%E3%81%97%E3%81%A6%E3%82%82%E6%97%A5%E6%9C%AC%E8%AA%9E%E3%81%A7%E5%85%A5%E5%8A%9B%E3%81%A7%E3%81%8D%E3%81%AA%E3%81%84%E5%95%8F%E9%A1%8C

## ibus-mozc のインストール
ここは参考記事と同じ。

```console
# ibus-mozcのインストール
$ sudo apt install ibus-mozc

# ibus-mozcの再起動
$ killall ibus-daemon
$ ibus-daemon -d -x&
```

 ## キーボード設定へ

 参考記事では、以下のダイアログに「Tools -> properties」という選択項目があったようだが、私の環境では「Tools」はなく、代わりに「Keyboard Settings」という項目になっていた。
<img width="500" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/532908/852f205d-085d-3cdd-0e3e-822a6d27a8eb.png">

ここをクリックすると、以下のUbuntuのキーボード設定画面が開く。当然設定アプリから直接開いても良い。
![Screenshot from 2025-01-01 21-34-21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/532908/357bd917-ea89-c8e7-ea02-14e22ad8709c.png)

## ショートカットの変更

ここで「日本語(Mozc)」の三点リーダから設定できるのか、と思ったがなぜか三点リーダ→「設定」をクリックしても何も起きず。

:::note info
よく調べたら設定は開けた。[追記：Mozcの設定画面を表示する](追記：Mozcの設定画面を表示する)参照。
多くの人はMozcの設定から設定したほうが良いかも。
:::

三点リーダには触れず一番下までスクロールすると、「キーボードショートカット」の欄に「ショートカットの表示と設定」の項目がある。

![Screenshot from 2025-01-01 21-44-48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/532908/d6c1b858-5b99-e8d8-541f-698c99ff4275.png)


ここで「タイピング」を選択して「次の入力ソースへ切り替える」をおしてCtrl+Spaceを押下すればOK。

<img width="300" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/532908/64e60c62-e9d7-8fc1-52ea-980acd808f31.png">
<img width="300" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/532908/e505f476-dd9b-9199-1417-0714d3530754.png">

少なくともCtrl+Spaceの場合は「次の入力ソースへ切り替える」を変更すると自動的に「前の入力ソースへ切り替える」もShft+Ctrl+Spaceに変更された。
本当はMacみたいに変換・無変換キーをかな・英数に割り当てたいのだが、Mozcの設定が開けないので仕方ない、、、

## 追記：Mozcの設定画面を表示する
以下の記事で解決できた。gui用のパッケージが足りていなかったらしい。

https://inno-tech-life.com/dev/linux/mozc_gui/

要は以下を実行すればいい。
```console
$ sudo apt install -y mozc-utils-gui
```

これでMozcの設定画面を開けるので、「一般」タブの下の方にある「キー設定の選択」から設定すればMacみたいなキー配置に設定できる。
ただ、私の場合はキーボードをWindows用と兼用している＆HHKBの配列をカスタマイズしている関係でうまく設定できなかったので、結局本記事の方法でCtrl+Spaceを使うことになった。
【GitHubActions】マトリックスを利用してScriptを実行する

### 概要

マトリックスを利用し、冗長性のあるワークフローをすっきりさせました。
複数のシェルスクリプトを実行させたい時に利用すると良いかもしれません。

### 元のコード

```yaml
name: Sequential Workflow

on:
  push:
    branches:
      - main
  pull_request:
    branches:
      - main

jobs:
  validation:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout code
        uses: actions/checkout@v4.1.7

      - name: Set up validation script permissions
        run: chmod +x .github/scripts/validation.sh

      - name: Run validation script
        run: ./.github/scripts/validation.sh

  setup:
    runs-on: ubuntu-latest
    needs: validation
    steps:
      - name: Checkout code
        uses: actions/checkout@v4.1.7

      - name: Set up setup script permissions
        run: chmod +x .github/scripts/set-up.sh

      - name: Run setup script
        run: ./.github/scripts/set-up.sh

  deploy:
    runs-on: ubuntu-latest
    needs: setup
    steps:
      - name: Checkout code
        uses: actions/checkout@v4.1.7

      - name: Set up deploy script permissions
        run: chmod +x .github/scripts/deploy.sh

      - name: Run deploy script
        run: ./.github/scripts/deploy.sh

```

### matrixを利用したコード

```yaml
name: Matrix Workflow

on:
  push:
    branches:
      - main
  pull_request:
    branches:
      - main

jobs:
  example_matrix:
    runs-on: ubuntu-latest
    strategy:
      matrix:
        script: [validation, set-up, deploy]
    steps:
      - name: Checkout code
        uses: actions/checkout@v4.1.7

      - name: Set up script permissions
        run: chmod +x .github/scripts/${{ matrix.script }}.sh

      - name: Run script
        run: ./.github/scripts/${{ matrix.script }}.sh
```

### まとめ

```yaml
    strategy:
      matrix:
        script: [validation, set-up, deploy]
```

上記のワークフローのリストにある `validation`, `set-up`, `deploy`を
下記の `${{ matrix.script }}` へ順番に代入し、実行しています。

```yaml
    - name: Set up script permissions
      run: chmod +x .github/scripts/${{ matrix.script }}.sh
```

これで冗長性のあるワークフローを短くまとめることができます。
#2025010122

ar		ca		　　result
setting3	ok	acHe	1	o
setting4	ok	gdQw	0	x
				
		caはreが0はno、1はok		
		arとreが同じならば、result1にo違う場合はxを入力する。		


Sub UpdateResultsFromCells()
    Dim ws As Object ' Worksheet型がエラーになる場合、Objectを使用
    Dim lastRow As Long
    Dim i As Long
    Dim ar As String
    Dim CA As Integer
    Dim re As String
    Dim result As String
    
    ' シート名 "se" を取得
    On Error Resume Next
    Set ws = ThisWorkbook.Sheets("Sheet1")
    On Error GoTo 0

    ' シートが見つからない場合のエラー処理
    If ws Is Nothing Then
        MsgBox "シート 'Sheet1' が見つかりません。正しい名前を確認してください。", vbCritical
        Exit Sub
    End If
    
    ' データの最終行を取得
    lastRow = ws.Cells(ws.Rows.Count, "A").End(xlUp).Row
    
    ' データをループして処理
    For i = 2 To lastRow ' ヘッダーが1行目にあると仮定
        ' セルから値を取得
        ar = ws.Cells(i, 2).Value ' "ar" は列 B
        CA = ws.Cells(i, 4).Value ' "CA" は列 D
        
        ' CA に応じて re を設定
        If CA = 0 Then
            re = "no"
        ElseIf CA = 1 Then
            re = "ok"
        Else
            re = "invalid"
        End If
        
        ' ar と re を比較して result を設定
        If ar = re Then
            result = "o"
        Else
            result = "x"
        End If
        
        ' 結果を列 E に出力
        ws.Cells(i, 5).Value = result ' "result" は列 E
    Next i
    
    MsgBox "セルの値を基に処理が完了しました！", vbInformation
End Sub
【あけましておめでとうございます】年末年始から業務効率化させるためのRubyスクリプトを作ってしまいました。

あけましておめでとうございます。
今年もよろしくお願いいたします。

私ごとながら、年末年始で体調を崩してしまいました。おかげさまでとっても暇でした。

なので、**Railsの`db/schema/rb`を読んで、マークダウン形式のDB仕様書を自動で作成するスクリプト**を作成しました。

やれやれ...

詳しくは、以下のリンクからご覧ください。

https://github.com/pdc-kurashina/create_markdown_schema_tools

細かいところまではきちんと実装していないですが、`I18n`をうまく使ったりして完全体にしていく予定です。

:::note info
ライブラリ化してみようか迷いましたが、スクリプトとして存在していた方がカスタマイズできるかなと思ったので、今のところはしない方向です。

というかライブラリを作ったことないので...
:::

以上
正規化と標準化の使い分け

# はじめに
最近まで機械学習について勉強する中で正規化と標準化を同じようなものとして捉えてしまってました。
機械学習の前処理でよく扱われるスケーリング手法の正規化と標準化を理解することでモデル精度の向上が期待できると思い本記事では私なりの正規化と標準化の違いを解説します。

### 正規化(Normalization)について
正規化はデータを特定の範囲にスケーリングする手法で、最小-最大正規化(Min=Max Normalization)がよく使われます。
#### 計算方法
実際に最小-最大正規化は以下の式でスケーリングします。
$$
x' = \frac{x - min(x)}{max(x) - min(x)} 
$$
ここで、xは元のデータ値、min・maxはそれぞれ特徴量の最小値と最大値です。これによって全てのデータが**0から1**の間に変換されます。

#### 使用されるモデル
正規化が使用されるモデルとしては以下が挙げられます。
・距離ベースのアルゴリズム(SVM,K近傍法など)
・ニューラルネットワーク

### 標準化(Standardization)について
標準化はデータを**平均0**、**標準偏差1**にスケーリングする方法です。
#### 計算方法
$$
x' = \frac{x - \mu}{\sigma} 
$$
ここで、$\mu$は特徴量の平均、$\sigma$は特徴量の標準偏差を表しています。これによってデータが**正規分布に従う**ように変換されます。
#### 使用されるモデル
標準化が使用されるモデルとしては以下が挙げられます。
・回帰分析、ロジスティック回帰
・SVMや線形回帰モデル、勾配降下法

### 正規化と標準化の違い
| 特徴     | 正規化(Normalization) | 標準化(Standardization)     |
|----------|------|----------|
| **定義** | データを特定の範囲(0~1)にスケーリング   | データを平均0、標準偏差1にスケーリング     |
| **計算方法** | 最小値と最大値によりスケーリング   | 平均と標準偏差でスケーリング     |
| **結果の範囲** | 0~1の範囲   | 範囲の固定はない   |
| **強み** | 距離ベースアルゴリズムに有効   | 外れ値に強く、正規分布を仮定するアルゴリズムに有効     |
| **弱み** | 外れ値に敏感  | 外れ値に依存することがある   |

### 正規化の強みと弱み
##### 強み
・**範囲が固定** : 正規化後のデータは、必ず指定されて範囲(通常は0~1)に収まるためデータが均等なスケールに変換される。
・**距離を使うアルゴリズムに有効** : KNNやSVMなどの距離を扱うアルゴリズムで効果的。

##### 弱み
・**外れ値に敏感** : 正規化は最大値と最小値に基づいてスケーリングを行うため、外れ値が存在するとスケーリングの結果が極端となり、モデルのパフォーマンスが低下することがある。
### 標準化の強みと弱み
##### 強み
・**外れ値に強い** : 標準化は平均と標準偏差を使用してスケーリングを行うため、外れ値の影響を受けにくい。
・**正規分布を仮定するアルゴリズムに有効** : 線形回帰やロジスティック回帰など、正規分布を仮定するモデルにおいて効果的。

##### 弱み
・**範囲が不明** : 平均が0、標準偏差が1になるが、データがどの範囲に収まるかが分からないため解釈が難しいことがある。

## まとめ
正規化と標準化は、どちらもデータをスケーリングする方法ですが、それぞれに強みと弱みがあります。

・**正規化**は、データを0〜1の範囲に収めるため、距離ベースのアルゴリズムやニューラルネットワークに有効です。ただし、外れ値に敏感であるため、外れ値のあるデータには注意が必要。

・**標準化**は、データを平均0、標準偏差1にスケーリングするため、外れ値に強く、正規分布を仮定するアルゴリズムに適しています。しかし、スケーリング後のデータの範囲が不定なため、解釈が難しいことがあります。
#0001（2025/01/01） ステートレスかステートフルか

# モチベーション
- AWS SAA の勉強中にネットワークACLとセキュリティグループのどちらがステートレスでどちらがステートフルかごっちゃになった

# 覚え方
## ネットワークACLとセキュリティグループ
- ネットワークACL(Access Control List)
    - サブネットレベルでのトラフィックの監視
    - 高速でシンプルな監視が求められる
- セキュリティグループ
    - EC2などのアプリケーションにアタッチする防御壁
## ステートレスかステートフルか
### ステートとは
- 通信の状態
- 疑問）セッションとは違うのか？
### ステートレス
- 通信の状態を維持しない
- 例えば、かかってきた電話をこちらからかけ直すことができない
### ステートフル
- 通信の状態を維持する
- 例えば、かかってきた電話について、状態がわかるため、かけ直すことができる

## 各サービスとステートレスorステートフル
- ネットワークACL→ステートレス
    - ネットワークの監視のため、状態の維持は不要
- セキュリティグループ→ステートフル
    - アプリケーションで状態を維持する

# ソース
- chatgptの回答を参考
(DAY8) 俺と学ぶRust言語~配列~

# 今日の内容
- 配列

# はじめに
[前回](https://qiita.com/FUKAch/items/573d678eeea13ea923a8)はシーザー暗号を通してRustについてより詳しく学びました。今日は、Rustでの配列について詳しく学んでいこうと思います。

# 配列
配列とは、固定サイズの要素を同じ型で格納するデータ構造です。
以下のように宣言します。
```rust
let 配列名 = [要素, 要素, 要素,..];
```
注意すべき点は、配列の長さは **変えることができません**。
定義した時点で配列の長さは固定されます。
例えば、
```rust
let a = [1, 2, 3];
```
であれば、配列aの長さは3です。これに要素を追加したり、削除したりすることはできません。とても不便なので、ほとんど配列を使うことはないでしょう。その代わりにRustでは **スライス** という機能があります。今日はこの機能には触れませんが、長さが可変です。
配列の要素数を変えることはできませんが、要素自体にアクセスして、いじることはできます。
```rust
fn main(){
    let numbers = [10, 20, 30, 40, 50];
    println!("１番目の要素: {}", numbers[0]);
    println!("配列の長さ: {}", numbers.len());
}
/******** 実行結果 ********
１番目の要素: 10
配列の長さ: 5
 ************************/
```
このプログラムは、配列numbersの一つ目の要素と、配列numbersの長さを取得し、表示させています。
配列の要素は以下のように取得します。
```rust
配列名[要素番号]
```
要素番号は0,1,2,..です。
配列の長さは、以下のように取得します。
```rust
配列名.len()
```

また、Rustでは他の配列の定義方法があります。
```rust
let 配列名 = [値; 配列要素数]
```
これは、「配列要素数」分、「値」で埋まった配列が作れます。

配列の要素をいじるには、配列自体を可変にする必要がありますが、これは今まで通り「mut」を配列名の手前につけるだけでよいです。
以下は、「0」で「10個」埋められた配列を、順番に0~9で置き換えるプログラムです。
```rust
fn main(){
    let mut a = [0; 10];
    for i in 0..a.len() {
            a[i] = i;
    }
}
```
表示を追加すれば、0~9に置き換えられていることがわかります。
また、配列とforの間にはおもしろい機能が用意されています。
以下のプログラムを実行してみてください。
```rust
fn main(){
    let a = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"];
    for i in a {
        println!("{}", i);
    }
}
/******** 実行結果 ********
Jan
Feb
Mar
Apr
May
Jun
Jul
Aug
Sep
Oct
Nov
Dec
 ************************/
```
さて、プログラム内では配列の個々の要素にアクセスしてるようには見えないのに、実行結果を見てみると、順番に表示されていることがわかります。さらに、for文の形が見慣れない方もいるかもしれません。
```rust
for 変数 in 配列名 {

}
```
のようにすることで、変数に配列の要素一つずつが入って繰り返されるようになります。

:::note alert
これについて調べていたらこんな使い方できないらしいので少し困惑しています。イテレーターにしたらできるとかなんとか。
:::

文字列にString型と&str型の二つがありますが、これは大雑把に,String型はスライスで、&strは配列です。つまり、String型は可変長ですが、&strは不変長です。
```rust
fn main(){
    let s = "abcdefg";
}
```
これは&str型です。
```rust
fn main(){
    let s = String::from("abcdefg");
}
```
これはString型です。

# おわりに
え？！もうおわり？！
すみません。昨日からついさっきまで「The Rust Programming Language 日本語版」を爆速で読んでたのですが、ここがいまだにこんがらがっていて、他にいろいろ説明したいことあったはずなのにもう疲れてしまいました..(´;ω;｀)。次回は入力について学んでいきます。また、めんどくさいところを..自分のバカ。
ご精読ありがとうございました。

# 追記
ここからは投降後の追記です。
```rust
fn main(){
    let a = [0,1,2,3,4,5,6,7,8,9];
    for i in a {
        println!("{}", i);
    }
}
```
これは、配列aを順番に表示するプログラムです。

```rust
fn main (){
    let a = [0,1,2,3,4,5,6,7,8,9];
    for i in (0..a.len()).rev(){
        println!("{}", i);
    }
}
```
これは、配列aの順番を逆から表示するプログラムです。
9
8
7...となります。
「0..a.len()」の部分で、「0から配列aの長さ-1まで繰り返すと」なります。それ自体を、「.rev()」でひっくり返しているので、順番を逆にできます。

```rust
fn main (){
    let a = [0,1,2,3,4,5,6,7,8,9];
    for i in (0..a.len()).step_by(2){
        println!("{}", i);
    }
}
```
これは、1番目を入れて、2番目を飛ばし、3番目を入れて、4番目は飛ばし、...となります。つまり実行結果は
0
2
4
6
8
となります。
「.step_by()」は、()内の数分を取得し、そのうちの一個目のみを返します。
NPCの行動制御に使える「Unity Behavior」は「Behavior」で「Behaviour」じゃない

Unity Behaviorは、NPCやオブジェクトの制御に利用できるビジュアルツールで、Unity公式のパッケージです。

https://docs.unity3d.com/Packages/com.unity.behavior@1.0/manual/index.html

# 「Unity Behavior」はBehaviorだよ、Behaviourじゃないよ

このパッケージは、「Unity Behavior」で、「Unity Behaviour」ではないことに注目してください。

ちなみに、

* Behaviorはアメリカ英語、単語中に「u」なし
* Behaviourはイギリス英語、単語中に「u」あり

らしいです。ビジュアルツールの「Unity Behavior」は、イギリス英語ではなく、アメリカ英語のBehaviorですね。

Unityに慣れているみなさん（特にブログなどUnityについての文章を頻繁に執筆する皆さん）は要注意ですね。絶対、指が勝手に「Behaviour」って書いちゃうんと思うので。

# Unityにおける「Behaviour」、たまに「Behavior」

Unityは、イギリス英語の「behaviour」とつくクラスやメンバーがたくさんありますよね。一番有名な「[MonoBehaviour](https://docs.unity3d.com/6000.0/Documentation/ScriptReference/MonoBehaviour.html)」を筆頭にたとえば次のようなものがあります。


* [Behaviour](https://docs.unity3d.com/6000.0/Documentation/ScriptReference/Behaviour.html)
* [PlayableBehaviour](https://docs.unity3d.com/6000.0/Documentation/ScriptReference/Playables.PlayableBehaviour.html)
* [StateMachineBehaviour](https://docs.unity3d.com/6000.0/Documentation/ScriptReference/StateMachineBehaviour.html)
* [AnimatorStateMachine.behaviours](https://docs.unity3d.com/6000.0/Documentation/ScriptReference/Animations.AnimatorStateMachine-behaviours.html)
* [AnimatorController.AddEffectiveStateMachineBehaviour](https://docs.unity3d.com/6000.0/Documentation/ScriptReference/Animations.AnimatorController.AddEffectiveStateMachineBehaviour.html)

一方で、実は「Unty Behavior」登場前から、アメリカ英語「behavior」とつくクラスやメンバーもあったみたいです。（知らなかった・・・）

* [ParticleSystemStopBehavior](https://docs.unity3d.com/6000.0/Documentation/ScriptReference/ParticleSystemStopBehavior.html)
* [StopBehavior](https://docs.unity3d.com/6000.0/Documentation/ScriptReference/Rendering.SplashScreen.StopBehavior.html)
* [PlayerSettings.iOS.appInBackgroundBehavior](https://docs.unity3d.com/6000.0/Documentation/ScriptReference/PlayerSettings.iOS-appInBackgroundBehavior.html)


---

ちなみに、クラス名やメンバー名だけじゃなく、公式ドキュメントにも「behaviour」という記述が多数登場します。


[PlatformEffector2D](https://docs.unity3d.com/6000.0/Documentation/ScriptReference/PlatformEffector2D.html)より。

> Applies "platform" behaviour such as one-way collisions etc.


また、「Unity Behavior」のドキュメント内に、「名詞」として「bahaviour」という単語が出てきます。

[BehaviorGraph](https://docs.unity3d.com/Packages/com.unity.behavior@1.0/api/Unity.Behavior.BehaviorGraph.html)より

> BehaviorGraph holds all the runtime graph instances linked together into a complete behaviour defined within a BehaviorAuthoringGraph.

困ったことに、「名詞」として「bahavior」という単語が出てくる場合もあります。

[iOSAppInBackgroundBehavior](https://docs.unity3d.com/6000.0/Documentation/ScriptReference/iOSAppInBackgroundBehavior.html)より

> Application behavior when entering background.

# まとめ

混乱しますね！マジで！

Unityの文章（特に印刷されるもの）は「Behaviour」になっているか気をつけていたのですが、「Behavior」が正しいパターンも出てきましたね。（ていうか、昔からあったんですね。）

もし、自分が間違ってたら、優しく教えてくれると嬉しいです。
ゲームボーイ RGBDS 開発メモ 第9回 チュートリアルを読んでいく (Input)

前回にひきつづきチュートリアルをすすめていきます。

[https://gbdev.io/gb-asm-tutorial/part2/input.html](https://gbdev.io/gb-asm-tutorial/part2/input.html)

### Input

```
UpdateKeys:
  ; Poll half the controller
  ld a, P1F_GET_BTN
  call .onenibble
  ld b, a ; B7-4 = 1; B3-0 = unpressed buttons

  ; Poll the other half
  ld a, P1F_GET_DPAD
  call .onenibble
  swap a ; A3-0 = unpressed directions; A7-4 = 1
  xor a, b ; A = pressed buttons + directions
  ld b, a ; B = pressed buttons + directions

  ; And release the controller
  ld a, P1F_GET_NONE
  ldh [rP1], a

  ; Combine with previous wCurKeys to make wNewKeys
  ld a, [wCurKeys]
  xor a, b ; A = keys that changed state
  and a, b ; A = keys that changed to pressed
  ld [wNewKeys], a
  ld a, b
  ld [wCurKeys], a
  ret

.onenibble
  ldh [rP1], a ; switch the key matrix
  call .knownret ; burn 10 cycles calling a known ret
  ldh a, [rP1] ; ignore value while waiting for the key matrix to settle
  ldh a, [rP1]
  ldh a, [rP1] ; this read counts
  or a, $F0 ; A7-4 = 1; A3-0 = unpressed keys
.knownret
  ret
```

さっそく関数です。これは解読するの大変でした（笑）。まずニブルというのは4bitのデータで半バイトをさします。P1F_GET_BTN を書き込むと下位4bitにボタンに関する値が入ります。ただ、すぐに入るとは限らず、安定するまで３回読み出しています。

上位4ビットに1をいれて返却。こんどは P1F_GET_DPAD を設定すると、十字パッドの値が下位４ビットに入ります。押している状態が0です。これを上位ニブルと下位ニブルをswapで反転して先ほどのあった値とXORをとると、上位のニブルにボタンに関するビットの反転が、下位のニブルが十字パッドに関する値の反転が格納され、これを ワークエリアに保存しています。XORにすることにより、押した状態が1になります。

wNewKeys は新しくかわった値、wCurKeys は今の値が入ります。

これをVBlank中に１回呼んでおけば、使いまわせる。

call .knownret しているのは、書き込んでから読み出せるようになるまで時間がかかるため、時間稼ぎをしているようです。call & ret は10 cycle かかるらしい。

この関数はいつでも使えそう。入力を読み取るのでも、アセンブラだと全然違いますね。
でもなんとか理解できました。

### 次回

次回はボールが登場。衝突のロジックも出てくるようです。
外付けSSDでUbuntuを導入する

## はじめに
HDD搭載で起動が遅くなったがために、ほぼ使われていなかった一体型PCにて  
Ubuntuを利用できるようにした際の備忘録です。

## Software
- Ubuntu 22.04

## Hardware
- [FUJITSU FMVF90A3B](https://www.fmworld.net/fmv/fh/1610/spec/)
	- ram 8GB
	- Intel® Core™ i7-6700HQ CPU @ 2.60GHz × 8
	- Mesa Intel® HD Graphics 530 (SKL GT2)
	- 容量 3TB HDD (Windows10)
- [Buffalo スティック型SSD](https://www.buffalo.jp/product/detail/ssd-put500u3-b_n.html)
	- 容量 500GB

## Ubuntuの導入
対象のPCにはHDDが使われており、SSD交換には分解が必要な機種となります。  
今回は手間がかかる交換を避けたかったため、外付けのコンパクトなスティック型SSDを購入し、  
そこへUbuntuのインストールを行っています。

USBインストールメディアの作成方法と詳細なインストール方法は割愛いたしますが  
以降の項目はインストール後に起動を行った際に、発生した問題の修正を対応したものとなります。

## 音が鳴るタイミングでノイズが発生することの対処
Ubuntuを利用して問題なく起動できたが  
動画などの視聴時に、音のなり始めのタイミングでノイズが発生するのに気が付いた。  
検索してヒットした下記の記事を参考にし、対応したところ解消した。

- Ubuntuで音のなり始めにノイズが聞こえる場合の対処法
	- https://qiita.com/aximov/items/b37383b7c71db9878bec

## GRUBの不具合
GRUBの挙動が想定と違うものだったため、boot-repiarを利用して修正を行った。  
修正後はGRUB上にて、Ubuntu or Windowsの選択も行えるようになった。  
（ちなみにWindowsの指定自体は、PC起動時にF12連打でも行えます。
  
- grubのバグ？を修正した
	- https://ocucraqp.hatenablog.com/entry/2020/04/26/114439

## マウントされたデバイスの非表示
Windowsが入っているHDDが自動でマウントされる状態だったため  
GUIにて設定の変更を行った。
  
- Ubuntu 20でデバイスの自動マウントを無効化
	- https://www.rootlinks.net/2022/01/01/ubuntu-20でデバイスの自動マウントを無効化/

## キーボードレイアウトが表示されない
設定の入力ソースを、日本語 → 日本語(Mozc) の順番へ変更し  
その後に、日本語項目の右側にある縦三点リーダーからレイアウトを表示させることが可能になった。
	　
## テンキーが使えない
設定より、キーボードレイアウトを表示させて  
認識しているキー配置を確認し、無効化されていたNumlockを有効化

## wifiが途切れる
5ghz帯を利用していたところ、頻繁に接続が途切れる問題が発生した。  
色々と調査してみたが解消に至らず、5ghz帯から2.4ghz帯に切り替えたところ  
途切れずに安定して接続できるようになった。  

## ディレクトリ名を英語に設定
下記のコマンドを実行し、設定を行っていたが  
再起動後の画面にて、うっかり"Keep Old Names"を選択してしまい再設定するはめになった・・・
```bash
LANG=C xdg-user-dirs-update --force
```

- 【Ubuntu 20.04】ホーム内のディレクトリ名を英語にする
	- https://qiita.com/peachft/items/fde3bebd356c17c1cef6

## ディレクトリ名を英語に再設定
### コマンドでの再設定(失敗)
まず、下記の記事を参考にして再設定を試みたが  
Ubuntuのバージョンが違いすぎるためか解消にはいたらず。

- LANG=C xdg-user-dirs-gtk-updateを再設定する
	- https://whitehawk-taka.tumblr.com/post/155615980831/lang-c-xdg-user-dirs-gtk-updateを再設定する

### 手動設定
検索してヒットした情報を参考にして  
フォルダ名の情報が記載されたファイルを手動編集し、再設定を行った
```bash
~/.config/user-dirs.dirs
```
- Ubuntuのデスクトップ環境のフォルダ名を日本語から英語にする
	- https://qiita.com/matoken/items/1e43b4f446060f64afa1
- Change the language of the home/user/ folders automatically
	- https://askubuntu.com/questions/465647/change-the-language-of-the-home-user-folders-automatically

## あとがき
UbuntuへとOSを切り替え、共用PCとして続投となった一体型PCですが  
PC購入時に付属していたマウスとキーボードもそのまま使えるのもあり  
ちょっとした調べものを行ったり、動画視聴などで大活躍してくれています。  
~~家での共用PCがUbuntuってあんま聞かないなとは思いつつ~~

## 参考
- Ubuntuをインストールしないで快適に使う方法 Ubuntu22.04.03版
	- https://qiita.com/9ever/items/0b8ad5e54b827891df3a
- XDG ユーザディレクトリ
	- https://wiki.archlinux.jp/index.php/XDG_ユーザーディレクトリ
自己紹介と決意

# 初めまして！

皆さん、こんにちは。このたびQiitaでの発信を始めることにしました。まずは簡単に自己紹介をさせてください。

## 背景とこれからの挑戦

40代の男性「すごろく」です。会計系・コンサルティング系の分野で活動をしています。最近では急速に進化するデジタル技術やAIの世界に強く惹かれています。その進歩には驚きと興奮を感じる一方で、これからの時代に必要なスキルを身につける重要性も日々実感しています。

そんな中で、思い切ってプログラミングの学習を始めました！正直に言うと、まだ手探り状態ですが、新しいことに挑戦する楽しさを大切にしながら取り組んでいます。

すごろく。時には追加で３マス進むこともあるし、逆に２マス戻ることもあったり、場合によっては１回休みもある、でもこれから３６５日後のゴールを目指して進んでいきます。



**発信の目的**

このQiitaでは、学んだことや試行錯誤の中で感じたことを共有していきたいと思っています。特に、

- プログラミングの学びの記録
- 学習中に感じた疑問点やつまずき
- それをどうやって解決したか

など、初心者目線のリアルな内容をお届けできればと思います。

## 見守っていただけると嬉しいです！

私自身、まだまだ学びの途中ですが、この挑戦を通じて少しずつ成長していきたいと思っています。興味を持っていただけた方には、ぜひ温かく見守っていただけると嬉しいです。

もし投稿を読んで何か感じることがあれば、ぜひコメントやフィードバックをいただけると嬉しいです。温かく見守っていただけると幸いです。

これからどうぞよろしくお願いいたします！
Amazon Connect　WFMの設定（メモ）

昨日に続き、最近はWorkForceManagementの提案も徐々に出ているため、WFMの設定をメモします。

■設定手順の概要:

　１．Amazon Connectの準備:
  ・新規のAmazon Connectインスタンスを作成し、管理者権限でアクセスする。
　・必要に応じて、キュー（例：Queue1、Queue2）を作成し、それらのARN（Amazon Resource Name）を控える。

　２．サンプルデータの準備:
  ・ワークショップで提供されているサンプルのCSVファイル（例：daily.csv、interval.csv）をダウンロードする。
　・これらのファイル内のプレースホルダーを、先に控えたキューのARNで置換します。

 　３．FCPS機能の有効化:
　・Amazon Connectコンソールの「予測、キャパシティプランニング、スケジューリング」セクションで、該当機能を有効化する。
　・「Forecast and schedule interval」を設定する（例：15分間隔）。

　４．予測グループの作成:
　・「Forecast Groups」で新しいグループを作成し、対象のキュー（例：Queue1、Queue2）を追加する。

　５．データのインポート:
　・修正済みのinterval.csvとdaily.csvをコンソールからアップロードし、ステータスが「Complete」になることを確認する。

　６．予測の作成と公開:
　・「Forecasting」セクションで新しい予測を作成し、先に作成した予測グループを選択する。
　・予測のステータスが「Complete」になったら、予測を公開する。

 少し前までは、最低でも6か月以上のデータを投入する必要がありましたが、先日から1日のデータでも予測が出来るようになったそうです。
　ちなみに、仕事の関係でExcelのForcast関数と、Amazon ConnectのWFMを比較して、どちらが実態に近いか確認したことがありました。
 Amazon ConnectのWFMに軍配があがりました。
アプリ開発日記 2日目

# 背景
Webアプリケーションを個人開発する。
開発のモチベーション維持や、履歴を辿れるようにするため、開発日記を残す。
あくまで自分向けの記事として書く。

# 開発するアプリケーション
- 読書管理アプリ

# 開発に至ったきっかけ
- 読書を習慣にするため色々な本を読んでおり、感想をブログに書いていた。
- 読書を習慣化しようと思ったきっかけは勉強のため。
- 読んだ本をもう少しわかりやすく管理したくなった。
- 既にある読書管理アプリを使ってみようか迷ったが、せっかくなので勉強がてら開発してみることにした。

# 前回やったこと
- 必要な機能・要件の洗い出し
    - 優先度づけ
- 技術選定
- 利用する外部サービスの選定
    - 本の検索

# 今回やったこと
- サーバ側の実装
    - ローカルの開発環境をdockerコンテナで構築する
        - rails v8.0.1 APIモード
        - postgresql v15.3
    - 本のデータを取得するAPI機能を開発する
        - Book, User, UserBook のモデルを生成する
        - ISBNコードを生成するPOROを生成する
        - 外部APIへリクエストを投げるクライアントを生成する

# 所感
最初の機能は小さく作ろうと思っている。
とりあえず、ユーザーと本の登録、ログイン機能、本の情報取得、一覧表示などができれば公開していきたい。
インフラはGCPを使ってみようと思っている。
これまではAWSを使う機会が多かったが、仕事でGCPを使う可能性も出てきたので触れておきたい。
この日記の体裁・テンプレートも前回と少し変えてみた。
「前回やったこと」を追加することで、これまでの作業を思い出せるようにしてみる。
FPGAに入門してみたがLチカだけで苦労したからまとめてみた

# 動機

機械系のスターリングエンジン実習．情報系のCPU実習という二大巨頭（大嘘）

https://qiita.com/tomabou/items/4e0dd2024a13304d082c

↑こんな記事を読んでいたらとても楽しそうだったので実際にやってみました．

しかし情報が少なく（特にquesta）Lチカさせるだけでも躓くポイントが多かったので最初の環境構築部分をまとめてみました．
少ないとはいえ大半はマクニカさんが丁寧な日本語資料を作っているのでそれを参考にすれば大丈夫です．

# FPGAの購入

秋月電子，digikeyでの購入などが一番簡単です．
今回はTerasicのサイトから購入しました．有名な話ですが個人輸入物の場合16666円以上だと関税を支払わなければいけない場合もあるので注意しましょう．（関税がかかる場合は配達時に配達員に払うことになります）
アカデミックライセンスとして購入したい場合はアカウントのプロファイルセッティングに大学名や学生証の登録が必要です．

今回は一番安くて遅い宅配で注文しましたが爆速で到着．
12/27の午前中に注文　→　学生認証できないからちゃんと登録してねというメールをもらい修正　→　12/27中に発送　→　12/31の午前中に配達（関税0円だったので受け取りのみ）

https://www.terasic.com.tw/cgi-bin/page/archive.pl?Language=English&CategoryNo=218&No=1021#contents

# 開発環境のインストール

開発環境はquartus prime lite edition，シミュレーターはqustaを用います．questaはquartusに付随してインストールできます．

以下サイトからquartus, questaをダウンロード，インストールします．最後にドライバーをインストールするかどうか聞かれるので忘れずにインストールしましょう．

https://www.intel.co.jp/content/www/jp/ja/software/programmable/quartus-prime/questa-edition.html

# questaセットアップ

次にquesta用のライセンスを取得します．インテルアカウントにサインアップ＆サインインしてください．今回自分はFIXEDライセンス（個人利用なら大半がFIXEDになると思う）でしたのでNIC ID（MACアドレス）やらを記入して環境変数パスやらの設定をします．

この辺のことも以下ページにすべて書いてあります．

https://www.macnica.co.jp/business/semiconductor/articles/intel/139706/

# 実機との接続

箱を開けるとFPGAボードとUSB type B　⇔　USB type Aケーブルが入っているハズです．
なにも考えずに接続するとCFMに書き込まれたサンプル回路が動作します．

questaと実機をつないで自分の回路を焼くにはドライバーの設定が必要です．
このこともマクニカさんが丁寧にまとめてくださっています．

https://www.macnica.co.jp/business/semiconductor/articles/intel/130525/

デバイスマネージャーからドライバの更新　→　手動検索　→　ドライバーパスを入力
自分はcドライブ直下にquartusをインストールしたので `C:\intelFPGA_lite\23.1std\quartus\drivers`でサブディレクトリも検索するにチェックを入れたら上手くいきました．

# Lチカ

これもマクニカさんが良い記事をだしています（感謝）

https://www.macnica.co.jp/business/semiconductor/articles/intel/113049/

ただここで使っているボードはDE10liteではないので細かい部分が異なりますが大体一緒なのであとはなんとかなるでしょう．
MyBatisにおける例外処理（PresistenceException）

# やりたいこと
JAX-RS（Jersey）× CDI × MyBatisの構成で開発するRESTful APIにおいて、SQLExceptionに対する例外処理を実施したい。

# 不具合
ExceptionMapperを用いてJAX-RSランタイムにて発生したSQLExceptionをキャッチできるような処理を追加したのですが、SQLExceptiontnがthrowされず処理できません。

# 原因調査
下記IBM様の記事サイトに以下のような記述がありました。

JPA プロバイダー実装は通常、SQL 状態またはエラー・コードがデータベース・サーバー問題またはネットワーク問題を示す可能性のある SQLException を伴う一般 PersistenceException をスローするだけです。（下記サイトから引用）

https://www.ibm.com/docs/ja/wxs/8.6.1?topic=reference-exceptionmapper-interface

今回O/RマッパーはJPAではなくMyBatisを使っていますが、どうやらフレームワークによってはSQLExceptionではなくSQLExceptionをラップしたPersistenceExceptionがスローされるようです。

# 解決策
SQLExceptiponではなく、PersistenceExceptionをキャッチするように書き換えれば処理できそうです。
以下、ExceptionMapperを実装してPersistenceExceptionをキャッチするサンプルコードです。
例)PersistenceExceptionMapper.java
```
package com.example.exception.exceptionmapper;

import java.sql.SQLException;

import jakarta.inject.Inject;
import jakarta.ws.rs.core.MediaType;
import jakarta.ws.rs.core.Response;
import jakarta.ws.rs.ext.ExceptionMapper;
import jakarta.ws.rs.ext.Provider;

import org.apache.ibatis.exceptions.PersistenceException;

import com.example.dto.ExceptionDto;
import com.example.exception.exceptionjson.ExceptionJson;
import com.example.util.Message;

@Provider
public class PersistenceExceptionMapper implements ExceptionMapper<PersistenceException> {

	@Inject
	private ExceptionJson json;

	@Override
	public Response toResponse(PersistenceException exception) {
		
		SQLException e = (SQLException)exception.getCause();
		ExceptionDto dto = new ExceptionDto(); 
		dto.setCode(Message.CODE_500);
		
		if("08001".equals(e.getSQLState())) {
			dto.setMsg(Message.EXCEPTION_4);
			return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
					.entity(json.exceptionJson(dto))
					.type(MediaType.APPLICATION_JSON)
					.build();
		}else {
			dto.setMsg(Message.EXCEPTION_5);
			return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
					.entity(json.exceptionJson(dto))
					.type(MediaType.APPLICATION_JSON)
					.build();
		}
		
	}

}
```
以下のように、PersistenceExceptionからSQLExceptionを取り出すことで、SQLExceptionのステータス等詳細に応じた処理を記述することができます。
```
        //PersistenceExceptionからSQLExceptionを取り出す
        //（exceptionはPersistenceException型）
		SQLException e = (SQLException)exception.getCause();
		ExceptionDto dto = new ExceptionDto(); 
		dto.setCode(Message.CODE_500);

        //SQLExceptionのステータスが08001かそれ以外かで処理分岐
  		if("08001".equals(e.getSQLState())) {
			dto.setMsg(Message.EXCEPTION_4);
			return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
					.entity(json.exceptionJson(dto))
					.type(MediaType.APPLICATION_JSON)
					.build();
		}else {
			dto.setMsg(Message.EXCEPTION_5);
			return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
					.entity(json.exceptionJson(dto))
					.type(MediaType.APPLICATION_JSON)
					.build();
		}
```

# ソースコード
上記サンプルコードはGithubにコミットしています。

https://github.com/SatoHiroto526/JerseySample/tree/master
【Windsurf】Playwrightのコードを自動生成してもらった【Playwright】

# はじめに
AI技術の進展は目覚ましく、もはや何が起こっているのか追いつけなくなってきた。
自分で調べるのが面倒くさいし、調べてもよくわからないことが多いので、Youtube等を垂れ流しながらフムフムとすることが多い。
年末年始にフムフムしていたら、WindsurfというVSCodeベースのAIエディタがリリースされていたので、少し触ってみた。

https://codeium.com/windsurf

# 何をしたか
自動テストをPlaywrightで書きたいが、当方はPlaywrightに詳しくないのでAIに助けてもらった。
ついでに、__自然言語で記述された自動テストシナリオをPlaywrightコード化することの実現可能性__ を少し想像した。

なお、Playwright/Javaである。

# WindsurfにPlaywrightコードを書いてもらう
## 作成したコードの内容
今回は、こんな感じの操作を行うコードを生成してみる。
1. 阿部寛のHPを開く
1. プロフィールページへのハイパーリンクを押下し遷移する

## Pageインスタンスの取得を簡素化
Playwrightを利用する際には、前準備として以下のステップを踏む必要がある。
1. Playwrightインスタンスの生成
1. PlaywrightインスタンスからBrowserインスタンスを取得
1. BrowserインスタンスからContextを取得
1. ContextからPageインスタンスを生成

このステップがなかなか呪文じみており、毎回ググる未来しかない。
そのため、このステップを簡略化するメソッドを作成してもらった。

Ctrl+Iを押すとプロンプトが開くので、ここに自然言語で指示を入力する。
一番最初のPlaywrightインスタンスはTry文で囲みたいため、生成済みのPlaywrightインスタンスを仮引数として指定する形で指示した。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3680589/0a383b96-71a8-6f35-b820-e0bf8cf9b704.png)

すると、以下のようなコードが提案された。
コードとしては正しいが、1行にまとまりすぎていて可読性が低い。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3680589/908583e2-feb7-1177-6503-7cf9503fecea.png)

そのため、即座にAcceptはせず、「複数行に分けて」という追加指示を与えた。
すると、いい感じに分けてくれた。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3680589/66456735-48d2-03ca-2b36-fad6c8e0dcd3.png)

ここまで作成されたメソッドを呼び出し、navigate()すれば阿部寛のHPを開くところまでは実行可能である。

## ハイパーリンクをクリックするメソッドを作成
続いて、ブラウザの画面上で特定の文字列を含むハイパーリンクを探索し、押下するメソッドを作ってもらった。
最初に提案されたコードが完全一致検索になっていたため、「部分一致にして」と追加指示を与えたところ、希望通りのコードが生成された。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3680589/ebab65c0-2882-5e4a-5241-9414eeff4171.png)

ここで面白かったのが、Playwrightオブジェクトを起点としてPageインスタンスを取得するコードが生成されなかったことである。
指示に「仮引数にPageインスタンスを含めて」等とは一切書いていないが、上記で作成したgetPage()メソッドの存在を考慮し、不要と判断したのだろうか。


## 既存メソッドを利用したコードの生成
ここまでくれば、各メソッドを呼び出すだけで「阿部寛のHPを開いてプロフィールページに遷移する」を実装するできる。
しかし、既存のコードを考慮した上でコード生成してくれるのであれば、せっかくなら書いてもらいたい。
ということで、操作内容を指示した。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3680589/f70d557e-ebfe-252c-d7c1-09a65dab68e0.png)

すると、上記で作成したgetPage()やclickByText()を利用したコードをちゃんと生成してくれた。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3680589/2d3e99c3-9a42-497c-efbe-a21a6c719362.png)

## 生成されたコードの実行
AIによって生成されたコードを実行すると、期待通りの動作をしてくれた。

![720p.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3680589/32410a56-4cef-d795-10aa-8d8e8bcbc43d.gif)

# おわりに
利用する生成AIに好みがないならば、完全無料でAIにコーディングしてもらえるのは非常にありがたい。
「有料の生成AIでないと使い物ならない」という意見も見かけたが、QAエンジニアのように「コーディングを生業にしない人」「複雑なコーディングはしない人」としては、無料AIでも十二分に有用に思えた。

また、脈絡のないコードを生成するのではなく、既存のオブジェクトをちゃんと利用したコードを書いてくれる点は、可能性を広げてくれそう。
例えば、PlaywrightにHTML要素を正確に認識させるには、querySelector()を知っている必要がある。
しかし、これを網羅的に記憶するのは大変だし、QAチーム全体に学習を強制するのも辛い。
そのため、今回のclickByText()メソッドのように、クエリがうろ覚えなままでも実装できる仕組みにすると、保守性・可読性が上がりそうだ。
Utility的な感じで頻用メソッドをあらかじめ作っておき、生成AIにはこれらを利用したコードを作成してもらう。
こうすることで、自然言語の指示からPlaywrightコードを自動生成させる仕組みが構築できるかもしれない。
　
　
　
従来の自動テストツールは、収録済み要素の認識にAIを活用したり(オートヒーリング)、アサーションにAIを活用する形が多かった。
いずれも画面が既に存在することを前提としたものであり、「回帰テストの自動化」という枠組みを越えていない。

今回の検証で感じたのは、「うまく使えばまだ存在しない画面の自動テストを実装できるかもしれない」である。
技術書展、コミケの人気ロボット・漫画

コミケに、アニメイトが「ロボットガールズZ」を出展している。
これのすごいところが、タイトルロゴがあの「マジンガーZ」風なのである。
https://www.animatetimes.com/news/img.php?id=1386130176&p=1&n=1

技術書展には、
「多変量解析で愛でる帝国海軍艦娘」が、
秋葉原ロボット部の近くで幟を立てられてました！数学の「多変量解析」が楽しく習得できます！
https://techbookfest.org/product/5845701630099456?productVariantID=5380233408544768

セガサターンで、ロボットゲーム「ガングリフォン」が人気でした！
2025年のコミケで、このガングリフォンの漫画が展示されてました！
このロボゲーの開発元は「グランディア」（RPG)のゲームアーツ社です。
https://www.pixiv.net/artworks/27663377
検証活動におけるフォルダ構成構築のポイント

## 背景

新しい技術を使う際に、SEには「検証活動」が常に付いて回る。
新人時代には、検証活動を行う際にフォルダ構成が雑で、上司によく怒られた。
そんなわけで、私が検証活動を行う際にフォルダ構成構築で心掛けていることをまとめておく。

## 気を付けるべきこと

### 入力データと出力データは全てファイル化して残す

当たり前のようだが、新人の時は意外と忘れがちだった。
残せるものなら実行時のログも残しておくと良い。

---------------------------------------

### 検証1回あたりでフォルダを切る

**もし各検証で共通的に使用するファイルがあったとしても、各回のフォルダにそれぞれ格納しておくべき**だろう。
なぜならそれが検証に使用したファイルの「証拠」となるからだ。

例えば以下のようなフォルダ構成にしておくと良い。

```plaintext
├ 検証1
|    ├ input
|    │   ├ input_file_A
|    │   └ input_file_Common
|    └ output
|        ├ output_file_A
|        └ output_file_B
|    
└ 検証2
    ├ input
    │   ├ input_file_B
    │   └ input_file_Common
    └ output
        ├ output_file_C
        └ output_file_D
```

検証1と検証2ではinput_file_Commonという共通のファイルを使用している。この場合、各検証ごとに格納しておく方が第三者から見てわかりやすいだろう。

---------------------------------------

今後も見つければ追記予定です。
7000円でクジを引く！

７００円のくじを引く、何としても欲しいアイテムが、
出現率５パーセントとする。7000円で１０回、ガチャくじを引ける。

●１　ガチャ率５パーセントなら、何パーセントなのか？
ガチャ１０回で、その出現率５パーセントが当たる確率は、余事象を使って以下の式になる。
1 - (0.95)^10 = 1 - 0.598 = 0.402 = 40.2パーセント

割と手に入る。ガチャ３回、５回、７回だとそれぞれ
1 - (0.95)^3 = 1 - 0.857 = 0.133 = 13パーセント
1 - (0.95)^5 = 1 - 0.773 = 0.227 = 22パーセント
1 - (0.95)^7 = 1 - 0.698 = 0.302 = 30パーセント

７回のくじ、つまり４９００円だと３０パーセントのゲット率だが、
１０回くじを引くと、４０％まで上がるので、どうしても欲しいアイテムは７０００円投資するのが妥当である。

くじの１等がガチャ率2パーセントだと仮定し、14000円投資すると、
1 - (0.95)^20 = 1 - 0.358 = 0.642 = 64.2パーセント

14000円で、ゲット率64パーセントなのである！
Strategyパターン

# はじめに
前回に引き続き,デザインパターンを扱っていきます.

今回は,Strategyパターンに焦点を当てていきます.

GoFデザインパターンのオブジェクトの振る舞いに関するものとなります.

# Strategyパターンとは?
Strategyパターンは,アルゴリズムを表すインタフェースを定義して,
このインタフェースから派生したクラスを作成し,
アルゴリズムを実行時には作成したクラスの中から選んで実行することができる
デザインパターンです.

これにより,たくさんのアルゴリズムが再利用できますし,変更に対して柔軟に対応することができます.

基本的な構成は以下のようになります.

ここで,Strategyはアルゴリズムを実装する際の共通のインタフェースです.

Contextは呼び出し元がどのアルゴリズムを使用するか決定する際に呼び出すクラスです.

![スクリーンショット 2025-01-01 180143.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3586226/699ca47e-cd49-260e-67dc-78374411588b.png)


# 具体例
ある数値を並び替えて出力する場合を考えてみます.

このとき，「並び替える」という行動がアルゴリズムを表すインタフェースとして定義できます.

そして,並び替える手段は,昇順か降順の2つだけ考えます.
(もちろん,もっと複雑な場合を考えるのが通常です)

すると,以下のような構造にすべきだと考えられます.

![スクリーンショット 2025-01-01 180706.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3586226/56ae77aa-30b7-8156-1ae3-76545d657c87.png)

この構造を参考にしてソースコードを作ったものが以下となります.

```java:SortStrategy.java
import java.util.List;

public interface SortStrategy {
    void sort(List<Integer> numbers);
}
```

```java:AscendingSort.java
import java.util.Collections;
import java.util.List;

public class AscendingSort implements SortStrategy {
    @Override
    public void sort(List<Integer> numbers) {
        Collections.sort(numbers);
    }
}

```

```java:DescendingSort.java
import java.util.Collections;
import java.util.List;

public class DescendingSort implements SortStrategy {
    @Override
    public void sort(List<Integer> numbers) {
        Collections.sort(numbers, Collections.reverseOrder());
    }
}
```

```java:Sorter.java
import java.util.List;

public class Sorter {
    private SortStrategy strategy;

    public void setStrategy(SortStrategy strategy) {
        this.strategy = strategy;
    }

    public void sort(List<Integer> numbers) {
        if (strategy != null) {
            strategy.sort(numbers);
        } else {
            throw new IllegalStateException("Sort strategy is not set.");
        }
    }
}
```

```java:Main.java
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class Main {
    public static void main(String[] args) {
        List<Integer> numbers = new ArrayList<>(Arrays.asList(5, 2, 8, 1, 3));

            
        Sorter sorter = new Sorter();

        // 昇順ソート
        sorter.setStrategy(new AscendingSort());
        System.out.println("Before sorting (ascending): " + numbers);
        sorter.sort(numbers);
        System.out.println("After sorting (ascending): " + numbers);

        // 降順ソート
        sorter.setStrategy(new DescendingSort());
        sorter.sort(numbers);
        System.out.println("After sorting (descending): " + numbers);
    }
}
```

```:出力例
Before sorting (ascending): [5, 2, 8, 1, 3]
After sorting (ascending): [1, 2, 3, 5, 8]
After sorting (descending): [8, 5, 3, 2, 1]
```

このようにアルゴリズム部分が共通のインタフェースを持つようにしたことで,
数値を別の方法で並び替えたいとなったときに,SortStrategyをインタフェースとして
新たにファイルを追加するだけで新たな並び替え方法を追加することができます.

さらに,ソースコードを修正する際にもどこを修正すればよいかがわかりやすいです.

Strategyパターンにより要件の変更や追加に対して強い設計になりました.

# 最後に
Strategyパターンを使うことによって,コードの可読性やメンテナンスを容易にすることができます.

Strategyパターンは使いやすそうなデザインパターンだと感じたので,
機会があればぜひ使っていきたいです.
Crystalでは delete_prefix, delete_suffix は lchop と rchop

タイトルの通りです。

Rubyには、`delete_prefix` `delete_suffix` という便利なメソッドがあります。これは Ruby 2.5 の時点で@sonotsさんによって追加されたメソッドで、正規表現が苦手な自分は愛用していました。

https://sonots.livedoor.blog/archives/52060810.html

> Ruby 2.5 の String クラスに文字列から接頭辞や接尾辞を削除する delete_prefix と delete_suffix メソッドを追加しました。
>
>```rb
>'foobar'.delete_prefix('foo') #=> 'bar'
>'foobar'.delete_suffix('bar') #=> 'foo'
>```
>
>いままでは、接頭辞の削除をするのに
>
>```rb
>'foobar'.sub(/^foo/, '') #=> 'bar'
>```
>
>のようにしている人が多かったと思いますが、このコードは正規表現を使うことになるので遅いです。高速に削除するには
>
>```
>'foobar'[3..-1] if 'foobar'.start_with?('foo')
>```
>のようにする必要があったのですが、これは面倒ですね。これを >String#delete_prefix を呼ぶだけで行うことができるようになりました。

これらのメソッドが Crystal では見当たらなかったのですが、別名で存在することがわかりました。それが、`lchop` と `rchop` です。

```crystal
"hello".lchop('h')   # => "ello"
"hello".lchop('g')   # => "hello"
"hello".lchop("hel") # => "lo"
"hello".lchop("eh")  # => "hello"
```

```crystal
"string".rchop('g')   # => "strin"
"string".rchop('x')   # => "string"
"string".rchop("ing") # => "str"
"string".rchop("inx") # => "string"
```

`lchop`, `rchop` は引数がない場合最初/最後の文字が削除されるようです。
`lchop?`, `rchop?` は chop されなかった場合はnilを返します。

CrystalとRubyは多くの点で似通っていますが、このように異なる名前がついていることも多いので注意が必要ですね。

この記事は以上です。
ハミング距離

>二つの符合語が異なるビット位置の数は、Richard Hammingにちなんで`ハミング距離(Hamming distance)`と呼ばれている。もし二つの符号語がハミング距離dだけ離れていれば、一方を他方にするためには、d個の1ビット誤りが必要であるということを意味する。
p194

### 符号語とは　データと検査ビットを含んだビット列
>ブロック全体の長さをn（すなわちn=m+r)としよう。これを(n,m)符号と記述する。`データと検査ビットを含むnビットの情報`をnビットの`符号語(codeword)`と呼ぶ。

### 二つの符合語が異なるビット位置の数でハミング距離を数える
>誤りがどのように扱われるか理解するためには、まず誤りが本当はどのようなものか綿密に見る必要がある。送信または受信されるかもしれない二つの符号語、例えば10001001と10110001が与えられると、何個の対応するビットが異なっているか決めることができる。この場合には3ビット異なっている。何ビット異なっているか知るためには二つの符号語の排他的論理和をとり、その結果に含まれる1のビットの数を数えれば良い。

https://bookplus.nikkei.com/atcl/catalog/23/03/16/00728/
2025年頑張りたいこと

# 筆者について

- もうすぐ卒業の高校３年生（一気に情報が減りましたね、ちょっと装飾考えておきます。）

# 本編

2024年12月のアドベントカレンダーの最後に、2024年の振り返りと称した懺悔記事を書きました。

https://qiita.com/0_terarin_0/items/a06ee572c9d66601147c

これを踏まえて、今年は全体的に自分のプログラムに取り組み姿勢を考えてみたいと思います。

## 1. 今年チャレンジすること/普段の習慣変

### 1-1.毎日必ず本を読む

最近SQLの勉強をしてて気づいたことがあるのですが、自分自身思ったよりも文章を読む能力がなかったりします。あれ、これってそういえば、、、と思ったことはすぐに戻ったりしたりして読んだりしているのですが、根本的に書いてあることが意味わからなかったり。やっぱ日本人として日本語が読めないのは言語道断だと思いますので、今後は積極的に本を読んでいきたいと思っています。

### 1-2.（できる限り）毎日Qiita・Zennなどの記事を書いていく

この記事、ほとんど同じものがZennにもQiitaにも上がっているのですが、実は僕今までQiitaにしか記事を投稿したことがありませんでした。しかし、QiitaにはQiitaの良さがあり、ZennにはZennの良さがあるとここ最近思っており、上げる記事の内容は別にはなりますが、毎日学習した内容やネタなどをアドベントカレンダーの時期に関わらず毎日上げていきたいと思います。

### 1-3. 様々な資格にチャレンジ！

今回いろいろな経験をさせてもらう上で改めて、資格って大事だなと思いました。それは、資格を持つこと自体に意味をなすのではなく、資格を持つまでの努力に意味があると思ったかっらです。そんなの当たり前やろ！って感じなのですが、今まで気づけてなかった自分がいるような気も、、、。ということで、今年は様々な資格のゲットにチャレンジしていきたいと思います。

### 1-4. いろいろな人との交流

これは本当に大事だと思います。自分が今までこのプログラミングの域で関わったことのある人って限りなく少なくて、このおかげですごいガラパゴス的な考え方が自分に根付いてしまっている気がします。今年こそは、様々な人との交流を通してこれを徐々に直していきつつ、自分の良さも発揮していきたいなと思っている次第です。

## 2. 今年チャレンジすること/技術編

### 2-1. Python

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/583428/ed9dab71-0ebb-eade-376a-6a79dd0e015c.png)

理由は単純です。今年が巳年だからです。というのはさておき、今まで触っていたけどSwiftとかFlutterとかとごっちゃになっていて改めて知識の整理をすることが大事だなって思ったのと、自分自身のPythonがそこそこの知識量からするともうちょっと頑張ったそれなりにy自由に扱えそうだなってことで頑張っていきたいと思います。（ラムダ式とかですかね）

### 2-2. Rust

![rustacean-orig-noshadow.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/583428/6b7153c2-29f5-a487-946c-781f020e08dd.png)

去年の最後の記事でも触れたのですが、Rustで書かれたものに去年は触れていたので、今年はそちらを自分でもかけるようになりたいなと思います。ちょっと難しそうですけど、この出会いをチャンスにしていきたいと思います。

### 2-3. 仮想化

![Proxmox Virtual Environment 8.2 - Cluster Summary](https://www.proxmox.com/images/proxmox/screenshots/Proxmox-VE-8-2-Cluster-Summary.png)

出典：Proxmox Virtual Environment 8.2 - Cluster Summary (https://www.proxmox.com/images/proxmox/screenshots/Proxmox-VE-8-2-Cluster-Summary.png)

ここで急に話題変わりまして仮想化ですね。なんだかんだいろんなマシンを触るのがすきなのですが、管理の面的にもお金の都合的にもずっと機械を買い続けるのには流石に無理がありますので、仮想化という素晴らしい技術を通して様々なことに挑戦してみたいなと思っている次第でございます。

## 最後に

今年も技術力向上に努めていきたいと思っていますので、に応援の方、よろしくお願いします。