OmniAICreator/Qiita-1.07M huggingface dataset:
GithubのレポジトリにおけるCDK/CDKTFの運用の素案

# これはなんですか？
Github ActionsのWorkflowを使ってcdkとかcdktfのレポジトリをアプリケーション開発のようにうまいこと回せないかと考察する記事。
cdk, cdktfの両者について、本記事内で機能的な差はないため、個別の事情には言及しない。
書いている人がアプリケーションエンジニアなのでその開発戦略を前提としているため、terraformを書捨ててる系の人が見ても理解に苦しむかもしれない。

# 図
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/570665/f8282265-7ecc-1ad1-55bf-ec2b45338958.png)

# 前提
まずこのGithubのレポジトリはCDKまたはCDKTFで構成され、適切に分割された複数のスタックがあり、設定ファイルによって適用する環境（例ではProd, Stg, Fooの環境)を切り替える。
それぞれの環境ではインスタンスのスペックや構成に差はあるがアプリケーションが動作する環境である。
ブランチ戦略はGithub Flow的なものを採用する。

# ブランチ戦略と環境適用の連動について
1. インフラ変更の要求に基づき、featブランチを起こす。
1. featブランチでは
    1. (Actions) commitごとに**すべての環境のdiff**がPRに投稿される。
1. PRレビュー時には変更点をdiffを見ながら精査する。
    1. (Review) 場合によっては部分的に特定の環境に適用または新規構築を行い動作確認を行う
1. 合意がとれたらマージ
    1. (Actions)マージと同時にProduction以外のすべての環境へfeatの内容が適用される
1. Production環境の運用状態を見てProduction環境へ適用

# 課題
## diffの検出精度がたまにばぐっている
cdktfで顕著なんだけど、たまにdiffを検出しなかったり誤検出したりすることがある。

## 適用するときにエラーになることが多々ある
diffだけではdeployしたときにエラーになることがあり、dry-runでも実適用時のエラーを検出できないことがある。

# おわりに
いくつか理由があり、考えるだけ考えたけど実施していません。
これはいつかいけてるインフラメンたちと仕事するときのための素案です。
Pythonで「文字列の連結と繰り返し(乗算)」の動作を確認してみた

# 概要

Pythonで「文字列の連結と繰り返し(乗算)」の動作を確認してみました。以下のページを参考にしました。

https://www.javadrive.jp/python/string/index6.html

# 実装

以下のファイルを作成しました。
```sample.py
print("ABC" + "DEF" + "GHI")
str1 = "Hello,"
str2 = "Python"
print(str1 + str2)
print("ABC" * 4)
str = "Hello！"
n = 3
print(str * 3)
```

以下のコマンドを実行しました。
```
$ python3 sample.py 
ABCDEFGHI
Hello,Python
ABCABCABCABC
Hello！Hello！Hello！
```

# まとめ

何かの役に立てばと。
【Vue.js】リロード時に一瞬見える{{}}を非表示にする

# はじめに
Vue.jsの課題に取り組んでいる際に気になったことを、備忘録として記録。

# 問題
Vue.jsでは{{ 変数名 }}(マスタッシュ構文)と書くことで、Vueで指定した変数の値をHTMLに埋め込むことができる。
しかし、リロード直後に一瞬{{ 変数名 }}が見える→変数の値が表示される、という具合なので、マスタッシュ構文がちらつかないようにしていく

# 解決方法
「v-cloak」と呼ばれるディレクティブを使う。
コンパイルで時間がかかると{{}}が残って見えてしまうようなので、CSSで非表示にする。

:::note info
このディレクティブは関連付けられた Vue インスタンスのコンパイルが終了するまでの間残存します。[v-cloak] { display: none } のような CSS のルールと組み合わせて、このディレクティブは Vue インスタンス が用意されるまでの間、コンパイルされていない Mustache バインディングを隠すのに使うことができます。
:::

以下のようにv-cloakを書き足す。
```ruby:HTML
<section id="user-goal" v-cloak>
    <p>{{ course }}</p>
</section>
```

```ruby:CSS
[v-cloak] {
  display: none;
}
```

# おわりに
結構リロード直後に{{}}がちらつくのが気になっていたので、解決できて良かった。他にもVue.jsでは様々なディレクティブがあるので活用していきたい

# 参考
https://jp.vuejs.org/v2/api/index.html#v-cloak
【ネットワーク】初心者向け！通信方式やプロトコルについて理解したい

## 概要
前回の記事は**ネットワークとは何か**、**ネットワークの３種類**（LAN、WAN、インターネット）、**ネットワークトポロジ**(バス型、リング型、スター型など）の説明をしました。
今回はその続きの内容となり、ネットワークの通信方式やプロトコルについて説明していきます。
前回の記事は下記のものとなります。
こちらの記事を読んでからの方が理解しやすいと思います。
是非、こちらも読んでみてください。

https://qiita.com/nakamura_slj/items/5841195df35a8325427e

## 対象とする読者
* ネットワークの基礎から学びたい人
* 前回の記事を読んだ人
* これからIT業界で仕事をしようと考えている人
* CCNAの資格を取ろうとしている人

# 通信の方式
ネットワークで通信行う際には宛先の指定により
**ユニキャスト**、**ブロードキャスト**、**マルチキャスト**の３つの通信方式があります。
まずはこの３つの通信方式について説明します。
※一般的なLANの場合は通信する際に、宛先をみなさんがよく耳にする**アドレス**というもので指定するのですが、それぞれの通信の方式で使用するアドレスは異なります。

### ユニキャスト
ある特定の宛先に対してのみデータを送信する方式です。
**1体1での通信**となり、通信したい相手を指定するアドレスを使用します。
![スクリーンショット 2023-10-31 16.24.11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3524075/1d639e07-6841-2d11-4e5d-52bffc730b2e.png)



### ブロードキャスト
不特定多数に対して同じデータを送信する方式です。
**1体多での通信**となり、全体宛を意味するアドレスを使用します。
ブロードキャストを意味するアドレスを宛先に１つのデータを送信すれば全体に送信できますが、
通信を必要としていない端末にも通信が届いてしまいます。
そのため、ブロードキャスト通信を多く使用するとネットワークに負荷がかかります。
※全体宛と言っても、同一のネットワーク(IPアドレスが同じネットワーク)範囲内の全端末という意味となります。
![スクリーンショット 2023-10-31 16.22.35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3524075/02a42abf-fdea-6ca4-9094-c80b02c0caaa.png)


### マルチキャスト
ある特定のグループに対して同じデータを送信する方式です。
**１対グループの通信**となり、グループを指定するアドレスを使用します。
マルチキャストを意味するアドレスを宛先に１つのデータを送信すれば特定のグループに送信ができます。
通常の集線装置の場合、マルチキャスト宛でも全端末に届いてしまいますが、
受信した端末はアドレスを見て無視できるため、ブロードキャストほどの負荷はかかりません。
設定次第で必要な端末にのみ転送可能になるため、効率的な通信方式となります。
![スクリーンショット 2023-10-31 16.28.22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3524075/c973077d-60ba-fba7-24d8-194eba701223.png)

# プロトコルとは
コンピュータ同士でデータのやり取りを行う時にデータをどのような形式でどのような手順で送るのか
または受け取るのかという規則を定めたものを**プロトコル**と言います。
ネットワーク上での通信手順や規約を定めたものは**通信プロトコル**と言います。
例えば買い物をするときに、商品をとって、レジに向かって、商品を店員に渡して、お金をはらって・・・というように手順と規則があります。
このようにデータの通信もプロトコルで決められた手順や規則に沿って実行し、ネットワークが機能します。
また、プロトコルは１つのみではなく複数存在します。
その複数のプロトコルを階層的に構成したものを**プロトコルスタック**と言います。

### プロトコルスタック
通信する際に必要となる機能を階層化し、それぞれの階層に対するプロトコルを定義したものとなります。
階層の考え方の代表例としては**OSI参照モデル**と**TCP/IPモデル**があります。


# 最後に
以上となります。
今回は通信方式とプロトコルについて説明しました。
次はOSI参照モデルについて説明をしようと思います。
OSI参照モデルについての記事は下記のものとなります！
是非、見てください！

https://qiita.com/nakamura_slj/items/0c827de1dab6ebc722d2
Debian系のVim-tinyをもう少し使いやすくする方法など

# Debian系のVimについて 
Ubuntu, Linux Mint などを含めてDebian系のVimについての話. デスクトップエディションのDebianにデフォルトでインストールされているのは vim.tiny という最小限の機能しかないVim. デフォルトの設定では vi との互換性を重視してあり使いにくい.
ホームディレクトリの.vimrcに
```
set nocomaptible
set backspace=indent,eol,start
set number
set hidden
```
などを書き込むと使いやすくなる. set mouse=a も利用可能.

Debian系のディストリビューションで
```
$ sudo apt install vim
```
によってインストールされるのは `/usr/bin/vim.basic`
コマンドライン版のVimの大抵の機能が使えるようになる.
```
$ sudo apt install vim-nox
```
によってインストールされるのが /usr/bin/vim.nox
Vim-basicに比べてRuby, Luaなどの機能が追加されている.

ターミナルから
```
$ vim --version 
```
と打てばVimのどのバージョンを使っていてどの機能が有効なのか表示される.
Vim起動中なら `:version` と打てば同様の表示が出てくる.
やる事が多過ぎててんやわんやした時のタスクマネジメント

<h2>きっかけ</h2>

タスク管理。
仕事でももちろん大切ですが、生きていくうえであれもやらなきゃ、これもやらなきゃとビジー状態に陥り何も手につかなくなることってあると思います。

人は色々なアプローチを試します。
優先順位をつける、すぐに終わるものからやってしまうなど。
僕も色々試してみましたが、優先順位ってどうつけるんやとか、時間かかるタスクばかりだよとか、自分の中での判断材料に欠け、あまり効果的でないなと感じていました。

そんな中、これかなり良いかも、と思った方法があるので紹介します。
<b>デッドラインを可視化させ、自分が今できることから手を付けていく</b>のです。

<H2>どうやるか</h2>
<b>メモ帳を開く。</b><br>そして、直近で自分が終わらせなければいけないことをリストアップする。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2821326/8d90c7a1-8613-a9af-69f0-e1fc98a551c1.png)


