OmniAICreator/Qiita-1.07M huggingface dataset:
keyballでfusion360の視点操作

# はじめに
keyball用のケースやスタンドを作成するためにfusion360を使用し始めました。
操作もkeyballでやっています。
トラックボールでの操作は細かい動きが難しかったり、視点移動さえも思ったようにできなかったりしていますが、まぁやるだけやってみてからまた考えようと思っています。
以下は現状の操作での工夫です。

# 環境
Mac

# 必要物品
1. keyball
1. [mac mouse fix](https://macmousefix.com)

# mac mouse fix 設定
* 以下の様に設定してください
![スクリーンショット 2024-05-26 15.21.05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/411737/a04ae1a2-2257-96f7-4af6-af85af6b9d72.png)
![スクリーンショット 2024-05-26 15.21.11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/411737/9331e895-a37a-4e4d-0af4-185ac7bee9b2.png)

# keyball設定
* スクロールスナップが使えるようにしてください
* スクロールレイヤーにBTN4を設定してください

# 使い方
## パン
スクロールレイヤーでカーソル移動なくパンができます。
中クリックと違って画面移動の制限なく動かせて便利ですが、斜め移動ができません。
柔軟に動かしたい時は中クリックで。
## 回転
普通にShift+中クリックで。
Shift+スクロールで水平方向のみ回転できますが……
垂直方向にも回転させて欲しい。
## ズーム
BTN4+スクロールでズーム可能です。
パンした後すぐにやろうとすると反応が微妙ですが。
## スマートズーム
BTN4をクリック。
全体を見やすい角度になります。

# 終わりに
3Dマウスみたいに柔軟に視点移動をしたいよ〜
keyballのファームいじってスクロールの処理いじればいいんだろうけど、スクロール方向を垂直水平方向で両方受けとるように書き換えればいけそう
できるのかはわからない
【エンジニアコミュニティ】人生初めてのエンジニアイベントに参加してみて感じたこと(ししとうLT #2)

# はじめに
5月からエンジニアになったエンジニアが初めてLT会に参加し、感じたこと、思ったことを綴ります。
ただの自分語りですが、もしエンジニアイベントに興味がある方や「行ってもなにもわからなくて置いていかれそう…」と考えてる方はぜひ見てください。少しは後押しできる内容になっていたらいいなと思っています。

# 今回参加したイベントについて
### 今回参加したイベントについて
![20240520 192708.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3784901/5ce957db-8646-ce5b-ea57-67b8bd62b4e5.jpeg)



今回参加させていただいたのはアスエネ株式会社様、フラー株式会社様、株式会社IVRy様、株式会社InsightEdge様株式会社HRBrain様の5社が共催している『ししとうLT #2 -若手LT会-』です。名前に「若手」と書いてあり、私自身が参加しやすそうな雰囲気だったので、予約させていただきました。
有志で登壇者を募り、発表を聞く形のLT会でした(大体どの方が主催のLT会でもそのような形が取られていると思います)。



### イベントの内容
https://4410.connpass.com/event/316005/

詳細は上記のURLから見ていただきたいのですが、若手エンジニアの方々がするべきことや「いまこんなことをしているよ・こんな技術があるよ」など様々でした。私より年下の方が発表している姿を見て、「IT業界の若手はすごいなあ」と考えさせられる発表でした。

# 結局参加してみてどうだったか
これだけは先に皆さんへ伝えたいです。<br>
**絶対に参加した方がいいです**<br>
結論はこれ一択です。初めていくイベント、しかも知識もない状態で行って、何の意味があるのかわからないと感じてしまうかもしれません。今からイベントに参加することを絶対に推す理由を5つ書かせていただきます。

# イベントに参加した方がいい理由5選
### 最新の技術や知識をインプットできる
皆さんがイベントに参加する目的は知識や技術のインプットが挙げられると思います。実際、イベントに参加することで私自身が知らなかったことをたくさん知ることができました(ただし、理解はまだ難しい…)。
エンジニアとして最新の情報を常に身につけないといけないと考えています。ただ、自分1人でパソコンをカタカタして、調べても全く頭に入ってきません。最新の技術や知識を利用している人の話を聞く方が圧倒的にわかりやすく、まとめられているので習得効率が上がると思います。

### エンジニアの人と交流ができる
今回のイベントを通して、一番のよかったなと思ったことです。LT発表会の後に「フリートーク」という参加者全員参加と交流することができる時間が設けられていました。時間の限り、私もエンジニアの方々と話をさせていただきました。フロントエンドからバックエンド、フリーランスの方など、話す人全員が魅力的な方々でした。自分の会社だけでは絶対に得ることができない、知識の広がりを感じることができる場になっていました。
「知識もないのに話しかけてもいいのかな」と感じる人もいると思いますが、イベントに参加されている方は優しい方が多いので、きっと大丈夫です!どんどん話かけちゃいましょう!!

### モチベーションにつながる
私は今回聞くことだけに徹底をしていましたが、とりあえずエンジニアの皆さんがかっこよかったです。「これは何語何だ…(笑)」と感じるぐらいわからないことだらけでしたが、そのような言語をスラスラと話している姿を見て、「自分も必ずこんなエンジニアになりたい…」としみじみと思う3時間でした。
そして、もう１つ、私が勤務している会社以外の会社に入れることもモチベーションを上げる要因です。今回会場提供してくださった株式会社HRBrain様の社内の画像です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3784901/0136b0fe-1141-dce8-6928-1217db249218.png)
>引用: https://paiza.jp/recruiters/5464


お察しの通り、おしゃれすぎる…(笑)。
「いつかここに入って、スタバでも飲みながら仕事をしたら」と考えるだけでかっこいいですね…。IT会社ならではの雰囲気などを実際に見学できるのでよい点だと思います。

### 会話力が身に付く
2つ目のエンジニアと交流ができるという理由と似ているのですが、年齢層や考え方が様々な方が一度に集まって交流できる場があります。普段、同僚としか話さないという方もいらっしゃると思いますが、いろんな人と交流する中で会話力が身につき、それが仕事で生きてくるなんてことが少なくないです。何の関係もない人が集まって行う交流会に参加するよりも、趣味・思考が共通している可能性が高い、エンジニアイベントの交流会に参加した方が、きっと話しやすいと思います。

### 自分のことを知ってもらえる。認めてもらえる。
繰り返しになりますが、私はIT業界に入って1ヶ月のベイビーエンジニアです。時折、私がした決断は間違っていないのか考えさせられることがあります。そんな中、イベントでお話をさせていただいた方々と話しているうちに「カジュアル面談いつでもおいで」「すごいな、頑張って」「わたしも◯歳からITに転職して…」など声かけをしてもらいました。教育業界からのIT業界の転職で不安だった私にとっては、現在活躍中のエンジニアの人から直接いただき言葉で元気が出ました。これから声をかけてくださった方々に追いつけるよう努力していきたいと思います。

# 最後に
最後まで読んでくださりありがとうございます。ここまで読んでいただいて参加してみたいと感じた方がいれば、ぜひ『connpass』というエンジニアWebサイトをお勧めします。私も今回ここで予約をしました。エンジニアイベントはここに集まっています。

https://connpass.com/user/koutorino/

<br>
また、私が参加した『ししとうLT #3』も開催予定です。気になる方はぜひ参加してみてください(5/26現在)。若手エンジニアの方にはお勧めできるイベントです。

https://4410.connpass.com/event/318108/
OSS-DB Silver を92点で合格する学習方法

# はじめに
LinuCもレベル3まで認定して次のOSS系資格は何を勉強しようかと思案した結果、OSS-DBを選びました。
OSS-DBの試験範囲となるDBは、オープンソースのPostgreSQLです。
PostgreSQLは以前の現場でちょっとだけコマンド打って操作したことがあったので、多少とっかかりやすいだろうと思った次第です。

# 何を利用して勉強したか
以下の2つをきちんとやれば絶対合格できます。

問題演習は主に下記のリンクで紹介されている学習教材からPing-tを。
（「最強WEB問題集 OSS-DB Silver」といやつです）

https://oss-db.jp/learning

Ping-tの問題演習は解説もあって、とても役立ちますが細かいことは抜けていたりします。
そこを埋めるためにLPI-Japanが公開している下記リンクの教科書を利用しました。

https://oss-db.jp/ossdbtext

PDF、EPUBで無償ダウンロードできるので追加費用もかかりません。

いろいろあって勉強時間を捻出できず、結局試験勉強に3カ月かかりましたが92点で合格しました。
（勉強する日もあればしない日もあり、やっても1日30分程度しかしてなかったので3カ月も…）

# 最後に
ただ試験に合格することだけを考えるならPing-tで問題演習をやりこむだけでもいいかもしれません。
しかし、DBの知識、技術も活かしてキャリア形成していくなら、前述の教科書を参照しながら手を動かして（環境作成したりコマンド打ったり）カラダで覚えていくのがおすすめです。

約半世紀ずっーーーーーと引きこもりで地球から一歩も出ていない石ころでもできるのですからガブガブいきましょう。
sin20*sin40*cos40:三角関数「和積公式と積和公式(Sum-to-product,Product-to-sum)」についてChatGPTとsympyとwolframalphaで調べてみた。(その2)

**パイソニスタの方へ**
(1)(2)(3)の違いがわかりませんでした。sympyで**三角関数の積和の公式**をやってみた。
アドバイスをいただけたら幸いです。

# ChatGPT-3.5先生へ
```
sin20 sin40 cos 10
```
(回答省略、大変参考になりました。丸写し???)

# sympyで
(1)(2)(3)
```python
# (1)
from sympy import *
A=rad(20)
B=rad(40)
C=rad(10)
expr=sin(A)*sin(B)*cos(C)                               ;print("#",expr)
expr=simplify(expand_trig(A,B)*cos(C))                  ;print("#",expr);print()
# (2)
from sympy import *
A=rad(20)
B=rad(40)
C=rad(10)
expr=sin(A)*sin(B)*cos(C)                                ;print("#",expr )
expr=simplify(Rational(1,2)*(cos(A-B)-cos(A+B)))*cos(C)  ;print("#",expr);print()
# (3)
from sympy import *
def MY_expand_trig(A,B):
    return Rational(1,2)*(cos(A-B)-cos(A+B))
A=rad(20)
B=rad(40)
C=rad(10)
expr=sin(A)*sin(B)*cos(C)                                ;print("#",expr)
expr=simplify(MY_expand_trig(A,B)*cos(C))                ;print("#",expr)
# sin(pi/9)*sin(2*pi/9)*cos(pi/18)
# pi*cos(pi/18)/9

# sin(pi/9)*sin(2*pi/9)*cos(pi/18)
# (-1/4 + cos(pi/9)/2)*cos(pi/18)

# sin(pi/9)*sin(2*pi/9)*cos(pi/18)
# sqrt(3)/8
```

# wolframalphaで

https://www.wolframalpha.com/input?i=sin20+sin40+cos+10&lang=ja

残念でした。

# いつもの? sympyの実行環境と 参考のおすすめです。
(テンプレート)

https://qiita.com/mrrclb48z/items/00dd08b0317069be9342

# いつもと違うおすすめです。
・知恵袋

https://detail.chiebukuro.yahoo.co.jp/qa/question_detail/q13221737378

・ヤッパリこれでしょうか？

https://docs.sympy.org/latest/modules/simplify/fu.html

・オリジナル(その1)

https://qiita.com/mrrclb48z/items/fa4c295cf877206889e6
boto3 list_resource_record_setsの罠

## 概要
業務にて、AWSのマルチリージョンフェイルオーバーを検証中
フェイルオーバー時に使用するDNSレコードの重みを変換するスクリプト内にてboto3の`list_resource_record_sets()`を利用していたのですが、不要なレコードまで引っ張ってきてしまっていたので仕様を紐解きます。

## list_resource_record_sets()の仕様
`list_resource_record_sets()`は、検索条件が指定できるものの、あくまでOR条件での検索になります。
検索条件は以下です(公式Docより引用: https://boto3.amazonaws.com/v1/documentation/api/1.26.88/reference/services/route53/client/list_resource_record_sets.html)
```python
response = client.list_resource_record_sets(
    HostedZoneId='string',
    StartRecordName='string',
    StartRecordType='SOA'|'A'|'TXT'|'NS'|'CNAME'|'MX'|'NAPTR'|'PTR'|'SRV'|'SPF'|'AAAA'|'CAA'|'DS',
    StartRecordIdentifier='string',
    MaxItems='string'
)
```

OR条件で検索後、**条件に最も合致しているレコードが上位にソートされる仕様になっています。**(最大300アイテム)
一見するとAND条件での検索に見えるため注意が必要です。

## 対応
シンプルですが、ターゲットのレコード名以外を弾く処理にしました。
Route53から引っ張ってきたNameは後半に"."が追加されている点も注意が必要です。
```python
# 対象のレコード以外は処理終了
if record_set["Name"] != f"{record_name}.":
    continue
```

## まとめ
当初検証用に新設したアカウントで実行しており、他レコードがなく上記仕様に気づいておりませんでした。本番アカウントで実行中に気付き、幸いことなきを得ましたが冷や汗をかきました。。。
みなさまもお気をつけください。
keyballのスクロール方向をOSによって反転させた

# はじめに
タイトルの通りです。
以前にも雑にスクロール方向を反転させましたが、今回はos_detectionを使用して反転させています。

# やること
1. keyballのファームを自分でコンパイルできるようにする（省略）
1. keyball/lib/keyball.cの188行目あたりの関数の最後に以下のように追記
1. コンパイルしてファーム書き込んで終わり

```keyball.c
__attribute__((weak)) void keyball_on_apply_motion_to_mouse_scroll(keyball_motion_t *m, report_mouse_t *r, bool is_left) {
    // consume motion of trackball.
    int16_t div = 1 << (keyball_get_scroll_div() - 1);
    int16_t x = divmod16(&m->x, div);
    int16_t y = divmod16(&m->y, div);

    // apply to mouse report.
#if KEYBALL_MODEL == 61 || KEYBALL_MODEL == 39 || KEYBALL_MODEL == 147 || KEYBALL_MODEL == 44
    r->h = clip2int8(y);
    r->v = -clip2int8(x);
    if (is_left) {
        r->h = -r->h;
        r->v = -r->v;
    }
#elif KEYBALL_MODEL == 46
    r->h = clip2int8(x);
    r->v = clip2int8(y);
#else
#    error("unknown Keyball model")
#endif

    // Scroll snapping
#if KEYBALL_SCROLLSNAP_ENABLE == 1
    // Old behavior up to 1.3.2)
    uint32_t now = timer_read32();
    if (r->h != 0 || r->v != 0) {
        keyball.scroll_snap_last = now;
    } else if (TIMER_DIFF_32(now, keyball.scroll_snap_last) >= KEYBALL_SCROLLSNAP_RESET_TIMER) {
        keyball.scroll_snap_tension_h = 0;
    }
    if (abs(keyball.scroll_snap_tension_h) < KEYBALL_SCROLLSNAP_TENSION_THRESHOLD) {
        keyball.scroll_snap_tension_h += y;
        r->h = 0;
    }
#elif KEYBALL_SCROLLSNAP_ENABLE == 2
    // New behavior
    switch (keyball_get_scrollsnap_mode()) {
        case KEYBALL_SCROLLSNAP_MODE_VERTICAL:
            r->h = 0;
            break;
        case KEYBALL_SCROLLSNAP_MODE_HORIZONTAL:
            r->v = 0;
            break;
        default:
            // pass by without doing anything
            break;
    }
#endif

// --- ここから追記 ---
    // windowsOSでスクロール方向反転
    if (detected_host_os() == OS_WINDOWS || detected_host_os() == OS_LINUX){
      r->h = -r->h;
      r->v = -r->v;
    }
// --- ここまで追記 ---

}
```

# 終わりに
本当はユーザーレベルで改変した方がいいのかな
できるのかな
laravelで外部キー制約をする 

# はじめに
外部キー制約とは、2つのテーブルを __親テーブル__ と __子テーブル__ にして生合成を保つために用いられる。

# 例
webアプリに次のテーブルがあるとする。(イメージはツイッターなどのアプリ)
- 親テーブル:usersテーブル
- 子テーブル:postsテーブル
:::note
 ここで注意するのは、誰が投稿したかがわかる`user_id`というカラムが`postsテーブル`にあること
:::

# ルール
:::note warn
migrationsフォルダに親よりも先に子を作るとうまくいかなくなるらしいので注意が必要
:::

## まずは//1のように``user_id``を作成します。

子テーブル
```databases/migration/create_posts_table.php
public function up()
{
    Schema::create('posts', function (Blueprint $table) {
        $table->id();
        $table->string('name')->unique();
        $table->unsignedBigInteger('user_id'); //1 外部キー ※型には注意！
        $table->foreign('user_id')->references('id')->on('users');//2 外部キー制約をつける 
        $table->timestamps();
    });
}
```


 
:::note alert
 この時注意しなければならないのは、``user_id``の``データ型``は何でもいいわけではない！
 usersテーブルのidカラムと同じでなければならない！
:::
デフォルトのusersテーブルではidカラムのデータ型は``unsignedBigInteger型``なので、作成するuser_idのデータ型も``unsignedBigInteger型``でなければなりません。

親テーブル

```databases/migration/create_users_table.php
public function up()
{
    Schema::create('users', function (Blueprint $table) {
        $table->id(); // ここが unsignedBigInteger型
        $table->string('name')->unique();
        $table->timestamps();
    });
}
```

## 次に//2で外部キー制約をかける
次に、//2のように外部キー制約を実装する。

子テーブル
```databases/migration/create_posts_table.php
$table->foreign('user_id')->references('id')->on('users');//2 外部キー制約をつける
``` 
1\. ``->foreign('xxx')``で外部キー制約したいカラムを指定する
2\. ``->references('yyy')``で参照したいカラム名を指定する
3\. ``->on('zzz')``でその参照したいカラムがあるテーブル名を指定する

これで、``userテーブルにあるidカラム``を``postsテーブルのuser_id``に参照させ、外部キー制約することができる！

## 実はもう一つ方法がある（省略型）
``foreignId``メソッドを使うことで前に書いた方法よりも短く書くことができる。

子テーブル
```diff_php
public function up()
{
    Schema::create('posts', function (Blueprint $table) {
        $table->id();
        $table->string('name')->unique();
        $table->unsignedBigInteger('user_id'); //1 外部キー ※型には注意！
-        $table->foreign('user_id')->references('id')->on('users');//2 外部キー制約をつける 
+        $tabel->foreignId('user_id')->constrained();//2 ここで foreignIdメソッドを使う
        $table->timestamps();
    });
}
```

```diff_php
$tabel->foreignId('user_id')->constrained();
```
1\. 外部キー制約したいカラム名を``foreignId``メソッドの引数に与える。
2\. ``constrained``メソッドは``foreignId``メソッドに与えられた引数から``どのテーブルのどのカラム``を参照したいのかを判断してくれる。

よって``uesr_id``をforeignidメソッドに与えると,constrainedメソッドが``user_id = usersテーブルのidカラム``を参照したいと判断してくれる。
メモリマップファイル

# メモリマップファイルとは
```ファイルの領域を仮想アドレス空間上にマップ```する。
mmap()関数を所定の方法で呼び出すことで、ファイルの内容をメモリに読み出して、その```領域を仮想アドレス空間にマップ```できます。

データを変更した場合は、後ほどストレージデバイス上のファイルに所定のタイミングで書き戻します。

# データ変更後のストレージデバイスへの書き戻し
```
root@***********:***********#　echo hello >testfile
root@***********:***********# go build filemap.go
root@***********:***********# ./filemap
*** testfileのメモリマップ前のプロセスの仮想アドレス空間 ***
00400000-004aa000 r-xp 00000000 08:05 402438                             /***********/filemap
....

testfileをマップしたアドレス: 0x7f26cfa74000

*** testfileのメモリマップ後のプロセスの仮想アドレス空間 ***
00400000-004aa000 r-xp 00000000 08:05 402438                             ***********/filemap
...
7f26cfa74000-7f26cfa75000 rw-s 00000000 08:05 796044                     ***********/testfile
...

root@***********:***********# cat testfile
HELLO
```
### 気づき
ファイルの上書きをしている。
ストレージデバイスが仮想メモリにマップして（実際はページテーブルに対応する物理メモリにマップする）ファイルの変更があれば仮想メモリ→物理メモリ→ストレージデバイスという流れでファイルの上書きがされるのか。

# 出典
https://gihyo.jp/book/2022/978-4-297-13148-7

# 感想
取り敢えず断片的に理解しよう
モデリングの世界に再入門：ミスユースケース図

# はじめに

UMLの基礎からしっかりと学び直し、プロジェクトで役立つ形にアウトプットしていきたいと考えました。
自分自身の理解を深めるとともに、同じような課題を感じている方々の一助となれば嬉しいです。

詳しいモチベーションはこちらの記事をご参照ください。

https://qiita.com/tkmsk/items/0ff91acf7397f80ace0b

これまではユースケース図・ユースケース記述に関してまとめました。

https://qiita.com/tkmsk/items/3be81fa1034770dab66a

https://qiita.com/tkmsk/items/df5830b58874731e8cbc

今回は、ミスユースケース図に関してまとめていきます。

# ミスユースケース図

## 概要

ミスユースケース図はユースケース図を拡張した図です。
システムの振る舞い（＝システムがどのような機能を提供するのか）を表すと共に、意図しない振る舞いや望ましくない事象も表すときに使用します。

## 例：ATM

```plantuml
left to right direction

actor "顧客" as customer
actor "銀行" as bank
actor "攻撃者" as attacker

rectangle "ATMシステム" {
    usecase transfer as "送金"
    usecase withdraw as "引き出し"
    usecase deposit as "預け入れ"
    usecase register as "ATM登録"
    
    usecase "不正引き出し" as misWithdraw
    usecase "セキュリティ対策" as security 
    usecase "システム障害" as systemFailure
}

customer "1" --> "0...1" withdraw
customer "1" --> "0...1" transfer
customer "1" --> "0...1" deposit
bank "1" --> "0...*" deposit
bank "1" --> "0...*" register

misWithdraw <-- attacker
security ..> misWithdraw : <<mitigate>>

transfer <<-- systemFailure : <<threaten>>
withdraw <<-- systemFailure : <<threaten>>
deposit <<-- systemFailure : <<threaten>>
security ..> systemFailure : <<mitigate>>
```

このミスユースケース図は、ある銀行のATMシステムの以下の振る舞いを表しています。

* 顧客は、自身の口座に対して引き出し・預け入れ・送金をすることができる
* 銀行は、ATMの登録・任意の口座への預け入れができる
* 引き出し・預け入れ・送金は、システム障害により失敗する可能性がある
* 攻撃者により、不正引き出しをされる可能性がある
* 不正引き出し・システム障害の対策として、セキュリティ対策を実施する

## 構成要素

※システム境界・ユースケース・アクターに関しては、ユースケース図の記事でまとめているので省略します。

### ミスユースケース

例にあげた、不正引き出し・システム障害がミスユースケースにあたります。
`threaten`の関係線を用いて表されます。
システムの誤った使用方法、意図しない動作、セキュリティ上の脅威などを表します。
システムにとって望ましくない事象を表し、リスクを特定するために使用します。

### 緩和ユースケース

例にあげた、セキュリティ対策が緩和ユースケースにあたります。
`mitigate`の関係線を用いて表されます。
ミスユースケースによる影響や被害を軽減または防止するための対策を表します。
1つの緩和ユースケースが複数のミスユースケースを緩和する場合もあります。

# さいごに

今回はミスユースケース図に関してまとめました。
ユースケース図を書いた後、ミスユースケース図を書くことで適切な対策が取れるようになると感じました。
【SQLの基本】未経験のエンジニア1年目が書くデータベース入門ガイド

# 目次
1. [はじめに](#1-はじめに)
2. [SQLの基本的な説明](#2-sqlの基本的な説明)
3. [SQL文の基本的な説明](#3-sql文の基本的な説明)
4. [SQL文の基本的な書き方](#4-sql文の基本的な書き方)
    - [DDL（データ定義言語）](#ddlデータ定義言語)
    - [DML（データ操作言語）](#dmlデータ操作言語)
    - [DCL（データ制御言語）](#dclデータ制御言語)
    - [TLC（トランザクション制御言語）](#tlcトランザクション制御言語)
5. [まとめ](#5-まとめ)
# 1. はじめに
こんにちは！新卒1年目の米満です。

この記事を開いていただきありがとうございます。
今回は、私が最近学んだSQLの基本概念とSQL文の使い方について書いていきます。

SQLはデータベースを操作するために欠かせないスキルです。
一緒に覚えていきましょう！
# 2. SQLの基本的な説明
SQL（Structured Query Language）は、リレーショナルデータベース管理システム（RDBMS）を操作するための標準的な言語です。データの定義、操作、制御、およびトランザクション管理を行うために使用されます。以下では、SQLの基本的な概念と主要な機能について説明します。
# 3. SQL文の基本的な説明
SQL文は、データベースに対する特定の操作を定義する命令文です。SQL文は大きく分けて以下の4種類に分類されます。
1. **データ定義言語（DDL）**: データベーススキーマの定義や変更を行うための文です。例として、テーブルの作成や削除があります。
2. **データ操作言語（DML）**: データの操作を行うための文です。例として、データの挿入、更新、削除があります。
3. **データ制御言語（DCL）**: データベースへのアクセス制御を行うための文です。例として、ユーザー権限の設定や取り消しがあります。
4. **トランザクション制御言語（TLC）**: トランザクションの管理を行うための文です。例として、トランザクションの開始、コミット、ロールバックがあります。
# 4. SQL文の基本的な書き方
SQL文は通常、大文字で書かれますが、小文字でも問題ありません。また、SQL文はセミコロンで終わります。次に、それぞれのSQL文の基本的な書き方について説明します。
## DDL（データ定義言語）
DDLは、データベースオブジェクトの構造を定義するための言語です。以下に、代表的なDDL文の例を紹介します。
- **CREATE**: テーブルやデータベースを作成する文
  ```sql
  CREATE TABLE users (
      id INT PRIMARY KEY,
      name VARCHAR(50),
      email VARCHAR(50)
  );
  ```
- **ALTER**: 既存のテーブルを変更する文
  ```sql
  ALTER TABLE users ADD COLUMN age INT;
  ```
- **DROP**: テーブルやデータベースを削除する文
  ```sql
  DROP TABLE users;
  ```
## DML（データ操作言語）
DMLは、データベース内のデータを操作するための言語です。以下に、代表的なDML文の例を紹介します。
- **SELECT**: テーブルからデータを取得する文
  ```sql
  SELECT * FROM users;
  ```
- **INSERT**: テーブルに新しい行を挿入する文
  ```sql
  INSERT INTO users (id, name, email) VALUES (1, 'Alice', 'alice@example.com');
  ```
- **UPDATE**: 既存の行を更新する文
  ```sql
  UPDATE users SET email = 'alice_new@example.com' WHERE id = 1;
  ```
- **DELETE**: テーブルから行を削除する文
  ```sql
  DELETE FROM users WHERE id = 1;
  ```
## DCL（データ制御言語）
DCLは、データベースへのアクセス権を管理するための言語です。以下に、代表的なDCL文の例を紹介します。
- **GRANT**: ユーザーに特定の権限を付与する文
  ```sql
  GRANT SELECT, INSERT ON users TO 'username';
  ```
- **REVOKE**: ユーザーから特定の権限を取り消す文
  ```sql
  REVOKE SELECT, INSERT ON users FROM 'username';
  ```
## TLC（トランザクション制御言語）
TLCは、データベーストランザクションを管理するための言語です。以下に、代表的なTLC文の例を紹介します。
- **BEGIN**: トランザクションの開始
  ```sql
  BEGIN;
  ```
- **COMMIT**: トランザクションの確定
  ```sql
  COMMIT;
  ```
- **ROLLBACK**: トランザクションの取り消し
  ```sql
  ROLLBACK;
  ```
# 5. まとめ
この記事では、SQLの基本概念と主要なSQL文の種類、およびその書き方について解説しました。
まず、SQLの概要とその重要性について説明しました。
次に、SQL文にはデータ定義言語（DDL）、データ操作言語（DML）、データ制御言語（DCL）、トランザクション制御言語（TLC）の4種類があることと、各種SQL文の具体例と基本的な構文を紹介しました。
SQLを理解し、実際に使ってみることで、データベースの操作や管理ができるようになります！
この記事が、データベース管理の理解を深める助けとなれば幸いです！
質問やフィードバックがあれば、ぜひコメント欄にお寄せください。
Laravel　多対多のテーブル設計と中間テーブルについて（初学者向け）

## はじめに
Laravelの学習中に、1対多のリレーションは組むことができたけれど、多対多の場合のテーブル設計はどう考えれば良いのか、また中間テーブルについてイメージが掴めなかったため、自分なりにまとめてみました。

## 作成するテーブル
以下の映画テーブルと俳優テーブルを例に考えてみます。

#### 映画テーブル
| id| タイトル (title) |公開年 (release_year) |
|:-:|:-:|:-:|
|  1 | インセプション  | 2010  |
|  2 |  タイタニック |  1997 |
| 3  | アベンジャーズ  |  2012 |

#### 俳優テーブル
| id | 名前 (name) |性別 (gender)|
|:-:|:-:|:-:|
|  1 |  レオナルド・ディカプリオ |male|
|  2 |  ロバート・ダウニー・Jr |male|
|  3 |  スカーレット・ヨハンソン |female|

１つの映画に複数の俳優が出演します。また1人の俳優は複数の映画に出演します。
つまり２つのテーブルの関係性は、多対多となります。

では、どの映画にどの俳優が出演しているかを紐づけるにはどうしたら良いか考えてみます。

## 1対多の場合
もし仮に１つの映画に1人の俳優しか出演しないとすれば、２つのテーブルの関係性は、1対多になるので、以下のように外部キーを設定することで出演した俳優を表せます。

#### 映画テーブル
| id| タイトル (title) |公開年 (release_year) |俳優ID（actor_id）|
|:-:|:-:|:-:|:-:|
|  1 | インセプション  | 2010  | 1|
|  2 |  タイタニック |  1997 | 1|
| 3  | アベンジャーズ  |  2012 | 2|

## 多対多（不適切な例）
これを踏まえて、多対多のテーブル設計をすると以下のようになります。

#### 映画テーブルに俳優IDを複数設定する（不適切な例1）
|id| タイトル (title) |公開年 (release_year) |俳優ID（actor_id）|俳優2ID（actor2_id）|俳優3ID（actor3_id）|
|:-:|:-:|:-:|:-:|:-:|:-:|
|  1 | インセプション  | 2010  | 1|NULL|NULL|
|  2 |  タイタニック |  1997 | 1|NULL|NULL|
| 3  | アベンジャーズ  |  2012 | 2|3|NULL|


映画ごとに出演する俳優の数は異なりますので、俳優の数が多い場合を想定して俳優IDのカラムをたくさん設定しておかなければいけないですし、俳優の数が少ない場合には無駄なNULLの値が増えてしまいます。

#### 俳優テーブルに映画IDを設定する（不適切な例2,3）
俳優テーブルに外部キーとして映画IDを設定し、出演映画を管理しようとすると、一人の俳優が複数の映画に出演しているので、複数の映画IDに対応する必要があります。

一つ目のテーブルはレコードが重複してしまいますし、二つ目のテーブルは一つのカラムに複数の値が挿入されるため、不適切です。

| id | 名前 (name) |性別 (gender)|映画ID（movie_id）
|:-:|:-:|:-:|:-:|
|  1 |  レオナルド・ディカプリオ |male|1|
|  2 |  レオナルド・ディカプリオ |male|2|
|  3 |  ロバート・ダウニー・Jr |male|3|
|  4 |  スカーレット・ヨハンソン |female|3|

| id | 名前 (name) |性別 (gender)|映画ID（movie_id）
|:-:|:-:|:-:|:-:|
|  1 |  レオナルド・ディカプリオ |male|1,2|
|  2 |  ロバート・ダウニー・Jr |male|3|
|  3 |  スカーレット・ヨハンソン |female|3|


多対多の設定の場合、映画テーブルや俳優テーブルに相手側の情報を持たせると、データが複雑になり管理が困難になるため、良くないようです。

## 多対多（中間テーブルの使用）
この問題を解決するため、中間テーブルという別のテーブルを作成して、管理することにします。

#### 映画俳優テーブル
| 映画ID(movie_id) | 俳優ID(actor_id) |
|:-:|:-:|
|  1 |  1 |
|  2 |  1 |
|  3 |  2 |
| 3  | 3  |

一見すると分かりづらいように思いますが、例えば1つ目のレコードは映画ID1の作品に俳優ID1の人が出演していることを表しています。

このように中間テーブルを使用することで、映画ごとに出演する俳優の数が多くなる場合にもカラムを増やす必要がなく、無駄な値も発生しません。


## おわりに
記事の作成にあたって、以下のページを参考にさせて頂きました。ありがとうございます。

https://qiita.com/fujita-goq/items/afd4307e90daf95c4f14

またテーブルの内容はChatGPTに考えてもらいました。

余裕があれば、Laravelでの多対多のテーブルのリレーションの設定方法についてもまとめたいと思います。
npm auditに毎回やられる。

# npm audit ってなに？

npm audit は、Node.js のパッケージマネージャーである npm のコマンドの一つで、プロジェクトの依存関係に含まれるセキュリティ脆弱性をスキャンし、レポートするためのものです。このコマンドは、依存関係に潜在的なセキュリティリスクがあるかどうかをチェックするために使用されます。

npm audit の基本的な使い方
スキャンの実行:
プロジェクトのルートディレクトリで npm audit を実行すると、現在インストールされているすべてのパッケージのセキュリティレポートが生成されます。


# 一回バックアップを取っておく

### 現在の依存関係のバックアップ
package.json と package-lock.json をバックアップして、問題が発生した場合に元に戻せるようにします。
```sh
cp package.json package.json.backup
cp package-lock.json package-lock.json.backup
```

### 依存関係の修正
npm audit fix --force コマンドを実行して、脆弱性を修正します。

```sh
npm audit fix --force
```

### 問題が発生した場合の対処
もし、npm audit fix --force を実行した後に問題が発生した場合は、以下のコマンドで元の状態に戻します。

```sh
mv package.json.backup package.json
mv package-lock.json.backup package-lock.json
npm install

```

```sh
rm -rf node_modules package-lock.json yarn.lock
```
Kotlin HashMap

## HashMapの使い方

HashMapは、Kotlinで提供されている一種のコレクションで、キーと値のペアを格納するためのデータ構造です。各キーは一意であり、それぞれのキーは特定の値にマッピングされます。HashMapは、キーに基づいて迅速に値を検索することができます。  以下に、HashMapの基本的な使用方法を示します：

```kotlin
fun main() {
    // HashMapの作成
    val map = HashMap<Int, String>()

// 要素の追加
    map[1] = "one"
    map[2] = "two"

// 要素の取得
    val one = map[1]  // "one"

// 要素の削除
    map.remove(1)

// HashMapのサイズ取得
    val size = map.size  // 1

// HashMapの全要素をループで処理
    for ((key, value) in map) {
        println("Key: $key, Value: $value")
    }
}
```

このように、HashMapはキーと値のペアを効率的に管理するための強力なツールです。

### 公式の情報

Hash table based implementation of the MutableMap interface

MutableMapインターフェースのハッシュテーブル・ベースの実装

https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/

https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/hash-map-of.html

------

IntelliJ IDEAで実行してプログラムを実行しています。

Returns an empty new HashMap.

空の新しい HashMap を返します。

```kotlin
fun main(args: Array<String>) {
    val map = hashMapOf<Int, Any?>()
    println("map.isEmpty() is ${map.isEmpty()}") // true

    map[1] = "x"
    map[2] = 1.05
    // Now map contains something:
    println(map) // {1=x, 2=1.05}
}
```

Returns a new HashMap with the specified contents, given as a list of pairs where the first component is the key and the second is the value.

指定された内容を持つ新しいHashMapを返します。指定された内容は、最初のコンポーネントをキー、2番目のコンポーネントを値とするペアのリストとして与えられます。

```kotlin
fun main(args: Array<String>) {
    val map: HashMap<Int, String> = hashMapOf(1 to "x", 2 to "y", -1 to "zz")
    println(map) // {-1=zz, 1=x, 2=y}
}
```

以上が、HashMapの使い方でした。
ABC355回答メモ

# 0.はじめに
　茶色へランクダウンが見えてきた今日この頃参加。
 A～Cは順調にいくも、Dでブレーキ。
 自分的には行けると思いましたが、ちょっとだめで
 TLE18個で終わりでした。
 レートも-14の810と、いよいよ崖っぷちです。

# 1.A - Who Ate the Cake?
　原理は単純だけど、実装はなかなか考える問題。
 【考え方】
 　・容疑者フラグを3つ用意し1をセット
 　・A・Bの証言で、犯人でないと分かった人の
   　容疑者フラグを0に変更
 　・容疑者フラグの合計が2なら犯人は絞れず-1を出力
   ・容疑者フラグの合計が1ならフラグが立っている人を出力
　上記考えで実装し、ＡＣでした。
   
　https://atcoder.jp/contests/abc355/submissions/53831705


# 2.B - Piano 2
　ちょっと前にでたpiano問題とは若干違った感じの問題。
 【考え方】
 　・リストAとリストBをリストCに登録。
  　その際、リストAは(値,0)のタプル、リストBは(値,1)のタプルで登録
 　・リストCを昇順ソート
 　・リストCをインデックスiで先頭から見ていき、
  　 C[i][1]が0のレコードが続いたらYesを出力して終了
 　・最後まで見ても0のレコードが続かなかったらNoを出力して終了

  上記でACとなりました。
  
　https://atcoder.jp/contests/abc355/submissions/53839877


# 3.C - Bingo 2
　素直にマス目を作ってチェックしていくだけだと
 TLEになるんだろうなという問題。
  行列斜め毎にマスを塗った数を集計し
  塗ったタイミングで塗った数がNになったら終了とすれば
  TLE回避できるかなと実装しました。
 
【実装】  
　・行ごとにN個、番号が呼ばれた数を集計するリストXを作成
　・列ごとにN個、番号が呼ばれた数を集計するリストYを作成
　・斜め用に2個、番号が呼ばれた数を集計するリストZを作成
　・リストAを先頭から見ていき以下の判断
 　-行チェック
　  ・A[i]をNで割った値をxに格納
   　→A[i]がNで割り切れる場合は、xから1マイナス
　  ・X[x]に1加算
   　　→加算後X[x]がNになったらi+1を出力して終了
 　-列チェック
　  ・A[i]をNで割った余り-1をyに格納
   　→A[i]がNで割り切れる場合は、yにN-1をセット
　  ・Y[y]に1加算
   　　→加算後Y[y]がNになったらi+1を出力して終了
 　-ななめチェック（左上から右下）
　  ・xとyが同じ場合
   　　→Z[0]に1加算
    　 →Z[0]がNになったらi+1を出力して終了
 　-ななめチェック（右上から左下）
　  ・xとN-y-1が同じ場合
   　　→Z[1]に1加算
    　 →Z[1]がNになったらi+1を出力して終了
　・リストAを最後までみてもビンゴがそろわなかったら-1を出力して終了

　最初適当に組んでみましたが意外とすーっとACとなりました。

　https://atcoder.jp/contests/abc355/submissions/53863100


以上
ファイルシステムへのアクセス

# ファイルシステムへの関数の種類
### 作成、削除
create(), unlink()など
### 開閉
open(), close()など
### 読み書き
read(), write(), mmap()など

# ディレクトリ操作
### 作成、削除
mkdir(), rmdir()
### カレントディレクトリ変更
chdir()
### 開閉
opendir(), closedir()
### 読む
readdir()

### 気づき
mkdir,rmdirは使ったことあるけどファイルシステムへの関数だったのか。
ファイルシステムの違いをこれら関数がユーザに対して意識させずに

# ファイルシステムアクセスへの流れ
* ファイルシステム操作用の関数が、```内部的にファイルシステム操作をするシステムコールを呼ぶ```。
* カーネル内の```仮想ファイルシステム(virtual filesystem, VFS)という処理```が動作し、そこから個々のファイルシステムの処理を呼ぶ。
* ファイルシステムの動作がデバイスドライバを呼ぶ。
* デバイスドライバがデバイスを操作する

### 気づき
図を見ると仮想ファイルシステムが複数のファイルシステムに対してアクセスし、それらがデバイスドライバをとおしてそれぞれのデバイス対して操作をしている。この図の意味がわからないが、取り敢えずこうなっている。

#### ext4とは
ext4とは、Linuxで標準的に利用される```ファイルシステム```の一つ。いわゆるextシリーズのファイルシステムで、ext3の後継として2008年に公開された。
 #### 出典
 https://e-words.jp/w/ext4.html#:~:text=ext4%E3%81%A8%E3%81%AF%E3%80%81Linux%E3%81%A7%E6%A8%99%E6%BA%96%E7%9A%84%E3%81%AB%E5%88%A9%E7%94%A8%E3%81%95%E3%82%8C%E3%82%8B%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB%E3%82%B7%E3%82%B9%E3%83%86%E3%83%A0%E3%81%AE%E4%B8%80%E3%81%A4%E3%80%82%E3%81%84%E3%82%8F%E3%82%86%E3%82%8Bext%E3%82%B7%E3%83%AA%E3%83%BC%E3%82%BA%E3%81%AE%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB%E3%82%B7%E3%82%B9%E3%83%86%E3%83%A0%E3%81%A7%E3%80%81ext3%E3%81%AE%E5%BE%8C%E7%B6%99%E3%81%A8%E3%81%97%E3%81%A62008%E5%B9%B4%E3%81%AB%E5%85%AC%E9%96%8B%E3%81%95%E3%82%8C%E3%81%9F%E3%80%82

# 出典
https://gihyo.jp/book/2022/978-4-297-13148-7

# 感想
ファイルシステムに対してのファイル操作の関数どこが疑問なのかわからない。取り敢えず頑張る
リモートデスクトップで追い出しを避ける方法

### 共有アカウントでRDPしていると他人を追い出す/追い出される・・・
 
Windowsのリモートデスクトップ（RDP）をする際に同じアカウントを利用している場合、
後から入った人が先に入っていた人を弾いてしまう。といった経験があると思います。

今回はそういったことが起こらないよう、
バッチとPowerShellを使ってRDPの追い出しを防止する仕組みを実現します。
<br>

↓まずはのようにbatとps1を同じフォルダに作ってください
（batの名前はなんでもよいです、文字コードを<b>ANSI</b>にしないと文字化けするかも）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2604770/cd8eeac7-143c-6c2b-cb72-95fcb3ad26e6.png)

<br>
bat内の「My_Computername」変数に接続したいホスト名を記入して下さい

```bat:aaa.bat
@echo off
cls

rem 接続したいホスト名を設定
set My_Computername=ComputerAAAAA

PowerShell -ExecutionPolicy Bypass -File "%~dp0リモート接追い出し防止.ps1" %My_Computername%
```
<br>
ps1の方は何も弄らなくていいです

```powershell:リモート接追い出し防止.ps1

# 変数の初期化
Remove-Variable -Name * -ErrorAction SilentlyContinue
Clear-Host

# 引数の取得
$MyHostname = $args[0]
$MyMode     = $args[1]
$MyPID      = $args[2]

# 観察モードでない場合の処理
if ($MyMode -ne "observation") {
    # ホスト名に一致するファイルの検索
    $MyHostnameFile = Get-ChildItem $PSScriptRoot -ErrorAction SilentlyContinue -Exclude "*.bat" | Where-Object { $_.Name -match $MyHostname }
    
    if ($MyHostnameFile) {
        # ログインユーザーの取得
        $LoginUser = Get-Content $MyHostnameFile.FullName
        Write-Host "既に $LoginUser さんがログオンしています"
        Write-Host "$LoginUser さんに連絡を取るか、5分後に再度お試しください。`r`n"
        Pause
        Exit
    }

    # ログインユーザー名をファイルに保存
    $env:USERNAME | Out-File "$PSScriptRoot\$MyHostname.txt"
    "$(Get-Date)：$env:USERNAME が $MyHostname へのリモートデスクトップ接続を開始しました" | Out-File "$PSScriptRoot\RDPlogs.log" -Append

    # mstsc.exe を起動
    $MyProcess = Start-Process mstsc.exe -ArgumentList " -v $MyHostname" -PassThru
    
    # PowerShellスクリプトを観察モードで再度起動
    Start-Process PowerShell -ArgumentList "-File `"$PSCommandPath`" $MyHostname `"observation`" $($MyProcess.Id)" -WindowStyle Hidden
    Exit
}

# 観察モードの処理
while ($true) {
    if (-not (Get-Process | Where-Object { $_.Id -eq $MyPID })) {
        "$(Get-Date)：$env:USERNAME が $MyHostname へのリモートデスクトップ接続を終了しました" | Out-File "$PSScriptRoot\RDPlogs.log" -Append
        Remove-Item "$PSScriptRoot\$MyHostname.txt"
        Exit
    }
    Start-Sleep 1
}
```


### ～仕組み～
batを起動するとRDPの画面が表示されます
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2604770/eb26fcf4-1bba-b2d4-3ca0-9b62f4081424.png)

RDPすると「My_Computername」変数に設定したホスト名のファイルが作成されます
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2604770/59cde08c-edbc-99fb-3a0e-9bbd9eda2bd9.png)

中には実行したユーザー名が記載されています
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2604770/9abb9986-bc37-f697-82f1-ac5563923710.png)

テキストファイルがある場合は、batを起動してもRDPできません。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2604770/c7c68cf2-1f15-7167-3bd0-c2e2a7de3151.png)

RDPが終了するとtxtファイルが自動的に削除されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2604770/609f596c-1e75-ce66-5554-df956c50e9b2.png)

「RDPlogs.log」ファイルには接続ログが記録されます
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2604770/8dc605ed-98e9-67a0-9f36-be780637bc29.png)
Dockerfile内でCPUを条件分岐する方法


# はじめに

こちらの記事では、Dockerfile 内で CPU を条件分岐する方法について書きます。

筆者は以前、M1 チップの Macbook で開発を進める際、プロジェクトの Dockerfile の環境構築がうまくできない事象に遭遇しました。
というのも、そのプロジェクトではそれまでは intel チップを前提として環境構築していたわけですが、そのまま M1 チップに適用できないようなのです。調べていくと CPU のアーキテクチャごとに、インストールする必要があるパッケージや設定が異なる場合があることが分かりました。

暫定対応として、ローカル環境のみ Dockerfile を書き換えることで開発自体を進めることはできます。しかし、管理が面倒なので、環境の差異を吸収できるような一元的な Dockerfile を作りたいという要望がありました。それを実現するために、ShellScript を使って CPU を判定し、処理を分岐することを考えました。

# 書き方

以下のように書くことができます。

```dockerfile:Dockerfile
# 共通のパッケージをインストール
RUN apt-get update && apt-get install -y curl

# アーキテクチャごとのパッケージをインストール
RUN if [ "$(uname -m)" = "aarch64" ]; then \
    apt-get install -y package-for-arm; \
elif [ "$(uname -m)" = "x86_64" ]; then \
    apt-get install -y package-for-x86; \
fi
```

RUN 命令は、Dockerfile 内でシェルコマンドを実行するための命令です。`uname -m`コマンドは現在のマシンのアーキテクチャを返します。`aarch64`は ARM64、つまり M1 Mac であることを判定できます。`x86_64`は Intel/AMD の 64 ビットアーキテクチャを指します。

このように Dockerfile 内では、ShellScript を用いてマシンのアーキテクチャに応じた条件分岐を書くことができます。
TypeScript勉強してみた④

# はじめに
初めまして！
エンジニアになって数年、今まで本を読むだけでしたが、もっとプライベートで楽しみながら成長したい！自分が学んだ足跡を残していきたい！と思い記事を書きました！
最終的には自在に開発できるようになりたいと思っています。:triumph:
いろいろな記事を参考にさせてもらっています。:bow_tone2:

**「いいね」か「ブックマーク」**
を頂けると僕のモチベーションアップになります！:thumbsup:
少しでも気に入っていただけたらよろしくお願いいたします！:thumbsup:


# 今回の目的
TypeScriptがわからなくてやばたにえんなので、ハンドブックで学んでみました。
（前回）

https://qiita.com/mr_noppo/items/fef33cb1e6d59dc07197

# 主に参考にさせていただいた記事

https://www.typescriptlang.org/docs/handbook/intro.html

### Type Assertions
asや<>を使用して型を限定的にできる。
```ts
//HTMLElement | nullが本来ついているが、HTMLCanvasElementの型に限定できる。
const myCanvas = document.getElementById("main_canvas") as HTMLCanvasElement;
const myCanvas = <HTMLCanvasElement>document.getElementById("main_canvas");
```

#### 型注釈との違いは？
型注釈は、変数に対して型を限定します。変数の型とは違う型を入れるとコンパイルエラーになります。
```ts
const x:string = "hello";
```
型アサーションは、値の型を限定します。推論でstringにせず宣言的に行います。
```ts
const x = "hello" as string;
```

### Literal Types
一つだけだと意味はあまりないがunionTypeと組み合わせると効果を発揮する
・一つだけ
```ts
const obj:{counter:0} = { counter: 0 };
```
・複数の場合
```ts
// alignmentはleft,right,centerのみ
function printText(s: string, alignment: "left" | "right" | "center") {
  // ...
}
// 戻り値にも対応できる
compare(a: string, b: string): -1 | 0 | 1 
// リテラルと非リテラルを組み合わせることもできる
function configure(x: Options | "auto") {
  // ...
}
```

### オブジェクトの推論
下記の場合、reqは{url:string, method:string}と推論され、req.method呼び出しでTypeScriptエラーになります。

```ts
declare function handleRequest(url: string, method: "GET" | "POST"): void;
 
const req = { url: "https://example.com", method: "GET" };
handleRequest(req.url, req.method);
```

型アサーションで固定するか、定数アサーションでそのものをtype化する必要があります。
・型アサーション
```ts
// Change 1:
const req = { url: "https://example.com", method: "GET" as "GET" };
// Change 2
handleRequest(req.url, req.method as "GET");
```
・定数アサーション
抽象的なstringではなく、具体的な値がLiteral Typesとして割り当てられます。
```ts
const req = { url: "https://example.com", method: "GET" } as const;
handleRequest(req.url, req.method);
```
reqのtypeは以下のようになります
```ts
const req: {
  readonly url: "https://example.com";
  readonly method: "GET";
}
```

#### filterでは型ガード
filterでまとめるものがstringのみである場合に型アサーションを使えるが、型ガードの方がより確実に型を狭めることができます。
```ts
const items: (string | undefined)[] = ['str', undefined]
// filter時にstringに狭める
const stringItems = items.filter((item): item is string => typeof item == 'string')
// 型安全がないため非推奨
const stringItems = items.filter(item => typeof item === 'string') as string[]
const upperString = stringItems.map(item => item.toUpperCase)
```
参考記事：

https://qiita.com/suin/items/cda9af4f4f1c53c05c6f

# 次回の予定

https://qiita.com/mr_noppo/items/a4e56a6225c28f5674f2
Spring データベースアクセス時の例外の基本

## **この記事に書いてあること**

- [プロになるためのSpring入門](https://gihyo.jp/book/2023/978-4-297-13613-0)のデータベースアクセス時の例外の内容を読んだまとめ
- データベースアクセス例外の問題点とSpringの汎用的な例外クラスによる解決

## データベースアクセス例外の問題

データベースアクセスでエラーが起きた時にスローされる例外クラスは、データベースアクセスの仕組みごとに異なる。

|  DBアクセスの仕組み | 例外 |
| --- | --- |
| Java標準JDBC | SQLException |
| MyBatis | (MyBatis)PersistenceException |
| JPA | (JPA)PersistenceException |
| Hibernate | HibernateException |
| … | … |

問題点：

- 例外をハンドリングするアプリケーションの処理は、それぞれの例外クラスをキャッチする必要があり、データベースアクセスの仕組みに依存する
- データベースアクセスの仕組みを変える場合は、例外をハンドリングしている部分の修正が必要になる

## Springの汎用的な例外クラスによる解決

- Springの機能を使うと、スローされた例外を汎用的な例外に変換してくれる
    - Spring JDBC
    - MyBatisなど他ライブラリとの連携機能
- 例外をハンドリングするアプリケーションの処理は、汎用的なSpringの例外クラスをキャッチしてハンドリングすれば良いため、データベースアクセスの仕組みを変えても影響なし

```java
try {
	...
} catch (Springの例外クラス) {
	...
}
```

## Springの汎用的な例外DataAccessExceptionクラス

- Springが提供するデータベースアクセスまわりの汎用的な例外クラスは、DataAccessExceptionを継承している
- DataAccessExceptionはRuntimeExceptionを継承している非チェック例外
- 非チェック例外であるため、例外をハンドリングできないのであれば、try-catchで例外をキャッチする必要はない

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2529381/d7b500e9-8dc9-0666-83d7-de2a690e099e.png)


参照：https://spring.pleiades.io/spring-framework/docs/current/javadoc-api/org/springframework/dao/DataAccessException.html

- DataAccessExceptionクラスの代表的なサブクラス

| サブクラス | 説明 |
| --- | --- |
| BadSqlGrammarException | 指定された SQL が無効な場合にスローされる例外 |
| DuplicateKeyException | データを挿入または更新しようとすると、主キーまたは一意性制約に違反した場合にスローされる例外 |
| DataAccessResourceFailureException | リソースが完全に失敗したときにスローされるデータアクセス例外: たとえば、JDBC を使用してデータベースに接続できない場合 |
| … | … |

上記のように、DataAccessExceptionを継承した例外のサブクラスが、エラーの原因ごとに提供されている。例外をハンドリングするアプリケーションは、ハンドリングしたいエラーの原因に応じて、対応する例外クラスをキャッチすれば良い。
【ABC355】AtCoder Beginner Contest 355【C++】

### コンテスト名
東京海上日動プログラミングコンテスト2024（AtCoder Beginner Contest 355）

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

### 開催日
2024/05/25 21:00-22:40

---

## [A: Who Ate the Cake?](https://atcoder.jp/contests/abc355/tasks/abc355_a)
**解法**
- 人 $A$ と人 $B$ が同じ場合は犯人を特定できない
- $1 + 2 + 3 = 6$ から $A$ と $B$ を引くことで求められる
```cpp:ABC355A.cpp
#include <iostream>
using namespace std;

int main(){
    int a, b;
    cin >> a >> b;

    if(a==b){
        cout << -1 << endl;
    }else{
        cout << 6 - a - b << endl;
    }

    return 0;
}
```

## [B: Piano 2](https://atcoder.jp/contests/abc355/tasks/abc355_b)
**解法**
- `vector<pair<int, int>>` で数列の要素とどちらの数列の要素かを記録する
- 昇順にソートして数列 $A$ の要素が連続しているかを判定する
```cpp:ABC355B.cpp
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

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

    vector<pair<int, int>> C;
    int a;
    for(int i=0; i<n; i++){
        cin >> a;
        C.emplace_back(a, 0);
    }
    int b;
    for(int i=0; i<m; i++){
        cin >> b;
        C.emplace_back(b, 1);
    }

    sort(C.begin(), C.end());
    for(int i=0; i<C.size()-1; i++){
        if(C[i].second==0 && C[i+1].second==0){
            cout << "Yes" << endl;
            return 0;
        }
    }

    cout << "No" << endl;
    return 0;
}
```

## [C: Bingo 2](https://atcoder.jp/contests/abc355/tasks/abc355_c)
**解法**
- 横、縦、対角線の各列について何マス印がついているかを記録する
- $i$ ターン目にビンゴになる可能性があるのは、 $A_i$ に関連する列だけ
    - $O(1)$ で更新・判定できる
- 計算量は長さ $N$ の配列の作成とターン数 $T$ で $O(N + T)$
```cpp:ABC355C.cpp
#include <iostream>
#include <vector>
using namespace std;

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

    vector<int> A(t);
    for(int i=0; i<t; i++){
        cin >> A[i];
        A[i]--;
    }

    vector<int> H(n), W(n);
    int naname1 = 0, naname2 = 0;
    for(int i=0; i<t; i++){
        int x = A[i] / n;
        int y = A[i] % n;

        H[x]++;
        W[y]++;
        if(x==y){
            naname1++;
        }
        if(x+y==n-1){
            naname2++;
        }

        if(H[x]==n || W[y]==n || naname1==n || naname2==n){
            cout << i+1 << endl;
            return 0;
        }
    }

    cout << -1 << endl;
    return 0;
}
```

## [D: Intersecting Intervals](https://atcoder.jp/contests/abc355/tasks/abc355_d)
**解法**
- 区間 `vector<pair<int, int>>` を昇順にソートして、 $l_j$ が $l_i$ より大きい区間のうち、 $l_j$ が $r_i$ より小さい区間 $j$ の個数をそれぞれ加算する
    - $i$ 番目の区間と共通部分をもつのは、左端が $l_i$ より大きくて $r_i$ より小さい区間である
- $l_j$ が $r_i$ より小さい区間 $j$ の個数は二分探索 `upper_bound()` で求める
    - 左端 $l$ を昇順にソートしたとき、 $r_i$ が何番目になるかを求める
```cpp:ABC355D.cpp
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

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

    int l, r;
    vector<pair<int, int>> V;
    vector<int> L;
    for(int i=0; i<n; i++){
        cin >> l >> r;
        V.emplace_back(l, r);
        L.push_back(l);
    }

    sort(V.begin(), V.end());
    sort(L.begin(), L.end());
    long long int sum = 0;
    for(int i=0; i<n; i++){
        auto [l, r] = V[i];
        sum += (upper_bound(L.begin(), L.end(), r) - L.begin()) - i - 1;
    }

    cout << sum << endl;
    return 0;
}
```
並列Lispによる素因数分解

# 素因数分解の難しさ
RSA暗号は素因数分解の困難さを応用しています。N=P*Q （P,Qは素数）は大きな桁数になると計算に時間がかかります。現在のコンピューターでは611桁の素因数分解には膨大な時間がかかることを応用したものがRSA暗号です。いろいろと数学を応用したアルゴリズムが考案されているそうです。ここでは単純な試し割によるアルゴリズムを並列で計算することによりどの程度、計算時間を短縮できるのかを試してみました。


# アイディア
試し割をするアルゴリズムでは√Nまでを奇数で割り算をしていきます。この区間にかならず１つの素数が見つかるはずです。これを並列により分割した区間を調べます。ここでは５つのプロセスに分割してマルチコアCPUで計算することにします。


![factors.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/33927/e8f9737f-2567-3537-d039-945b413b247e.png)





# 並列構文の拡張
以前の記事で(mp-part)という並列構文を用いました。これは複数の計算のうちのいずれか１つがnilを返したきたときに残りのプロセスを中断して結果を返すというものでした。

今回はいずれか１つのプロセスがnil以外の値を返したときに残りのプロセスを中断して結果を返す機能が必要です。(mp-part)にモードを追加しました。

```
(mp-part mode (foo1) (foo2) (foo3) (foo4) (foo5))
```

modeにnilあるいはtを与えることで動作を変えます。tを与えるといずれかのプロセスがnil以外の値を返したときにその値を返します。

# コード
このmp-partを利用して並列計算で素因数分解をするコードを書いてみました。比較のために逐次で書いたコードもあわせて示します。

```
;;parallel
(defun factors* (n)
    (let* ((limit (isqrt n))
           (span (+ (div limit 5) 1))
           (p (mp-part t (cofactor n 3 span)
                         (cofactor n (near-odd span) (* 2 span))
                         (cofactor n (near-odd (* 2 span)) (* 3 span))
                         (cofactor n (near-odd (* 3 span)) (* 4 span))
                         (cofactor n (near-odd (* 4 span)) (* 5 span)))))
                (list p (div n p))))

(defun cofactor (n s e)
    (cond ((> s e) nil)
          ((= (mod n s) 0) s)
          (t (cofactor n (+ s 2) e))))

(defun near-odd (n)
    (if (= (mod n 2) 0)
        (- n 1)
        n))


;; sequence
(defun factors (n)
    (let ((p (cofactor n 3 (isqrt n))))
        (list p (div n p))))

```


# 計算結果

![bandicam 2024-05-26 12-43-25-025.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/33927/b75c0728-b342-6fb1-d149-0121d07f30fd.jpeg)



素数P,Qが大きく、近い数になっている場合には並列計算の効果が表れています。Pが小さいときには逐次の方が高速になります。並列計算によるオーバーヘッドがあるためでしょう。


# Easy-ISLisp
オープンソースソフトウェアです。githubにて公開しています。
https://github.com/sasagawa888/eisl
(java gold)Set

## Set

* 重複した要素を含むことができないコレクション
* 順序があるとは限らない

* Setを継承したクラス
1. `HashSet`: 値の重複を許さない順不同の要素集合を扱います
2. `TreeSet`: 値の重複を許さないソートされた要素集合を扱いま

## Setのメソッド
### 追加
| メソッド名 | 概要 |
|:--|:--|
set.add(o) | オブジェクト o を配列の末尾に追加する

### 削除
| メソッド名 | 概要 |
|:--|:--|
set.remove(o) | オブジェクト o にマッチする要素を削除する
|  set.clear() | 配列をクリアする  |


### 取得
:::note warn
メソッドは用意されていない
:::



### 要素数
| メソッド名 | 概要 |
|:--|:--|
|`list.size()` | 要素の個数を得る|
(java gold)List


## List

* 順序付けられたコレクション。重複した要素を含むことができる、ユーザーは要素を挿入する場所やインデックスによって要素にアクセスすることを正確に制御できる<br><br>
* Listはインターフェースなのでインスタンは生成できない<br><br>
* Listのメリットはコレクション(データ型)に変更したい場合、宣言時に手を加えなくていい<br><br>
* ListのデメリットはArrayListにしかメソッドがないときにキャストしなければならない<br><br>
* Listは以下のクラスで実装されています
1. `ArrayList`: 配列を扱う一般的なクラス
2. `LinkedList`:  要素がどのように並んでいるか別で管理しているために要素を削除したり追加する場合にArrayListよりも高速に動作するが、要素を順にたどるため検索などはArrayListよりも遅くなる
3. `Vector` : ArrayList や LinkedList と同じように扱うことができますが、同期をとるためパフォーマンスが悪い(スレッドセーフ)
4. Stack

### 追加
| メソッド名 | 概要 |
|:--|:--|
`list.add(o)` | オブジェクト o を配列の`末尾`に追加する
`list.add(n, o)` | オブジェクトを n で指定した場所に追加する
`list.set(n, o)` | n番目の要素をオブジェクト o で置き換える
`list.addAll(list2)` | 配列の`末尾`に配列 list2 を追加する

### 削除
| メソッド名 | 概要 |
|:--|:--|
|  `list.remove(n)` | n番目の要素を削除する  |


### 取得
| メソッド名 | 概要 |
|:--|:--|
|   `list.get(n)` | n番目の要素を得る   |
|   `list.indexOf(o)` | オブジェクト o と等しい要素のインデックスを探す  |
|   `list.contains(o)` | オブジェクト o と等しい要素があるか調べる   |



### 要素数
| メソッド名 | 概要 |
|:--|:--|
|`list.size()` | 要素の個数を得る|
(java gold) Deque

## Deque

* 後に入れたデータを先に取り出す仕組みのLIFO(Last In First Out)を使うためのもの
* 先に入れたものを先に取り出す仕組みはキュー(Queue)、FIFO(First In First Out)と呼ばれます
* Dequeの実装クラスは
1. `ArrayDeque`: 挿入、削除、取得を両端でしか行わない場合、ArrayDequeのほうが高速に動作
1. `LinkedList`: 配列の中間にアクセスする場合（containsやindexOfなど）は、LinkedListのほうが速い

### 追加
| メソッド名 | 概要 |
|:--|:--|
|   queue.addFirst(o) | oをデックの先頭に追加する(エラー時は例外を返す)   
|   queue.addLast(o) | oをデックの最後に追加する(エラー時は例外を返す)   |
queue.offerFirst(o) | oをデックの先頭に追加する(エラー時はfalseを返す)
queue.offerLast(o) | oをデックの最後に追加する(エラー時はfalseを返す)


### 削除
| メソッド名 | 概要 |
|:--|:--|
queue.removeFirst() | デックの先頭の値を取り出して削除する(エラー時は例外を返す)
queue.removeLast() | デックの最後の値を取り出して削除する(エラー時は例外を返す)
queue.pollFirst() | デックの最初の値を取り出して削除する(エラー時はnullを返す)
queue.removeFirstOccurrence(o) | デックから最初に現れるoを削除する。見つからなければfalseを返す。
queue.removeLastOccurrence(o) | デックから最後に現れるoを削除する。見つからなければfalseを返す。
### 取得
| メソッド名 | 概要 |
|:--|:--|
queue.getFirst() | デックの最初の値を取り出す。削除しない(エラー時は例外を返す)
queue.getLast() | デックの最後の値を取り出す。削除しない(エラー時は例外を返す)
queue.peekFirst() | デックの最初の値を取り出す。削除しない(エラー時はnullを返す)
queue.peekLast() | デックの最後の値を取り出す。削除しない(エラー時はnullを返す)
### 要素数の取得
| メソッド名 | 概要 |
|:--|:--|
queue.size() | 要素の個数を得る
(java gold) 並列処理

## スレッド
* `スレッド`とはプログラムを実行した場合の最小単位
* プログラムの実行単位を複数のスレッドに分割して実行することを`マルチスレッド`
* スレッドの制御には`java.lang.Threadクラス`と`java.lang.Runnableインターフェース`を使用

## スレッドの実行
* Runnable.run()メソッド
* Thread.start()メソッド
  * start()メソッドの中ではオーバーライドしたrun()メソッドの呼び出しを行っている

:::note warn
スレッド処理の開始はstart() メソッドだが
(run()メソッドを直接呼び出してもスレッドは開始されない)
:::


## スレッドの優先度
* 優先度を取得・設定するメソッド

| メソッド名 | 概要 |
|:--|:--|
| static Thread currentThread| 現在実行中のスレッドオブジェクトを取得する  |
| final String getName() | スレッドの名前を返す  |
| final int getPriority | スレッドの優先度を返す |
| final void setPriority(int newPriority) |  スレッドの優先度を設定する。1～10まで設定できる |

### 優先度を表す定数
| 定数名 | 概要 |
|:--|:--|
| MAX_PRIORITY | 最大値で10を表す |
| NORMPRIORITY | デフォルト値で5を表す |
| MIN_PRIORITY | 最小値で1を表す |

## スレッドの制御
### Threadクラスのメソッド
 
| メソッド名 | 概要 |
|:--|:--|
| Sleep(long n) | nミリ秒呼び出したスレッドが休止する |
| join() | 実行中のスレッドが終了するまで待機 |
| yield() | 呼び出したスレッドを休止し、ほかのスレッドを実行する |
| interrupt() | 休止中のスレッドに割り込みを入れる |


## 排他制御と同期制御
* 複数のスレッドを運用する際、同じオブジェクトを操作することがあり、その際の値の取り扱いを制御する

### 排他制御
* メソッド内の処理が行われている間は、ほかスレッドの参照を禁止する
* syncronaizedキーワードを使用

### 同期制御
* Objectクラスの制御用メソッド

| メソッド名 | 概要 |
|:--|:--|
| wait() | 現在のスレッドを待機 |
| notify() | 待機中のスレッドを1つ再開させる|
| notifyAll() | 待機中のスレッドをすべて再開させる |

## デッドロック
* 2 つ以上のスレッドなどの処理単位が互いの処理終了を待っているためどの処理も先に進めなくなってしまうこと
## ライブロック
* 2 つ以上のスレッドなどの処理単位が互いにロックしているリソースの解放をビジー状態で待っているため処理が進行しているにも拘らずどのスレッドもリソースが獲得できなくなってしまうこと
## スタベーション
* 2 つ以上のスレッドなどの処理単位が並列処理を実行中に、ある特定の処理単位がスケジューリングの問題でリソースを獲得できなくなってしまうこと
(java gold) ストリームAPIの生成

## ストリームAPI(StreamAPI)
* 繰り返し処理をサポートするライブラリ
* コレクション、配列、ファイルなどのデータの集合(データソース)から要素を取り出し処理の流れ(Stream)に引き渡す。

* `中間処理` : 戻り値はStream<T> 
* `終端処理` : 終端処理のタイミングでうとりーむ一連の処理が実行される
* メソッドチェーン : ストリーム生成から中間処理/終端演算子.演算子で連結できる

## リスト・マップ

```java
//リスト
    var list = new ArrayList<String>(
        Arrays.asList("ant", "elephant", "hamster"));
            list.stream()
                .forEach(System.out::println);
    // 並列処理
    list.parallelStream().forEach(System.out::println);

//マップ
    var map = new HashMap<String, String>(
            Map.of("orange", "みかん", "apple", "りんご", "strawberry", "いちご"));
            map.entrySet()
                .stream()
                .forEach(System.out::println);
```

## Arraysクラスのstreamメソッド

```java
int[] numbers = {1, 2, 3, 4, 5};

Arrays.stream(numbers)
    .filter(n -> n % 2 == 0) // 偶数をフィルタリング
    .map(n -> n * n) // 要素を自乗する
    .forEach(System.out::println); // 出力: 4, 16
```

①：numbers配列をstream()メソッドでストリームに変換
②：続けてfilter()[predicate]メソッドで偶数をフィルタリング
③：map()[Function]メソッドで要素を自乗
④：forEach()[Consumer]メソッドを使用して、処理結果を出力

:::note warn
プリミティブ型の配列（Int、long、doubleなど）を扱う場合、Stream型（参照型）ではなくプリミティブ型の戻り値を戻すため注意する。
:::


## 引数/ラムダ式

* ofメソッド
```java
 var stream = Stream.of("first", "second", "third");
    stream.forEach(System.out::println); //first, second, third
```

* `generare`メソッド
  * 指定されたラムダ式(`Supplier`)の戻り値でストリーム生成
    * ex: 1~100の乱数を生成、ストリーム化
    * 無限にストリーム生成するので中間/終端処理で明示的に中断
    * 以下の例ではlimit(10)で先頭10件のみ処理している

```java
    var stream = Stream.generate(() -> {
      var r = new Random();
      return r.nextInt(100);
    });
    
    stream.limit(10)
          .forEach(System.out::println);
          
    //46 24 42 80 61 67 69 22 85 1
```

* `iterate`メソッド
  * 指定された初期値とラムダ式(`UnaryOperator`)でストリーム生成
    * 第一引数に初期値、第二引数に直前の結果を渡す

```java
    var stream = Stream.iterate(1, (num) -> {
      return num * 2;
    });
    
    stream.limit(10)
          .forEach(System.out::println);
          
    // 1 2 4 8 16 32 64 128 256 512
```

* builderメソッド
  * ストリームを組み立てるためのStream.Builderオブジェクト生成

```java
    var stream1 = Stream.of("Munchkin", "Siamese", "Persian");
    var stream2 = Stream.of("Corgi", "Poodle", "Shiba");
    Stream.concat(stream1, stream2).forEach(System.out::println);
    // Munchkin Siamese Persian 
    // Corgi Poodle Shiba
```

* concatメソッド
  * 複数のストリームを結合し1つのストリームにまとめる
```java
    var stream1 = Stream.of("Munchkin", "Siamese", "Persian");
    var stream2 = Stream.of("Corgi", "Poodle", "Shiba");
    Stream.concat(stream1, stream2).forEach(System.out::println);
    // Munchkin Siamese Persian 
    // Corgi Poodle Shiba
```
(java gold) Collector

## Collector

ストリームのリダクション操作のためのインターフェースであり、処理途中のオブジェクトを適切に扱うことができる。

```java
public interface Collector<T, A, R> {
    Supplier<A> supplier();
    BiConsumer<A, T> accumulator();
    BinaryOperator<A> combiner();
    Function<A, R> finisher();
    Set<Characteristics> characteristics();
}
```
* T : ストリームないの要素の型
* A : 処理途中の値を保持するためのオブジェクト
* R : 最終結果の型
* supplier() : 処理途中の値を保持するためのオブジェクトを生成する
* accumulator() : 具体的に実行したい処理を記述したBiConsumer型のラムダ式を返す
* combiner() : 二つの部分結果を結合する（並行処理時に使用される）
* finisher() : 処理結果を返すラムダ式を提供する
* characteristics() : Collectorの特徴を表わすEnumのセットを戻す

上記のメソッドはすべて実装が必要
(java gold) mapメソッド

## map

* ストリーム内の要素を別の値に変更する際に使用
* 基本的な構文は以下の通りである

```java
stream.map(function)
```

* stream : 元のストリームを表す
* map()メソッド : Function型の引数を受け取る
* function : 各要素を変更するための関数

```java
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
List<Integer> doubledNumbers = numbers.stream()
                                      .map(number -> number * 2)
                                      .collect(Collectors.toList());
```

numbersという整数のリストを作成し、mapメソッドを使って各要素を2倍に変換している。この場合、ラムダ式number -> number * 2がFunction型の引数として渡され、各要素が2倍になった新しいストリームが生成する

## mapToInt,mapToLong,mapToDouble,mapToObj

mapにはint型に変換する`mapToInt`,long型に変換する`mapToLong`,double型に変換する`mapToDouble`,Object型に変換するmapToObjが存在する。

```java
List<String> nums = asList("1", "2", "3");

int sum = nums.stream()
            .mapToInt(Integer::parseInt)
            .filter(i -> i % 2 == 1)
            .sum();
```
(java gold) Comparableインタフェース

## Comparableインターフェースとは

下記はAPIドキュメント
>public interface Comparable
このインタフェースを実装する各クラスのオブジェクトに全体順序付けを強制します。この順序付けはクラスの自然順序付けと呼ばれ、このクラスのcompareToメソッドは自然比較メソッドと呼ばれます

Javaのクラスが自然な順序付けをサポートするために実装するインタフェースである。自然な順序付けとは、オブジェクト間の大小関係を定義することを意味する。

位置付けとしてはクラス（オブジェクト）の共通メソッドであるがequalsやtoStringなどと違い、他と違ってComparableはObjectには宣言されていない。

必要に応じてクラス作成時に実装し、抽象メソッドであるcompareTo()メソッドをオーバーライドしなければならない。このメソッドは、自身のオブジェクトと引数として与えられた他のオブジェクトとの比較結果を返す

:::note warn
Comparableを実装せずに自然順序付けに従ってソート実行しようとすると"ClassCastException"が発生する
:::

### compareTo()メソッドの戻り値

* 負の整数：自身のオブジェクトが引数よりも小さいことを示す。
* 0：自身のオブジェクトが引数と等しいことを示す。
* 正の整数：自身のオブジェクトが引数よりも大きいことを示す。

例
<Shoseクラス>
```java
import java.time.LocalDate;

public class Shose implements java.lang.Comparable<Shose> {

    public Integer price;
    public String name;
    public LocalDate dateOfIssue;

    Shose(Integer price, String name, LocalDate dateOfIssue){
        this.price = price;
        this.name = name;
        this.dateOfIssue = dateOfIssue;
    }

    @Override
    public int compareTo(Shose shose){          // Comparableの抽象メソッド
        return this.price.compareTo(shose.price);   // 自分自身と引数を比べる
    }
}
```
<並び替えを行うMainクラス>
```java

import java.time.LocalDate;
import java.util.ArrayList;
import java.util.List;
import java.util.Collections;


public class Main {
    public static void main(String[] args) throws Exception {

        // ソート対象の作成
        List<Shose> shoseList = new ArrayList<>();
        shoseList.add(new Shose(8710, "jordan",LocalDate.of(1985,9,15)));   
        shoseList.add(new Shose(10000, "Super Star",LocalDate.of(1969,4,1)));
        shoseList.add(new Shose(7700, "ALL STAR", LocalDate.of(1917,4,2)));

        // ソート実行
        Collections.sort(shoseList); 
        // priceの値の昇順ソート対象を表示する
        shoseList.forEach( s -> System.out.println(s.price + ":" + s.name + ":" + s.da));
    }
}
```
処理結果
```java
// 7700:ALL STAR:1917-04-02
// 8710:jordan:1985-09-15
// 10000:Super Star:1969-04-01
```

上記の例では、PersonクラスがComparable<Shose>を実装している。
Comparableインタフェースによって、Shoseオブジェクト同士を値段に基づいて比較することができる。

Mainクラスでは、Shoseオブジェクトを要素とするArrayListを作成し、そのリストをCollections.sort()メソッドを使用して自然順序でソートしている。sort()メソッドは、要素がComparableインタフェースを実装している必要がある。

## Comparableの問題点
上記の例のように、Comparableインタフェースを実現したクラスは、compareTo()メソッドにどのような並べ替えをしたいのかというアルゴリズムを記述することができる。
しかし、アルゴリズムを1つしか記述できない（＝状況に応じた並べ替えに対応できない）という問題がある。