OmniAICreator/Qiita-1.07M huggingface dataset:
2022～2024年のAIの流れについて

以下にここ3年のAIの流れ、トレンドについてまとめます。

2022年のAI
----------
画像生成技術の台頭
●生成的敵対ネットワーク（GANs）、生成的事前訓練（GPT）などの技術
●Midjourney、StableDifussion
　ウェブサイトでテキストを入力するだけで、無料で画像が生成することが可能
　生成した画像は基本的には商用・非商用を問わず、自由に利用できるというライセンス
●自然言語処理（NLP）の進化：NLP技術は急速に進化し、より自然な会話型AIや翻訳、要約などの応用増加。
　特に、GPT-3.5のような大規模な言語モデルが注目

2023年のAI
----------
CHATGPTモデルの対応
●GPT-4モデルをベースとして登場し、より自然な会話や高度な生成が可能
　※ChatGPTは、GPTモデルを基にした会話型AI
　※GPT（Generative Pre-trained Transformer）モデルは、
 　OpenAIによって開発された自然言語処理（NLP）のためのAIモデル
●AIによる医療の進化: AIが診断支援や治療計画の最適化に役立つようになり、
　医療分野での応用が広がる
●DALL-E 3が2023年8月登場（OpenAI）
●2023年5月からDALLをCHATGPT、Copilot活用可能

2024年のAI
----------
生成AIの進化
●自動テキスト生成技術のほぼ実用化
　無料版でもそれなりにOK
●Copilotの普及
　（MicrosoftはOpenAIと協力体制であり、実はCopilotの中で動いているAIはOpenAI製）
 
[Copilotに比べて、ChatGPTのほうが、エンジンのGPTはグレードが高い。
・下記は有料版の比較
　GPT-4TurboはGPT-4Turbo
　ChatGPTPlusはGPT-4Turbo・GPT-4o・GPT-4omini

・ExcelやWordなどのOffice製品との連携に関しては、Copilotの方が圧倒的に簡単
　画像生成には、どちらもOpenAIのDALL•E3（ダリ・スリー）というAIを利用
　入力トークン数に関しては、圧倒的にChatGPTが上であるため、
　多くのテキストを読み込ませたい場合はChatGPTを使用する必要あり。

・CHATGPT
　無料版、有料版の違いは内部のエンジン、反応速度（優先アクセス）、
　入力データ数
　無料版CHATGPTは画像生成不可

・COPILOT
　無料版、有料版の違いは内部のエンジン、反応速度（優先アクセス）、
　入力データ数、生成画像数、Officeアプリでの利用有無
 ]

・マルチモーダル技術の向上
　AIが複数の異なる種類のデータ（例えば、画像、音声、テキストなど）を
　同時に処理・理解する技術のこと
　ユーザーが写真をアップロードし、その写真に関連するテキストを入力すると、
　その画像とテキストを組み合わせて理解し、適切な情報を提供することができる
　また、音声認識と画像認識を組み合わせることで、ユーザーが「この写真の説明を教えて」と
　言ったときに、AIは画像を認識し、その説明を提供することができる

・なくならないハルシネーション
　デルの特質　そもそもの学習データの質が原因
　
・生成AIは『過度な期待』のピーク期の下り方向にある。
『想定以上にコストがかかっている』といった幻滅的な事象も発生。
 GPUやサーバのコスト、維持管理。冷却水の問題。
 LLM（largelanguagemodel)のオープンソース化、小規模化に向かっている事象もあり。


2025年のAI
----------
  2025年はAI新規開発の中断や既存AIの流用に向かう可能性もあり。
OSSチャンスを掴みキャリアアップに成功したエンジニアがOSS活動してみたい人の背中を押してみる🫷🏻