■手順１ 
自分がボールを持っているもの、他人がボールを持っているものでラベル分けする。（今すぐ一人で手を付けられるものとそうでないもの、とも言い換えられます）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2821326/976e367e-b463-ebbc-6851-7fdda918ed49.png)


 ■手順２ 
 この日まで終わらない予定のもの、この日までに終わらせなきゃいけないものを分け、日付を書き添えていく

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2821326/822b7796-e613-0272-cb44-0c3776b32342.png)



■手順３
自分がボールを持っているものは細分化していくとこの日までに終わらせなきゃいけないタスクに分類されるので、それぞれデッドラインを確認した上ですぐに手を付けられるものから上に並べていく（例だと既に並べ変わっているので割愛）<br><br>
<b>すると、あら不思議！</b><br>
無謀にも思えたタスクの数が、今日やれる範囲のものに絞られ、まず最初にやればいいことが見えてきます。
一週間後までに終わらせなければいけないものもストーリーラインに乗ったようにすべて可視化されているので、スケジュールも組みやすく、明らかにこなせないタスク量だった場合一目で分かるというメリットもあります。

また、タスクの状況に応じて都度ボールを持っているのが自分なのか、そうでないのかを更新します。例の場合だと、11/25の会議が終われば成果物用意は自分になったり、~11/28のレビュー結果で修正があれば納品準備完了は自分になる、みたいな感じです。

<h2>TrelloやJiraでよくない？</h2>
<b>ダメです</b>、僕は。<br>

たしかにやってることは似通っているし、タスク管理用に開発されたツールがあるならそれを使った方がよさそうというのは一理あるので使ってみたんですが、どうにも合いませんでした。
メモ帳を使い慣れているというのもあるのでしょうが、究極に直感的に操作できるのはメモ帳だし、すべてテキストで管理しちゃうのでカスタマイズ性も高いです。ツールで無理くり帳尻を合わせようとするとそれ自体の管理コストが上がっちゃいます。<br>
<b>ただ、チーム開発のタスク管理には使えない</b>のが難点です。

<h2>効能分析</h2>
- 今日必ずやらなければいけないことの少なさに気付く<br>
- 漠然と先延ばしにしていたけど今日でもやれることがあることに気付く<br>
- デッドラインを設定することで指標を立てて動くことができる<br>
- ボールを持っている人を明確にするのでタスクの動きが曖昧にならない、止まらない<br>

ということで、色々メリットがあると感じました。
人生もエンジニアも初心者の僕が手応えを感じたアプローチということで、諸先輩方からすると稚拙な部分もあるかと思いますが、少しでも役立てていただけたら幸いです。
SQLを学びます。⑨

こんにちはiwanagaです。

今日はハロウィンですがよくよく考えるとそれ即ち今年も後2ヶ月という事になります。年々時間が過ぎるのは早いですね。何なら早すぎですけどね笑まだ今年食べた雑煮の味を覚えているのですがこのまま行くと気分的には毎週お雑煮みたいな気分になるのでしょうか。

今回もSQLを学んでいくのですがいつもと違う事をやりたいと思います。今までは知識的な事やクエリを学習してきましたが、自社の尊敬する上司Mr.IDさんから頂いたアドバイスでSQLの高速化、つまりいかにSQLの遅延を防げるかが今後の鍵になるとのことでしたので学習していこうかと思います！

確かに昨今どこでもデータベースには数万件レベルでデータがあります。なのでその膨大な量のデータを遅延なく抽出、上書きするにはどうすればいいか？次の項目で説明させていただきます！

# そもそも遅れる理由は？
そもそも遅れる理由とは何か？
自分が知っている範囲では以下の理由がございました。

・大量のデータ処理
テーブル内に大量のデータがある場合、クエリの実行に時間がかかることがあります。これはシンプルに容量が増えれば遅くなるというだけなので対策としていらないデータを消去するなどの対策が取れます。
(まぁそんなに簡単に現場でデータをポンポン消せないんですけどね💦)

・ハードウェアの制約
データベースサーバーのハードウェアリソース（CPU、メモリ、ディスク速度など）が不足している場合、クエリのパフォーマンスに影響を与えることがあります。

・複雑なクエリ
複雑なJOINやサブクエリを含むクエリは、処理に時間がかかる可能性があります。不要なJOINを避け、必要なデータのみを取得するように心がけるとパフォーマンスが向上します。前回までサブクエリとJOINを学習してる身としては少し悲しいですが、抽出する際はただ複雑にして一発で抽出するだけが良いのではなく、前述のハードウェアの制約も含め仕事で使うデータベースのスペックや処理時間も踏まえて最適なクエリを使用することを心掛けるのが遅延対策になるのだと思います。

ここまでは何やかんや想像できますが、ここからが学習していくうちに知った理由でした。

・不適切なクエリのキャッシュ
言われてみれば確かにそうなのですがキャッシュが適切に設定されていない場合、クエリの実行に時間がかかることがあります。

・デッドロック
複数のトランザクションが同時にデータベースリソースにアクセスし、相互にロックをかけた場合、デッドロックが発生し、クエリが停滞することがあります。お互いがお互いを待ってしまっているのでダチョウ倶楽部見たいな事が起こっていると考えれば分かりやすいですね。なお、デッドロックはSQLに限らずIT業界ではよく行き交う言葉なので覚えた方がいい様です。

・不適切なインデックス設計
データベース内のテーブルに適切なインデックスが設定されていない場合、データの検索や結合が遅くなることがあります。適切なインデックスを設計することで、データベースのパフォーマンスを向上させることができるとの事です。

(なるほど...そもそもあんまりインデックスを理解していない💦)

なので次項からインデックスの学習をします。

# インデックス
そもそもインデックスとは何か？一言で言うとテーブルに格納されているデータを高速に取り出す為の仕組みを意味します。インデックスは主に高速なデータ検索やデータの整合性維持、ソートの高速化の為にあり、前述でもある通りこのインデックスの設計が適切でないとSQLが遅くなってしまいます。

インデックスの構造について、本当は図を作成して説明したいのですが記入できないので文で軽く説明させていただきます。

・B-ツリーインデックス (B-Tree Index)
B-ツリーは、データベースで最も一般的に使用されるインデックス構造です。データが平衡木構造に保存され、高効率で範囲検索と精确検索をサポートします。形のイメージとしては根っこが枝分かれしているイメージです。

他にも色々ありますが自分であまり理解できていないところもありますので今度リベンジします。


# SQLを早くする方法
今までは遅くなる原因でしたが今度は早くするコツを記載します。

・行数を数えるときは「COUNT(列名)」を使う
シンプルな話ですが行数を数えるだけなら全体が無くてもカラム一つで出来るのでおすすめです。

・キーワードは大文字
これは簡単です。SQLのキーワードをすべて大文字で書くだけです！理由は大文字で書くことでキャッシュを使う確率が上がるのと、SQLの高速化につながる上に、キーワードを大文字で統一することで検索キーワードなどに指定ができるのでデバッグにも役立ちます。下記に例文を記載します。

```
--悪い例
select * from テーブル where カラム = food;
 
--良い例
SELECT * FROM テーブル WHERE カラム = food;
```

・インデックスの再構築
インデックスの再構築を定期的に行い、インデックスの効率を保ちましょう。インデックスが膨れ上がってしまった場合などに有用です。

・ハードウェアのアップグレード
ハードウェアリソースが不足している場合、CPU、メモリ、ディスクなどのハードウェアをアップグレードすることでパフォーマンスを向上させることができます。これがまた意外と見落としがちで職場でみんなであーでもないこーでもないと考えてたらシンプルにPCをアップグレードするだけでほぼ改善される時も多々ありますのでご注意ください。灯台もと暗しです。

・極値関数(MAX / MIN)でインデックスを活用する
SUM関数などソート領域の使用は、パフォーマンス悪化の原因になりやすい一方、極値関数はソート処理の負荷を軽減可能な場合があります。単純に全部出すよりは負担軽減になりますよねという話です。

# 最後に
今回もご覧いただきありがとうございました！
やはり自分が使っていくSQLに関して使用方法だけでなく理屈もしっかりと押さえないとダメだなぁと痛感させられました。今後も精進していきます！

次回はデータベースの理屈について自社の尊敬する先輩Mr.ITさんから教えて頂いたことや自分が学習したことをまとめいきますのでよろしくお願いいたします。


参照
https://learning.zealseeds.com/contents/text/IPA/technology/database/transaction/exclusive-control/index.html
https://products.sint.co.jp/siob/blog/index
https://style.potepan.com/articles/26070.html

エンジニアファーストの会社 株式会社CRE-CO　iwanaga
SQLを学びます。⑧

こんにちはiwanagaです。

11月も近いのに今日も電車で汗だくでした💦極端に暑いのも寒いのも嫌ですが流石にこうも気温がガチャガチャだと体調も崩れちゃいますね。自分は先週扁桃炎で39度以上熱が出てなかなか大変な事になっていましたので皆様もお気をつけください。

さて、今回も全く脈絡のない事を話しましたが今回も前回に引き続きSQLの学習をしていきたいと思います。今回はサブクエリについて学んでいきたいと思います。

# サブクエリ
そもそもサブクエリとは何かという話になりますが、簡単にいうとサブのクエリです笑
ふざけている訳ではありませんがメインのクエリで該当箇所を探すための条件として使用される事が多いです。

例を幾つか説明させていただくにあたって必要なテーブルを下記に記載します。

テーブル名：group

|ID|first_name|last_name|team|salary｜
|:---:|:---:|:---:|:---:|:---:|
|1|taro|yamada|IT|200000
|2|jiro|suzuki|food|220000
|3|sabro|kitano|book|320000
|4|hanako|iwai|IT|110000
|5|matuko|dx|food|250000
|6|yuta|abe|IT|540

