OmniAICreator/Qiita-1.07M huggingface dataset:
DHCPの基礎

# DHCPとは
IPアドレスなどの割り当て情報を配布するプロトコル。
一般家庭では、ルーターがDHCPサーバの役割を担っていることが多い。
以下の手順で、IPアドレスを自動で割り当てる。

## IPアドレスを割り当てる手順
### 1 DHCP DISCOVER
クライアントA「IPアドレスをください。でも、宛先がわかんないから、とりあえず同じネットワーク内の全員に聞いてみるヨ。」　※ブロードキャスト
DHCPサーバ「自分が承ります。」

### 2 DHCP OFFER
DHCPサーバ「Aさん、xxx.xxx.xxx.xxxとかどう？」　※ユニキャスト
クライアントA「THX」

### 3 DHCP REQUEST
クライアントA「このIPアドレスを使いたいです。でも、やっぱり宛先がわかんないから、とりあえず同じネットワーク内の全員に聞いてみるヨ。」　※ブロードキャスト
DHCPサーバ「自分が承ります。」

### 4 DHCP ACK（アック）
DHCPサーバ「Aさん、そのIPアドレス使っていいよ。」　※ユニキャスト
クライアントA「THX」

### 5 GARP（DHCPサーバの役割外）
クライアントA「このIPアドレスを使おうと思うんだけど、だれも使ってないよね？」　※ブロードキャスト
仲間「・・・」
クライアントA「だ、大丈夫そうだね。」

## ひとこと
現実世界では、質問した時にリアクションがないのは不安だと思います。

# 参考
https://youtu.be/PNDoemWWs54?si=SgLcaLiznfgGVH_j
Meta-Llama-3-8BでのFew-Shot Promptingによる日本語品詞付与

[Meta-Llama-3-8B](https://huggingface.co/meta-llama/Meta-Llama-3-8B)は、[Swallow-7b-plus-hf](https://huggingface.co/tokyotech-llm/Swallow-7b-plus-hf)と同様のLLaMAモデルなのだが、[昨日の記事](https://qiita.com/KoichiYasuoka/items/d562e35fe61d8028000d)にも書いたとおり、トークナイザの日本語対応がイマイチである。これがどういう問題を引き起こすか、国語研短単位でのUPOS (Universal Part-Of-Speech)品詞付与をFew-Shot Promptingで挑戦してみよう。5つの例文は、[この記事と全く同じもの](https://qiita.com/KoichiYasuoka/items/8b63a42dc730d8141dea)を選んだ。

```
>>> class TextUPOSList(list):
...   __str__=lambda self:"\n".join("###text:"+"".join(t for t,u in s)+"\n###UPOS:"+"|".join(t+"_"+u for t,u in s) for s in self)+"\n"
...
>>> ex=TextUPOSList()
>>> ex.append([("一","NUM"),("直線","NOUN"),("に","ADP"),("伸びる","VERB"),("電撃","NOUN"),("を","ADP"),("放ち","VERB"),("、","PUNCT"),("電撃","NOUN"),("ダメージ","NOUN"),("を","ADP"),("与える","VERB"),("。","PUNCT")])
>>> ex.append([("色々","ADV"),("と","ADP"),("面白い","ADJ"),("メニュー","NOUN"),("の","ADP"),("ある","VERB"),("店","NOUN"),("。","PUNCT")])
>>> ex.append([("しかも","CCONJ"),("、","PUNCT"),("ここ","PRON"),("は","ADP"),("コース","NOUN"),("が","ADP"),("リーズナブル","ADJ"),("な","AUX"),("の","SCONJ"),("です","AUX"),("。","PUNCT")])
>>> ex.append([("彼","PRON"),("は","ADP"),("コンピュータ","NOUN"),("を","ADP"),("個人","NOUN"),("の","ADP"),("持ち物","NOUN"),("に","ADP"),("し","VERB"),("まし","AUX"),("た","AUX"),("。","PUNCT")])
>>> ex.append([("2007","NUM"),("年","NOUN"),("9","NUM"),("月","NOUN"),("現在","ADV"),("、","PUNCT"),("以下","NOUN"),("の","ADP"),("メーカー","NOUN"),("から","ADP"),("対応","NOUN"),("製品","NOUN"),("が","ADP"),("発売","VERB"),("さ","AUX"),("れ","AUX"),("て","SCONJ"),("いる","VERB"),("。","PUNCT")])
>>> from transformers import pipeline
>>> tgn=pipeline("text-generation","meta-llama/Meta-Llama-3-8B",max_new_tokens=128,token="hf_this_token_is_dummy_use_your_own_one")
>>> print("\n".join(tgn(str(ex)+"###text:国境の長いトンネルを抜けると雪国であった。\n###UPOS:")[0]["generated_text"].split("\n")[len(ex)*2:len(ex)*2+2]))
###text:国境の長いトンネルを抜けると雪国であった。
###UPOS:国境_NOUN|の_ADP|長い_ADJ|トンネル_NOUN|を_ADP|抜けると_AUX|、_PUNCT|雪国_NOUN|であった_AUX|。_PUNCT
```

『雪国』の冒頭文に品詞付与させてみたところ、Meta-Llama-3-8Bは「`抜ける_VERB|と_ADP|雪国_NOUN|で_AUX|あっ_AUX|た_AUX`」が正しくトークナイズできなかった。この結果「`抜けると_AUX`」や「`であった_AUX`」が1語になってしまったり「`、_PUNCT`」が勝手に挿入されたりしている。もう一度やってみよう。

```
>>> print("\n".join(tgn(str(ex)+"###text:国境の長いトンネルを抜けると雪国であった。\n###UPOS:")[0]["generated_text"].split("\n")[len(ex)*2:len(ex)*2+2]))
###text:国境の長いトンネルを抜けると雪国であった。
###UPOS:国境_NOUN|の_ADP|長い_ADJ|トンネル_NOUN|を_ADP|抜けると_AUX|、_PUNCT|雪国_NOUN|であった_AUX|。_PUNCT
```

どうやら同じ結果だ。ならば「予想に反して品詞付与の精度がイマイチ」という文はどうだろう。

```
>>> print("\n".join(tgn(str(ex)+"###text:予想に反して品詞付与の精度がイマイチ\n###UPOS:")[0]["generated_text"].split("\n")[len(ex)*2:len(ex)*2+2]))
###text:予想に反して品詞付与の精度がイマイチ
###UPOS:予想_NOUN|に_ADP|反して_ADJ|品詞_NOUN|付与_NOUN|の_ADP|精度_NOUN|が_ADP|イマイチ_ADJ|。_PUNCT
```

「`反し_VERB|て_SCONJ`」がうまくトークナイズできていない上に「`。_PUNCT`」が勝手に追加されている。Meta-Llama-3-8Bは、まだ日本語対応が未熟で、まずはトークナイザの改良が必要だということだ。ただ正直なところ、Byte-Pair Encodingは日本語に対しては筋悪で、私(安岡孝一)個人としては[Unigram](https://huggingface.co/docs/tokenizers/main/en/api/models#tokenizers.models.Unigram)にしてしまいたい。さて、どうしたものか。
【Typst】subequation環境を実装する

Typstには，LaTeXでいう`subequation`に相当するものが標準搭載されていません．どうしてもsubequationをしたい時のために，似た機能を実装する方法を考えていました．

案は色々あると思いますが...

# 案1 : subequation専用カウンタを作る

```plaintext:実装
#set math.equation(supplement: "式", numbering: num=>{//ラベルの表示内容の定義
    set text(fill: blue) //分かりやすさのため，青色で表示（実用時は黒でOK）
    [(#num)] //表示
})

#let subequation=inner=>{
  counter(math.equation).step()
  context[
    #let eqc = counter(math.equation).get() //equationのカウンタ情報
    #let eqcDsp = eqc.at(0) //equationのカウンタ番号
    #let subeqc = counter("subeq") //専用カウンタ
    #subeqc.update(1) //専用カウンタを1に設定する
    
    #set math.equation(numbering: num=>{ //ラベルの表示内容の定義
      set text(fill: red) //分かりやすさのため，赤色で表示（実用時は黒でOK）
      subeqc.step() //専用カウンタを進める
      [(#eqcDsp.#subeqc.get().at(0))] //表示
    })
    
    #inner //内容
    
    #counter(math.equation).update(eqc) //equationのカウンタ情報の復元
  ]
}
```
`subequation`という関数を定義します．この関数内では，数式が表示される度に専用のカウンタ`subeqc`が動くようにします．また，`math.equation`に紐づけられたカウンタを固定（しているように見せかけてるだけだけど）し，これと`subeqc`の内容をnumberingとして表示することとします．

次に示すように，subequationにしたい数式を`subequation`関数の引数内に入れて使います．
```plaintext:使用
@A,@B,@C,@D,@E,@F,@G

#v(1cm)

$ a = 1 $ <A>
$ b = 2 $ <B>

#subequation[
$ c = 3 $ <C>
$ d = 4 $ <D>
$ e = 5 $ <E>
]

$ f = 6 $ <F>
$ g = 7 $ <G>
```

### 結果
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3116310/30339704-d5c1-44d5-e7cd-325f650398b4.png)
通常の数式のラベルは青色に，subequation内で表示されている数式のラベルは赤色になっています．ちゃんとリンクも機能しています．

### 問題点？
問題点としては，subequationを入れ子構造にするとカウンタが変な挙動をしてしまう点です．まあ入れ子構造にすることは滅多にないので気にしなくてよいと思います．

あとは細かい話として，通常の数式とsubequationとのnumberingの形式を手動で揃えないといけないということで，そこらへんの保守性が低いことが挙げられます．
例えば，通常の数式のnumberingが`[1],[2],...`で，subequationのnumberingが`(1.1),(1.2),...`となってると，
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3116310/fd12d763-9854-3d8e-ea12-8e836cb1dfbe.png)
こういう感じの変な見た目になってしまいます．
初心者大学生が作った機械学習ライブラリがGitHubでスター数300を超えた話