この記事は [ex-crowdworks Advent Calendar 2024](https://qiita.com/advent-calendar/2024/ex-cw)の4日目の記事です。

# はじめに
今年、株式会社クラウドワークスを退職した@nisyuuです。黄色と黒を勇気のしるしに戦っています。🟡⚫️🏪🥊 🥤 💼🗺️🥊 🧑🏻‍💼🇯🇵🧑🏻‍💼
エンジニアとしてクラウドワークステック（旧クラウドテック）というフリーランスと企業をマッチングするエージェントサービスを開発していました。

この記事を開いていただいているということは、OSSに興味があるということですね :relaxed:
ようこそOSSの世界へ。

クラウドワークスは**OSSチャンス**がいくつもあり、私もチャンスを掴みOSSの世界を開くことができました。
過去のチャンスについてはこちらをご覧ください。

https://qiita.com/nisyuu/items/71dd6007422cead27204

https://qiita.com/nisyuu/items/722149c35a228d7d6164

こんなチャンスもありました

https://qiita.com/nisyuu/items/b4219f9c7da9c379771f

OSSには興味があるけど、どこから手をつけていいか分からないし難しそうと感じている方は多くいると思います。
本記事はOSSに貢献してみたい人への背中を一押しできたらと考えています。

# OSSとは
OSS(Open Source Software)は、無償でソースコードを公開、再使用、改変、再配布することが可能なソフトウェアのことです。単にオープンソースと呼ばれることもあります。
RubyやPython、LinuxもOSSであり世の中のほぼ全てのシステムにはOSSが使われています。OSSがあるからこそ自由に開発を行い新しいものを創造できます。

# OSS活動をすることのメリット
OSSに貢献することで得られるメリットはこういったものがあります。

- スキルアップ
- ポートフォリオになる
- どこかの誰かを救う
- 英語を学べる

OSS活動することはスキルアップにつながります。仕組みを考えコードについて理解し実装に落とし込むことは、小さな1コミットでも、人生においては偉大な1コミットです。

コミットが採用されれば、実績になりキャリアアップのために使うこともできます。
そして、世界のどこかで困っていた人、今後困る人を助けることにもなります。

OSSのIssueやPull Requestでは英語で会話することが多いため、英語の勉強にもなります。

# OSS活動の始め方
OSSへの貢献の仕方は様々で、バグの修正や新機能の提案、ドキュメントの更新もOSS活動の一環です。必ずしも難しい実装をコミットすることだけがOSS活動ではありません。

まずはどのOSSに対して貢献するかですが、仕事や個人開発などで使っているオープンソースのライブラリが身近で貢献しやすいと思います。
よく使用しているライブラリであれば、バグに気づいたりドキュメントの記載が不十分だと思うことがあるでしょう。そういった時にOSSチャンスは訪れます。

もしリポジトリにOSS貢献へのルールを定めている場合は、先に読んでおきルールに従いながら活動しましょう。

## Issueを作る
OSSに対して何か問題や課題を発見できたら、まずはIssue一覧を確認してみてください。
まだIssueになっていない問題・課題であれば、Issueを立ててみてください。

GitHubのドキュメントですが、Issueついてはこちらをご覧ください。

https://docs.github.com/ja/issues/tracking-your-work-with-issues/creating-an-issue

## リポジトリのフォーク
作成したコミットは直接OSSのリポジトリにpushするのではなく、フォークしたものに対してpushします。

https://docs.github.com/ja/get-started/quickstart/fork-a-repo

## プルリクエストを作る
プルリクエストはフォークしたリポジトリから、オリジナルのリポジトリに対してブランチを向けて作成します。

https://docs.github.com/ja/pull-requests/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/creating-a-pull-request

プルリクエストを作ってから、正式リリースされるまでに時間がかかることもあるかもしれません。
気長に待ちましょう。

# コントリビュートするだけがOSS活動でない
コントリビュートも立派なOSS活動ですが、自らOSSを立ち上げメンテナーになることも立派なOSS貢献です。
まだどこにもリポジトリ化されていない良いアイデアがあれば、ぜひオープンソースにして公開してみてください。

# OSS活動のコツ
最後にOSS活動のコツを挙げて締めくくろうと思います。

- 身近なオープンソースに貢献してみる
- 待ちの精神
- 思い切り

それでは、良いOSSチャンスに巡り会えることを🧎🏻

アーメソ
Laravelの基礎：Rails開発者向けにフレームワークの概要を理解する

### はじめに
Ruby on Rails（以下Rails）に慣れ親しんだ開発者にとって、Laravelは新しい挑戦のように感じるかもしれません。しかし、RailsとLaravelはどちらも「開発者体験を重視したフレームワーク」という共通点を持っており、基礎を押さえれば違いを楽しみながら学べるはずです。この記事では、Laravelの概要をRailsと比較しながら解説します。

## 1. Laravelとは？
Laravelは、PHPで構築されたモダンなフレームワークです。
Railsと同じく「使いやすさ」と「効率的な開発」を追求しています。
特に以下のような特徴があります。

 - **MVCアーキテクチャ**：Railsと同様に、モデル、ビュー、コントローラを分離した設計

 - **Eloquent ORM**：RailsのActive Recordに似た、データベースとやり取りするための強力なORM

 - **豊富な公式ドキュメント**：Railsと同じく、Laravelも公式ドキュメントが充実しています。

[公式ドキュメントはこちら](https://laravel.com/docs/11.x)

## 2. LaravelとRailsの共通点
Railsを使ったことがある方にとって、Laravelの次のポイントは馴染みやすいでしょう。

### (1) フォルダ構成
Laravelのフォルダ構成はRailsと似たような構造を持っています。

app/：アプリケーションのメインコード（MVCの主要ファイルが含まれる）。
routes/：Railsのconfig/routes.rbに相当するファイル。
resources/views：Railsのapp/viewsに相当。

### (2) Artisanコマンド
Railsのrailsコマンドに相当するのが、Laravelのartisanコマンドです。たとえば、新しいコントローラを作成する際は以下のように実行します：

```php:bash
php artisan make:controller ExampleController
```

## 3. Laravelの特有の特徴
LaravelにはRailsにない独自の便利機能も多数存在します。
いくつか代表的なものを紹介します。

### (1) Bladeテンプレートエンジン
Laravelには、Bladeという軽量なテンプレートエンジンが標準で組み込まれています。
たとえば、条件分岐やループを簡潔に記述できます。

```php:blade
@if ($user)
    <p>こんにちは,{{ $user->name }}さん！</p>
@endif
```

### (2) マイグレーションの簡易性
Laravelでは、マイグレーションファイルに簡単に変更を記述できます。
以下はusersテーブルを作成する例です。

```php:migration
Schema::create('users', function (Blueprint $table) {
    $table->id();
    $table->string('name');
    $table->string('email')->unique();
    $table->timestamps();
});
```

## 4. Rails開発者向けの学習ポイント

### (1) PHPの基礎を押さえる
LaravelはPHPベースのフレームワークであるため、PHPの基本文法を知っておくとスムーズに学べます。

### (2) Composerの利用
Laravelでは、ComposerというPHPのパッケージ管理ツールを使用します。
RailsのBundlerに相当します。

```php:bash
composer require laravel/ui
```

## 5. Laravelを学ぶためのリソース
公式ドキュメント：[Laravel Documentation](https://laravel.com/docs/11.x)
API：[Laravel API](https://laravel.com/api/11.x/index.html)
PHP公式ドキュメント：[PHP Documentation](https://www.php.net/docs.php)

## まとめ
Rails開発者にとって、Laravelは新しい視点で学びを深める絶好のチャンスです。この記事で紹介した基礎知識をもとに、公式ドキュメントを参照しながら実際に手を動かしてみてください。Railsの経験がある方なら、Laravelもすぐに習得できるはずです。

Laravelの世界に飛び込んで、新たな開発体験を楽しみましょう！
最近のOpenBSD（後編）

[最近のOpenBSD（前編）](https://qiita.com/omasanori/items/4eda78987f4fbd42967c)に引き続き、2023年の春にリリースされたOpenBSD 7.3から2024年の秋にリリースされたOpenBSD 7.6までの変更を振り返り、私が特に強く関心を寄せているものを紹介します。なお、サブプロジェクトやPortsの変更は割愛します。

## OpenBSD 7.3（2023年4月）

2023年4月10日にリリースされたOpenBSD 7.3はApple M1上でのサスペンドとレジュームをサポートするようになった他、RockchipのRK3566やRK3568上で動作するようになりました。引き続き、OpenBSD/arm64の開発に勢いを感じます。また、Intelの無線LANチップのデバイスドライバの安定性が改善されたのもうれしいところです。

また、セキュリティの向上を目的に[pinsyscall(2)](https://man.openbsd.org/OpenBSD-7.3/pinsyscall.2)と[mimmutable(2)](https://man.openbsd.org/OpenBSD-7.3/mimmutable.2)が追加されました。

## OpenBSD 7.4（2023年10月）

2023年10月16日にリリースされたOpenBSD 7.4はTSOやLROといったパケット処理の一部をNICにオフロードする機能が実装され始め、将来的なスケーラビリティーの向上を見据えて[pfsync(4)](https://man.openbsd.org/pfsync.4)が書き直されるなど、ネットワーク関連の向上が目覚ましいものでした。

また、CFIを見据えてIBT（amd64）やBTI（arm64）、SSBS（arm64）、PAC（arm64）といった拡張への対応が進められました。

## OpenBSD 7.5（2024年4月）

2024年4月5日にリリースされたOpenBSD 7.5ではRockchipやAllwinnerを中心にarm64対応が進みました。また、QualcommのWi-Fi 6に対応したデバイスドライバーも追加されました。

[pinsyscall(2)](https://man.openbsd.org/OpenBSD-7.4/pinsyscall.2)は[pinsyscalls(2)](https://man.openbsd.org/OpenBSD-7.5/pinsyscalls.2)に改名され、引数の型と個数にも変更が加えられました。

## OpenBSD 7.6（2024年10月）

2024年10月8日にリリースされたOpenBSD 7.6ではarm64にQualcomm Snapdragon X Eliteの初期サポートが導入されました。ただし、このではOpenBSD開発者向けの段階と認識するべきでしょう。

他にも様々なデバイスドライバーが追加されましたが、中でもAMD PSPに対応するための[psp(4)](https://man.openbsd.org/psp.4)はSEVとの将来的な連携強化も期待できるものでした。
【PostgreSQL】Windows版のShared_buffersの最大512MB制限撤廃について

# はじめに
これは、[PostgreSQL Advent Calendar 2024](https://qiita.com/advent-calendar/2024/postgresql)の1日目の記事となります。
この記事は 2024/04/30 に投稿したのですが、12/01時点で、いいね 0 ストック 0 
1766 views とさびしい限りです。
有用な記事だと思っているので、トップバッターを務めさせて頂きます。

以前サーバーリプレース作業(Windows Server 2008R2 + Oracle 11g → Windows Server 2016 + PostgreSQL 9.6)に移行しました。

https://qiita.com/yaju/items/7cf5ab6987ecd1d83b13

その際 `Shared_buffers`の設定値としてサーバーの搭載メモリ(16MB)の25％程度が目安のなか、Windows版に関しては公式ドキュメントに従い、最大の512MBに設定しました。
>Windowsでもshared_buffersに対し大きな値を設定することはあまり有効でありません。 設定値を比較的小さく保ち、代わりにオペレーティングシステムのキャッシュを使用することが、より良い結果になるでしょう。 Windowsシステムでの有効なshared_buffersの範囲は一般的に64MBから512MBです。
https://www.postgresql.jp/document/9.6/html/runtime-config-resource.html

その後に PostgreSQL 9.6 から PostgreSQL 12 にアップグレードした際にも、そのまま設定を引き継ぎました。

# 問題
## 現象
先日、更新SQLを実行した際に、「Exception while reading from stream」エラーが発生し、トランザクションによりロールバックされ更新されない問題が発生しました。
これ自体は、接続文字列にCommandTimeout=600 (10分)が指定されていたことが原因でした。1800 (30分)に設定を変更したことで、最後まで更新されることが出来ました。

社内DBでは数分以内に終わる更新処理が、ユーザーのDB上では20分以上かかってしまうことが問題であり、ユーザーのDBを社内に構築してインデックスや設定見直し等のチューニングの調査を同僚に依頼しました。

## 調査
ユーザーのDB上は複数のスキーマが構築されています。問題となったスキーマ自体のデータ量は少なく、他1つのスキーマが巨大になっている状態です。

同僚の報告結果によるとインデックスの追加も少しは効果がありましたが、一番効果が大きかったのは、`Shared_buffers`の設定値を大きくしたことでした。なんと 20分 以上かかっていた更新処理が 2分 になったとのこと。

:::note warn
他にも統計情報など何かが影響している可能性があることは否定できません。
:::

筆者は、`Shared_buffers`の設定値が 512MB が最大と公式資料の値を信じていたので、これは意外な報告でした。

# 本題
>Windowsでもshared_buffersに対し大きな値を設定することはあまり有効でありません。 設定値を比較的小さく保ち、代わりにオペレーティングシステムのキャッシュを使用することが、より良い結果になるでしょう。 Windowsシステムでの有効なshared_buffersの範囲は一般的に64MBから512MBです。
https://www.postgresql.jp/document/9.6/html/runtime-config-resource.html

調べてみると、この文言は PostgreSQL 10以降の公式ドキュメントからは削除されていたのです。しかし、「[EDB Postgres ドキュメントのshared_buffers](https://www.enterprisedb.com/docs/epas/latest/database_administration/01_configuration_parameters/03_configuration_parameters_by_functionality/01_top_performance_related_parameters/01_shared_buffers/)」ページには最新版であっても文言が残ったままです。

この文言が消えた理由の根拠があればと思って、調べてみるとPostgreSQLの性能関連パラメータの推奨値を提示してくれる「[PGTune](https://pgtune.leopard.in.ua/)」というツールの discussions に辿り着きました。

>OS として Windows を選択した場合、Shared_buffers の値は常に 512Mb になります。
>PG のバージョン 9.6 以降、このルールは無効になり (PG の専門家に確認済み)、RAM の 1/4 のルールが適用されるべきだと思います。
https://github.com/le0pard/pgtune/discussions/50

どうやら下記のPostgreSQLのメーリングリストのやり取りの中で、PostgreSQL 10以降のドキュメントから文言が削除されるに至ったようです。

>2016-09-20 富士通株式会社 綱川 貴之さんが発信
pgbench の読み取り専用モードと読み取り/書き込みモードを実行しましたが、shared_buffers を増やしても明らかなパフォーマンスの低下は見られませんでした。

https://www.postgresql.org/message-id/flat/0A3221C70F24FB45833433255569204D1F5EE995@G01JPEXMBYT05

## 推奨値
現在では、PGTuneのWindows版 Shared_buffers の推奨値は、RAM の 1/4 のルールが適用されるように修正されています。

https://pgtune.leopard.in.ua/

|搭載メモリ|推奨値|
|:--|:--|
|2GB|512MB|
|4GB|1GB|
|8GB|2GB|
|16GB|4GB|

:::note warn
Shared_buffers が 12.5 % から 25% に増加すると、読み取り/書き込みパフォーマンスが低下するようです。というメーリングリストのやり取りもありますが、それは別のトピックであり、他の OS にも当てはまります。
:::

# 最後に
今回、トラブルがなかったら気が付かなったし、もし筆者がトラブル担当をしていたら、Shared_buffers 512MB制限のままで設定を変更することもしなかった可能性が高いです。

この記事を見て、Windows版の Shared_buffers の設定を見直してみてはいかがでしょうか。
1日目: RadixHeapを実装する

[競プロ用ライブラリを作る Advent Calendar 2024](https://qiita.com/advent-calendar/2024/yukkku-ribitol)の1日目です.

https://qiita.com/advent-calendar/2024/yukkku-ribitol

# RadixHeapって?

- 非負整数型のような型 (後述) である
- 最後に取り出した値より小さい値を入れることはできない

という条件がある代わりに速めな優先度付きキューです.

## 非負整数型のような型って?

上で書いた「非負整数型のような型」の要件を書きます.
全順序がある型$T$をRadixHeapに乗せるには次の条件を満たす関数$\def\dfunc{\operatorname{d}}\dfunc: T \times T \rightarrow \Bbb{N} \cup \set{0}$が存在して, ある程度高速に計算できる必要があります.

- $\dfunc$が返す値は小さめの上限$M$を持つ (計算量は$M$に比例します)
- $\forall x, y \in T [x = y \iff \dfunc(x, y) = 0]$
- $\forall x, y, z \in T [x < y < z \implies \dfunc(x, z) \le \dfunc(y, z)]$
- $\forall x, y, z \in T [\dfunc(x, y) < \dfunc(x, z) \implies \dfunc(x, z) = \dfunc(y, z)]$

非負整数型の場合は$\dfunc(x,y)=\lfloor\log_2((x\oplus y)+1)\rfloor$とすると条件を満たし, Rustでは`T::BITS - (x ^ y).leading_zeros()`のようにして計算することができます. このとき$M$の値は`T::BITS`になります.

# 仕組み

型`T`のRadixHeapは長さ`M + 1`の「`T`の配列」の配列`buckets: [Vec<T>; M + 1]`と最後に取り出した値`last: T`を持ちます.
前述の通り`last`よりも小さい値を新たにRadixHeapに入れることは出来ません.

要素を`d(last, x)`の値に応じて`bucket`で分類して管理するイメージです. `buckets[i]`の要素`x`について`d(last, x) == i`が成り立ちます.

```rust
// サンプルコードではu32型の場合を書く
type T = u32;
fn d(x: T, y: T) {
    T::BITS - (x ^ y).leading_zeros()
}
// 関数dが返す値の最大値は今回は32
const M: usize = 32;

struct SampleRadixHeap {
    buckets: [Vec<T>; M + 1],
    last: T,
}
```

## `new` (初期化)

`buckets`には空の配列を詰めて, `last`には型`T`の最小値を入れておきます.

```rust
impl SampleRadixHeap {
    fn new() -> Self {
        Self {
            buckets: std::array::from_fn(|_| vec![]),
            last: T::MIN,
        }
    }
}

```

## `push`

要素`v`をRadixHeapに入れるときは`d(last, v)`を計算し, その値で`buckets`の中のどの配列に入れるか分類します.

```rust
impl SampleRadixHeap {
    fn push(&mut self, v: T) {
        assert!(v >= self.last);
        self.buckets[d(self.last, v)].push(v);
    }
}
```

## `pop`

まず, `bucket`の中の配列で, 要素を持っている最初のものを探して取り出し, 代わりに空の配列を入れておきます.
取り出した配列は`rak`と呼ぶことにします

`rak`中から最小値を見つけて`last`をその値で置き換え, その`last`の値に基づいて`rak`の要素をRadixHeapに入れ直します.

最後に, `bucket[0]`は必ず要素を持っているので, その値を取り出して返り値にします.

```rs
impl SampleRadixHeap {
    fn pop(&mut self) -> T {
        // 要素を持っている最初の配列を探して, 取り出す
        let rak = {
            let lak = self.buckets.iter_mut().find(|v| v.len() > 0).unwrap();
            std::mem::take(lak)
        };

        // 最小値を見つける
        self.last = *rak.iter().min().unwrap();

        // rakの要素を詰め直す
        for v in rak {
            self.buckets[d(self.last, v)].push(v);
        }

        // `buckets[0]`に要素が入ってるので, 取り出して返す
        return self.buckets[0].pop().unwrap();
    }
}

```

# 実装

- [`radixheap.rs`](https://github.com/Yukkku/ribitol/blob/main/src/radixheap.rs)

実装では`d`を`radix_dist`に, `M`を`MAX_DIST`と名前を変えています.
抽象化もばっちりしました.

# まとめ

いかがでしたか?
明日はこのRadixHeapを使ってDijkstra法を実装します.
[Git] diff コマンドの復習

こんにちは！

先日、久々に `git diff` コマンドを使ったので復習。

# git diffの概要

git diffは変更内容を確認するために使います。
元ネタは[こちら](https://git-scm.com/docs/git-diff)

1. 基本的な使い方
```
git diff            # 作業ディレクトリとステージング領域の差分
git diff --cached   # ステージング領域と最後のコミットの差分
git diff HEAD       # 作業ディレクトリと最後のコミットの差分
```

例えば、手元の App.tsx を修正して `git diff` を実行したところ、以下の出力が得られました。
```
% git diff
diff --git a/src/App.tsx b/src/App.tsx  # aは変更前、bは変更後
index abaedd2..a9559d3 100644
--- a/src/App.tsx  # 削除された部分
+++ b/src/App.tsx  # 追加された部分
@@ -20,7 +20,7 @@ import {
   format,
   startOfWeek,
   endOfWeek,
-  // startOfMonth,   # ここが削除された
+  startOfMonth,      # ここが追加された
   // endOfMonth,
 } from 'date-fns';
 import { v4 as uuidv4 } from 'uuid';
```

VSCodeなどでも差分は確認できますが、コマンドラインでも確認できるようにしておくと、役立つことがあります。

# 主要なオプション

私は基本的な使い方をすることが多いですが、せっかくなのでオプションを調べました。

1. 出力形式の制御
- `--stat`: 変更の統計情報を表示
- `-p`: パッチ形式で表示（デフォルト）
- `--name-only`: 変更されたファイル名のみ表示
- `--name-status`: ファイル名と変更種類（追加/削除/変更）を表示

2. 差分の検出設定
- `-B`: 空行の変更を無視
- `-w`: すべての空白の変更を無視
- `-b`: 行末の空白の変更を無視
- `--word-diff`: 単語単位での差分を表示

3. ファイルの変更検出
- `-M`: リネームされたファイルを検出
- `-C`: コピーされたファイルを検出
- `--find-copies-harder`: より詳細なコピー検出

# よく使うユースケース

以下は、私がよく使うケースです。

1. コミット間の差分確認
```bash
git diff commit1 commit2  # 特定の2つのコミット間の差分
git diff HEAD^           # 最新のコミットと1つ前のコミットの差分
```

2. ブランチ間の差分確認
```bash
git diff branch1 branch2  # 2つのブランチの差分
git diff main..feature    # mainブランチとfeatureブランチの差分
```

3. 特定のファイル/ディレクトリの差分確認
```bash
git diff -- path/to/file  # 特定のファイルの差分
git diff -- directory/    # 特定のディレクトリ内の差分
```

# まとめ
git diff コマンドを使えるようにしておくと、コミット間の差分やブランチ間の差分を素早く確認することができます。
様々なツールでも同様のことができますが、コマンドラインでも使えるようにすることをおすすめします！
Kafkaのトピック作成

Kafkaのトピックを作成する方法はいくつかありますが、ここではコマンドラインツールを使用してトピックを作成する方法を説明します。Kafkaがインストールされていることを前提としています。

### 1. Kafkaのインストールと起動
まず、Kafkaがインストールされていることを確認し、KafkaブローカーとZookeeperを起動します。Kafkaのインストール方法については、Kafkaの公式ドキュメントを参照してください。

Kafkaをダウンロードして解凍したディレクトリに移動し、以下のコマンドを実行してZookeeperを起動します。
```
bin/zookeeper-server-start.sh config/zookeeper.properties
```
次に、別のターミナルウィンドウを開き、Kafkaブローカーを起動します。
```
bin/kafka-server-start.sh config/server.properties
```
### 2. トピックの作成
Kafkaブローカーが起動している状態で、以下のコマンドを実行してトピックを作成します。
```
bin/kafka-topics.sh --create --topic my_topic --bootstrap-server localhost:9092 --partitions 1 --replication-factor 1
```
このコマンドのオプションの意味は以下の通りです：

--create: トピックを作成することを指定します。
--topic my_topic: 作成するトピックの名前を指定します。
--bootstrap-server localhost:9092: Kafkaブローカーのアドレスを指定します。
--partitions 1: トピックのパーティション数を指定します。
--replication-factor 1: トピックのレプリケーションファクターを指定します。
### 3. トピックの確認
トピックが正しく作成されたかどうかを確認するために、以下のコマンドを実行します。
```
bin/kafka-topics.sh --describe --topic my_topic --bootstrap-server localhost:9092
```
このコマンドは、指定したトピックの詳細情報を表示します。

### 4. トピックのリスト表示
現在存在するすべてのトピックをリスト表示するには、以下のコマンドを実行します。
```
bin/kafka-topics.sh --list --bootstrap-server localhost:9092
```
これで、Kafkaのトピックが作成され、確認できました。Spring Bootアプリケーションからこのトピックにメッセージを送信する準備が整いました。
matplotlibのtableのセル余白を調整する

## セル余白がセル幅に比例してしまう
FDAの運航情報のうち、備考情報のみを抽出して画像化を行った。
matplotlibのtableのセル幅を個別に設定すると、セル余白はセル幅に比例してしまい、幅の広いセルの余白が大きくなってしまう。
![matplotlib_table_1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3943774/bc126141-930c-5b35-8637-c9bb8c0075bf.png)

## セル余白の設定（公式ドキュメントから）
セル余白の設定は `PAD` に値を入れることで行える。デフォルトは 0.1 (相対値)。

https://matplotlib.org/stable/api/table_api.html#matplotlib.table.Cell.PAD

このPADの指定は、table関数の引数としては取れない。
最初はPythonスクリプト内で設定する方法がわからず、ライブラリ内のファイルを直接いじってごまかした。さすがによろしくないので色々調べた結果、以下の方法で指定できることがわかった。

## セル単位でセル余白を設定する方法
`table._cell[行番号, 列番号].PAD` に設定したい余白(相対値)を入れるとよい。

```Python: table描画部(抜粋)
now = datetime.datetime.now()
table_list = ['flight', 'fleet', 'fromdest', 'notes']
columns_list_j = ['便名', '機', '出発予定 - 到着予定', '備考']
nowstr = now.strftime('%Y/%m/%d %H:%M')
title = '備考情報 (' + nowstr + '現在)'
plt.rcParams['font.family'] = "IPAPGothic"
plt.rcParams["font.size"] = 7
fig, ax = plt.subplots(figsize=(8, 4.5))
plt.subplots_adjust(left=0.1, right=0.9, bottom=0.03, top=0.93)
ax.axis('off')
table = ax.table(cellText=df_notes[table_list].values,
                 colLabels=columns_list_j,
                 loc='center',
                 cellLoc='left',
                 colWidths=[0.1,0.03,0.23,1.18],
                 )
table.auto_set_font_size(False)
    table.set_fontsize(8)
    table.scale(0.8, 1.2)
    for row in range(len(df_notes)):
        table._cells[row+1, 0].PAD = 0.01
        table._cells[row+1, 1].PAD = 0.02
        table._cells[row+1, 2].PAD = 0.01
        table._cells[row+1, 3].PAD = 0.003
ax.set_title(title)
plt.savefig(filename_img, format="png", dpi=300)
```
PADの値を微調整することで、以下のようにセル余白がほぼ均一の表を作ることができた。
![matplotlib_table_2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3943774/c910dcdd-38df-9d8a-efc2-d9ccec71d2dc.png)
MeePet を Android 端末として使う

## ブラックフライデーセールで MeePet を買ってみた
ソースネクストがブラックフライデーセールで KAIGIO MeePet（ミーペット）を2980円で販売している。

https://www.sourcenext.com/pt/sale/2024/11/black-friday/

この端末はテレビ会議専用端末として売られているが、普通に Android 端末としても使えるという情報があったため、買ってみることにした。

Fire HD 8（第8世代）と比較するとこんな感じ。画面の大きさはほぼ同じ。
![meepet_1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3943774/2f92887d-721a-9048-ab84-c61a4d30356f.jpeg)


## MeePet を Android 端末として使うには
MeePet を Android 端末として使う方法はすでにいくつかのサイト・動画で解説されている。

USB デバッグを利用し、PC に接続して PC からアプリをインストールする方法

https://maytake-diy.com/archives/10702

をするまでもなく、 USB メモリにアプリを入れて、ファイルアプリから実行すればホームアプリがインストールできてしまうことを発見した方も。

https://www.youtube.com/watch?v=6ApMB2y4lRg

この方は設定画面からデベロッパーモードに移行する操作を解説しているが、実はデベロッパーモードに移行する必要すらない。
WiFi設定画面からファイルアプリを呼び出し、 USB メモリからホームアプリをいきなりインストールできてしまう。
今回の検証は現時点での最新バージョン（ソフトウェアバージョン：1.0.7、ファームウェアバージョン：1.2.5）で行ったため、過去や将来のバージョンてここまで簡単にインストールできるか保証はできない。少なくとも現バージョンはデフォルトで MeePet 以外のアプリ切り替えこそ制限しているものの、それ以外の制約はほとんど無いと言ってよい。

## 簡易サイネージとして使う
普段は RSS のニュースを表示させておこうと、簡易サイネージソフトを探してみたところ、 Slideshow というアプリが良さそうなので入れてみた。

https://slideshow.digital/

日本語の解説もある。

https://www.omakase.net/blog/slideshow-digitalsignage.html

起動すると、8080ポートで Web サーバーも立ち上がるので、別 PC から Web ブラウザを使って設定することもできる。

設定画面が多岐にわたってわかりづらいので大まかに解説。
画面のデザインは画面レイアウトタブから設定。
![meepet_2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3943774/44770748-9983-37fa-5238-c03468091730.png)

パーツの設定はアイテムタブから。文字色はアイテムの設定画面で指定しておく。
![meepet_3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3943774/b25c8d25-2805-a52e-919f-2aa8b1781383.png)

ただし、ここで秒単位の時計を設定しても10秒単位でしか更新されない。
更新間隔はプレイリストタブから操作する必要がある。ここから時計パーツのプレイリストを編集→コンテンツの長さを1秒に設定。
![meepet_4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3943774/cce22141-4fb1-72e9-4ac6-d0061a2aed89.png)

最後にアイテムパーツを画面レイアウトの各部分に紐づけていくが、レイアウト設定の一番下にある `ゾーンのプレイリスト スケジュール` を開く（パネルを追加した直後は `ゾーンのプレイリスト スケジュール` ボタンが表れないため、一度画面レイアウトを保存する必要がある）。
![meepet_5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3943774/df42460e-a882-b6ba-9edd-2d84c4dfc612.png)

プレイリストに追加すれば、そのコンテンツが画面に表示されるようになる。
![meepet_6.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3943774/d0503eb3-8d45-c38f-8c3a-9866ccdd71f9.png)

動作例はこんな感じ。バッテリー駆動で満充電から1時間放置したらバッテリー残量が78%になった。
![meepet_7.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3943774/3a00d6e9-a169-7e84-2db1-f3d827e32195.png)

なお、 RSS 以外の Web ページを表示させたい場合は RSS に変換するサービスを利用するとよい。

https://happyou.info/fs/

https://fetchrss.com/

## ややもっさりだが、価格からすれば十分使える
他にも VLC や Kiwi Browser などを入れて動画視聴や Web 閲覧等をしてみた。
Web 閲覧はややもっさりしているが、十分実用の範囲と言ってよい。
PC用の Chrome 拡張機能を使って2倍速を超える YouTube の再生も可能であった。

唯一欠点と言えそうなのは、アプリの切り替え制限があること。
Navigation Bar をインストールすれば戻るボタン・ホームボタンは追加できるが、アプリ切り替えボタンは機能しない。どんどん起動アプリが溜まってしまう問題がある。
設定画面からアプリの強制終了以外の方法があればよいのだが。

その欠点を承知しつつ、単一アプリ起動もしくは定期的に再起動すると割り切って使えば、それなりに使える端末と言える。
特に、 **USB-A ポート2基**、**通常サイズの HDMI 出力ポート**、さらに**4Wスピーカーが2基**備わっている点は注目したい。 Android タブレットでもここまで備えているものはほとんど無いだろう。
USB メモリや SSD/HDD をつないで画像・音楽・動画再生端末として使ってもよいし、キーボードを繋いで入力作業を行う用途でも使えそうである。
新しい自分への挑戦

# 現在の自分について
　30歳後半の年齢になり、将来のことを考えるようになりました。このまま今の仕事をしていて、退職した後も稼げるスキルがあるのか？職場の先輩方を見ていても退職後も仕事をしている。自分が同じような状況になった時、世の中がどのようになっているのかは分からないが、確実に収入を得ていないと生活できないことはほぼ確実。何かスキルを身につけたい・・・そう漠然と思って過ごしているとエンジニアという分野にかかわる機会をいただいた。エンジニアって何？という知識レベルの状況でしたが、とりあえずやろう！という性格なもので、WEBアプリケーションを作る未知の世界に飛び込みました。楽しい・・・意味不明なコードに触れ、最初は全然理解ができないが少しずつ理解が深まり、アプリケーションが出来上がっていく開発の楽しさを知りました。アプリケーションってこういう原理でできているのか。漠然と理解できるようになり、もしかして自分で作りたいものが作れる世界？ということを知り、ますます楽しさを実感。これを仕事にしたい！そう思いました。調べていくとリモートでの仕事ができてしまう世界。そうなると出勤退社時間が不要で時間が確保できる。ということは家族が体調不良のピンチの時も休憩時間に家事もできてしまうし、副業もできる。そんな素晴らしい環境で仕事ができるようになることを目標に日々学習。元々継続することに対して抵抗はなく、学習継続はできました。しかし、学習を進めていくにつれスキルが上がっている実感が湧かなくなってきました。このままで目標にたどり着けるのか？厳しい予感がしてきた。1番の近道はどの分野においても成功者から学ぶ！それが1番早いと理解していたので、以前から気になっていたJISOUの門を叩きました。
 　現役エンジニアの代表の方の熱いお話、今もアウトプットを行動されており、スクールの手厚いサポート内容。すぐにエンジニア会のスクールでも本物だと思い即決入会。これからどんな結果になることやら、楽しみです。

# 将来について
　3カ月後：Reactでアプリ開発カリキュラム終了。
　6か月後：フルリモートでのエンジニアの仕事に就く（フロントエンド or フルスタック）
  1年後：不安なくエンジニアの仕事を継続しており、空いた時間で副業の準備を進める。
　作りたいアプリ：大規模災害時のNPO法人団体が活動している際の部隊管理位置情報共有アプリ

 ※　なぜJISOUを選択したか。学習の仕方について学び、習得したいと思ったから！臣さんのの自分について
　30歳後半の年齢になり、将来のことを考えるようになりました。このまま今の仕事をしていて、退職した後も稼げるスキルがあるのか？職場の先輩方を見ていても退職後も仕事をしている。自分が同じような状況になった時、世の中がどのようになっているのかは分からないが、確実に収入を得ていないと生活できないことはほぼ確実。何かスキルを身につけたい・・・そう漠然と思って過ごしているとエンジニアという分野にかかわる機会をいただいた。エンジニアって何？という知識レベルの状況でしたが、とりあえずやろう！という性格なもので、WEBアプリケーションを作る未知の世界に飛び込みました。楽しい・・・意味不明なコードに触れ、最初は全然理解ができないが少しずつ理解が深まり、アプリケーションが出来上がっていく開発の楽しさを知りました。アプリケーションってこういう原理でできているのか。漠然と理解できるようになり、もしかして自分で作りたいものが作れる世界？ということを知り、ますます楽しさを実感。これを仕事にしたい！そう思いました。調べていくとリモートでの仕事ができてしまう世界。そうなると出勤退社時間が不要で時間が確保できる。ということは家族が体調不良のピンチの時も休憩時間に家事もできてしまうし、副業もできる。そんな素晴らしい環境で仕事ができるようになることを目標に日々学習。元々継続することに対して抵抗はなく、学習継続はできました。しかし、学習を進めていくにつれスキルが上がっている実感が湧かなくなってきました。このままで目標にたどり着けるのか？厳しい予感がしてきた。1番の近道はどの分野においても成功者から学ぶ！それが1番早いと理解していたので、以前から気になっていたJISOUの門を叩きました。
 　現役エンジニアの代表の方の熱いお話、今もアウトプットを行動されており、スクールの手厚いサポート内容。すぐにエンジニア会のスクールでも本物だと思い即決入会。これからどんな結果になることやら、楽しみです。

# 将来について
　3カ月後：Reactでアプリ開発カリキュラム終了。
　6か月後：フルリモートでのエンジニアの仕事に就く（見た目の実装が好きなので、できればフロントエンド）
  1年後：不安なくエンジニアの仕事を継続しており、空いた時間で副業の準備を進める。
　作りたいアプリ：大規模災害時のNPO法人団体が活動している際の部隊管理位置情報共有アプリ

 # なぜJISOUを選択したか。
　学習の仕方について学び、習得したいと思ったから！臣さんの投稿を見て「確かに！！！」と納得。学習の仕方について今まで考えたことが無かったし、圧倒的な投稿の多さに「自分もこんな風になりたい」このスキルは今後も必須であり身につけたら一生ものだと思った。
　身になっていない学習時間ほど無駄なものはない。時間は全ての人に平等に与えられているもの、それをどのように使うかによってこの先の結果に大きく影響する。そこを習得できる唯一のスクールだと思ったからです。
　6か月以降の自分の投稿を楽しみにコツコツいきます！

 https://qiita.com/Sicut_study/items/79838a4b8ec36bc3a961

# JISOUのメンバー募集中！
プログラミングコーチングJISOUでは、新たなメンバーを募集しています。
日本一のアウトプットコミュニティでキャリアアップしませんか？
興味のある方は、ぜひホームページをのぞいてみてくださ！
▼▼▼

https://projisou.jp
【Ruby】配列の要素を数える方法

配列に対して`length`メソッドを使用すると、その配列に含まれる要素の数を返します。

```ruby
empty_array = []
puts empty_array.length  # 出力: 0

mixed_array = [1, "two", :three]
puts mixed_array.length  # 出力: 3
```

## `size`メソッド

`size`メソッドも`length`メソッドと同様に使用できます。

```ruby
array = [1, 2, 3]
puts array.length  # 出力: 3
puts array.size    # 出力: 3
```
Excelプラグインが不便なので修正してみた


### Excelプラグインについて
少し前の記事でObsidianのおすすめプラグインとして「Excel」を紹介しました。

[Obsidianをプラグインでもっと便利に！ #初心者 - Qiita](https://qiita.com/Kei_Adachi/items/1f5d01230334574f2e26#excel)

このプラグインは.mdのファイルを作成しExcelのように表示してくれて、エクスポート、インポートもできます。
しかし、エクスポートの際に罫線、文字色、太字、イタリック、関数など諸々が反映されずかなり不便です。
そもそも使える関数の数がめっちゃ少ないです。筆者が無知なだけで使える関数とか増やせるのであれば教えてください！

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3853726/d03ecf6f-5453-f6ad-f37d-a5b7f8202c20.png" width="50%">

↑スクロールすれば他の関数も出てくるとかでもない。
この時点で本家のExcel使えやって感じですが、\(プラグイン作ってくれた方ごめんなさい)授業の課題でPython使ってなにか作れと言われたので、正しくエクスポートできるプログラムを作成しました。
かなりChatGPTの力を借りてます。


### 使い方

GitHubにPythonプログラムとサンプルの.mdファイルを置いておいたのでよければ試してください。

[GitHub - Kei-Adachi0709/md\_to\_xlsx: Convert markdown to Excel file](https://github.com/Kei-Adachi0709/md_to_xlsx)

Excelプラグインで作成した.mdファイルを`md_to_xlsx.py`があるフォルダに移動して↓のコマンドを実行すれば.xlsxとして出力してくれます。
引数として.mdファイルの名前を与えてください。
```cmd
python md_to_xlsx.py sample.md
```

↓実行して出力された.xlsxファイル

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3853726/5033b138-6e47-f672-4965-bea92abc00e0.png" width="50%">

いちいち.mdファイルを移動させずともExcelプラグインの設定から.mdファイルを作成するフォルダを指定できます。

記事を投稿する直前に、文字の色が反映されていないことに気づきました。試行錯誤しましたが文字の色は反映されませんでした。
そもそも罫線、文字色、太字、イタリックぐらいしか補足していないことにいま気づきました。Pythonの課題として提出したものなのであたたかい目で見ていただければ幸いです。
時間があればちゃんと修正したものをGitHubに置き、こちらの記事でもアナウンスしようと思います。
ただ、筆者は就活で忙しいのでいつになるかはわかりません...。ここまで読んでくださった方には申し訳ないです。

### 最後に
ここまで読んでくれた方は気づいていると思いますが、本家のExcelプラグインを使った方がいいと思います。
せっかくプログラム作ったしQiitaに投稿しようと思っただけっすね。そのプログラムも欠陥があるのでどうしようもないですね...。
そんなわけで記事はここまでです。ご覧いただきありがとうございました。
【競技プログラミング】AtCoder Beginner Contest 195_D問題

# 問題
https://atcoder.jp/contests/abc195/tasks/abc195_d

# 既存投稿一覧ページへのリンク
[一覧ページ](https://qiita.com/o_chan_t/items/fc759695acfaef8df2cc)


# アプローチ

1. 荷物を価値の降順でソートする。
2. 各クエリに対して、使用可能な箱のリストを作成する。
3. 使用可能な箱を大きさでソートする。
4. 価値の高い荷物から順に、入れられる最小の箱に割り当てていく。
5. 割り当てが終わったら、その時点での価値の合計を出力する。

# 解法手順

1. 入力を受け取り、荷物のリストを作成する。
2. 荷物を価値の降順でソートする。
3. 各クエリに対して以下の処理を行う：
   - 使用可能な箱のリストを作成する（L-1番目までとR番目以降の箱）。
   - 使用可能な箱を大きさでソートする。
   - 価値の高い荷物から順に以下の処理を行う：
     - 二分探索を使用して、荷物が入る最小の箱を見つける。
     - 適切な箱が見つかったら、その箱を使用済みとしてリストから削除し、価値を合計に加算する。
     - 使用可能な箱がなくなったら処理を終了する。
   - 合計価値を出力する。


# ACコード
```python:ac.py

import bisect  # 二分探索のためのモジュールをインポート

# 1. 入力を受け取り、荷物のリストを作成する
N, M, Q = map(int, input().split())  # N: 荷物の数, M: 箱の数, Q: クエリの数
item = [list(map(int, input().split())) for _ in range(N)]  # 荷物のリスト（重さと価値）
X = list(map(int, input().split()))  # 箱のサイズのリスト

# 2. 荷物を価値の降順でソートする
item.sort(reverse=True, key=lambda x: x[1])  # 価値の降順でソート

# 3. 各クエリに対して処理を行う
for _ in range(Q):
    L, R = map(int, input().split())  # クエリの入力（L番目からR番目までの箱は使用不可）
    
    # 使用可能な箱のリストを作成する
    w = X[:L-1] + X[R:]  # L-1番目までとR番目以降の箱
    w.sort()  # 箱を大きさでソート
    
    res = 0  # 合計価値を初期化
    
    # 価値の高い荷物から順に処理
    for weight, value in item:
        # 二分探索を使用して、荷物が入る最小の箱を見つける
        idx = bisect.bisect_right(w, weight)
        
        if idx > 0 and w[idx-1] == weight:
            # 荷物の重さと同じ大きさの箱がある場合
            w.remove(w[idx-1])
            res += value
        elif idx < len(w):
            # 荷物が入る箱がある場合
            w.remove(w[idx])
            res += value
        else:
            # 荷物が入る箱がない場合は次の荷物へ
            continue
        
        # 使用可能な箱がなくなったら処理を終了
        if not w:
            break
    
    # 合計価値を出力
    print(res)


```
CDKでIoTルールを作ったら古いSQLバージョンのものが作られていてつまづいた話

## 概要

基本的にタイトルの通りです。
AWS IoT ルールアクションをCDKで作成したところ、利用していたCDKバージョンでデフォルト値となっていたSQL ステートメントのバージョンが（執筆時2024.11.30現在）推奨となっている `2016-03-23` ではなく `2015-10-08` となっていたことで、ルールがうまく動かず、解決に時間を要したという話です。

### 環境

- CDK: `2.163.1` (2024.10.23　リリース)

## つまづいた背景・原因

いくつかありますが、大きなものは以下です。
 
1. CDKで作成する**前に**手動でIoT ルール・SQLステートメントを作成し、動作確認をしていた

手動で作成した場合、デフォルトでは `2016-03-23` が選ばれております。また他の選択肢を見ても、 `Recommended` が入っているため、普通に作れば古いバージョンを選ばないと思います。
![スクリーンショット 2024-11-30 23.35.32.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/259081/cd6f7e27-c96f-c38e-0f51-b961166a8cc3.png)

そもそもCDKで作るならなぜ手動でも作るんだ？というツッコミもあるかと思います。いろんな事情がありますが、SQLステートメントの記述修正でデプロイを繰り返したくないこと・デバイス側からのデータI/Fの延長線上にある処理であることなどから、とりあえず疎通を先に試す、という背景が主な理由です。
 
2. CDKでIoT ルールを定義する際に、バージョンまで意識していなかった

他のバージョンの状態を把握しているわけではありませんが、少なくとも今回利用していたCDKバージョンでは、IoT ルール作成時にSQLバージョンの指定が必須ではありませんでした。つまり「CDK側でよしなにしてくれる」範疇になっていたので、まさか現在推奨されているバージョンではないものがデフォルトとして設定されているとは思いもよりませんでした。
また、今までSQLバージョン間の差異についても特別意識したことがなかったです。

## 問題のSQLステートメント

引っかかったのは以下の部分でした。

```sql:SQL ステートメント
SELECT parse_time("yyyy-MM-dd'T'HH:mm:ss'Z'", timestamp) as registered_time FROM "#"
```

[公式のリファレンス](https://docs.aws.amazon.com/ja_jp/iot/latest/developerguide/iot-sql-functions.html)引用：
> parse_time 機能を使用して、タイムスタンプを人間が判読可能な日付/時刻形式にフォーマットします。**SQL バージョン 2016-03-23 以降でサポートされています。** タイムスタンプ文字列をミリ秒に変換するには、「time_to_epoch(String, String)」を参照してください。

実際のエラーは以下の通りです。
上記で作成しようとしていたキー（registered_time）はテーブルのソートキーに当たるものでした。

ルール： `dynamoDBv2`
エラー：

> DynamoDBv2 Put record failed. The error received was One or more parameter values were invalid: Missing the key registered_time in the item (Service: AmazonDynamoDBv2; Status Code: 400; Error Code: ValidationException; (以下略)


SQLバージョン `2016-03-23` では動くのに、 `2015-10-08` では動かなかったのはこのせいでした。
上記 `parse_time` 関数はIoT Coreでのデータ受信時刻を後続処理で活用するのに不可欠な関数かと思っていますが、旧バージョンにはなかったということですね。

## 問題のCDK

該当の問題のIoTルール作成時の引数に関する[公式のリファレンス](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-iot-topicrule-topicrulepayload.html#cfn-iot-topicrule-topicrulepayload-awsiotsqlversion)の引用：

> AwsIotSqlVersion
The version of the SQL rules engine to use when evaluating the rule.
**The default value is 2015-10-08.**
Required: No
Type: String

`2015-10-08` がデフォルトの設定値です、とはっきり書いてありますね。
Githubでfeature-request出そうかめちゃくちゃ迷いました。

## 最後に

リソースに何らかのバージョン指定があれば、デフォルト設定しているのかもっと気をつけなければいけないですね。

（そういえば、CDKがらみでバージョンにまつわる[記事](https://qiita.com/USI/items/8adf46f989d8896bcb2e)を過去にも書いていました... ）
day7 『偏愛マップ』

## はじめに
　とあるお客から教えていただきました。
 コロナでリモートになってから入ったプロジェクトだったので、担当の多くの皆さんと実際に会うことなく仕事を進めていましたが、順番に回ってくる朝15分間の「何でも良いから発表会」の中で、課長さんの順番が来た際に紹介していただき、その後、実践となりました。なかなか良いです。
　ぜひ、自分の「偏愛マップ」を作って、新しいコミュニケーションに進んでください。

![偏愛マップ 目次2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/533414/e7c40c35-77a3-ff6c-c1f9-d74be1deca8f.png)


 ちなみに表紙

![偏愛マップ 表紙.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/533414/d86cbe35-f232-4d1b-8bd4-f98021a47680.png)


## ポイント
### 偏愛マップとは、自分の「大好きなもの」を書き込んだマップ
- 好きなことを書き込むだけです。表現形式は問いません。

![偏愛マップ 形態2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/533414/019b4ed4-3796-a0a1-42e5-2aa931ec6b37.png)


### 飲みニケーションに代わる、偏愛マップ相互開示のコミュニケーション
- これ以上、言う事ありません。でも、うまく使うと、チームの潤滑剤となります。


## 書誌情報
- 書籍名：偏愛マップ
- 著者：斎藤 孝
- 出版社：NTT出版
- ISBN：4-7571-0128-7

## 参考
-
【初心者向けAI解説①！！】大規模言語モデルについて

私の知識の整理も兼ねて、超初心者向けに大規模言語モデルとモデルの種類について解説します！

# 大規模言語モデル（LLM）
数年前から巷で話題のLLMの事で、Large Language Modelの略です。
大量のテキストデータを学習して作成されたモデルで、自然言語処理を理解して生成することが出来ます。
つまり、**人の言語を理解し、言語を生成することが出来るモデル**です。
モデルという言葉が理解できない場合、**勉強し終わった後の脳みそ**と考えてもらえればOKです。
**育った環境で人の性格が変わるように、LLMも学習の方法や元となったデータによって、様々な個性を発揮します。**

:::note warn
**厳密には・・**
脳みそは思考するものですが、LLMは厳密には思考しているわけではなく、言語パターンにもとづいて確率的に高い文章を生成します。LLMが独創的な文章生成を指示することはできますが、それは独創的な言語パターンを元に独創的っぽいものを生成しているだけで、言語化されていない本当の意味で独創的なものを生成しているわけではないです。
:::

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3812370/dc2a576d-796c-ef84-e87d-1bc7d0f2a6f6.png)


# 自然言語処理（NLP）ってなに？
LLMとほぼセットで語られることの多い用語で、Natural Language Processingの略です。
コンピュータが人間の自然な言語を理解し、処理／生成できるようにする**技術全般**を指します。
NLPの技術をもって作成されたモデルがLLMです。

# LLMは何ができるの？
前述で触れた通り、NLPを用いて学習されてモデルなので、自然言語を理解し生成することが出来ます。
**非常に広いスコープをカバーしている**ので活用も多岐にわたります。

### 【対話】
言語を用いる最も一般的な行動は、**言語を用いた会話**です。
Chat-GPTなどが代表的で、相手の**質問を理解し、質問に対する回答を生成**することでき、これにより**自然な会話を成立させる**ことが出来ます。
最近では音声処理の技術などを組み合わせて、音声による自然な対話を実現するなど、日々の進化が凄まじいジャンルです。

### 【翻訳】
LLMは言語を理解しているため、**文章の文脈を理解し、それを別の言語に置き換える事も得意**です。
LLMが流行る前から様々な翻訳サービスが存在しておりましたが、**LLMの登場により精度が飛躍的に向上**しています。

**◆◆ 翻訳の進化の歴史 ◆◆**
- **ルールベース期（～1990年代）**
    - 文法や辞書を元にルール化された処理を通して翻訳する方法
    - 人が頑張って作成したルールなので、処理が非常に複雑化する
    - ルールにそって翻訳するので回答が安定している（精度は別の話。。）
- **統計ベース期（1990～2010年代）**
    - 大量の原文と訳文のペアによって作成された**統計モデル**を用いて、原文に対して確率的に高い翻訳を行います。
    - 統計**モデル**とは言葉ではあるが、現在的なAI技術のモデルとは仕組みが異なり、固定のアルゴリズムを用いて処理される。
- **ニューラル機械翻訳機期（2010年代～）**
    - 現代的なAI技術によって学習された**LLMを用いて翻訳**する方法
    - 言語を理解しているため、**文脈を理解した自然な表現での翻訳**ができる。

### 【文章の生成】
これまでに触れた機能も含めた包括的な話とはなりますが、LLMは非常に汎用的な仕組みなので、言語に関わるだいだいのタスクはこなせます。
例えば
 - メール文章の作成
     - 適当に描いた文章を「ビジネス表現に直して」という使い方や、「〇〇という失敗をしてしまった。顧客に不信感を抱かせない事を意識して謝罪文を作って」など
 - 教育資料の生成
     - 「新入社員向けにAIに関する教材を作って」など
 - 結婚式の挨拶の生成
     - 「〇〇さんと〇〇さんが結婚します。私は〇〇さんと友達です。当たり障りのない一般的な結婚挨拶を考えて」

などですが、例を見て頂いたらわかる通り、これ以外にも日常生活で文章を生成するケースは沢山あると思います。LLMはそれらのほとんどのタスクをこなすことが出来ます。

# ただし・・
LLMは過去の様々の文章を学習したものなので、**すごく頭の良いゼネラリスト**ですが、人と同じで以下のような弱点があります。
 - **知らない事は答えれない**
     - 膨大な情報を元にLLMは作成されていますが、**すべて過去のデータ**なので、**リアルタイムの情報（今日の天気は？）** には対応できない。
     - 特定の会社のルールなど、**世の中に公開されていない知識は知らない。**
 - **知らない事でも頑張って回答してしまう**
     - LLMは言語を生成する仕組みのため、**知らない事を知ってる知識で無理に回答してしまう事**がある。これにより、自信満々に間違った情報を生成することがある。
     - これは**ハルシネーション**と呼ばれる挙動ですが、詳細については別途記事を作成するので、そちらを参照してください。

# どのように対策する？
LLMは前述のような弱点がありますが、今では以下のような対策法が確立されており、数多くの実用的なサービスが存在しています。

- **知らない事を覚えさせる** 
知らない事を知識としてモデルに**追加学習させる方法**です。
モデルそのものをチューニングする方法で**ファインチューニング**と呼ばれます。
これを比較的簡単に行うサービスも提供されていますが、それでも**AIの専門的な知識が必要**となるため難易度は高いです。
また、非常に手間もかかるため、**変化の多い情報に対しては実用的ではありません。**
例えば、「今日の天気」を回答できるようにするために、毎日天気のデータを学習させることは非常に非効率です。

- **知らない事を補足情報として教える** 
ファインチューニングとは異なり、**補足情報として関連データを提供**して、関連データと合わせて回答を生成する方法です。
例えば、自分の考えたオリジナルゲームに関する回答を生成してもらう場合、そのゲームのルールを補足情報として与える事で、ルールにそった回答を生成できますね。
ファインチューニングと比較すると実用的になるケースが多いですが、補足情報を探すプロセスが発生するため、ファインチューニングよりは当然処理に時間が掛かります。また、探した情報が間違っていた場合は当然回答の精度にも影響します。**やることが増えるため、その時間も掛かるし失敗する機会も増やすことになります。**

上記の２つの方法については、別途記事を作成するため、詳細はそちらを参照してください。


以上です！！

※掲載しているイラストはDALL-Eで作成したものです。
エクセルやスプレッドシート自動化のためのVBA、GAS、openpyxl対応表

導入などについては[こちら](https://www.youtube.com/watch?v=v2hHK_YGQGU)も参照

| 処理 | VBA | GAS | openpyxl |
| ---- | ---- | ---- | ---- |
| ブック作成 | Workbooks.Add | SpreadsheetApp.create("hoge"); | Workbook() |
| シート追加 | Worksheets.Add | SpreadsheetApp.getActiveSpreadsheet().insertSheet("hoge"); | WorkBook.create_sheet(title="hoge") |
| シート名変更 | Worksheets("hoge") | SpreadsheetApp.getActiveSpreadsheet().getSheetByName("hoge").setName("fuga"); | Workbook.active.title = "fuga" |
| セルの値を取得 | <ul><li>Range("A1").Value</li><li>Cells(1,1).Value</li></ul>| SpreadsheetApp.getActiveSpreadsheet().getActiveSheet().getRange("A1").getValue() | <ul><li>Workbook.active["A1"].value</li><li>Workbook.active.cell(1,1).value</li></ul> |
| セルに値を挿入 | <ul><li>Range("A1").Value = "hoge"</li><li>Cells(1,1).Value = "hoge"</li></ul> | SpreadsheetApp.getActiveSpreadsheet().getActiveSheet().getRange("A1").setValue("hoge") | <ul><li>Workbook.active["A1"] = "hoge"</li><li>Workbook.active.cell(1,1).value = "hoge"</li></ul> |
| 入力プロンプト表示 | InputBox("メッセージ") | SpreadsheetApp.getUi().prompt("メッセージ"); | input("メッセージ") |
| ログ出力 | Debug.print "hoge" | <ul><li>console.log("hoge");</li><li>Logger.log("hoge");</li></ul> | print("hoge") |

ちなみに型宣言の有無、コードの冗長性の観点での個人的な使いやすさで言うと以下。
```
openpyxl > VBA > GAS
```

スプレッドシート関連の処理以外の処理でいうと、JavaScriptに慣れているのもあってGASはスラスラ書けるんだけども、スプレッドシート関連の処理に関してはいかんせん冗長で仕様の把握がしづらい。

対応表を見ての通り、openpyxlではシート名やセルの指定にキー指定する形をとっているが、GASではgetterの引数という形で指定するので、ある操作に対応するメソッドを把握する必要がある上にメソッド名が長くてコードの1行が長くなってなんかヤダ。

VBAはopenpyxlでは原理的にムリなMsgBoxでのExcelのメッセージボックス表示などが出来たり、セル指定をする際などはアクティブなブックやシートを明示的に指定しなくてもよいなどのグッドポイントがあるが、`For`～`Next`、`Do While`～`Loop`、`If`～`End If`など制御構文の終わりを構文として書くのが面倒くさい。

余談だけども最近はPythonでExcelいじったりAtCoderやったりしてるせいもあってJavaScriptの`if`文`for`文の条件部分のカッコ`()`や処理部分の波カッコ`{}`にも違和感を覚えるようになってしまった。
AWS Lambdaに新しくレイヤーを追加する際に詰まった話です。

# 結論：`docker run`の際にアーキテクチャを指定する
https://repost.aws/ja/knowledge-center/lambda-layer-simulated-docker

を参考にLambdaへpydanticのレイヤーを追加しようとしていたが、`No module named 'pydantic_core._pydantic_core’` というエラーが出た。調べてみるとLambdaのアーキテクチャに関係するエラーだということが分かった。

Lambdaには2種類のアーキテクチャが用意されている
[Lambda 関数の命令セットアーキテクチャの選択と設定 - AWS Lambda](https://docs.aws.amazon.com/ja_jp/lambda/latest/dg/foundation-arch.html)
- arm64 — AWS Graviton2 プロセッサ用の 64 ビット ARM アーキテクチャです
- x86_64 — x86 ベースプロセッサ用の 64 ビット x86 アーキテクチャです

レイヤーに追加するZipを作成するコンテナのアーキテクチャとLambdaのアーキテクチャを揃えなければならない。自身のMacはAppleシリコンなのでCPUのアーキテクチャは`arm64`です。しかし、Lambdaのアーキテクチャはintelに合わせて`x86_64`としてある（技術負債でもある）ので、互換性が無いため追加したレイヤーが認識されずエラーになったのです。

[M1 Mac の基礎知識｜M1 Mac で Docker を動かすための知識とノウハウ](https://zenn.dev/suzuki_hoge/books/2021-12-m1-docker-5ac3fe0b1c05de/viewer/2-arm)

結論としては
`docker run --platform=linux/x86_64 -v "$PWD":/var/task "public.ecr.aws/sam/build-python3.12" /bin/sh -c "pip install -r requirements.txt -t python/lib/python3.12/site-packages/; exit”`
として、使用するアーキテクチャを指定するべきであった。


# 番外

模索中にDockerでLambdaの実行環境を再現し、そこでzipを作成すればいけるんじゃね？と思ったけどダメだった。

実際に使ったもの→`aws/codebuild/amazonlinux-x86_64-lambda-standard:python3.12`

[Lambda コンピューティングイメージ - AWS CodeBuild](https://docs.aws.amazon.com/ja_jp/codebuild/latest/userguide/lambda-compute-images.html)

作成したイメージをinspectで見てみると`"Architecture": "arm64”`

うーんだめ

`run`する時にアーキテクチャを指定しないとダメだった。
アドベントカレンダー1日目

# 自己紹介
　八戸工業大学システム情報科4年の学生Ono_0714です。
　自身が卒業研究で作ったものをアウトプットする場が欲しくアドベントカレンダーに参加しました。

# 概要
　卒業研究で実験したことをアウトプットとして書いていきます。研究テーマは様々ですが、私が担当する日は、マイコンを使用した研究を紹介していきます。

# 研究の理由
　卒業研究で作ったものと大雑把に書きましたが、もう少し詳しく書くと、生活が少しだけ豊かになるようなものを作りたいと思ったことがきっかけでした。
　改善するまでもないけど、少し気になる…となりがちな小さな悩み事を、所属している研究室で利用したことのあるマイコンをうまく活用して解決できないか、と思い立ったことが研究の初めでした。

# 研究で作ったもの
１　忘れ物確認システム
２　湿度チェックアラーム
３　来客お知らせシステム
４　長時間座り防止アラーム
５　持ち物提案アシスタント
６　睡眠の環境チェッカー

　私が作ったのはこの6つです。明日の記事から順番に書いていこうと思います。よろしくお願いします。
[Git] resetとrevertの違いを復習

最近、Gitでリモートにプッシュ済みのコードを切り戻したいケースがあったので、復習です。

修正したコードを切り戻したいとき、`git reset` と `git revert` って何が違うんだっけ？と迷いますよね。

# 結論
細かいことは置いといて、まずは結論。

### リモートにプッシュ済みのコードを切り戻したいとき
`git revert` を使います。

**手順:**
1. git revert <コミットハッシュ>
1. git push origin <ブランチ名>

これでコミットが打ち消されて、かつリモート上に履歴も残ります。

コミットハッシュについては、`git log` で確認できます。
```
% git log
commit aaxxd9bbexxcca773d50f8cf77d8b2xx14890806 (HEAD -> MY_APP-2, origin/MY_APP-2)
Author: Your Name　<your.mail@gmail.com>
Date:   Tue Oct 8 00:58:58 2024 +0900

    コメント
```

### ローカルのコミットを取り消したいとき
`git reset` を使います。

**手順:**
1. git reset

オプションなしで実行した場合、デフォルトでは`--mixed` が適用されます。
通常、以下の順番でコミットしますね。

1. ファイルを修正
1. ステージング
1. コミット

この状態で`git reset` を実行すると、1の状態、つまりステージング前の状態に戻ります。

基本的には、ここまでを覚えとけば大丈夫という認識。

## reset と revert の違い

`git reset` と `git revert` はどちらもコミットの変更を元に戻すコマンドですが、異なる動作をします。

| 特徴        | `git reset`                               | `git revert`                                   |
|-------------|-------------------------------------------|------------------------------------------------|
| **動作**     | コミット自体を削除または移動する          | 新しいコミットを作成して変更を元に戻す           |
| **履歴**     | 履歴を書き換える (危険性あり)              | 履歴を書き換えない (安全)                     |
| **共同作業** | リモートブランチにプッシュ済みコミットをresetすると、共同作業者に影響を与える可能性が高い | リモートブランチにプッシュ済みコミットをrevertしても、共同作業者への影響が少ない |
| **用途**     | ローカルでのミス修正、ブランチの整理       | 公開済みのコミットの修正、共同作業での変更元に戻し |


### `git reset`

`git reset` は、指定したコミットまでHEADを移動させます。
つまり、そのコミット以降の変更を履歴から削除します。

* **`--soft`**: 作業ツリーとインデックスには変更が残る。
* **`--mixed`**: 作業ツリーには変更が残るが、インデックスはクリアされる。
* **`--hard`**: 作業ツリーとインデックスの変更が完全に消える。（危険なオプション。元に戻した変更は完全に失われる）


**例:**  `git reset --hard HEAD~2` は、直近2つのコミットを完全に削除。


### `git revert`

`git revert` は、指定したコミット取り消す新しいコミットを作成します。元のコミットは履歴に残りますが、その変更は打ち消されます。公開済みのコミットを修正するのに最適。

**例:** `git revert <コミットハッシュ>` は、指定されたコミットを元に戻す新しいコミットを作成。


### まとめ

| 状況                               | `git reset` | `git revert` |
|------------------------------------|-------------|-------------|
| ローカルでのミスを修正したい       | 〇           | ×           |
| 公開済みのコミットを修正したい     | ×           | 〇           |
| ブランチを整理したい               | 〇           | ×           |
| 共同作業で、公開済みコミットの変更を元に戻したい | ×           | 〇           |
| 履歴をクリーンにしたい (危険性あり) | 〇           | ×           |


`git reset` は誤って使用すると履歴が破損する可能性があり、注意が必要。

公開済みのコミットに対しては、常に`git revert`を使用した方がいいですね。
Haskellでラムダ計算：等式と不等式

等式と不等式を定義しましょう。まずは不等式から定義します。
$x\geq y$を判定する関数$\textbf{G}$を下記のように定義します。
$$\textbf{G}\equiv(\lambda xy.\textbf{Z}(x\textbf{P}y))$$

### 3>2を証明する
$3>2$を判定します。
$\textbf{G32}\equiv
(\lambda xy.\textbf{Z}(x\textbf{P}y))\textbf{32}\rightarrow
\textbf{Z}(\textbf{3P2})\rightarrow
\textbf{Z}((\lambda sz.s(s(s(z))))\textbf{P2})$
$\rightarrow\textbf{Z}(\textbf{P}(\textbf{P}(\textbf{P}(\textbf{2}))))
\rightarrow
\textbf{Z}(\textbf{P}(\textbf{P}(\textbf{P2})))
\rightarrow\textbf{Z}(\textbf{P}(\textbf{P}(\textbf{1})))
\rightarrow\textbf{Z}(\textbf{P}(\textbf{0}))$
ここで[算術編](https://qiita.com/Trubetzkoy/items/10a960c806b11702337f)の結果$\textbf{P2}\rightarrow\textbf{1}、\textbf{P1}\rightarrow\textbf{0}$を使ったので。

更に$\textbf{P}(\textbf{0})$を求めます。
$\textbf{P0}
\rightarrow(\lambda n.(n\Phi(\textbf{B}))\textbf{F})\textbf{0}
\rightarrow(\textbf{0}\Phi(\textbf{B}))\textbf{F})
\rightarrow((\lambda sz.z)\Phi(\textbf{B}))\textbf{F}$
$\rightarrow(\lambda z.z)\textbf{F}
\rightarrow\textbf{F}$
この結果から、$\textbf{G32}\rightarrow
\textbf{ZF}
\rightarrow(\lambda x.x\textbf{F}\neg\textbf{F})\textbf{F}
\rightarrow\textbf{FF}\neg\textbf{F}$
$\rightarrow(\textbf{FF}\neg)\textbf{F}
\rightarrow(\neg)\textbf{F}
\rightarrow\textbf{T}
$となり、$3>2$であることを証明できました。

### 2>3を計算する
逆の場合の$2＞3$はどうなるでしょうか。
$\textbf{G23}
\rightarrow(\lambda xy.\textbf{Z}(x\textbf{P}y))\textbf{23}
\rightarrow\textbf{Z}(\textbf{2P3})
\rightarrow\textbf{Z}((\lambda sz.s(s(z)))\textbf{P3})$
$\rightarrow\textbf{Z}(\textbf{P}(\textbf{P}(\textbf{3})))
\rightarrow\textbf{Z}(\textbf{P}(\textbf{2}))
\rightarrow\textbf{Z}(\textbf{1})
\rightarrow(\lambda x.x\textbf{F}\neg\textbf{F})\textbf{1}
\rightarrow\textbf{1}\textbf{F}\neg\textbf{F}$
$\rightarrow(\lambda sz.s(z))\textbf{F}\neg\textbf{F}
\rightarrow\textbf{F}(\neg)\textbf{F}
\rightarrow\textbf{F}$
$2>3$は偽となりました。

### 2=2を計算する
$\textbf{G22}
\rightarrow(\lambda xy.\textbf{Z}(x\textbf{P}y))\textbf{22}
\rightarrow\textbf{Z}(\textbf{2P2})
\rightarrow\textbf{Z}((\lambda sz.s(s(z)))\textbf{P2})$
$\rightarrow\textbf{Z}(\textbf{P}(\textbf{P}(\textbf{2})))
\rightarrow\textbf{Z}(\textbf{P}(\textbf{1}))
\rightarrow\textbf{Z}(\textbf{0})
\rightarrow\textbf{T}$
Haskellの式は後ほど。
iOS の Widget で "embedded binary’s bundle identifier is not prefixed with the parent app’s bundle identifier." エラー

昔作った iOS Widget アプリを久しぶりにメンテしようと思ったら、エラーが出て困りました。
エラーの内容は以下。

> embedded binary’s bundle identifier is not prefixed with the parent app’s bundle identifier.

問題自体は単純でしたが、解決に少し時間を食ってしまったので、備忘録として残しておきます。

## 原因

調べるとすぐ出てきますが、 Widget ターゲットの Bundle ID は、 App ターゲットの Bundle ID で始まる必要があります。

例えば、App の Bundle ID が `com.example.ios.app` ならば、 Widget の Bundle ID は `com.example.ios.app.MyWidget` のようにするということです。

## チェックポイント①

Xcode のプロジェクト情報で、各ターゲットの General > Identity > Bundle Identifier を確認します。
ここが先述の形式を守っていない場合は、修正しましょう。

## チェックポイント②

Info.plist を開き、 Bundle Identifer (CFBundleIdentifier) の値が正しくセットされているか確認します。
通常は `$(PRODUCT_BUNDLE_IDENTIFIER)` のような値が入っているのが正しいかと思います。


## 終わりに

①をいくら確認しても正しい形式で、「なんでや〜」となっていたのですが、 Info.plist を見たら情報が少なく違和感を覚え、試しに値を入れてみたら動きました。
何かの拍子に消してしまったのかもしれません。
Info.plist がどんな情報を扱っているのか把握しておくのは大切ですね。
保険について

## 初めに
皆さんこんにちは、大野です。

現在私の仕事は保険の帳票を作成することです。私はこの仕事をするまで保険について全然知りませんでした。特に20代だと私と同じようにあまり詳しくない方も多いのではないかと思います。そこで今回の記事では保険の種類について簡単に説明したいと思います。保険といいましても、種類や説明がとても多くなるので、何回かに分けて書きます。今回はその1回目になります。まずは一般的な種類を知ってもらいたいと思います。

※保険商品の内容は保険会社によって細部が違います。当記事だけで納得しないでご自分でも調べてください。

##  保険とは
保険とは、多くの人が保険料を出し合い、生活の中で起こるさまざまなリスクに備える制度のことです。ただ、一口に「保険」と言っても、その種類はさまざまです。特に、民間の保険会社が運営する任意加入の保険には、とても多くの種類があります。保険によって備えるべきリスクや必要な保障（補償）は、人によって異なるため、種類ごとの違いを理解した上で自分に合った保険選びをすることが大切です。
ここでは、民間の保険会社が提供する保険の種類について説明します。

## 保険の種類一覧
生命保険
 - 終身保険
 - 定期保険
 - 収入保障保険
 - 医療保険
 - 女性向け医療保険
 - 引受基準緩和型医療保険・無選択型医療保険
 - がん保険
 - 就業不能保険
 - 介護保険
 - 個人年金保険
 - 養老保険
 - 学資保険
 等

損害保険
 - 火災保険
 - 地震保険
 - 自動車保険
 - バイク保険
 - 自転車保険
 - 傷害保険
 - 所得補償保険
 - 海外旅行傷害保険
 - ペット保険
 - ゴルファー保険
等

## 生命保険と損害保険
民間の保険は、「生命保険」と「損害保険」に分けられます。生命保険は、主に被保険者の死亡または病気やケガに備える保険です。一方、損害保険は、災害や事故によって生じる損害に備える保険です。

さらに、生命保険と損害保険の中にも、それぞれいくつもの種類があります。例えば、生命保険には終身保険・定期保険・医療保険・がん保険等があり、損害保険には火災保険・地震保険・自動車保険・旅行保険等があります。

## 保険商品の説明
#### 終身保険
終身保険は、保険期間が一生涯続く生命保険です。被保険者が死亡または保険会社所定の高度障害状態になった際に、加入時に定めた死亡・高度障害保険金が支払われます。また、満期の仕組みがなく、一定期間加入した後に解約した場合は解約返戻金を受取れるため、貯蓄として活用することも可能です。解約時期や契約内容によっては、保険料払込期間終了後に、払込保険料の総額を上回る解約返戻金を受取れる保険商品もあります。
保険料の払込方法には、払込みを一生涯続ける「終身払タイプ」や、一定年齢または一定期間で払込みが満了する「有期払タイプ」、一度にまとめて払込む「一時払タイプ」があり、加入目的や将来設計に応じて選択できます。

#### 定期保険
定期保険は、保険期間があらかじめ決まっている生命保険です。終身保険と同じく、被保険者が死亡または保険会社所定の高度障害状態になった際は、死亡・高度障害保険金が支払われますが、保険期間が一定年齢や一定期間に定められているという特徴があります。一般的に、満期保険金や解約返戻金がない掛け捨て型の保険となり、その分、保険料は終身保険よりも割安です。
定期保険の期間の設定方法には2種類あります。「加入から10年間」というように年数で設定する「年満了」と、「60歳まで」のように被保険者の年齢で設定する「歳満了」です。年満了は満期になったら契約が自動更新となる「更新型」で、歳満了は満期になると契約終了となる「全期型」であることが一般的です。

#### 収入保障保険
収入保障保険は、被保険者が死亡または保険会社所定の高度障害状態になった際、年金のように、満期まで毎月決まった額の保険金が支払われる保険です。支払われる保険金の額は毎月一定で、保険期間の経過とともに受取る期間が短くなるので、受取総額は徐々に減少していきます。一般的には定期保険より保険料が割安な傾向にあり、低年齢の子どもがいる世帯からのニーズが高い保険です。

## 今回はここまで
まだまだ続き長くなるので今回はここまでです。次回では続きの説明をしたいと思います。

以上、大野でした
【Java】Javaで使う型について

# 初めに
Javaでは数値や文字列を扱うための型という定義が存在する。これらは別の型から別の型に変換できるものもあれば、変換に一工夫が必要なものもある。

# 型の種類について
Javaで取り扱う型は以下が存在する。

〇基本データ型(プリミティブ型)
値をそのまま保持するイメージ。
|型名  |分類  |範囲  |サイズ  |
|---|---|---|---|
|byte  |整数  |-128~127|8bit|
|short  |整数  |−32,768 ～ 32,767  |16bit|
|int  |整数  |−2,147,483,648 ～ 2,147,483,647  |32bit|
|long|整数  |−9,223,372,036,854,775,808 ～ 9,223,372,036,854,775,807 |64bit|
|float  |小数  ||32bit|
|double  |小数  ||64bit|
|char  |1文字  ||16bit|
|boolean  |真偽値  ||1bit|

整数のデフォルトはint型、小数のデフォルトはdouble型である。またlong型では末尾に**L**、float型では末尾に**F**をつける。

〇参照型
メモリ上に存在するデータを参照するイメージ。
|型名  |分類  |
|---|---|
|String  |文字列  |

なおString型はchar[]のようなイメージ。String型でabcの文字列があったとしたら以下のように考えることができる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2521217/b81affd0-ca79-428d-9a8b-c93ceb867509.png)

またString型は参照型だが疑似プリミティブ型とも呼ばれる。その理由として不変性がある。

突然だが以下のようなソースの結果はどうなるだろうか？

```ruby:Main.java
public class Main {
	public static void main(String[] args) {
		String str = "Hello";
		str.replace("H", "A");
		System.out.println(str);
	}
}
```

replaceメソッドは第一引数の文字を第二引数の文字に置き変えするメソッドである。どのような結果になるか考えてみよう。

<!-- open属性あり -->
<details open><summary>解答はこちら</summary>

```
Hello
```

この場合Aelloにはならない。strは不変なオブジェクトなので、代入しない限りstr自体が変更されることは無い。
</details>

## StringBuilderクラス
String型は不変だがStringBuilderクラスは可変なクラスである。以下の問題を考えてみよう。

```ruby:Main.java
public class Main {
	public static void main(String[] args) {
		StringBuilder str = new StringBuilder("Hello");
		str.replace(0,1,"A");
		System.out.println(str);
	}
}
```
<!-- open属性あり -->
<details open><summary>解答はこちら</summary>

```
Aello
```

この場合StringBuilerクラスは可変なので、replaceメソッドで文字列の書き換えが行われ、strにも反映される。ここで注意なのがreplaceメソッドの使い方。String型とは異なり、第1引数から第2引数までの文字を第3引数の文字に変換する。

</details>



## まとめ
* Javaでは基本データ型(プリミティブ型)と参照型が存在する
* 整数を取り扱う型では取り扱うことができる範囲が異なるので注意
* String型は不変なオブジェクトなので、代入されない限り値が変わることは無い
* StringBuilderクラスは可変なので、文字列の書き換えが可能
【Java】パッケージのアクセス制御

# 初めに
Javaではアクセス修飾子やモジュールを用いたアクセス制御が存在する。その中でも今回はパッケージによるアクセス制御に着目してみた。

## パッケージとは？
パッケージはクラスやインタフェースを管理するために使うもので、以下の機能を提供する。

* 名前空間を提供
* アクセス修飾子と組み合わせてアクセス制御機能を提供
* クラスの分類を可能にする

以下のようにしてパッケージは設定できる。この時package→import→classの順番に記述する。

```ruby:Java
package beta;
import alpha.Base;
public class Main{
	public static void main(String[] args) {
		//source
	}
}

```

## 無名パッケージから無名パッケージへのアクセス
パッケージ名を明示的に設定していない場合は無名パッケージ(デフォルトパッケージ)の扱いとなる。この時、無名パッケージから無名パッケージのアクセスは設定等必要ない。

```ruby:Java(Main.java)
public class Main {
	public static void main(String[] args) {
		Hensu.hensu();
	}
}
```

```ruby:Java(Hensu.java)
public class Hensu {
	public static void hensu(){
		int hensu = 1;
		System.out.println(hensu);
	}
}
```

結果
```
1
```

## 無名パッケージ・名前ありパッケージから名前ありパッケージへのアクセス
以下のようにimport文を使用してアクセス可能。

```ruby:Java(Main.java)
import alpha.Base;
public class Main {
	public static void main(String[] args) {
		Base base = new Base(1);
		System.out.println(base.getValue());
	}
}
```

```ruby:Java(Base.java)
package alpha;
public class Base {
	private int value;
	public Base(int value) {
		this.value = value;
	}
	public int getValue() {
		return value;
	}
}
```
結果
```
1
```

## 名前ありパッケージから無名パッケージへのアクセス
これは不可能。無名パッケージは同じく無名パッケージからしかアクセスできない。以下のようにメソッドを指定すると、エラーになる。

```ruby:Java(Hensu.java)
public class Hensu {
	public static void hensu(){
		int hensu = 2;
		System.out.println(hensu);
	}
}
```

```ruby:Java(Base.java)
package alpha;

public class Base {
	public 	static void main(String[] args) {
    		Hensu.hensu();//無名パッケージのクラスを呼び出し
	}
}
```
結果
```
Exception in thread "main" java.lang.Error: Unresolved compilation problem: 
	Hensu を解決できません

	at alpha.Base.main(Base.java:5)
 ```

 ## まとめ
 * パッケージの役割は名前空間の提供・アクセス修飾子と組み合わせてアクセス制御機能を提供・クラスの分類
 * 無名パッケージから無名パッケージへのアクセスに設定は必要ない
 * 無名パッケージ・名前ありパッケージから名前ありパッケージへアクセスする場合はimport文を使う
 * 名前ありパッケージから無名パッケージへのアクセスは不可