上記のテーブルから給料が200000より多い人を抽出する際にサブクエリを使用した文にすると下記のようになります。

```
SELECT ID, first_name, last_name, salary
FROM group
WHERE ID IN (SELECT ID FROM group WHERE salary >= 200000);
```

上記の文でどの様なIDを抽出するかの条件に対して、カッコ内で(給料が200000以上)と条件を絞っています。このカッコ内で実行しいているクエリがサブクエリとなります。

この文を抽出される内容は下記の様になります。

|ID|first_name|last_name|team|salary｜
|:---:|:---:|:---:|:---:|:---:|
|1|taro|yamada|IT|200000
|2|jiro|suzuki|food|220000
|3|sabro|kitano|book|320000
|5|matuko|dx|food|250000


ただここで一つ疑問が出ると思います...

『これ、普通のSELECTで良くないか...?』

正直この基本的な文だけだとその通りです。なんせ普通に下記の文で同じ結果が出ます。

```
SELECT order_id, customer_id, order_date, total_amount
FROM orders
WHERE salary >= 200000;
```

では違いは何か？カラムの枠を超えて抽出ができます。普通のSELECT文ですと給料を知らないと抽出できませんがサブクエリがあればIDや名前など多角的に情報を抽出できるのでおすすめです。逆に様々な情報を元により正確なデータを抽出する事ができます。

# JOIN
やってて思ったのですがサブクエリが個人的にかなり難しいのでまたの機会にやります。なので気分転換にJOINをやります。

JOINがあるとテーブルとテーブルを結合して抽出ができるので便利です。例として下記に二つのテーブルを記載します。

a_table
|ID|first_name|last_name|salary｜
|:---:|:---:|:---:|:---:|
|1|taro|yamada|200000
|2|jiro|suzuki|220000
|3|sabro|kitano|320000
|4|hanako|iwai|110000
|5|matuko|dx|250000
|6|yuta|abe|540

b_table
|ID|first_name|last_name|team|
|:---:|:---:|:---:|:---:|
|1|taro|yamada|IT
|2|jiro|suzuki|food
|3|sabro|kitano|book
|4|hanako|iwai|IT
|5|matuko|dx|food
|6|yuta|abe|IT

これらを結合して必要な情報だけ抽出する場合下記の様な文になります。

```
SELECT a_table.first_name, b_table.team,
a_table.salary AS price
FROM a_table
JOIN b_table ON a_table.ID = b_table.ID;
```

すると下記の様な結果が抽出されます。

|ID|first_name|price|
|:---:|:---:|:---:|
|1|taro|200000
|2|jiro|220000
|3|sabro|320000
|4|hanako|110000
|5|matuko|250000
|6|yuta|540

内容が結合した上で必要なデータだけ抽出できるので便利ですね。

# 最後に
いやぁ...今回のところは割と難しかったですね。
今までの４大命令文は単文でしたがここからは複数の文が折り重なった長文になっていくのでレベル高いです。

ただまぁめげずに頑張ります。

今回もご覧いただきありがとうございました！

参照
https://products.sint.co.jp/siob/blog/what-is-sql-subquery#toc-1

エンジニアファーストの会社 株式会社CRE-CO　iwanaga
SQLを学びます。⑦

こんにちはiwanagaです。

今年もハロウィンの季節がやってきましたね。特段何かするわけではありませんが行事はあるに越したことはありません。ただカボチャが苦手なので代わりになるような美味しいものがると良いですね。

さて、全く脈絡のない事を話しましたが今回も前回に引き続きSQLの学習をしていきたいと思います。今回はINSERT文を学んでいきたいと思います。

# INSERT文
実は自分自身あまりUPDATE文との違いがよくわかっていない所もありますので、まずは下記に違いや用途などざっくりと記載させていただきます。

・NSERT文

挿入: INSERT文は新しいデータをテーブルに挿入するために使用されます。
既存データへの影響: INSERT文は既存のデータに影響を与えません。新しいデータが既存のデータと競合しない限り、既存のデータは変更されません。
主な用途: 新しいレコードをデータベースに追加する際に使用され、データの作成に適しています。

・UPDATE文

更新: UPDATE文は既存のデータを更新または変更するために使用されます。指定された条件に一致する既存の行のデータを変更します。
既存データへの影響: UPDATE文は既存のデータに影響を与えます。指定された条件に一致する既存の行のデータが更新されます。
主な用途: 既存のデータを変更、修正、更新するために使用され、データの修正や更新に適しています。

要約すると、INSERT文は新しいデータを挿入する際に使用され、データベースに新しいエントリを作成します。一方、UPDATE文は既存のデータを更新または変更する際に使用され、既存のデータを修正します。まとめてみると割と簡単ですね。

# 基礎
まず今回のINSERT文を紹介するにあたって必要なテーブルを下記に記載させていただきます。

テーブル名：group

|ID|first_name|last_name|team|salary｜
|:---:|:---:|:---:|:---:|:---:|
|1|taro|yamada|IT|200000
|2|jiro|suzuki|food|220000
|3|sabro|kitano|book|320000
|4|hanako|iwai|IT|110000
|5|matuko|dx|food|250000
|6|yuta|abe|IT|540

基本的にINSERT文は下記の様な構成となっています。
```
INSERT INTO table_name (column1, column2, ...)
VALUES (value1, value2, ...);
```
・table_name: データを挿入するテーブルの名前。
・column1, column2,:挿入する列の名前。
・value1, value2,:列に挿入する値。

この基本形を上記のテーブル例にすると以下のようになります。
```
INSERT INTO group 
(ID, first_name, last_name, team, salary)
VALUES (7, 'aoi', 'ito', 'IT', 160000);
```

すると下記の様な結果になります。

|ID|first_name|last_name|team|salary｜
|:---:|:---:|:---:|:---:|:---:|
|1|taro|yamada|IT|200000
|2|jiro|suzuki|food|220000
|3|sabro|kitano|book|320000
|4|hanako|iwai|IT|110000
|5|matuko|dx|food|250000
|6|yuta|abe|IT|540
|7|aoi|ito|IT|160000

このINSERT文により、新しい従業員のデータがemployeesテーブルに挿入され、変更後のテーブル図が示されます。

# 応用
今度は複数同時にデータを追加します。

例 1: 複数の従業員を一度に挿入する場合
```
INSERT INTO employees 
(ID, first_name, last_name, team, salary)
VALUES (8, 'ichiro', 'sato', 'IT', 300000),
       (9, 'yuko', 'ogura', 'food', 240000),
       (10, 'bob', 'sap', 'food', 280000);

```

結果は下記の様になります。

|ID|first_name|last_name|team|salary｜
|:---:|:---:|:---:|:---:|:---:|
|1|taro|yamada|IT|200000
|2|jiro|suzuki|food|220000
|3|sabro|kitano|book|320000
|4|hanako|iwai|IT|110000
|5|matuko|dx|food|250000
|6|yuta|abe|IT|540
|7|aoi|ito|IT|160000
|8|aoi|ito|IT|300000
|9|aoi|ito|food|240000
|10|aoi|ito|food|280000

応用とは言いましたが割と簡単ですね。増やしたければ増やしたいだけ前述にある基本形を記入すれば良いだけなのでやりやすいです。

# 注意点

・データ型の整合性
挿入するデータのデータ型がテーブルの列と整合していることを確認してください。不一致のデータ型を挿入しようとするとエラーが発生します。正直自分がINSERT文で一番ミスしたのはここです。

・トランザクションの使用
INSERT文を実行する前にトランザクションを開始し、変更を確認することをお勧めします。トランザクションを使用すると、変更を一括してコミットまたはロールバックできます。

・重複データの処理
重複データを挿入する前に、データベース内に同じキーまたは一意性の制約を持つデータが存在しないことを確認してください。重複データを挿入しようとするとエラーが発生することがあります。

・挿入順序
テーブルにデータを挿入する場合、列の順序を指定することができます。必要に応じて列の順序を指定して挿入してください。

・バックアップ
重要なデータの挿入前に、データベースのバックアップを取得しておくことを検討しましょう。誤ってデータを挿入した場合、バックアップからデータを復元できます。ここさえちゃんとしていれば大体大丈夫です。

・権限とセキュリティ
INSERT文を実行するために必要な権限を確認し、不正なアクセスを防ぐためにセキュリティ対策を実施しましょう。

# 最後に
今回もご覧いただきありがとうございました！
これで4大命令文も終わったので次回からはより応用的なトピックか今までのおさらいをしようかと思います。

参照
https://products.sint.co.jp/topsic/blog/sql-insert

エンジニアファーストの会社 株式会社CRE-CO　iwanaga
今開いているサイトでサイト内検索するためのブックマークレット

### ソースコード

これをブックマークに登録

```javascript
javascript: (function () {
    let frm = document.createElement("form");
    frm.style.position = "fixed";
    frm.style.top = "10px";
    frm.style.left = "10px";
    frm.style.zIndex = 999999;
    frm.style.width = "300px";
    frm.style.height = "20px";
    frm.action = "https://www.google.co.jp/search";
    let q = document.createElement("input");
    q.type = "text";
    q.name = "q";
    q.style.width = "200px";
    q.onkeydown = function(e){
        if(e.key === 'Escape'){
            frm.parentNode.removeChild(frm);
        }
    };
    frm.appendChild(q);
    let hid = document.createElement("input");
    hid.type = "hidden";
    hid.name = "as_sitesearch";
    hid.value = window.location.hostname;
    frm.appendChild(hid);
    let sub = document.createElement("input");
    sub.type = "submit";
    sub.value = "検索";
    frm.appendChild(sub);
    document.body.appendChild(frm);
    q.focus();
  })();
  ```

### 実行結果

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/53489/51e5b8e5-188f-4298-801c-956f5d0cea54.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/53489/72ed8f57-98e2-2aae-855f-fcc4aad18517.png)