## この記事について

この記事では、プログラミング初心者の大学生である(であった)私が試行錯誤しながらなんとかスター数300越えのOSSライブラリを作った過程をまとめたものです。ライブラリ自体はまだまだ発展中のためこの記事も適宜更新してく予定です。ライブラリ自体の詳細というよりも、自作OSSの認知度を上げで他の人に使ってもらうために有用そうな知見をまとめていこうと思います。

## ライブラリの概要

今私が作っているのは、[AIJack](https://github.com/Koukyosyumei/AIJack)という、機械学習モデルがもつセキュリティ・プライバシー上の脆弱性についての各種攻撃・防御手法を実験するためのPythonツールです。既存のライブラリの多くは特定の種類の攻撃や防御に特化したものが多く、複数のタイプの攻撃・防御を組み合わせて実験するためにはいくつものライブラリを組み合わせる必要がありました。そこでAIJackでは、できる限り統一的なAPIで様々な攻撃・防御手法を実装することを目標にしています (まだ道半ばですが...)。

具体的な手法としては、差分プライバシー (Differential Privacy)・準同型暗号 (Homomorphic Encryption)・K-匿名化 (K-anonymity)・連合学習 (Federated Learning)などの防御手法や、Evasion Attack・Poisoning Attack・Model Inversion Attackなどの攻撃手法をサポートしています。

この記事を書いている時点で、GitHub上のスター数が300、フォーク数が60、ダウンロード数が3000を超えており、外部のコントリビューターが5人、5本の論文と1冊の書籍で使用されていることを確認しています。

## 認知度の挙げ方

主に以下の媒体でOSSの宣伝をしてみました。

- [Paper With Code](https://paperswithcode.com/): 主に機械学習関連の論文の実装をまとめたサイトです。誰でも自由に自分の実装を登録することができます。AIJackも20本以上の論文を実装してPaper With Codeに登録しており、現在ではトラフィックの最も多い流入元となっています。
- [Reddit](https://www.reddit.com/): 英語版2チャンネルと呼ばれることもある交流サイトです。人の多いチャンネル (上位1%くらい) に投稿するたびに、2~3日の内はかなり人が流入してスター数が急増する傾向があります。ただし、チャンネルによっては自分のプロジェクトの宣伝が制限されている場合もあるので、注意が必要です。
- [Hacker News](https://news.ycombinator.com/newest): アメリカのベンチャーキャピタルによって運営されているニュース投稿サイトです。他の人の記事によるとかなり効果があるそうですが、自分が何回か投稿した限りではあまり人は流入してきませんでした。
- [DEV Community](https://dev.to/): 英語版Qiitaのようなものです。めちゃくちゃ爆速で使いやすいサイトで、いくつかAIJackに関する記事を書いてみたのですが、あまり効果はありませんでした。

## ドキュメント・CI/CDの整備

他のユーザーに使ってもらったり、OSSに貢献してもらうためには分かりやすいドキュメントや使いやすいCI/CDパイプラインを整備しておくことが大事です。AIJackでは以下のツールを使っています。

- [Sphinx](https://www.sphinx-doc.org/): ドキュメント自動生成ツールです。コードのドクストリングなどから自動でAPIドキュメントを作ってくれます。個人的には、jupyterノートブックの取り込みやすさや見やすさの点から、`sphinx_book_theme`がおすすめです。

![Screenshot 2024-04-20 095002.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2959953/e71aad76-5f9a-90d2-2358-568cdf7e2c5b.png)

- [Codacy](https://www.codacy.com/): コードのフォーマット・脆弱性などの問題点を自動で検出してくれるサービスです。GitHubのPublicレポジトリに対しては無料で使うことができます。重複しているコードの検知、不安定な数値計算を改善する方法などまで提案してくれるので、とても重宝しています。

![Screenshot 2024-04-20 095531.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2959953/f790d940-f969-17cb-3bd7-10b322024072.png)


- [black](https://github.com/psf/black): pythonのコードのフォーマットを自動で直してくれます。シンプルに神。
- [isort](https://pycqa.github.io/isort/): pythonのimportの順番をいい感じにしてくれます。blackとの連携でたまにおかしくなりますが、ググればなんとかなります。
- [pytest](https://docs.pytest.org/): python用の単体テストツールです。
- [googletest](https://github.com/google/googletest): C++用の単体テストツールです。
- [GitHub Actions](https://github.co.jp/features/actions): 上記のようなツールを一つづつ実行するのは面倒なので、GitHub Actionsを使って自動化しました。[workflow](https://github.com/Koukyosyumei/AIJack/tree/main/.github/workflows)は他のプロジェクトにも流用できるかもしれません。

## OSSを頑張ってよかったこと

- インターンの面接のときに受けが良くなった。
- laprasのスコアが爆上がりした (GitHubスコア4.1、技術力スコア3.81)。
- 機械学習関連の論文をたくさん実装したことで、AI・ML周りの技術力・数学力が上がった(気がする)。
- 修士を経由せず、学部から直接の応募だったが、米国トップスクールのコンピューターサイエンス博士課程に複数合格できた。自分自身が運営しているOSSのスター数がそこそこ多いことや、第三者の論文・書籍で採用されているという話は、面接でもそれなりに受けていた気がします。出願した研究室の論文もいくつかAIJackに実装されていたことも大きかったかもしれません。
アルゴリズム ~データ構造~

データ構造は端的に話せば、データの並び方である。電話帳をイメージするとわかりやすいだろう。

電話帳を追加すると50音順に並べることもあれば、追加した順番、メールアドレスのアルファベット順など
並び方がさまざまである。

データ構造によって処理速度に影響を及ぼす。ではどのような影響を及ぼすのか、
またどのようなデータ構造があるのかを見ていく。

<h3>どのような影響?</h3>
追加した順番だと、ランダムに並ぶことを意味する。追加した日付が古い順に並び、データに対する集合体の順序で並ぶわけではない。これが重要なポイントである。例えば、追加した電話帳を「検索する際に」検索にかなり負荷がかかる。理由は、並ぶ順序と欲しいデータに関連性がないからだ。
一方で、名前順に関しては検索しやすい。山田さんや佐々木さん、など欲しいデータの情報を元に検索するために検索負荷は少なく、処理橋やすい。しかし、更新においては、並ぶ順序に従って追加、削除するため負荷がかかる。

Ex
青木さん, 金子さん、佐々木さん....

ここに柿谷さんを入れたい。となれば、金子さんと佐々木さんの間に入れなければいけない。一行削除して、柿谷さんを追加するため、負荷がかかる。
このようにデータ処理において、データ構造は密接に関わる。

<h3>データ構造の種類</h3>
上記のように処理に応じて適切なデータ構造は異なるため、データ構造の種類を理解する必要がある。
いかに紹介する

1. リスト
    1. リストはデータ構造の一つで,「データを一直線に並べた構造」。追加や削除画しやすい反面、アクセスには時間がかかる

    BLUE→Yellow→RED
    と並び、それぞれには**ポインタ**と言われるものが存在し「対」になっている。データのメモリ上の位置を指し示す。リストにあるデータは**連続した領域に格納される必要はなく**一般に離れた領域のバラバラになる。

バラバラに格納されているため、**各データはポインタを辿ることでしかアクセスできない。**

上記で言えば、Redにアクセスしたいなら、BLUE→Yellowとたどらないといけない。
アクセスはめんどくさい。
    一方で、データの削除や追加はしやすい。ポインタを組み替えて作成しなおせば、削除や追加ができる!!

    計算時間は、データの数をnにした場合の計算時間が(線形探索になるので)アクセスしたいデータが後の方にある場合はO(n)になる!追加・削除時間はO(1)の時間になる!


::: warn 補足
各自で調査して欲しい単語
環状リスト
双方向リスト

:::

1. 配列
配列はデータ構造の一つで、データを一列に並べる。**リスト**とは対称的に「データへのアクセスは簡単だが追加や削除には時間がかかる。」

配列のなかのデータには添え字 ([0],[1]...)が存在し、メモリの連続した領域に順番通り格納される!
アクセス時は、添字を使って計算ができ各データに直接アクセスできる(ランダムアクセス)

一方で、データ追加・削除はコストがかかる。
空白のデータは末尾に作り、追加箇所　≒該当箇所までずらしていく。

削除する際は、先に該当箇所(データ)を削除し、**空白**ができるのでずらして埋める。

配列の計算時間
アクセスする時間は、「O(1)」。削除や追加する際は、1つずつずらさないといけないため、データ数nに対し、O(n)かかる。

1. スタック
    スタックは、データを1列に積み上げた時のように新しく追加したデータからしかアクセスできない。新しいデータが到着すると、現在のデータの一番上に置かれる。スタックからデータを取り出す場合は一番上　つまり、最新のデータから取り出される。
    スタックのように後から入れたデータを先に取り出すことをLIFOと呼ぶ
1. キュー
    1. キューはデータを一列に並べた構造である。簡潔に話せば、待ち行列である。行列はアタrしく来た人は一番後ろに座り、一番前の人から処理される。　スタックと真逆の処理がなされる。
    
1. ハッシュテーブル
1. ヒープ
    ヒープはプライオリティキューを実現するために使われている。プライオリティキューは「データ構造の1種で、データを自由に追加できる。一方で、データを取り出すときには最小値から選ばれる。自由に追加でき、小さいものから取り出す。」ヒープを取り出す木構造は各頂点をノードと呼ぶ

    ヒープの基本: 親が一番最小値になるようにセットする。データを追加する際に、親の数字　 > 子供の数字になっていたら繰り返し取り替えていく。
    
1. 2分探索木
【画像あり】SDK does not contain ・・・のエラー

# 対処法

①Potsを開く

![スクリーンショット 2024-04-20 9.37.14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3760972/37ec8438-4f32-d720-1591-4026b9335773.png)

②任意のTARGETSを選択

![スクリーンショット 2024-04-20 9.37.53.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3760972/79be6344-e818-90a9-2fda-a5ce442c8664.png)

③Generalを選択

![スクリーンショット 2024-04-20 9.37.33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3760972/dd74593f-96ef-660a-1b4e-ab26737a1388.png)

④Minimum Deploymentsを上げる

![スクリーンショット 2024-04-20 9.38.14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3760972/1d0079ff-4c33-609b-607e-9130541fb882.png)
弁護士が教える生成AIに関する基本知識・適法違法の勘所（１）

# １．はじめに
初めまして、弁護士の前田です。現在データサイエンスや画像生成、文章や動画の編集まで生成AIの利用が様々なところで促進されています。
その一方で生成AIの利用が様々な場面で問題視されており、現在決まった実務上の解釈が一致していないケースも存在するなど様々な議論を呼んでおります。
そこで、生成AIにまつわる法律上の問題点や注意点、どういうときに生成AIの開発や学習、違法になりうるのか、データサイエンスやAIに関する法務を扱う弁護士である私が、その勘所を事例やジャンルごとに即して不定期に発信していくシリーズを始めました。
本サイトをご覧いただく方々は主にITやデータサイエンスなどを通じてAIの開発はもちろん生成AIツールを日常的に使う方も多いと考えられます。そうした方々が気軽にAIに関する法律知識や考え方を知ることができるコーナーを目指してまいりますので皆様よろしくお願いいたします。
**また、ご質問も歓迎します。** 当記事のスレッドにてご質問をご記入いただければ、リサーチの必要ない範囲での回答であれば任意に回答します。（リサーチが必要な内容や事件相談は**有料（1回2時間まで、33,000円**）で対応いたしますので、その場合は弊所アドレス(**maeda@kittenlawoffice.com**)までご連絡ください。）

# ２．生成AI・AIと法律
生成AIの開発や利用、生成AIの生成物に関しては主に以下の点について関係法律が問題になります。
（１）学習データの収集の問題：収集するデータが個人情報であったり著作物である場合に収集が適法になるのかどうかという問題
**→個人情報保護法や著作権法、不正競争防止法の規定の問題**
（２）学習データによるAIモデルへの学習行為
**→個人情報保護法の情報提供の成否、著作権法第30条の4における非享受利用の規定の適否の問題**
（３）AIツールによる生成物の権利関係
**→著作物にあたりうるのか、プロンプトの内容の情報管理体制の問題、プロンプトによる創作的寄与の有無の問題など主に著作権法上の問題が多く関係する**
（４）学習済みAIモデルの保護問題
**→モデル自体を特許などで保護する方法や営業秘密として不正競争防止法上の仕組みで保護する方法、さらなるチューニングをするにあたり実装やモデル開発に関する情報やリソースのオープン・クローズ戦略の問題**
（５）AIツール利用者が著作権侵害を行った場合におけるAI開発者、AIツール提供者の責任問題
**→著作権侵害の主体の判断、著作権侵害の幇助責任を負うリスクはどこまであるのかの検討**

以上の各論点それぞれの一つをとっても簡単には解決する方法論を用意することは難しい論点です。
さしあたりまずは、
（１）AIに個人情報を入れるときの個人情報保護法周りのリスク
（２）生成AIと著作権法との関係性と生成モデルごとの考察に関する議論の進捗
（３）個別の法律を踏まえた御社及び各フリーランスの皆様のIPとの付き合い方・戦略論に分けて順次説明していく予定です。
難しい論点も含みますので必要があれば補足も随時改定しながら加筆しますし、[弊所HP](https://www.kittenlawoffice.com/)にて私のコラムがありますのでそちらも随時ご参照いただけますと幸いです。
これからも皆様と懇意にコミュニケーションが取れれば幸いです。よろしくお願いいたします。
# ３．弁護士前田拓郎のプロフィール

## 経歴
2005年3月	早稲田大学法学部卒
2007年以降	都内出版社編集部数社に勤務
2015年3月	東京大学法学政治学研究科　法曹養成専攻（法科大学院）卒
2017年12月	司法研修所入所（71期）
2019年1月	都内法律事務所勤務
2022年1月	前田拓郎法律事務所設立
## 主な取扱分野
知的財産法（著作権・商標・特許）・AI/Iot・VR/AR/XR・メタバース関連事業・漫画（二次創作含む）イラスト・出版・動画制作などのコンテンツビジネス・一般企業法務（会社法）・個人情報関連事業ほか

## 所属学会
著作権法学会
日本商標協会
人工知能学会
デジタルアーカイブ学会　ほか
事務所の詳細
前田拓郎法律事務所の資料は[こちらからダウンロード](https://www.kittenlawoffice.com/materialsdownload/)いただけます。
HPに記載されていない情報も、掲載しておりますのでぜひご覧くださいませ。
活動実績はこちらを参照くださいURL:https://www.kittenlawoffice.com/lawyer/
AmiVoiceクーポン適応する場所と一言

AmiVoiceのイベント最近開催中ですが、私もそれを使って見たくて登録しましたが、クーポンを入力するところが見つからなくて一瞬あせりました。最終的に見つかりましたが、あんまりにも導線が見つかりにくくて、簡単な記事を作成します。

https://qiita.com/official-events/23333339b694ca71810a


## 入り口はここ

https://acp.amivoice.com/account/mypage_confirmation.php

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/457921/1b6d3907-b752-3792-11c8-124b5d4d0eb4.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/457921/58ef327e-fa27-5989-c289-9d97b09b2dcc.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/457921/02f4893d-7a4f-4a8a-ef63-e83506eecd08.png)


## 最後に一言

- Mypageへの入り口はサイトになくて（あるいは私が見つかっていないかもしれません）、結局Direct Accessでしかアクセスできないのはやや使いにくいと思いました

もしどなたか以下のAmiVoiceのサイトから、MyPageへの入り口が見つかりましたらぜひコメントいただければと思います。

https://acp.amivoice.com/
picoCTF 2021 writeup Wave a flag

## Wave a flag (General Skills)

Can you invoke help flags for a tool or binary? This program has extraordinarily helpful information...

添付ファイル
・warm

添付ファイルに拡張子がついていないので、とりあえずメモ帳で開くと、ELFファイルであることが分かる。と、同時にflagも得られた。

`picoCTF{b1scu1ts_4nd_gr4vy_d6969390}`

一応、`chmod +x warm`で実行権限を付与して実行してみた。
```
> ./warm 
Hello user! Pass me a -h to learn what I can do!
> ./warm -h
Oh, help? I actually don't do much, but I do have this flag here: picoCTF{b1scu1ts_4nd_gr4vy_d6969390}
```
firebase login で(command not found: firebase)- nodenv環境

## はじめに

こんにちは！[@nyakako13](https://qiita.com/nyakako13 "Qiita ページ") です。

Reactアプリをfirebaseにデプロイする過程で少しつまづいたので対処法をまとめます。


## 問題
Firebase CLI のインストール
```shell
$ npm install -g firebase-tools
```

の後に、Firebase Hosting へのデプロイのために
```shell
$ firebase login
```

すると
```shell
zsh: command not found: firebase
```


## 解決方法
下記コマンドで解決しました。
```shell
$ nodenv rehash
```

## 原因
nodenvのshims下にfirebaseのパッケージコマンドがありませんでした。

https://qiita.com/awa2/items/1659347ce4109d9b4138


:::note info
nodenv rehashとは
nodenv 上の Node 実行可能ファイル（~/.nodenv/versions/*/bin/* や ~/.nodenv/versions/lts/*/bin/* など）のシムをインストールします。
nodeの新しいバージョンをインストールした後、または実行バイナリを提供するnpmパッケージをインストールした後に、このコマンドを実行します。
:::






nodenv-package-rehash プラグインを入れると、npm パッケージがグローバルにインストールされた時、自動的に nodenv rehash を実行してくれるみたい。

https://github.com/nodenv/nodenv#nodenv-rehash



## おわりに
よかったら[X(@nyakako13)](https://twitter.com/nyakako13 "Xプロフィール")もフォローしてもらえると嬉しいです。

[Qiita100投稿](https://qiita.com/nyakako13/items/03ad61cfb82a1582b5d1)まで残り96！

未経験や浅経験、厳しいと言われている年代でエンジニアへの転職活動されている方、負けずにがんばりましょう！！

## 参考

https://qiita.com/awa2/items/1659347ce4109d9b4138

https://github.com/nodenv/nodenv#nodenv-rehash

https://t-cr.jp/memo/24517926d09ed0a4
StampS3のPWMで遊ぶ


参考

↓クリック↓

https://tamanegi.digick.jp/computer-embedded/mcuboa/m5stamps3/

↓クリック↓

http://www.musashinodenpa.com/arduino/ref/

目的
PWMのテスト

![o_coq045.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/877bac51-8b60-05a8-5d62-c14c210fb4ed.jpeg)



```c++


//PWM_test1_M5S3


//初期化
void setup() {

  //出力ピンの初期化
  pinMode(5, OUTPUT);

} //setup


//メインループ
void loop() {

  //256回繰り返す
  for (int i = 0; i < 256; i++) {

    analogWrite(5, i); //PWM出力

    delay(20); //20ms待つ

  } //for i

} //loop



```
EC2インスタンスが何度も起動・停止を繰り返す


最近、相談されたことを備忘録として、記事化します。

## 発生している事象
- 身に覚えのないEC2インスタンスが大量に起動・停止を繰り返している

## 背景
- 開発環境として、EC2のスポットインスタンスを利用
- 管理ツールとして、CloudFormationを利用
- EBSは暗号化しており、KMSを利用
- 前日、EC2を更新するため、CloudFormationで指定しているAMIIDを変更

## 結論から
- スポットインスタンスを利用する場合、
  スポットフリートロールにKMSの権限を付与する必要あり

https://docs.aws.amazon.com/ja_jp/batch/latest/userguide/spot_fleet_IAM_role.html

- 不要になった、スポットインスタンスは、スポットリクエストをキャンセルする
    - 今回は、CloudFormationで展開しており、裏でリクエストが行われている
    - キャンセルは手動で行う必要があった
 
## 調査内容
#### EC2が大量に起動/停止をしているエラーについて

起動時に以下のエラーが発生している
```
Client.InvalidKMSKey.InvalidState: The KMS key provided is in an incorrect state 
```

![1713433307.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3747609/356b9906-6d80-2913-447c-0b6c0ca5cec0.png)

指定しているAMI自体は、KMSを使っておらず、暗号化されていない。
何が起きているかさっぱりだった。

#### とりあえず、起動できないAMIを手動で起動してみる
⇒起動できた。手動だとOK？

#### 起動時のログ確認
CloudTrailを確認
なぜ、起動できていないのか手掛かりになるログを探す

通常時
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3747609/fd739e85-1bbb-aadd-62b6-7950ad658480.png)

今回
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3747609/bee808d4-4c2f-430d-6963-e7faa8d30388.png)

⇒ユーザーが、InstanceLaunchになっている。
そんなユーザーはいない、、何者？

下の方の、イベントレコードを確認したところ、arnに以下が入っていた。

```
arn:aws:iam::{accountID}:role/aws-service-role/spot.amazonaws.com/AWSServiceRoleForEC2Spot 
```
⇒上記のマネージドロールがEC2を起動しようとしている。

KMSの権限には、上記ロールへ権限付与されておらず。。

EC2を立ち上げようとして、指定しているKMSで暗号化しようとしたところ、
権限がなく、起動⇒エラー⇒再試行⇒大量の起動できなかったEC2たちがリストにというのが結果だった。

InstanceLaunchというユーザーは、スポットインスタンスという特性上、
入札額を上回ったり下回ったりした際に、停止・起動するユーザーだと思われる。

## 回避するためには
- KMSに以下のロールで、権限を付与する

```
arn:aws:iam::{accountID}:role/aws-service-role/spot.amazonaws.com/AWSServiceRoleForEC2Spot 
```

- CloudFormationでスポットインスタンスを利用する場合には、
スポットリクエストを手動キャンセルするか、カスタムリソースを作成する

参考

https://dev.classmethod.jp/articles/cfn-ec2-spot-instance/

最近、私がスポットインスタンスをCloudFormationで利用する場合は、
上記のカスタムリソースを一緒に組み込んでいます

AMIが変更されて、新しいスポットリクエストができた後に、
旧スポットインスタンスのリクエストをキャンセルしてくれるLambdaが作られます。

とても便利なので、CloudFormation × スポットインスタンスを利用する場合は、
組み込んでおいた方がよいでしょう

それでは、また！
Android studio 「Unresolved reference: main」エラー

# Android開発でのUnresolved Referenceエラーの解決方法

Androidアプリケーションの開発中には様々なバグやエラーに直面することがあります。今回取り上げるのは、Kotlinを使用したAndroidプロジェクトでよく見られる「Unresolved reference」エラーです。このエラーは、プロジェクト内の参照が解決できない時に発生します。具体的には、以下のようなエラーメッセージが表示されることがあります。

```
    e: file:///YourProjectfilepath/app/src/main/java/com/websarva/wings/android/hellosample/MainActivity.kt:14:69 Unresolved reference: main
```
このエラーは、MainActivity.kt ファイルの特定の行で main という名前が解決できないという問題を指摘しています。
    
## エラーの原因
エラーメッセージによると、main というIDが見つからないために発生しています。このIDは通常、アプリケーションのレイアウトファイル内でビューを識別するために使用されますが、エラーが発生したコード行ではこのIDに基づいて何らかの操作を試みていますが、適切なIDの設定がされていないために問題が発生しています。
    
## 修正方法
この問題を解決するためには、アプリケーションのレイアウトファイルに適切なIDを追加する必要があります。具体的には、以下の手順で修正を行います。
    
プロジェクトの `app/res/layout/activity_main.xml` ファイルを開きます。
ファイル内の最も外側の親要素に対して、以下のようにIDを追加します。
    
```xml
    android:id="@+id/main"
```
このIDは、例えばアクティビティやフラグメントのルートビューなど、アプリケーションのメインコンテンツを含むビューに設定することが一般的です。
    
## 結論
Unresolved reference エラーは、IDや変数の参照が適切に設定されていないことにより発生します。このエラーに遭遇した場
node.jsでalexaスキル その8

# 概要
node.jsでalexaスキル、やってみた。
練習問題やってみた。

# 練習問題
Alexa-hostedで、暗算、インテントを追加せよ。

# 方針
- attributesManagerを使う。

LaunchRequest
「暗算ゲームをはじめます。それでは問題です。20足す40は？」

AnswerIntent
「60だぜ」

「すごい正解です。20足す40は60です。よくわかりましたね！」

「70だぜ」

「残念20足す40の答えは60です。」

# 写真

![スクリーンショット 2024-04-20 065343.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/cfc79117-6ca1-d222-0bcd-09d0f6e46e2c.png)

# アンサー、インテントを追加
- 対話モデル>インテント>インテントを追加>カスタムインテントを作成
AnswerIntent

- 対話モデル>インテント>インテントを追加>サンプル発話
" {ans} だぜ"

- 対話モデル>インテント>インテントを追加>インテントスロット
ans AMAZON.Number

- 対話モデル>インテント>インテントを追加>保存>スキルをビルド



# サンプルコード

```
const LaunchRequestHandler = {
	canHandle(handlerInput) {
		return Alexa.getRequestType(handlerInput.requestEnvelope) === 'LaunchRequest';
	},
	async handle(handlerInput) {
		let attributes = handlerInput.attributesManager.getSessionAttributes();
		const min = Math.ceil(1);
		const max = Math.floor(30);
		const a = Math.floor(Math.random() * (max - min) + min);
		const b = Math.floor(Math.random() * (max - min) + min);
		attributes.a = a; 
		attributes.b = b; 
		handlerInput.attributesManager.setSessionAttributes(attributes);
		let speechText = '暗算ゲームを始めます。それでは問題です。' + attributes.a + '足す' + attributes.b + 'は？';
		return handlerInput.responseBuilder.speak(speechText).reprompt(speechText).getResponse();
	}
};


const AnswerIntentHandler = {
	canHandle(handlerInput) {
		return handlerInput.requestEnvelope.request.type === 'IntentRequest' && handlerInput.requestEnvelope.request.intent.name === 'AnswerIntent';
	},
	handle(handlerInput) {
		let attributes = handlerInput.attributesManager.getSessionAttributes();
		const a = attributes.a;
		const b = attributes.b;
		const ans = handlerInput.requestEnvelope.request.intent.slots.ans.value;
		let speechText = '';
		const v = a + b;
		if (v === parseInt(ans))
		{
			speechText = 'すごい！正解です！' + a + ' 足す ' + b + 'は ' + v + 'です。よくわかりましたね！'
		}
		else
		{
			speechText = '残念！' + a + ' 足す ' + b + 'は ' + ans + 'ではありません。正解は' + v + 'でした。'
		}
		return handlerInput.responseBuilder.speak(speechText).reprompt(speechText).getResponse();
	}
};

```

以上。
SAP Build Code (Joule) で既存のCAPプロジェクトをサポートしてもらう方法

## はじめに
Jouleでは現状、SAP Buildのロビーまたはローコード用のテンプレートで作成したプロジェクトしかサポートされません。`cds init`で作成したプロジェクトでJouleのアイコンをクリックしても、"Not Available"と言われてしまいます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/276021/675fb8de-9310-ff20-a733-cc307d94068d.png)

Jouleのロジック生成やテストコード生成はかなり便利であり、既存のプロジェクトでも使いたいと思い、試してみました。

**SAP Build Codeを使ってみた記事はこちら**

https://qiita.com/tami/items/ae57beb9ec8166f2c002


## 結論
package.jsonに以下の設定を追加することで、既存のコードに対してもJouleが有効になります。なお、この方法はCAP Node.jsに対してのみ有効で、Javaはサポートされません。

```json
  "lcap": true
```

## 実施したステップ
### 1. プロジェクトを作成

```
cds init <プロジェクト名>
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/276021/5e536eec-9fca-d1be-559d-5dd0dbf799f4.png)


この時点ではJouleは有効ではありません。 
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/276021/8b9ae5c5-6982-8dab-80c4-fda202959cff.png)

### 2. package.jsonに設定を追加
以下の設定を追加します。

```json
  "lcap": true
```

全体は以下のようになります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/276021/8f09a14d-a32e-22f0-7839-8bcf152a1bbd.png)


### 3. dependencyをインストール
@sap/low-code-event-handlerをインストールします。

```
npm install @sap/low-code-event-handler
```

テンプレートで生成したコードはこのモジュールを使用します。

```javascript:例
/**
 * Code is auto-generated by Application Logic, DO NOT EDIT.
 * @version(2.0)
 */
const LCAPApplicationService = require('@sap/low-code-event-handler');
const books_Logic = require('./code/books-logic');

class CatalogService extends LCAPApplicationService {
    async init() {

        this.after('CREATE', 'Books', async (results, request) => {
            await books_Logic(results, request);
        });

        return super.init();
    }
}


module.exports = {
    CatalogService
};
```

### 4. Jouleが有効になったことを確認
ブラウザをリフレッシュしてからJouleを開きます。（リフレッシュしないと元の状態のままです）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/276021/1db90e07-f3aa-a07d-151b-a4447d47a89d.png)

このあと、`cds add tiny-sample`によるデータモデルの追加、およびJouleによるアプリケーションロジックの生成を行い、Cloud Foundryにデプロイして正常に動くことを確認しました。

## 注意点
既存のソースファイルに対してはJouleは利用できません。試しにイベントハンドラがすでにある状態でJouleを有効化してみます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/276021/5dd87f7d-19c6-2541-a838-9163cffc3743.png)

Open Guideが表示されますが、このソースに対してはサポートが有効ではありません。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/276021/dd33df98-0ce3-b6e0-1862-87751e9325af.png)

Graphical Modelerからロジックを追加すると、**既存のソースは上書きされます**。よって既存のソースがある場合は退避しておく必要があります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/276021/d0fdce90-704f-c20d-41cd-7aedc4e959ca.png)
Pythonで「ファイル名またはディレクトリ名を変更する」の動作を確認してみた

# 概要

Pythonで「ファイル名またはディレクトリ名を変更する」の動作を確認してみました。
以下のページを参考にしました。

Qiitaはメンテナンスのためサービスを一時的に停止しています。

# 実装

以下のファイルを作成しました。
```sample.py
import os

oldpath = './test/book.txt'
newpath = './test/memo.txt'
os.rename(oldpath, newpath)

oldpath = './test/back'
newpath = './test/old'
os.rename(oldpath, newpath)
```

以下のコマンドを実行しました。
```
$ mkdir test
$ touch test/book.txt
$ mkdir test/back
$ ls test
back  book.txt
$ python3 sample.py 
$ ls test
memo.txt  old
```

# まとめ

何かの役に立てばと。
Python標準入力受け取り方メモ

# 数値と文字列を同時に受け取る
入力される数値と文字列
```pyton
ピカチュウのレベル 95
```
一度str型で受け取ってからint型にする
```python
text,level=map(str,input().split())
level=int(level)
```
# 文字列で入力された配列を受け取る
入力
```python
[1,2,3,4,5]
```
まずリストで受け取って" [ "  と" ] "を外す。その後int型に変換して新しいリストに格納する。
```python
receive=list(map(str,input().split()))
receive=receive[1:-1] # "1,2,3,4,5"
new_list=[]
for i in range(len(receive)):
    new_list.append(int(receive[i]))

```
# 数値を同時に受け取る
## 変数で受け取る
入力される値
```python
1 2
```
変数で受け取る
```python:
A,B=map(int,input().split())
```
## リストで受け取る
```python
num_list=[(map(int,input().split()]
```
# 数値を連続で受け取る
入力される値
```python
1 2
3 4
```
空のリストを作ってそれぞれに格納する
```python
N=2
A_list=[]
B_list=[]
for i in range(N):
    A,B=map(int,input().split())
```
学習日記#4: 環境構築

## ゴール
自宅PCにNotebooks環境を構築

## 教材
PythonではじめるKaggleスタートブック

## やったこと
- Dockerインストール
- Githubからサンプルコード一括DL
- Dockerで環境構築

## 詰まった
- ターミナルで```docker-compose up --build```を実行したところ処理の途中で```jupyter The requested image's platform (linux/amd64) does not match the detected host platform (linux/arm64/v8) and no specific platform was requested 0.0s 
Attaching to jupyter-1```というエラーが出て失敗。色々調べたが解決策わからず、、、
- とりあえずKaggleのNotebookかGoogle Colabで進めるかぁ、、、
Sail環境でのTailWind導入

Sail環境で新規に追加したTailWindが反映されなかった時の対処について

# TailWindとは
オープンソースのCSSフレームワークで、Bootstrapなどの他のCSSフレームワークとは異なり定義済みクラスを提供しないのが特徴。
代わりに、ユーティリティCSSクラスを提供するので、これを組み合わせて要素をスタイリングする。

https://tailwindcss.com/


# Tailwind CSSの導入
### インストール
Sailを立ち上げている状態でコマンド実行
```
sail npm install -D tailwindcss postcss autoprefixer
```
sailコマンドで以下をインストールするコマンド
* Tailwind CSS
* PostCSS
* Autoprefixer

### 初期設定
Tailwind CSSの初期設定ファイルを生成
```
sail npx tailwindcss init -p
```
* `npx`　npmリポジトリからパッケージを一時に実行する
* `init`　初期設定ファイルを生成
* `-p`　プリセットのオプション

作成されたtailwind.config.jsとresources/css/app.cssファイルにそれぞれへ、以下を記述
```js:tailwind.config.js
import defaultTheme from 'tailwindcss/defaultTheme';
import forms from '@tailwindcss/forms';

export default {
    content: [
        './vendor/laravel/framework/src/Illuminate/Pagination/resources/views/*.blade.php',
        './storage/framework/views/*.php',
        './resources/views/**/*.blade.php',
    ],

    theme: {
        extend: {
            fontFamily: {
                sans: ['Figtree', ...defaultTheme.fontFamily.sans],
            },
        },
    },

    plugins: [forms],
};

```
* `content:` Tailwind CSSが解析するCSSファイルのパスを指定。blade.php 拡張子を持つBladeファイルや、.php 拡張子を持つLaravelのビューファイルなどが指定される

```css:resources/css/app.css
@tailwind base;
@tailwind components;
@tailwind utilities;
```
* `@tailwind base;` ベーススタイルを適用する指示で、ブラウザのデフォルトスタイルをリセットし、基本的なHTML要素に対して一貫性のあるスタイルを適用
* `@tailwind components;` コンポーネントスタイルを適用する指示で、再利用可能なコンポーネントのスタイルがプロジェクトに適用
* `@tailwind utilities;` ユーティリティクラスを適用する指示で、テキストスタイル、マージン、パディング、色などの簡潔なクラスが使用できるようになる


### 実行

```
sail npm run dev
```
開発用のサーバーが起動するのでTailWindを追加で記述しても反映され始める。
Importmapを利用したJavaScriptの適切な管理とパフォーマンス向上

## はじめに
Rails 7では、JavaScriptバンドラーを使わずにJavaScriptを効率的に管理するために、Importmapが導入されました。Importmapを利用することで、必要なJavaScriptだけをページごとに読み込むことが可能となり、パフォーマンスの最適化が期待できます。この記事では、Importmapを使用してJavaScriptの読み込みをページ固有で管理し、不要なスクリプトの読み込みを減らす方法について説明します。

## Importmapの基本
Importmapは、ブラウザのネイティブなJavaScriptモジュールローダーを活用して、指定されたJavaScriptファイルをWebアプリケーションに直接インクルードする仕組みです。`config/importmap.rb` ファイル内でJavaScriptファイルを「ピン」することで、どのファイルがどのキーワードでアクセスされるかを定義します。

## Importmapの設定方法
まず、`config/importmap.rb` ファイルにJavaScriptファイルをピンします。例えば、特定のページでのみ使用する `staff_selector.js` がある場合、以下のように設定します。

```ruby
# config/importmap.rb
pin "staff_selector", to: "staff_selector.js"
```

### ビューでのImportmapの使用
特定のビューでJavaScriptファイルを読み込むには、`javascript_importmap_tags` ヘルパーを使います。このヘルパーによって、指定したJavaScriptファイルがページに読み込まれます。

#### IDを用いる場合
```erb
<%= javascript_importmap_tags "staff_selector" %>

<%# 以下は通常のビュー %>
<div class="container mt-4">
  <h2><%= "#{@start_date.strftime('%Y年 %m月')}の月間スケジュール" %></h2>

  <%= form_with(url: '#', method: :get, local: true, id: "staff-selector-form") do |form| %>
    <%= label_tag :staff_id, "スタッフを選択:" %>
    <%# 以下のstaff_idに変更があった場合にJS発火 %>
    <%= select_tag :staff_id, options_from_collection_for_select(current_company.staffs, :id, :name, prompt: "スタッフを選択"), class: "form-select" %>
  <% end %>

  <%= month_calendar do |date| %>
    <div>
      <%= date.day %>
    </div>
  <% end %>
</div>
```

#### Classを用いる場合
```erb
<%= javascript_importmap_tags "staff_selector" %>
<div class="container mt-4">
  <h2><%= "#{@start_date.strftime('%Y年 %m月')}の月間スケジュール" %></h2>

  <%= form_with(url: '#', method: :get, local: true, id: "staff-selector-form") do |form| %>
    <%= label_tag :staff_id, "スタッフを選択:" %>
    <%# 以下のstaff_idに変更があった場合にJS発火 %>
    <%= select_tag :staff_id, options_from_collection_for_select(current_company.staffs, :id, :name), prompt: "スタッフを選択", class: "form-select staff-selector" %>
  <% end %>

  <%= month_calendar do |date| %>
    <div>
      <%= date.day %>
    </div>
  <% end %>
</div>
```

このタグをビューファイルの適切な場所（通常は `<head>` セクション）に配置することで、指定したJavaScriptがページに組み込まれます。

### JavaScriptの適用
ページ特有のJavaScriptを適用するために、例として `staff_selector.js` で以下のような処理を行います。

#### IDを用いる場合
```javascript
// app/javascript/staff_selector.js
document.addEventListener("turbo:load", function() {
  const selectElement = document.getElementById("staff_id");
  selectElement.addEventListener("change", function() {
    const selectedStaffId = this.value;
    window.location.href = `/staffs/${selectedStaffId}/monthly_schedule`;
  });
});
```

#### Classを用いる場合
```javascript
document.addEventListener("turbo:load", function() {
  document.querySelectorAll(".staff-selector").forEach(selectElement => {
    selectElement.addEventListener("change", function() {
      const selectedStaffId = this.value;
      if (selectedStaffId) {
        window.location.href = `/staffs/${selectedStaffId}/monthly_schedule`;
      }
    });
  });
});

```

### まとめ
Importmapを利用することで、Rails 7アプリケーションのJavaScriptの管理が簡素化され、ページごとに必要なスクリプトのみをロードすることが容易になります。これにより、ページの読み込み速度の向上が期待でき、エンドユーザーにとってより快適なブラウジング体験が提供できるようになります。
NeurIPS2023の量子化論文 (1)

# 概要

この記事では、[NeurIPS2023](https://neurips.cc/Conferences/2023)の量子化論文を紹介します。[^1]

[^1]: 画像や数式は論文から引用しています。


# QLoRA: Efficient Finetuning of Quantized LLMs

https://arxiv.org/abs/2305.14314

- 概要：4bit量子化モデルからのLoRA
- 新規性：4bitでもFine-tunign(LoRA)できることを初めて示した。
- キモ：(1) 4bit-Normal Float. 4bitのintやfloatより良い。(2) Double Quantization. 量子化係数を量子化する。 (3) Paged optimizers. NVIDIAの共有メモリでページングを高速化。


# Memory Efficient Optimizers with 4-bit States

https://arxiv.org/abs/2309.01507

- 概要：オプティマイザの状態(Adamのモーメント)のビット数を減らして学習時のメモリ削減。
- 研究機関：Bosch
- 新規性：従来の8bitから今回は4bitに削減。
- キモ：(1) モーメント部分の外れ値が複雑なカラムがあるのでブロックサイズを小さくして量子化する。(2) 2次モーメントは0を除いて量子化することで、Adam計算中に現れる$1/(\sqrt{V}+\varepsilon)$の値が大きくならないようにする。


# QuIP: 2-Bit Quantization of Large Language Models With Guarantees

https://arxiv.org/abs/2307.13304

- 概要：LLM向け2bit PTQ
- 新規性：Hessianの方向を使って丸めを正確にする方法。


# Quantizable Transformers: Removing Outliers by Helping Attention Heads Do Nothing

https://arxiv.org/abs/2306.12929

- 概要：Transformerの量子化における外れ値対策
- 研究機関：Qualcomm
- 新規性：外れ値はAttentionが'no-op'(0を常に出力)を学習することが原因だと仮定し、clipped softmaxとgated attentionによる対策を提案した。
- キモ：まず言語モデルで[sep]が'no-op'に対応することを示し、ViTでも画素の外れ値は更新しなくなることを示した。Fig. 4の仮説を立てた。


# Training Transformers with 4-bit Integers

https://arxiv.org/abs/2306.11987

- 概要：Transformerの4bit量子化
- 研究機関：Bosch
- 新規性：今のGPUで使えるINT4で学習。FP16の2.2倍高速。
- キモ：外れ値を3.3節のHadamard変換で小さくす。Back propagationはINT4を2つ使ってINT8で計算する。
file 抽出

```ruby:title.rb

import os
import csv

# 対象のディレクトリパスを設定
directory_path = 'D:/'

# 出力ファイル名
output_file = 'file_list.csv'

# 対象のディレクトリ内のファイルをリストアップ
file_names = []
for filename in os.listdir(directory_path):
    if filename.endswith('.csv'):
        # 拡張子 '.out' を除いたファイル名をリストに追加
        file_names.append(filename[:-4])

# CSVファイルに書き出し
with open(output_file, mode='w', newline='') as file:
    writer = csv.writer(file)
    for name in file_names:
        writer.writerow([name])  # CSVの各行にファイル名を出力

print(f"{len(file_names)} files found and listed in {output_file}.")

```
C

```c:c.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main() {
    FILE* fp;
    char buffer[1024];
    char* filename;
    char* context = NULL; // strtok_s用のコンテキストポインタ
    char filepath[1024];
    errno_t err;

    // CSVファイルを開く
    err = fopen_s(&fp, "D:/file_list.csv", "r");
    if (err != 0) {
        fprintf(stderr, "ファイルオープンに失敗しました: %d\n", err);
        return EXIT_FAILURE;
    }

    // CSVファイルから一行ずつ読み込み
    while (fgets(buffer, 1024, fp)) {
        // 改行文字を削除
        buffer[strcspn(buffer, "\n")] = 0;

        // ファイル名を取得（strtok_sを使用）
        filename = strtok_s(buffer, ",", &context);
        if (filename == NULL) {
            continue;
        }

        // .txtファイルパスを構築
        snprintf(filepath, sizeof(filepath), "D:/%s.txt", filename);

        // 新しい.txtファイルを作成して開く
        FILE* txtfile;
        err = fopen_s(&txtfile, filepath, "w");
        if (err != 0) {
            fprintf(stderr, "ファイル '%s' を作成できませんでした。エラーコード: %d\n", filepath, err);
            continue;
        }

        // 例えば、何かの内容を.txtファイルに書き込む
        fprintf(txtfile, "このファイルは%sに基づいて作成されました。\n", filename);

        // テキストファイルを閉じる
        fclose(txtfile);
    }

    // CSVファイルを閉じる
    fclose(fp);

    return EXIT_SUCCESS;
}


```
2値分類のしきい値をいじって精度の調整

Scikit-LearnやKerasやその他いろいろと最後にシグモイド関数を使って分類する事は2値分類(陽性か陰性)では多いです。
ですが、2値分類において大体の場合しきい値は0.5以上だと1(一般に陽性)で0.5未満だと0(一般に陰性)とすることが初期設定では多いです。
ただ、もちろんそれに合わせて回帰しているのでその考え方自体は間違っていないのですが、時として他の値をしきい値にすることでより汎化する事もあります。
そこで以下の指標を基に実際にロジスティック回帰のしきい値を変えて汎化能力を考察してみましょう。
- 正解率
- 再現率
陽性・陰性のデータが実際に陽性・陰性と判断された割合
- 適合率
陽性・陰性と判断されたデータが実際に陽性・陰性だった割合
- f1
再現率と適合率の調和平均

# コーディング
## ライブラリのインポート
ロジスティック回帰を分かりやすくするためここではstatsmodelsを使用します。
```Python3
from sklearn.metrics import classification_report
import statsmodels.api as sm
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
```

## データの読み込み
ここでは分かりやすく陰性と陽性を扱いたいのでScikit-Learnにあります乳がんのデータセットを使います。あらかじめCSVにしているのでそれを読み込みます(目的変数の名前が当時解析できなかったので「y」としています)。
```Python3
df = pd.read_csv("breast_cancer.csv")
df.head()
```

## 目的変数と説明変数で分ける
ここではstatsmodelsを使用しているため何もしないと切片が出来ないため「add_constatnt」を行いcontantという説明変数を作り「1」で埋めます。
※なお、本当は自由に値を最後に入れてテスト(シミュレーション)をする場合は変数間の相関、つまり多重共線性を考慮しないといけないので<a href="https://qiita.com/murasaki1994/items/b7f76390752d4423846c">VIF</a>を本当なら計算して因子を選択しましょう。
```Python3
x = sm.add_constant(df.drop("y", axis=1))
y = df["y"]
```

## モデルの生成と回帰
実際にロジスティック回帰を作成して説明変数をテストデータとして値を出力させます。
```Python3
model = sm.Logit(y, x).fit_regularized()
y_pred_proba = model.predict(x)
y_pred_proba
```
するとこのように出力されます。
```
0      6.312334e-55
1      1.152860e-32
2      2.268552e-41
3      4.608393e-20
4      9.211627e-26
           ...     
564    6.152497e-61
565    1.854253e-35
566    6.885977e-10
567    1.064712e-47
568    1.000000e+00
Length: 569, dtype: float64
```

## しきい値をいじって判別
ここからが本題で、ロジスティック回帰におけるシグモイド関数のしきい値を0.5以外で設定した時にどのように精度が変動するかを見ていきます。
```Python3
acc = []
rcl0 = []
rcl1 = []
pcs0 = []
pcs1 = []
f10 = []
f11 = []
x = []
for i in range(1, 10):
    y_pred = np.where(y_pred_proba.values >= i/10, 1, 0)
    rep = classification_report(y, y_pred, output_dict=True)
    acc.append(rep["accuracy"])
    rcl0.append(rep["0.0"]["recall"])
    rcl1.append(rep["1.0"]["recall"])
    pcs0.append(rep["0.0"]["precision"])
    pcs1.append(rep["1.0"]["precision"])
    f10.append(rep["0.0"]["f1-score"])
    f11.append(rep["1.0"]["f1-score"])
    x.append(i/10)
plt.plot(x, acc, marker="x", label="accuracy")
plt.plot(x, rcl0, marker="x", label="recall 0")
plt.plot(x, rcl1, marker="x", label="recall 1")
plt.plot(x, pcs0, marker="x", label="precision 0")
plt.plot(x, pcs1, marker="x", label="precision 1")
plt.plot(x, f10, marker="x", label="f1 0")
plt.plot(x, f11, marker="x", label="f1 1")
plt.legend()
plt.show()
```
これによって以下のような折れ線グラフが出力されます。
(横軸：しきい値、縦軸：精度)
![oresenn.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2782889/39e3c683-9dbf-31cf-c03d-3791398881f8.png)
これらを総合的に見るとしきい値はどの値が適切かを考察できます。
例えばこのグラフから陰性の適合率は値が大きくなるにつれて下がりますが、陽性の適合率は陰性の適合率ほどの変動はありません。
正解率やf1に着目すると0.3と0.4が適切になります。
その他にもいろいろ考察できますが、何が言いたいかというと正解率単体に着目していると予測のバランス(陰性と陽性の正誤の比率)が悪くなったり、陰性と陽性の識別はトレードオフだったり案外f1(F値)が再現率と適合率のバランスにおいてその辺役に立つなどがあります。

いずれにせよ、別に本来のしきい値の0.5でも問題ないんですけどね、本当は。ただ、一度こういう実験をしてみるのも大切かなと思った次第です。
外部ライブラリを利用せず、structをPretty Printしたい

外部ライブラリを利用せず、Go言語でstructをPretty Printする方法を2つ紹介します。

# fmtパッケージを利用する

`fmt.Printf`を利用する場合、書式指定子に`%+v`を指定すればよいです。

```go
package main

import (
	"fmt"
	"time"
)

type Employee struct {
	ID       int
	Name     string
	HireDate time.Time
}

type Department struct {
	ID        int
	Name      string
	Employees []Employee
}

func main() {
	department := Department{
		ID:   9876,
		Name: "営業部",
		Employees: []Employee{
			Employee{ID: 100, Name: "佐藤", HireDate: time.Date(2001, 1, 1, 1, 1, 1, 1, time.UTC)},
			Employee{ID: 200, Name: "田中", HireDate: time.Date(2002, 2, 2, 2, 2, 2, 2, time.UTC)},
			Employee{ID: 300, Name: "高橋", HireDate: time.Date(2003, 3, 3, 3, 3, 3, 3, time.UTC)},
		},
	}

	fmt.Printf("%+v\n", department)
}
```

実行結果は以下の通りです。

```
$ go run main.go
{ID:9876 Name:営業部 Employees:[{ID:100 Name:佐藤 HireDate:2001-01-01 01:01:01.000000001 +0000 UTC} {ID:200 Name:田中 HireDate:2002-02-02 02:02:02.000000002 +0000 UTC} {ID:300 Name:高橋 HireDate:2003-03-03 03:03:03.000000003 +0000 UTC}]}
```

# jsonパッケージを利用する

structをjsonとして扱う方法もあります。

```go
package main

import (
	"encoding/json"
	"fmt"
	"log"
	"time"
)

type Employee struct {
	ID       int
	Name     string
	HireDate time.Time
}

type Department struct {
	ID        int
	Name      string
	Employees []Employee
}

func main() {
	department := Department{
		ID:   9876,
		Name: "営業部",
		Employees: []Employee{
			Employee{ID: 100, Name: "佐藤", HireDate: time.Date(2001, 1, 1, 1, 1, 1, 1, time.UTC)},
			Employee{ID: 200, Name: "田中", HireDate: time.Date(2002, 2, 2, 2, 2, 2, 2, time.UTC)},
			Employee{ID: 300, Name: "高橋", HireDate: time.Date(2003, 3, 3, 3, 3, 3, 3, time.UTC)},
		},
	}

	b, err := json.MarshalIndent(department, "", "  ")
	if err != nil {
		log.Fatalf("unexpected error: %w", err)
	}
	fmt.Println(string(b))
}
```

実行結果は以下の通りです。

```
$ go run main.go
{
  "ID": 9876,
  "Name": "営業部",
  "Employees": [
    {
      "ID": 100,
      "Name": "佐藤",
      "HireDate": "2001-01-01T01:01:01.000000001Z"
    },
    {
      "ID": 200,
      "Name": "田中",
      "HireDate": "2002-02-02T02:02:02.000000002Z"
    },
    {
      "ID": 300,
      "Name": "高橋",
      "HireDate": "2003-03-03T03:03:03.000000003Z"
    }
  ]
}
```

# 環境情報

```
$ go version
go version go1.22.1 linux/amd64
```
VSCodeでペットを飼う

# はじめに

こんにちは。エンジニアの皆さん。

日々の業務にお疲れではないでしょうか？
消えないエラー、動かないプログラム、迫る締切、etc...
数あるストレスで限界になっていませんか？

...

...!!!

そんな時はペットを飼いましょう！！！！！！！！！！

...というわけで、VSCode上でペットを飼うことができる拡張機能を紹介します。


## その名も、vscode-pets.......!!!!!!!!!!

![summary.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3383150/faee9346-5d34-f718-9cbc-1c5d7c460be5.png)

これです。**vscode-pets**で検索しましょう。


## 導入

インストールしたらコマンドから`Pet Coding: Start pet coding session`を実行します。

![start.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3383150/26abf621-7a67-791d-85f8-a520ef65a8c6.png)

`Pet Coding:Spawn additional pet`から好きなペットを選んで...

![firstpet.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3383150/367a51b2-6c89-4ae7-52a2-95f02238a4cc.png)

ほわああああああああ！！！！！！！

殺伐としたVSCodeに一輪の花が爆誕しました。かわいいですねー。

## あそびかた

すでにだいぶ癒されますが、結構遊べる機能がついてます。
`Pet Coding:Roll-call`から呼び出しができたり。

![rollcall.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3383150/d1b75313-f7c8-947f-97fc-12716a5b8379.png)


カーソルで触れてみると...

![cursor.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3383150/6120e570-ae47-f0ab-2985-8109c0506c24.png)

こんなふうにリアクションがあったり。
右上の丸いマークを押すとボールで遊べたり。

![ball.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3383150/ba249d46-337c-765a-77c5-eda4ab3a6abb.png)

ちなみにコマンドで`Pet Coding:Throw ball`を実行しても同じです。
設定から`Throw Ball With Mouse`を有効にしておけば、マウスを使ってボールの操作ができたりしちゃいます。


## カスタマイズ


今は猫だけ出してますが、他にも結構種類があるんですよねー。

![totoro.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3383150/a2e9e841-b8ae-da1c-ffed-1106709bea8b.png)

トトロとかいます。

設定から大きさとかも変えられちゃいます。

![medium.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3383150/67b752aa-17bb-ab5f-51c0-3681a443fe17.png)

背景なんかも変えられます。

![bg.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3383150/58faf4b6-6aea-a420-f9b0-6a1334e08f19.png)

ペット用のパネルとか出せます。

![panel.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3383150/415df454-cabf-79fa-e78c-de666978ce3f.png)

# 終わりに

というわけでストレスフルなコーディングライフを過ごしている方に向けたペットの紹介記事でした。
詳細な説明や動作等は公式リポジトリやドキュメントを読んでいただければと思います。

https://github.com/tonybaloney/vscode-pets

https://tonybaloney.github.io/vscode-pets/usage.html
【完全解決】2Dのスプライト描画で隙間や変な線、隣の色が出る問題

# 対象者
2Dのスプライト描画に悩まされていて、本質を知りたい人向けです。
正しく解説されている記事を見つけられなかったので、執筆に至りました。

# 原因
+ 描画位置がずれている。
+ カメラの位置がずれている。
※DirectX, OpenGL, Unity, UEどれも原因は一緒

# 補足
+ ゲームエンジンやライブラリの不具合ではない。
+ 補間方法の指定は関係ない。
+ 1ピクセル大きく描画しても解決している訳ではない。
+ テクスチャ周辺を透明ピクセルで埋めても解決はしていない。

# どうしたらいいの？
描画位置とカメラの位置をずれないようにする。

# なんでずれるの？
作り手が気づいてない＆本質を理解できておらず発生しています。

# 解説
ディスプレイはピクセルという単位で描かれています。
大切なことなので、もう一度いいます。ディスプレイはピクセル単位です。

ピクセルを扱う座標は整数です。
もう一度いいますね。ピクセルは整数です。

3x3ピクセルの画像
![3x3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/252222/409c565a-6407-5c87-3a40-aa50ff2cb428.png)

この画像の中心座標は(1,1)です。※赤い部分
![3x3g.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/252222/bf9ce2be-6cd8-8a42-9962-eae6196258bd.png)

次に大切なことを言います。ゲームエンジン/ライブラリは浮動小数で座標を扱います。
もう一度いいますね。ゲームエンジン/ライブラリは浮動小数です。

3x3背景の中に2x2のスプライトを中心に描画するとこうなります。
![3x3b.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/252222/5d29bc2e-9422-2f08-8a98-1b18d27651a0.png)

これはピクセル領域から「はみ出ている」ので描画できません！
んじゃどうなるの？

**パターン１ 切り捨て**
スプライトを並べた時に隙間が出来たり、欠けたりする原因はこれ
![3x3c.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/252222/bda36502-43d5-7b7b-4f7e-df80668243be.png)

**パターン２ 混ざる**
UVのサンプリングに影響を与えて隣の色が出たり、変な色になる原因はこれ。
![3x3d.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/252222/495ea4eb-ec75-46b1-9def-909d16aa343c.png)

本質はこれのどちらかです。
小数の具合に応じて、切り捨てられたり混じったり変化します。
なので、動かしてから隙間が出たりする訳です。

# どうしたらいいの？
ピクセルでぴったり表示できる座標にする。
これだけです…本当にこれだけ…
![3x3f.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/252222/119a561a-d38b-9e47-5db5-175dbf44f5aa.png)

偶数ピクセル数の画像を描画するときは、描画位置を整数化つまりintキャストを実施して+0.5もしくは-0.5を行えばよいです。※どちらにずらすかはお好みで

奇数ピクセルの画像を描画するときは、描画位置の整数化が必要になります。
当然のことですが、幅/高さが偶数・偶奇か判定して、それぞれ計算しなければなりません。

同様にカメラの位置もずれてはいけません。こちらも気をつけましょう。

**カメラの位置に応じて偶数時・奇数時の計算式が逆になりますのでご注意ください。**
**※整数か0.5刻みかによって違う**

# 参考(Unity)
**正常系**
ピクセルぴったりにすると補間方法の違いも影響を受けていません。
正確には補間されていますが、計算結果が同じ値になります。
(高速化の観点ではニアレストネイバーの方がよいです)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/252222/f1120738-bffe-cf0c-de1e-8a5a3ae8fd22.png)

**異常系(GameObjectを正常に表示できない位置にずらす)**
色が混じっていることが分かりますね。
補間方法が効いており、真ん中の部分がバイリニアだと隣の色が混じっています。

一見するとニアレストネイバー(Unityではポイント)が綺麗に見えるため
解決すると勘違いされる部分です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/252222/1b6e64b6-b47b-0c50-8c02-48f67a393932.png)

スライスするとバイリニアは隣の色を拾って問題になることが分かりやすいですね。
内側1ピクセルスライスしたらよいとか、1ピクセル大きくすればよい、もしくは空ければよいと言われる部分です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/252222/574218ce-06cd-a1fa-d158-7aae74fe828e.png)

位置を変えれば、ニアレストネイバーでも隣の色を拾うので、何の解決にもなっていません。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/252222/5144b16a-b48c-c44c-9a66-05557ecca856.png)

**異常系(カメラを正常に表示できない位置にずらす)**
オブジェクトの位置が正常でも、カメラの位置がずれてると台無しです。
同様の問題が発生します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/252222/a5729fa0-9dd8-0f38-c8bd-9cd87946ca0a.png)
javascriptの非同期開発

### 非同期処理とシングルスレッド
#### 非同期とは
```javascript
console.log(100)
setTimeout(function() {
	console.log(200)
}, 1000)
console.log(300)
```

```javascript
console.log(100)
alert(200)
console.log(300)
```
#### 非同期処理が必要になるのはどのような場合ですか?
1. 待機が発生する場合
2. 待機中はalertのようにプログラムをブロックすることを避けたい時
なので、「待機の場合」に非同期処理が必要

#### フロントエンドで非同期開発を使用するシナリオ
1. スケジューリングタスク： `setTimeout`, `setInverval`
2. Networkリクエスト: ajaxリクエスト、動的に<img>のload
```javascript
console.log('start')
$.get('./products',function(data) {
  console.log(data)
}
console.log('end')
```
```javascript
console.log('start')
let img = document.createElement('img')
img.onload = function() {
  console.log('loaded')
}
img.src = '/xxx.png'
console.log('end')
```

3. イベントバインディング
```javascript
console.log('start')
document.getElementById('btn1').addEventLister('click', function() {
  alert('click')
}
console.log('end')
```
#### 非同期と同期の違い
SSOなどの認証方式について理解まとめ

# はじめに
認証方式についての知識があいまいだったので自分なりに調べてまとめてみました。
メモ程度なのでざっくりとした内容ですが、認証方式を知るための取っ掛かりになれば幸いです。

# 認証方式の種類
- Basic認証
- Digest認証
- セッションベース認証
- トークンベース認証
- シングルサインオン（OAuth, OpenID Connect, SAML）

## Basic認証とは

ユーザIDとパスワードのみで制限をかける簡易的なHTTP認証

**メリット**
・容易に設定可能

**デメリット**
・平文で送信するためセキュリティの脆弱性がある
・リクエストごとに認証を行う必要がある


## Digest認証とは

Basic認証と同じくユーザIDとパスワードのみで制限をかけるが、ハッシュ化して送信するためBasic認証より脆弱性を改善

**メリット**
・Basic認証よりセキュリティ性が高い

**デメリット**
・リクエストごとに認証を行う必要がある

## セッションベース認証とは
セッションIDをCookieに保存し、それを利用して認証を行う
セッションIDにはユーザ情報を含むためステートフル

**メリット**
・ログアウト時点でアクセス不可となりセキュリティ性が高い

**デメリット**
・サーバ負荷がトークンベース認証より高い

## トークンベース認証とは
アクセストークンをCookieに保存し、それを利用して認証を行う
アクセストークンにはユーザ情報を含まないためステートレス

**メリット**
・サーバーに認証のための情報を持つ必要がないためスケーラビリティが高い

**デメリット**
・ステートレスであるためアクセストークンの流出による不正アクセスのリスクあり

## シングルサインオン（OAuth, OpenID Connect, SAML）とは

1度のユーザー認証で複数のシステムの利用が可能になる仕組みがシングルサインオン
OAuth, OpenID Connect, SAML等は上記を実現するためのプロトコル

**メリット**
・ユーザのログインする負担を軽減できる

**デメリット**
・同一のIDパスワードを使用するためログイン情報漏洩時のリスクが大きい

# 認可と認証の違い
認証：誰であるかを特定すること
認可：権限を与えること

# SSOについて
**SAML認証**
SSO実現における**認証・認可**プロトコル

**OAuth2.0**
SSO実現における**認可**プロトコル

**Open ID Connect**
OAuth2.0を認可に加えて**認証**として活用するための拡張仕様であり、アクセストークンに加えてIDトークン（ユーザ情報を含む）を発行する

- 認証・認可においてOAuth2.0を利用する場合は、Open ID ConnectまたはSAMLのいずれかを併用する
- Open ID ConnectおよびSAMLは単体での利用が可能

**SAML認証の流れ**
・IdP Initiated方式
IdPにログインし、その後に利用するSPを選択してログイン

・SP Initiated方式
SPにアクセスし、SPからIdPに認証リクエストを送り、IdPからSPにSAMLアサーションが送信されてログイン

※ IdP（認証プロバイダー）とSP（サービスプロバイダー）

# IDaaSについて
読み方：「アイダース」や「アイディーアース」

複数のサービス（Webサービスやアプリケーションなど）に登録されているIDやパスワードを一元的に管理できるクラウドサービスであり、SaaSの一種

日本語では「クラウド型ID管理サービス」

IDaaSを提供しているのがIdP（認証プロバイダー）

**主な機能**
・シングルサインオン
・多要素認証
・IDの一元管理
・ID連携
・アクセス管理
・認可

**代表サービス**
okta, AzureAD, Oneloginなど
【GAE】ウォームアップリクエストとは


業務でウォームアップリクエストに関わる機会が増えたので、備忘として整理します。

## GAEとは？
そもそもGoogleAppEngine（GAE）は、Googleが提供するクラウドサービスの一つで、
ウェブアプリケーションやモバイルアプリケーションを開発・運用するためのプラットフォームです。
特にスケーリング（サービスの利用状況に応じて自動的にリソースを調整する機能）が重要なポイントになります。

## ウォームアップリクエストとは？
ウォームアップリクエストとは、アプリケーションのインスタンスがユーザからのリクエストを受ける前に、あらかじめそのインスタンスを「暖めて」おく（準備しておく）ためのリクエストのことです。
これにより、初めてのリクエストが来た時にインスタンスが既に準備されているため、応答速度が向上します。

[参考：ウォームアップ リクエストを構成してパフォーマンスを改善する](https://cloud.google.com/appengine/docs/standard/go/configuring-warmup-requests?hl=ja)

## なぜ必要なの？
GAEでは、新しいユーザーのリクエストに対応するために新しいインスタンスを動的に作成することがあります。
しかし、新しいインスタンスが起動するとき、そのサーバ上でアプリケーションを実行するには、ある程度の時間が必要です。
この **「冷え切った状態」からリクエストを処理しようとすると、処理が遅くなる可能性があります。** そこでウォームアップリクエストが使われます。

## ウォームアップリクエストの流れ
##### 1. インスタンスのスケーリング
GAEがリクエストの増加を検知し、新しいインスタンスの起動が必要だと判断します。
##### 2. ウォームアップリクエストの送信
新しいインスタンスが起動すると、GAEは自動的にそのインスタンスに対してウォームアップリクエストを送信します。
##### 3. ユーザーリクエストの処理
ウォームアップリクエストが完了した後、インスタンスはユーザーからのリクエストを迅速に処理できる状態になります。

## まとめ
ウォームアップリクエストは、GAEのスケーリング機能と密接に関連していて、アプリケーションのパフォーマンスを向上させるための重要な工夫の一つです。
この仕組みにより、ユーザーはより速い応答時間を体感することができるという訳でした。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3762672/677eea63-54f5-60c1-2c14-f7fccdf8dd34.png)