### 解説

- サイト内検索のためのGoogle検索パラメータを埋め込んだフォームを今開いているbodyにappendChildしているだけ
- エスケープキーで消えるとかはこの手のPOPUPでありがち
- スタイルの調整はあまりしてないので、今開いてるページのスタイルに引っ張られるけど、特に不便はないので、最低限のスタイル調整
Azure認定資格 AZ-500を取得しました

セキュリティ系のAzure認定資格を取得したので体験記を残します。
3か月くらい前に受けたときは不合格だったのでリベンジとなりました。
今回の試験の目玉はなんといっても受験中にMicrosoft Learnで検索できるようになったことです。このあたりの所感もまとめておきたいと思います。

他の資格体験も書いていますのでよければご覧ください。
* [Azure認定資格 AZ-400を取得しました](https://qiita.com/shingo_kawahara/items/1e0d371276d264fe65fc)
* [Azure認定資格 AZ-900を取得しました](https://qiita.com/shingo_kawahara/items/86b4b7599318996f6f60)
* [Azure認定資格 AZ-203を取得しました](https://qiita.com/shingo_kawahara/items/551ac6b880a4a59e4291)
* [Azure認定資格 AZ-300を取得しました](https://qiita.com/shingo_kawahara/items/7d1c217e2588c5a232e3)
* [Azure認定資格 AZ-301を取得しました](https://qiita.com/shingo_kawahara/items/5e5c1febeb773a95b6af)

# 試験の傾向は？
* 問題：52問
  他の試験と同じように「2択問題」「1問1答」「ケーススタディ」は出題されました。各セクションを先に進めると前のセクションに戻ることができません。
* 時間：120分
  申込みでは140分になっていますが、そのうち20分は事前の同意書などの時間なので、実際は120分でした。
* 合格ライン：700点

# 試験範囲
* ID とアクセスを管理する (25 - 30%)
* セキュリティで保護されたネットワーク (20 - 25%)
* コンピューティング、ストレージ、データベースのセキュリティ保護 (20 - 25%)
* セキュリティ オペレーションを管理する (25 - 30%)

[学習ガイド](https://learn.microsoft.com/ja-jp/credentials/certifications/resources/study-guides/az-500)に詳しく出題内容が示されています。

EntraIDやSentinel、Defender for Cloudといったセキュリティ関連サービスは当然出題されますが、VMやApp Service等の各種サービスに対するセキュリティ施策も問われます。

# 学習方法
Azureでは珍しく、AZ-500の試験対策本が販売されています。
「最短突破 Microsoft Azureセキュリティ テクノロジ[AZ-500]合格教本」
こちらを一通りやったのと、Microsoft LearnのAZ-500項目を全てやって受験しました。
私のスキルセット的に各種リソースのセキュリティ施策は問題ないのですが、Entra IDやSentinelの管理をやったことがないので、そのあたりを中心に対策本の問題集を解いたり、Learnを何度も見返したりしました。
Entra ID Plan2とか簡単に試せないサービスが多かったことに今回てこずりました。

# Microsoft Learn
AZ-500に限らずですが、最近のアップデートで試験中にMicrosoft Learnを確認することができるようになりました。
これがかなり強力でした。実際に問題を解きながらLearnを画面にうつして調べることができます。
Learn内であれば検索も可能ですが、Ctrl+Fを使った文字列検索はできなかったです。
今後Learn検索力も必要になってくるなと感じました。
ただ、調べすぎには注意する必要があります。これまで試験中に時間が足りないなんてことはなかったのですが、今回序盤に調べすぎたことによって、最後時間がギリギリになってしまいました。
時間配分は意識して望む必要があります。

# まとめ
Learnで調べることができるのは強力ですが、全く分からないものを一から調べるというのは時間的に無理があるなと思います。
ある程度あたりを付けて、迷ったところをLearnで補完するみたいな使い方がよいと思います。
例えばEntra ID P1/P2でそれぞれなにができるのかとか、コマンドのオプションとかですかね。
暗記しないといけないものが減ったのはとてもよいと思います。（普段仕事しててもコマンドのオプションとか結局Learnで調べるので）

次はAZ-700を目指したいと思います！
THE NUNOBLOGが紹介するおすすめのフリーランスエージェント

おすすめのフリーランスエージェントを各社の口コミ調査と僕やフリーランスチームの実体験をもとに、職種別にまとめました。各エージェントの実際の口コミなども紹介しているので、ぜひ参考にしてみてください。

https://the-nunoblog.com/freelance-agent/
RailsでCSVファイルをエクスポートしてみた（文字化けも対処）

どうもこんにちは。

最近、RailsでCSVファイルをエクスポートする方法を学んだのでメモします。

# 実装手順

## 1. クラス定義

導入方法は至って簡単です。使用したい機能のコントローラファイルの一番上に、以下のようにライブラリを定義します。

```ruby
require 'csv'

class SampleController < ApplicationController
...
```

これだけで`CSV`クラスのメソッドをコントローラ内で使用することができるようになります。

## 2. exportアクションを定義

まず、使用したいコントローラに`export`メソッドを定義します。

```ruby
class SampleController < ApplicationController
    def export
    end
end
```

## 3. ルーティングを定義

```ruby
resources :samples do
    collection do
        get 'export'
    end
end
```

## 4. exportアクションに処理を記述

```ruby
def export
    respond_to do |format|
      format.csv do
        headers['Content-Disposition'] = 'attachment; filename="samples.csv"'
        headers['Content-Type'] ||= 'text/csv'
      end
    end
end
```

## 5. viewファイルを追加

ファイルの名前を`sample.csv.erb`としてcsvファイルに表示したい項目を記述します。

```erb
サンプル1, サンプル2, サンプル3, サンプル4
```

また、エクスポート用のリンク（ボタン）をページに設置します。

```erb
<%= link_to 'エクスポート', export_samples_path(format: 'csv') %>
```

# 完成じゃない！

完成かと思いきや、このままエクスポートしたファイルをエクセルで開くと、**文字化け**してます。。。

なので、エンコード的なことをしてからcsvファイルを出力する必要があります。
（文字を**BOM化**することでUTF-8の文字をエクセルで閲覧できるようにします。）

# 処理修正

## 6. コントローラ修正

```ruby
def export
    respond_to do |format|
      format.csv do
        bom = "\uFEFF"
        csv_data = CSV.generate(bom) do |csv|
          csv << ['サンプル1', 'サンプル2', 'サンプル3', 'サンプル4']
        end
        send_data(csv_data, filename: "samples.csv")
      end
    end
end
```

## 7. viewファイル修正

`sample.csv.erb`のファイルの中身を空にします。
（手順6で追加項目を設定しているので不要になりました。）

# 完成

これで正常にCSVファイルを出力することができました！

# 付録（文字コードとBOM）

## 文字コードとは

- エンコードは方法
- 文字や記号をコンピュータが理解できるバイトまたはビットの並びにマッピングするルールのセット
- テキストをデジタルデータとして表現、転送、保存するために使用される

## BOMとは

- BOMはオプション
- UTF-16やUTF-32などのエンコーディングで使用される特殊なマーカー
- テキストファイルの先頭に配置され、テキストファイルのバイトオーダーを識別するのに使用される
- UTF-8のBOMは必須ではなく、また一部のアプリケーションでは問題を引き起こす可能性がある

# まとめ

今回の文字化けの対処では、UTF-8で設定した文字をエクセルで見れるようにするために文字をBOM化しました。

 これらの違いは、「文字をバイト列に変換する」ものが文字コードのエンコード、「すでにエンコードされた文字がどのようにエンコードされているかを示すマーカー」がBOMであるということです。

 めちゃめちゃややこしいですが、今回はBOMを通じて文字をエクスポートすることでエクセルで文字化けするのを防いだということになります。
Windows Subsystem for Android™️ でデバッグする

# はじめに
期間が空くと忘れてしまうので、メモしておきます。

### 前提
- Windows Subsystem for Android (WSA)が導入済みで、開発者モードが有効化済みとします。
- Unity、または(および)、Android Studioが導入済みで、`adb`が使用可能とします。

### 確認した環境
- Windows 11 22H2
- WSA 2309.40000.10.0
- Unity 2022.3 LTS
- adb 33.0.2-8557947

# アプリのインストール
「Android™️ 用 Windows サブシステム」で「詳細設定」タブを開き、「開発者モード」欄の「ADB は 127.0.0.1:58526 で開きます。」を確認して、ポート番号が異なる場合はメモしてください。

## Unityの場合
1. `Build Settings`を開きます。
1. `Run Device`で`Enter IP`を選び、`127.0.0.1:58526`を入力します。
1. `Run Device`が切り替わったことを確認して`Build And Run`を実行します。
なお、設定はプロジェクトに保存されるようです。

## adbの場合
1. `adb connect 127.0.0.1:58526`を実行します。
1. `adb devices -l`を実行してデバイスの`ID`を確認します。
1. `adb -t <ID> install <option> <file>.apk`でアプリをインストールします。
既にインストール済みのアプリに対してダウングレードになる場合は、オプション`-d`を指定します。

### apkの入手
- デプロイ済みなら、GooglePlayコンソールの「App Bundle エクスプローラ」からダウンロードできます。
    - Unityで`aab`を作っている(`Build App Bundle`)場合は、手元で取り出すより楽に感じます。

# アプリのマウス操作
- 「`Alt`キー + 左ボタン」で、「二本指タッチ」相当になります。
    - 二本指での「タップ」や「ドラッグ」が可能です。
- 「`Ctrl`キー + ホイール」で、「ピンチ イン / アウト」相当になります。
- 「`Alt` + `←`キー」で、ナビゲーションバーの「戻るボタン」相当になります。
- 「ホイール」は、上下にドラッグしたような挙動になります。

# 資料

https://learn.microsoft.com/ja-jp/windows/android/wsa/

https://developer.amazon.com/ja/apps-and-games/blogs/2023/07/debug-android-apps-for-windows-11

# おわりに
最後までお読みいただきありがとうございました。
他にも「こうすれば」、「こうできる」のようなことがあれば、コメントいただけると助かります。
よろしくお願いいたします。
Github Actions の setup-ruby が遅いので新規PR作成時にもキャッシュを有効にする

# 問題

新規PRを作成するとRuby (setup-ruby)のキャッシュが使われず時間がかかる

```yml
name: My workflow
on: [pull_request]
jobs:
  test:
    runs-on: ubuntu-latest
    steps:
    - uses: actions/checkout@v4
    - uses: ruby/setup-ruby@v1
      with:
        ruby-version: '3.2' # Not needed with a .ruby-version file
        bundler-cache: true # runs 'bundle install' and caches installed gems automatically
    - run: bundle exec rake
```

# 結論

Github Actions ではブランチの単位でキャッシュが生成されるみたいだ。
なので新規PR作成時に新しいブランチを使うと、参照するキャッシュヒットせずRubyのセットアップで数分の時間がかかる。

ただしそのPRのベースブランチ、またはデフォルトブランチのキャッシュは利用できるようなので、
この記事の通り、ベースブランチにマージされた時 (push指定) にもCIを有効にしておけば良い。


```yml
# github/workflows/ci.yml

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

https://zenn.dev/mallowlabs/articles/github-actions-cache-scope

# 公式

https://github.com/ruby/setup-ruby

# 補足 -  キャッシュ指定

cache-versionを指定すれば良いようだ
ただ非推奨らしい

```yml
    - uses: ruby/setup-ruby@v1
      with:
        bundler-cache: true
        cache-version: 'XXXX'
```

## 生成されるキャッシュの確認

Githubレポジトリで Actions > Caches で確認できる


バージョン指定なしの場合に生成されるキャッシュ

```
(色々省略)/api-with--without--only---Gemfile.lock-(Gemfile.lockをハッシュ化した値)
```

バージョン指定ありの場合に生成されるキャッシュ

```
(色々省略)/api-with--without--only--v-XXXX-Gemfile.lock-(Gemfile.lockをハッシュ化した値)
```

上のように通常のキャッシュ名に加えて `cache-version` が付与される形のようなので、特に無指定のままで良さそうだ
株式会社キュービック_ラクスタ

▼キュービックについて
株式会社キュービックは、Twitterキャンペーンや認知拡大のプロモーションに強みがある広告代理店です。
 
同社ではTwitterの運用に特化した「ラクスタ」「トレンドブースト」2種類のサービスを展開しており、
Twitterキャンペーンの効果UPや戦略的にトレンド入りを狙うことで認知効果の最大化を目指すことが可能です。
 
少数精鋭のマーケティングチームがクライアントのマーケティングパートナーとして、
戦略立案〜運用、効果検証〜分析・改善まで全て一貫して提供しており、
デイリーで欠かさずPDCAを回すほどの細かな広告運用を実施いただける点も魅力の一つです。
 
クリエイティブ制作ではクライアントのビジネスをしっかりと理解した上で
幅広い層への訴求方法の立案から検証まで行っており、 魅せ方の引き出しの多さに定評があります。
 
代理店の枠組みにとらわれず、顧客のマーケティング課題に向き合い戦略立案から実行までしっかりと並走できる点に
大きな強みがあります。


▼ラクスタについて
弊社が開発・提供しているTwitterキャンペーンツールの「ラクスタ」について簡単にご紹介させていただきます。

【キャンペーンツール】
ラクスタ：インスタントウィン型（Web遷移型）
ラクスタLite：事後抽選型キャンペーン

【ラクスタの特徴】
・多様なキャンペーン形式に対応　　　　　　　　　　　　
・業界トップクラスのコストパフォーマンス
・タイムリーなキャンペーン展開(最短2週間でスタート可能)

多くの企業様から高い評価をいただいているラクスタは、これらの特長によりお客様の多様なニーズに対応しています。
詳細な仕様、導入事例、料金プランについては、以下のURLから資料を無料でダウンロードできます。
もしご興味ありましたら、どうぞお気軽にダウンロードください。

【ラクスタ資料・お問い合わせ】
https://www.cubic-corp.co.jp/rakusta
https://www.cubic-corp.co.jp/rakusta-lite
ゆっくりに論文を解説（？）してもらいながら読む方法

# 最終的にやりたいこと

https://twitter.com/hibit_at/status/1716994552605847713

　こういうことをしたいです。

# 1. pdf を手動でコピペする

 ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/288125/a38b9970-9f0f-0128-5fb6-c08440b06d66.png)

# 2. Shaper で整形する

https://dream-exp.net/shaper/

　このような神 Web アプリがあります。

 ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/288125/485db2f2-981d-1b29-931c-4512ee333d2b.png)

　整形されます。

 　そのまま「DeepL で翻訳」ボタンを押します。

# 3. DeepL で翻訳

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/288125/a6a6dfa5-5c30-0cab-9d60-3485b25587db.png)

　DeepL で翻訳します。すごい勢いで翻訳枠を食っていくので、無課金の民は気をつけましょう。実際、Google 翻訳や他の翻訳アプリでも差し支えない気がします。

 # 4. ゆっくりムービーメーカーで字幕をつける

https://manjubox.net/

 　ゆっくり解説動画でおなじみの「ゆっくりムービーメーカー」を使います。私は持っているバージョンが 3 だったので 3 を使いましたが、最新版は 4 なので、4 を使うのがよいかもしれません。とりあえず以下の実例は 3 です。

  　知らない方に説明すると、テキストを入れるとゆっくり音声と字幕と（必要であればアニメーション）を生成してくれるという、解説動画を作ることに特化した神動画作成アプリです。

   ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/288125/b7cd3917-1dda-b3ef-b480-1ba3136dcdc7.png)

　デフォルトの設定（いわゆる「ゆっくり霊夢」）では少し遅い気がするので、好みの設定にしてプリセットキャラクターを作ります。上の図では「論文読み上げちゃん」と名付けて、速度を少し上げています。ここら辺は好みでどんどん調整してしまっていいと思います。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/288125/3afe2e7d-7154-dc2d-5031-cdf91fed6e4b.png)

　プリセットを「論文読み上げちゃん」にして、テキストをコピペしてエンターキーを押すと、
 
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/288125/2ecf0d2d-5d9e-d100-5aff-c9ef6229fa05.png)

　このように字幕の動画オブジェクトが生成されます。テキストによっては、特殊な文字が入っているせいか、短いオブジェクトになってしまいますが、音声自体は最後まで生成されているので、そういう場合はマウスで末尾を調整すれば大丈夫です。

 　後は、この動画（≒音声）を流しながら論文の該当箇所を読めば、まるでゆっくり音声で丁寧に解説してもらっているかのような錯覚に陥り、疲労が少なくなるとともに読解力が爆上がりします。

  # Limitations and Future Work

  　このワークフローにおいて、人間の負担を拭い去れていない点はいくつかあります。

   - pdf からのコピペ
   - いくつかのクリック
   - ブラウザのタブ間、またはブラウザとゆっくりムービーメーカーとの行き来
   - それらの往復を何回も繰り返すこと

　このあたりをうまく自動化できたら、pdf を読み込ませたら自動的に（疑似）解説音声を生成してくれるようなスクリプトが出来て、更に生産性が上がるかもしれません。
<storybook>ValidationError: Invalid options object. CSS Loader has been initialized using an options object that does not match the API schema.

# 前提
version
next.js: 13.4 app router
tailwind 3.3
storybook: 7.4
pnpm 8.8

```ts:.storybook/main.ts
import type { StorybookConfig } from '@storybook/nextjs'

import { join, dirname } from 'path'

/**
 * This function is used to resolve the absolute path of a package.
 * It is needed in projects that use Yarn PnP or are set up within a monorepo.
 */
function getAbsolutePath(value: string): any {
  return dirname(require.resolve(join(value, 'package.json')))
}
const config: StorybookConfig = {
  stories: [
    '../app/**/*.stories.@(js|jsx|mjs|ts|tsx)',
    '../components/**/*.stories.@(js|jsx|mjs|ts|tsx)',
  ],
  addons: [
    getAbsolutePath('@storybook/addon-links'),
    getAbsolutePath('@storybook/addon-essentials'),
    getAbsolutePath('@storybook/addon-onboarding'),
    getAbsolutePath('@storybook/addon-interactions'),
  ],
  framework: {
    name: getAbsolutePath('@storybook/nextjs'),
    options: {},
  },
  docs: {
    autodocs: 'tag',
  },
}
export default config

```


# エラー
`pnpm storybook`を時効した際に次のエラーに遭遇。厳密にはtailwind関連の設定をglobal.cssから読み込んだ時に起きていた。
```bash
ValidationError: Invalid options object. CSS Loader has been initialized using an options object that does not match the API schema.
```

# 解決法
postcss を installすればいけた。
```bash
pnpm add --save-dev css-loader
```

これ別途入れる必要あるっけ?


# 参考
https://github.com/storybookjs/storybook/issues?q=is%3Aissue+%22CSS+Loader%22
[ブランチ保護ルール]mainブランチへのPRはdevelopブランチからしか許可しないように設定する方法

## はじめに

現在起業家兼エンジニアをしており、フリマサービスを開発しています！

https://twitter.com/dall_develop

今有志を集めて合計１０人ほどでサービスを開発しているのですが、よく間違えてmainブランチにPRを作ってしまうということがありました。

運用ルールとしては

main←develop←feature

とするようにしているのですが、main←featureとしてしまうことが何回かありました。
そのため、mainにはdevelopからしかPRを作れない設定をしたいと思いましたが、あんまりいい記事が出てこなかったので、ここに記しておきます。

## 手順

### まずはGitHubでブランチ保護ルールを作成する

(設定してる人はこの手順は飛ばしてOK)

GitHubでmainブランチへのPRをdevelopブランチからのみに制限するためには、リポジトリのブランチ保護ルールを使用して設定します。以下の手順で設定できます。

1. GitHubリポジトリのページにアクセスします。
2. 右上の`Settings`をクリックします。
3. 左サイドバーの`Branches`をクリックします。
4. `Branch protection rules`セクションで、`Add rule`または`Edit`（既にルールが存在する場合）をクリックします。
5. `Branch name pattern`に`main`と入力して、mainブランチに対するルールを作成することを示します。
6. さまざまな保護オプションが表示されますが、特に`Restrict who can push to matching branches`のセクションで、`Allow Deletions`のチェックボックスをオフにします。
7. PRの制限のために、`Require pull request reviews before merging`を有効にします。これにより、mainブランチへマージする前にPRのレビューが必須になります。
8. このルールでは特定のブランチからのPRを制限する直接的な設定は提供されていません。そのため、この制限を実施するには、追加のツールやスクリプト、GitHub Actionsなどを使用する必要があります。

### GitHub Actions でルールを設定

GitHub Actionsを使用してこの制約を適用する基本的な例：

`.github/workflows/branch_restrictions.yml` ファイルを作成します。

```yaml
name: Branch Restrictions

on:
  pull_request:
    branches:
      - main

jobs:
  check_base_branch:
    runs-on: ubuntu-latest
    steps:
      - name: Fail if not from develop branch
        run: |
          if [[ "${{ github.event.pull_request.head.ref }}" != "develop" ]]; then
            echo "Error: PRs to main must come from the develop branch."
            exit 1
          fi
```

このWorkflowは、mainブランチへのPRが開かれた際にトリガーされ、PRがdevelopブランチからのものでなければエラーを返します。

もっとやるのであれば、hotfixは通すとか、そういう設定はしてもいいかもしれません。

## 感想
チームで開発を行うようになり、サラリーマンの業務だとPdMやテックリーダーがいかにみんなが働きやすい環境を整備してくれているのかということを日々実感しています笑

チーム開発を行うためには、環境の整備が全てだなと感じます。
もちろん仲間の力を借りながらですが、Lintの設定やprettierの設定

pull_request_templateやissue_templateなど、上げたらキリがないほどルールを敷いて、水準を確保することは重要です。

ここら辺の大変さや、レビューの大変さはやらないと僕はわからなかったので、日々エンジニアとして働く皆様はマネージャーさんの努力なども感じられるようになるとすごくいいかなと思います(実際に僕はすごく感じました笑)

## 最後に

　現在Swappyという同人誌のフリマサイトを開発中です！
 参加したいと思う方は随時募集しているので、お気軽にDMください！

 Next13で開発してます。

 詳細

 https://ring-brand-8a1.notion.site/5948c0f2bd5e44548fd6e1f814b137d0?pvs=4

 Twitter

 https://twitter.com/dall_develop

### 参考

https://qiita.com/onishi_820/items/d98c61e0faa67f417829
PreprosでNODE_ENVを使ってステージングと本番でJSの処理を切り替える

## 意外と多機能Prepros
Sassのコンパイラとしてやたら紹介されがちなPreprosですが、実はHTMLやJS、画像圧縮処理などの機能も付いています。

![Prepros 2023_10_31 12_14_20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/189779/8cb2679f-f4e2-df34-e1cb-5dbc48fe65fa.png)
↑設定項目たくさん

Prepros is 何？ な方はこのへんをご覧ください。
[Dart Sass、使ってる？Preprosを使えばコンパイルも楽勝！ | Webクリエイターボックス](https://www.webcreatorbox.com/tech/dart-sass)
[SassやPugをコンパイルしてくれる便利なアプリ『Prepros』使ってますか？ - 株式会社DOL](https://dol.co.jp/archives/column/sass%E3%82%84pug%E3%82%92%E3%82%B3%E3%83%B3%E3%83%91%E3%82%A4%E3%83%AB%E3%81%97%E3%81%A6%E3%81%8F%E3%82%8C%E3%82%8B%E4%BE%BF%E5%88%A9%E3%81%AA%E3%82%A2%E3%83%97%E3%83%AA%E3%80%8Eprepros%E3%80%8F)

## NODE_ENVの利用
NODE_ENVとはNode.jsの環境変数に付ける定番の名前で、その実行環境の情報が入った変数です。
クライアントサイドではあまり使わないと思うので、馴染みのない方もいるかもしれません。

今回のシチュエーションとして
・JavaScript内で
・ステージングだったらステージング用のテキストを設定
・本番は本番用のテキストを設定
と仮定します。

### 実行してみる
では早速Preprosで使ってみましょう（Prepros自体のセットアップ手順は省きます）。

Node.jsで環境変数を参照するには、`process.env`を利用します。
任意のjsファイルで `console.log(process.env.NODE_ENV);` と記載し、適当なHTMLで呼んでブラウザで表示＆コンソールを見てみてください。

参照できていれば「production」と表示されます。
デフォルトではproduction（=本番モード）が設定されています。  

※jsファイルは自動で処理対象にならないので、ファイルを選択してから「Process File」をクリックするか、「Process Automatically」にチェックを入れてからファイルを保存してください。

### 切り替えてみる
では今度はdevelopment（=開発モード）にしてみましょう。

1. Preprosで対象のjsファイルを選択します。
1. 右のメニューにある「Development Mode」にチェックを入れます。

![Prepros 2023_10_31 12_44_34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/189779/65355b51-5c55-08d9-bb8a-a82dc7791438.png)
これだけでOKです。

では先ほどと同じように、`console.log(process.env.NODE_ENV);`の記載があるjsファイルを表示させてみてください。
「development」と表示されれば成功です。

では実際に分岐処理を書いてみましょう。
```javascript
const text = process.env.NODE_ENV === "development" ? "ステージングです" : "本番です";
```

これだけ。
```javascript
let text = "";
if(process.env.NODE_ENV === "development") {
  text = "ステージング";
else {
  text = "本番";
}
```
こうとかでもいい。
何をデフォルトの値とするかは大事ですので、考えて設定してくだされ。

## 運用
作業としてはチェックの付け外しだけですが、いうてこういうのって忘れやすいやん・作業あるなら変数書き換えるのと対して変わらんやんてなるので
実際はGitの本番用ブランチ（main等）には、PreprosのDevelopment Modeチェックを外して設定ファイルをプッシュしておくのが良いのではないかと思います。

## 終わりに
Sass以外でPreprosがあんまり取り上げられないのは割と不思議に思ってたのですが、
まあこういうことしたいと思う方は、そもそもGUIを使っていないってことかも。
環境変数の概念からしても、CUIに触れたことがなければつかみにくいのかなと思いました。

Preprosはマークダウンの処理やTypeScriptなどにも実は対応しているので、
すでに活用されている方は使い倒してみてください！
Cognitoのユーザ全部消す

# これはなに

Cognitoのユーザプールの中に登録されているユーザを全部クリアする方法です。
一発で実施する方法を探してみつからなかったので載せています、知ってる方は教えてください。

普通ユーザ全消しオペレーションはしないので、それなりに時間はかかります。

# 前提
1. 要AWS CLIのインストール及びクレデンシャルの設定
1. 要jq (いらない方法もあったはず・・)

```
#!/bin/bash

USER_POOL_ID=ap-northeast-1_xxxxxxxxx

 aws cognito-idp list-users --user-pool-id $USER_POOL_ID > prod_userpooluser_list.json
usernames=`jq -r .Users[].Username prod_userpooluser_list.json`

for username in $usernames; do
  aws cognito-idp admin-delete-user --user-pool-id $USER_POOL_ID --username $username
done
```

# 何をしているのかの解説
shell上では2回AWS CLIを実行しています。

## 前者
ユーザプールから全ユーザを抜き出しています

## 後者
抜き出したユーザのsub(UUID)を1件ずつ消しています。

以上です。
React material-uiでAccordionを実装する

## はじめに
表題通り、Reactのmaterial-uiでAccordionを実装します。

### 成果物
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/599049/502d720b-72ba-9510-0af8-f4bb9e21a5f3.png" alt="スクリーンショット 2023-10-31 13.53.46.png" width="150">

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/599049/8140939b-739a-6544-7899-254e1a25fbe3.png" alt="スクリーンショット 2023-10-31 13.53.46.png" width="150">

```shell:ディレクトリ構成
~/develop/react/acodion_material_ui$ tree -I node_modules
.
├── README.md
├── package.json
├── public
│   ├── favicon.ico
│   ├── index.html
│   ├── logo192.png
│   ├── logo512.png
│   ├── manifest.json
│   └── robots.txt
├── src
│   ├── App.tsx
│   ├── MyAccordion.tsx
│   ├── index.tsx
│   └── logo.svg
├── tsconfig.json
└── yarn.lock

3 directories, 14 files
```

```tsx:App.tsx
import React from 'react';
import { MyAccordion } from './MyAccordion';

function App() {
  return <MyAccordion />;
}

export default App;
```

```tsx:src/MyAccordion.tsx
import React, { useState } from 'react';
import {
  Accordion,
  AccordionSummary,
  AccordionDetails,
  Typography,
} from '@material-ui/core';
import { KeyboardArrowUp, KeyboardArrowRight } from '@material-ui/icons';

export const MyAccordion: React.FC = () => {
  const [expanded, setExpanded] = useState(false);
  const toggleAccordion = () => {
    setExpanded(!expanded);
  };

  return (
    <Accordion expanded={expanded} onChange={toggleAccordion}>
      <AccordionSummary
        expandIcon={expanded ? <KeyboardArrowUp /> : <KeyboardArrowRight />}
      >
        <Typography variant="h6">アコーディオン タイトル</Typography>
      </AccordionSummary>
      <AccordionDetails>
        <Typography>アコーディオンサンプルです！！！！</Typography>
      </AccordionDetails>
    </Accordion>
  );
};
```
grep

<!--
2023/11/7
-->

[picoCTF][Forensics][Lookey here]

## Writeup
* 基本の`file`コマンドを実行
テキストファイルのようなので、`grep`してみた。
![screenshot.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/160736/4cae5219-5c9a-bfb6-d582-590e4728ab78.png)

* 以上です。
CodeCommitからのクローン / CodeCommitへの初回push方法（GRC)


いつも忘れるので、個人的備忘録

# CodeCommitからのクローン
 | 設定 | コード |
|:-:|:-:|
| AWSプロファイル指定なし  |  `git clone　codecommit::[リージョン名]://[リポジトリの名前]`  |
| AWSプロファイル指定あり  |`git clone codecommit::[リージョン名]://[プロファイル名]@[リポジトリ名]`   |

# CodeCommitへの初回Push
 | 設定 | コード |
|:-:|:-|
| AWSプロファイル指定なし  |①`git remote add codecommit::[リージョン名]://[リポジトリ名]`<br> ②`git push [リモートリポジトリ名] [ローカルリポジトリ名] `   |
| AWSプロファイル指定あり  |①`git remote add codecommit::[リージョン名]://[プロファイル名]@[リポジトリ名]`<br> ②`git push [リモートリポジトリ名] [ローカルリポジトリ名] `   |

:::note info
gitやgit-remote-commitのインストール、aws-cliのconfigure設定が完了していることが前提です。
:::

:::note warn
2023年 10/31 の情報です。AWSは日々アップデートがあるため、うまくいかない場合はリファレンスを確認してください。
:::
【RxSwift】BehaviorRelayとPublishRelay

# 目次
[1.BehaviorRelayとPublishRelayの特徴](#1-BehaviorRelayとPublishRelayの特徴)
[2.実例](#2-BehaviorRelayとPublishRelayの違い)
[3.おわりに](#3-おわりに)

# 1. BehaviorRelayとPublishRelayの特徴
- BehaviorRelayとPublishRelaは.nextメソッドのみ流せる
- .errorと.completedが流れない
- .nextメソッドを流すには`.accept()`を使用する

# 2. BehaviorRelayとPublishRelayの違い

|  |BehaviorRelay  |PublishRelay  |
|---|---|---|
|初期値の有無  |有  |無  |
|valueプロパティの有無  |有  |無  |
|現在値流しの有無  |有  |無  |

~~~swift:behaviorRelay基本形
var disposeBag = DisposeBag()
let behaviorRelay = BehaviorRelay<Int>(value: 1)

behaviorRelay.subscribe { event in
    print(event)
}.disposed(by: disposeBag)

behaviorRelay.accept(2)
bahaviorRelay.accept(3)

// 実行結果
// next(1)
// next(2)
// next(3)
~~~

~~~swift:PublishRelay基本形
var disposeBag = DisposeBag()
let behaviorRelay = PublishRelay<Int>()

behaviorRelay.subscribe { event in
    print(event)
}.disposed(by: disposeBag)

behaviorRelay.accept(2)
bahaviorRelay.accept(3)

// 実行結果
// next(2)
// next(3)
~~~

### 補足：現在値流しの有無
~~~swift:現在値流し
var disposeBag = DisposeBag()
let behaviorRelay = BehaviorRelay<Int>(value: 1)

behaviorRelay.subscribe { event in
    print(event)
}.disposed(by: disposeBag
// ここまで書いただけで初期値value=1が流れる
// 実行結果
// behaviorRelay next(1)
~~~

# 3. おわりに
本記事を最後まで読んでいただきありがとうございました！
RxSwift、combine、SwiftUIなど目まぐるしく変わるiOSのトレンドですが、頑張って食らいつきましょ
input要素でEnterキー入力を検出する方法が、いつの間にかアップデートされていた

# フォーム入力などで、テキスト入力してEnterキー入力を検出する方法

 いくつか方法があって、簡単に説明すると例えばこんなやり方でしょうか：

 1. input要素にキー入力イベントリスナーを設ける方法。
 1. form要素のsubmitイベントで処理する方法。

 input要素を対象にした方法に絞って、以下の説明を続けます。

# よく見る例（非推奨のコードが含まれます）

```javascript
let text_form = document.getElementById('text_form');
let output = document.getElementById('output');

text_form.addEventListener('keypress', test_ivent);

function test_ivent(e) {
  if (e.keyCode === 13) {
    output.innerHTML = text_form.value;
  }  
  return false;
}
```
引用元：JavaScript | フォーム内でのEnterキーの入力を取得する方法 | 1 NOTES 
https://1-notes.com/javascript-fire-event-of-enter-key/ 

## このコードの問題点

1. **keypressイベント**は既に非推奨とされており、いつかwebブラウザでのサポートが打ち切られてしまう可能性があること。[^1]
1. **keyCodeプロパティ**によるキー判別が既に非推奨とされており、いつかwebブラウザでのサポートが打ち切られてしまう可能性があること。[^2]

[^1]: Element: keypress イベント - Web API | MDN 
https://developer.mozilla.org/ja/docs/Web/API/Element/keypress_event 

[^2]:  KeyboardEvent.keyCode - Web API | MDN 
https://developer.mozilla.org/ja/docs/Web/API/KeyboardEvent/keyCode 

# 問題点を解消したコードの例

```javascript
const text_form = document.getElementById("text_form");
const output = document.getElementById("output");

text_form.addEventListener("keydown", test_event);

function test_event(e) {
  if (e.key === "Enter") {
    output.innerHTML = text_form.value;
  }  
  return false;
}
```

## 変更点

1. keypressイベントからkeydownイベントに変更しました。
1. keyCodeプロパティでなくkeyプロパティにして比較してみました。

# Element: keydown イベント

Element: keydown イベント - Web API | MDN 
https://developer.mozilla.org/ja/docs/Web/API/Element/keydown_event 

 keyCodeプロパティは非推奨になっていて、似た役割としては[keyプロパティ](https://developer.mozilla.org/ja/docs/Web/API/KeyboardEvent/key)と[codeプロパティ](https://developer.mozilla.org/ja/docs/Web/API/KeyboardEvent/code)があります。
 
## keyプロパティとcodeプロパティの違い

 codeプロパティの解説ページにある「[結果](https://developer.mozilla.org/ja/docs/Web/API/KeyboardEvent/code)」で試すとわかりやすいです。

 - KeyboardEvent.key プロパティは、ユーザーが押したキーの値を、Shift キーなどの修飾キーやキーボードのロケールやレイアウトを考慮した値で返す
 - KeyboardEvent.code プロパティは、（キー入力によって入力された文字ではなく）キーボード上の物理的なキーを表す
 
 例えば、ShiftキーやCtrlキーや（機種によってはAltキーも）役割が同じでも複数存在するようなキーを確実に区別するときには、codeプロパティを使います。
 単にEnterキーが入力されたことを検出したい場合には、フルキー側のEnterでもテンキー側のEnterでもどちらでも構わないと考えて、この場合はkeyプロパティを使うべきでしょう。

 keyプロパティと比較するためのキーの値のリストはこちらにあります。 気になる方はどうぞ：

Key values for keyboard events - Web APIs | MDN 
https://developer.mozilla.org/en-US/docs/Web/API/UI_Events/Keyboard_event_key_values 

# Enterキーで検索ボタンクリックさせたい

```javascript
const text_form = document.getElementById("text_form");

text_form.addEventListener("keydown", (e) => {
  if (e.key === "Enter") {
    const btn_search = document.getElementById("btn_search");
    btn_search.dispatchEvent(new PointerEvent("click"));  // clickイベントを発生させて、送り込む
    e.preventDefault();  // Enterキー入力を他に伝搬させないために
  }  
  return false;
});
```
NLP concept extraction library using a pre-trained model - 組み込みAI セルフサービス型デジタル共創体験(DSCE)

# 組み込みAI セルフサービス型デジタル共創体験(DSCE)とは

[組み込みAI セルフサービス型デジタル共創体験](https://qiita.com/trtrbohz/items/356a5a4b66624b2c94a2)に記載しておりますが、現在STT(speech-to-text)、TTS(test-to-speech)、NLU(natural-language-understanding)等のAIがサーバーに接続しなくても組み込んで利用することが可能となりました。

その情報がこちらの[サイト](https://dsce.ibm.com/)、DSCE([Digital Self-Serve Co-Create Experience](https://dsce.ibm.com/);"組み込みAI セルフサービス型デジタル共創体験"？)にて紹介されております。

今回はそのDSCEの中から、「NLP concept extraction library using a pre-trained model」 の実施方法を説明します。
※個人的な利用は無償ですが、商用利用は有償となります。

# 今回は 「NLP concept extraction library using a pre-trained model」 
https://dsce.ibm.com/wizard/try/results/embed-nlp-concept-container-pt#try
この NLP concept extraction library は 入力テキスト内で直接参照していないけども直接参照されているか、言及されている一般的なコンセプトを識別し、抜き出すタスクです。このタスクの目的はテキスト文書の中から最も重要で関連性の高いコンセプトを識別して、その内容を意味ある方法で要約するところにあります。キーワード抽出に似ていますが、単語と句の間の意味関係を考慮することで単純なキーワード抽出の機能を超えることができます。


# 1. 前提
* ターミナル環境
mac : ターミナルを使います。[ココ](https://support.apple.com/ja-jp/guide/terminal/apd5265185d-f365-44cb-8b09-71a064a42125/mac) を見てターミナルを起動できるようにしてください。
windows : powershellを使います。[ココ](https://learn.microsoft.com/ja-jp/powershell/scripting/install/installing-powershell-on-windows?view=powershell-7.3) を見てpowershellを起動できるようにしてください。
* リソース取得
下のURLにアクセスしリソースを取得します。
https://github.com/IBM/dsce-sample-apps/tree/main
※コード改変＆プルリクをするのであれば「git clone」コマンドを使うのですが、今回はソースコードの入手が目的ですので以下の様に Zip 形式でリソースを入手します。
![スクリーンショット 2023-08-12 22.28.26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/682574/e97bd8bc-0767-b52e-9914-d11c0af69259.png)
リソース取得後、zipファイルを展開すると以下のようなフォルダ構成になっていると思います。今回はその中の[sentimet-analysis]配下にあるリソースを使用します。

# 2. 手順
# 2.1. [relation-extraction]フォルダに移動
* zipファイルを解凍した場所を起点として[relation-extraction]フォルダに以下のようにして移動します。

      cd dsce-sample-apps-main/concept-extraction

# 2.2. 必須ライブラリのインストール

      pip3 install -r requirements.txt

# 2.3. アプリ実行

     python3 relation-extraction.py

# 2.5. Access the local application
ブラウザを開き、[localhost:8050](localhost:8050) にアクセス
以下の様な画面が表示されます。
そこにはサンプル分文章とその文章のコンセプト抽出例が表示されております。
文章に関連の深いコンセプトが下に記載される数値と共にグラフとしても表示されます。

ご自身の文章を用いたい場合には、
1. 画面上部のテキスト欄に文章を入力してください。
2. テキスト欄右の「Extract concepts」ボタンをクリック
3. 分析した結果が表示されます。

![スクリーンショット 2023-10-31 13.27.43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/682574/ed128f18-021e-0742-f4b4-b41611ee4f0f.png)

参照：[NLP concept extraction library using a pre-trained model
](https://dsce.ibm.com/wizard/try/results/embed-nlp-concept-container-pt#try)
PredictDynamics-of-BlueCarbon-Review

# 問題概要
千葉工業大学 人工知能・ソフトウェア技術研究センター主催のAIコンペティション「ブルーカーボン・ダイナミクスを可視化せよ！　〜沖縄県沿岸の水深・水温等の環境条件のデータから、海草藻場の被度を予測しよう！〜」がSIGNATEにて開催された。
上位三位までは賞金と2023年度人工知能全国大会 (JSAI2023)出場、登壇権利が得られる。

# 結果
研究室メンバーと計4人で参加し、391人投稿中で302位であった。
かなり渋い結果となった理由としては、
- コンペティション初参加
- 開催期間の半分の1ヶ月のみでの挑戦
- 衛星画像のランドマークと入力の解釈が難しい

# 入出力
訓練データが14140個、テストデータが4039個。
入力
- 被度文献データ(緯度経度、年月日、気象情報)
- 海洋環境要因データ
- 2019年に撮影された衛星センチネル画像テーブルデータ
- 被度文献データの年月日に最も近い衛星ランドサット画像テーブルデータ
- 2000からの2020年までの衛星ランドサット画像テーブルデータ

出力
- 沖縄の指定された地点の藻の被度

評価指標
- RMSE：平均二乗偏差

# データ分析
訓練データとテストデータの分布を確認するため緯度経度で散布図を作成した。
青が訓練データ、赤がテストデータを表す。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3487085/d723c2e2-32a2-5f39-974a-d19fc0c5afc3.png)

緯度経度による目的変数の分布の偏りを確認するために、ヒートマップを作成した。
目的変数の値が大きいピークの地点が2点ほど存在することがわかる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3487085/1606661e-a50a-4c0d-2f24-13118f52696f.png)

台風が来た年には大きく目的変数が減少することがあると考え、気象庁から台風情報を取得した。
台風の回数を値とした年月でのヒートマップ。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3487085/bd356792-341b-6583-9b14-563a3389c52d.png)

目的変数の平均値を値とした年月でのヒートマップ。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3487085/ad9dc79e-d855-72a4-4852-adbef66de254.png)

訓練データとテストデータに大きな差異がないかを確認するために訓練データか否かのラベルを目的変数としたモデルを作成した。
モデルはLightGBMで作成し、正答率が99.67%と非常に高い結果となった。
しかし、この事実は締め切り一週間前に得られた為、具体的アクションプランが立たないままクローズとなった。

# 使用したモデル
- LightGBM
- 全結合ニューラルネットワーク
- 最近傍法

以上のモデルから、重み付き平均のアンサンブルを作成した。
また、全結合ニューラルネットワークに入力する値は正規化を施し、
LightGBMには被度文献データｍ衛星画像のRGB値を
最近傍法には緯度経度、年月を入力した。
提出したモデルは、LBの値を比較しながらアンサンブル比を調整した。
（これが順位を大きく落とす結果となった。単一のモデルであれば49位のモデル。）

# 工夫した点
コンペティション初参加で手探りが多かったが、形になるものをでき及第点と考えている。
衛星画像データの欠損値の補完についてはチームメンバが作成した。
方法としては、入力対象の衛星画像の欠損値を前後年の値から線形補間を行う。


# 他参加者から吸収したこと
14位
- Linear Quiz Blending：アンサンブル方法
すべて0のLBスコア、複数の予測値-LBスコアペアから適したアンサンブル比を計算できる

3位
- 地点を均等に学習するようにグループFoldを作成する
- 欠損の有無を特徴量にする
- モデルの安定性が着実にスコアを上げるために必要

2位
- 目的変数の分布からTweedie分布を仮定し評価指標を作成
- 提供データの値の粒度が均一でないことを考慮した意図的な丸め
- メッシュごとの上位10％の平均値を特徴量に加える
- CVとLBの差を確認し、CVを信じる
- PublicLBとPrivateLBの差が大きい緯度経度の値はを考えすぎない

1位
- どのような場合に目的変数の値が大きくなるのか想定する
- 生育しない条件を予測するモデルの為、最も過酷で現実に近そうな最小値を採択する

# ソースコード
https://github.com/rakawanegan/bluecarbon_portfolio
Agentを使って状態管理をする

- [Agentとは](#agentとは)
  - [基本的な使い方](#基本的な使い方)
  - [Agentをスーパーバイザーに追加する](#agentをスーパーバイザーに追加する)
    - [モジュール](#モジュール)
    - [スーパーバイザー](#スーパーバイザー)
  - [結論](#結論)

# Agentとは

**Agent**とは<font color="red">単一の状態を保持する仕組み</font>である。

GenServerより状態管理が簡略化されおり、また値を取得する方法が提供されている。(`Agent.get()`)

高可用性を求める場合には、代わりに**GenServer**を使用すること。

## 基本的な使い方

Agentはプロセスと同じように生成する。

```elixir
{:ok, agent} = Agent.start_link(fn -> 初期状態 end)
```

生成されたAgentに対して更新や値の取得は、下記のように行う。

```elixir
# 更新
Agent.update(agent, fn 状態 -> 状態の更新処理 end)

# 値の取得
Agent.get(agent, fn 状態 -> 出力 end)
```

生成したAgentを終了させるには、以下を記述する。

```elixir
Agent.stop(agent)
```

## Agentをスーパーバイザーに追加する

Agentもプロセスなので、**スーパーバイザー**の**監視ツリー**に追加することができる。

ここでは実際にAgentのモジュールを記述して、監視ツリーに追加してみる。

### モジュール

Agentモジュールは、大体以下の要点を考慮して記述を行うと良い。

* `use Agent`の記述
* `start_link()`関数の実装

```elixir
defmodule 省略.SampleAgent do
  use Agent

  def start_link(init_status) do
    Agent.start_link(fn -> init_status end, name: __MODULE__)
  end

  # 取得する値別に関数を作成するとよい
  def get() do
    Agent.get(__MODULE__, fn status -> 値を取得する処理 end)
  end

end
```

### スーパーバイザー

スーパーバイザーの詳しい解説は[こちら](https://qiita.com/B_tanuki/items/461166a760971a33e660#%E3%82%B9%E3%83%BC%E3%83%91%E3%83%BC%E3%83%90%E3%82%A4%E3%82%B6%E3%83%BC)。

以下のように記述して子プロセスのリストに追加する。

```elixir
children = [
  {省略.SampleAgent, %{name: "Takashi", age: 42}}
]
```

上記の記述によりAgentをスーパーバイザーの監視ツリーに追加すると、
Agentが終了したとき再起動するようになった。

なお、当たり前だが`Agent.stop()`によって、Agentは終了しなくなる。

## 結論

AgentはGenServerより簡略化された状態管理の仕組み。

Phoenixを起動しながら実行するサーバーサイドの処理で使用する
状態を、個別に管理、状態を取得する、というような使い方ができる。

高可用性が求められる場合はGenServerを使用すること。(~~と書いてあった~~)
【小ネタ】【VisualStudio】スニペットってのが便利すぎる

# はじめに
クソ便利。
今まで知らなかったのがもったいない



# スニペットとは
これ。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2419795/62e93fdf-6f6b-669f-9bb8-3354ba232169.png)

Tab2回押すとこうなる
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2419795/53756f32-e56a-32dd-a438-6306007c9431.png)






# 使い方
1. このサイトでスニペットのファイルを作成する
    https://tools.unitycoder.com/VisualStudioSnippetsGenerator/

    - `Generate`ボタン押してから`Download`ボタン押すとファイル作成されます

1. スニペット用のフォルダを作る


1. ツールバーの`ツール / コードスニペットマネージャー`をクリック
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2419795/38ea0648-44a7-d65d-1df4-19a0b402515f.png)


1. 使ってる言語を選択して、スニペットファイルを入れたフォルダを追加する
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2419795/e648c293-8fd3-c6f9-5a18-e68df2102787.png)
    - 「インポート」で追加すると、`My Code Snippets`っていうフォルダに追加される




# いい感じのスニペット
## summaryの追加
![snipet_summary.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2419795/97211818-83bf-b848-ab9f-6c8db6e803ca.gif)
- デフォルトの三行の`summary`よりもコンパクト！


## 見出し的なコメントを追加する
![snipet_header.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2419795/420d5fc5-8510-12f5-69de-d422b3cfb38b.gif)

- Methods, Fields, Properties...のように種別に分けるときとかに使ってます
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2419795/acae1235-0dea-0e06-a71d-eff785980e7b.png)


## 区切り線的なものを追加する
![snipet_line.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2419795/bdcdf75a-70f1-63d0-5b6b-0446c8ca3ee8.gif)

- これも種別ごとに分けるときに使ってます






# さいごに
便利！

## 参考
https://zenn.dev/crowiin/articles/e1f7e9d77c94cdad136e