OmniAICreator/Qiita-1.07M huggingface dataset:
どうして私がiOSエンジニアに。24卒文系凡骨大学生がメガベンチャーエンジニアになれた訳

私は就職活動を兼ねてからの希望である、第一希望のメガベンチャーのiOSエンジニアとして内定をいただき、就職活動を終えました。この就職活動の経験を元に、意識していたことや気づきなどをここに書きます。
私のように文系でもエンジニアとして働きたいという方や、文系理系に限らず将来はエンジニアとして働きたい方に向けて背中を押すことができればいいなと思っています。

# 筆者について
- 中堅大学の文系大学4年生（経済系）
- プログラミングサークルに所属していた。ここではHTML,CSS,Pythonについてざっくり学ぶ。活動内ではiOS開発には未着手（約2年間在籍）
- YouTubeやUdemy、ネットの記事などを参考にiOS開発をしてみる（約1年間）
- 2023年の3月に個人で開発したアプリをリリースし、これをポートフォリオとして就職活動を進める

# そもそもiOSエンジニアになりたいと思った理由
私がiOSエンジニアになりたいと思った理由は、単純にApple製品がカッコよくて大好きだからです。
最初にiOSに触れたのは、中学一年生に購入したiPod touchの5世代。アプリケーションをインストールをすることによって、iPod一台が何にでもなれる可能性に惹かれました。その経験を重ねていくうち、アプリを作る側に立ちたいと思うようになってiOSの開発に着手し始めました。

# 未経験でもエンジニアとして内定をいただけた3つのこと
就活を経験した中で気づいたことや心がけたことを3つに分けて挙げていきます。

### 1. ポートフォリオになるものを作ってみる
#### 世の中にリリースしてみよう

就活において「これだけ学習しました！」「こういう経験をしました！」をアピールすることは欠かせません。しかし、その学習や経験から何かしらの行動に移すことの方が重要だと考えています。つまり、**0から1を生み出すことができるか**ということです。

その一つとして、アプリケーションを開発してリリースすることがiOSエンジニアとして内定に近づける一つの指標になると思っています。

個人で開発してアプリをリリースすることの良さとして
- 一からアプリを開発した経験がある
- リリースを通して、自分自身のスキルを目に見える形でアピールすることができる
- アプリの運用を早いうちに経験できる
- etc.

**要するに、自身の開発経験を形としてアピールできることがリリースすることの良さだと考えています。**
また、リリースした経験があると面接官に驚かれることが多々あったので、それも他の就活生との差別化を図る一つの要因になったのかもしれません。

それって、世の中に出ているアプリと被っちゃダメなの？と思うかもしれませんが、そんなことはありません。私もリリースしたアプリは真新しいものではありません。経験を形にするということが大事なんです。

### 2. 人柄の良さを押し出す
#### 愛嬌ってあった方がいいよね

エンジニアはただひたすらPCと向き合う業種だと思っていましたが、就活を進めていく中で実は人柄や性格も大事だと考えていました。

私が以前Webメディアの企業でインターンをしていた際に、皆がPCと向き合っているオフィスワークでありながらも頻繁にミーティングをしたり、社員さん同士がたわいもない話をしたりする光景を目にしてきました。その光景からコミュニケーションを通じて会社が作られていく経験を肌身で感じ、人柄の良さって大事だなと改めて思いました。

その経験から、私は少しでも**愛嬌を良くすること**を心がけていました。
具体的に心がけていた事としては、面接の時は気持ち口角を上げてみたり、相手の話に対してうなづいてみたりと、「**この人って感じがいいな**」と思われるように意識していました。

あとからわかったのですが、YouTubeで面接において笑顔は大事であるという動画を見ました（どの動画だったか忘れました）。仮に一流大学ではないのなら、人柄で勝負するのが良いと話していたので、面接では笑顔や愛嬌がある方が印象は良さそうです。

私は有名大学ではないので学歴では他に劣ってしまいます。しかし、私はスキルだけではなく人柄もアピールして就活をしていたので、結果として第一希望の企業にいくことができたのだと思います。

### 3. 経験を交えながら話す
#### 経験を話すことが人を動かしやすい

これはエンジニアに限った話ではないのですが、経験を交えながら話すことは私が就活を進める上で重点を置いて意識をしていたことでした。

私は日常生活で様々な業界の方々とお話をする機会があり、毎度毎度刺激になることが多いのですが、その方々に共通していることがありました。それは経験を交えながら話していることです。
経験を話すことで、あたかも聞く人がその場にいるように感じ、共感を生みやすく、話にも説得力が出るようになると思っています。

これは面接だけでなくESを書く際にも使えるので、ぜひ経験を織り込むことを意識して就活をしてみましょう。

# 内定後に実感したこと
ここからは内定後に同期と接する中で実感していることを挙げていきます。

### 文系出身が故に基礎知識の無さを痛感
当たり前ちゃ当たり前の話ですが、周りの同期は理系出身が多く、コンピュータサイエンスに関する知識が身についた状態だと考えています。それに比べ、私が大学で学んだ分野といえばせいぜいITパスポートの勉強程度。明らかに話についていけていないことを痛感しました。

現在は私も同じ土俵に立とうと、コンピュータサイエンスの勉強を始めました。

### モチベーションがめちゃめちゃ上がる
もちろん良いこともたくさんあります。その一つとして開発のモチベーションが大幅に上がります。文系大学出身なので周りの友人や同級生にエンジニアを志望する人はいませんでした。もちろん1人で開発していたので競う人もおらず、ましては開発の話題で話をする人もいません。

しかし、同期と接するようになってからはエンジニア関連の話題で話したり、質問しあってみたり、さらにはGitHubのアカウントを交換したりしました。その結果、今までの自分のいた世界がガラリと変わりました。実際、同期の中でも強強な人がいることや同じiOSエンジニアの仲間がいたりと刺激になることが多いです。

同期と関わることで自分はもっと成長しないといけない、今のままじゃだめだなと気づかされ、以前よりも自然と開発する時間が増えました。


# 最後に
ここまでずらずらと書いてきましたが、「こんなの当たり前だよ！」と思えるかもしれない内容がたくさんあるかもしれません。ただ、この私の気づきや経験が不特定多数のたった一人にでも役に立つことができたら幸いです。
JAWS-UG名古屋の2023年の振返り

JAWS-UG名古屋の篠田です
JAWS-UG名古屋の2023年の活動を振返りをしていきます！

https://jawsug-nagoya.doorkeeper.jp/

## 開催回数
```
* 23年の開催回数：13回
    * 物理開催：12回（12月開催予定も含む）
    * オンライン開催：1回
```

今年一年間無事に**毎月の物理開催**が達成できそうです
2年前は毎月開催をできていなかったので、今となってはこれが当たり前の感覚になっていますが
毎月物理で開催できるというのは改めてすごいということだなと感じています
同時にスタッフの皆さんのたゆまぬ努力とみんなの協力があってからこそだと思っています

まだ残り12月分の開催が残っていますが、皆さんに**ありがとうございましたという気持ちとお疲れ様でしたという気持ち、さらにまた来年もよろしくお願いしますという言葉を送らさせてください**

また今年はJAWS-UG名古屋としてJaws FestaでLTを私がして、上野さんがAPACの方でもLTをしたので国内国外にもアピールできたことを嬉しく思っています

# JAWS-UG 名古屋のスタッフ数
### トータル：15名
Festa以降に鈴木さんが加わり＋1名となったのでトータル15名です！
毎月開催ができるのはこのスタッフ数がいるからこそです
（2021年は6名だったんだよ）
```
森さん、上野さん、三浦さん、世良さん、河知さん、川路さん、鈴木さん、山下さん
内木さん、フィリップさん、田中さん、高木さん、筒井さん、伊藤さん、篠田（順不同）
```
# 月の担当は主担当/副担当制
JAWS-UG名古屋では毎月の担当を主担当と副担当（3名）で構成されています
この仕組みによって、担当者の負荷を軽減させる効果がありますし実際に機能しています
```
* 主担当
    * 当月の担当者なのでテーマや方針など自由に決められます
* 副担当
    * 副担とは主担当の補佐で、主担当が忙しかったり、手が回らないタスクを拾って実施してくれます
```
ちなみに担当月になったけど、その時期が多忙になる場合もありますよね
（例えば4月の時点で10月担当に決まったけど、当初は多忙になるのが予測できなかった）
そんなときは誰かが担当月を交代してくれます

# スタッフは名古屋（愛知県）以外にも居る
JAWS-UG名古屋のスタッフは名古屋以外に在住しているスタッフが複数名います
大阪、静岡、横浜からはるばる名古屋へ来て勉強会に参加します

# 開催テーマ
JAWS-UG名古屋では様々なサービスをテーマにしています
毎月ごとの当番制となっていて、担当月の人が好きなテーマを選べます
自分が得意なテーマを開催するのも、不得意なテーマだからこそ開催するというのも全然ありです

2023年は以下の内容を開催しました
```
01月 - IoTと位置情報系サービス てんこ盛り回 with 自動車系サービス
02月 - AWS CDKハンズオン
03月 - 推しのAWSサービスを語るLT会
04月 - AWS 初心者向け(?) S3&EC2 かECSかCDK アラカルトハンズオン
05月 - ​​IDとアクセス管理を語る（オンライン）
05月 - AWS Demo-1グランプリ
06月 - AWS 画像認識AIハンズオン
07月 - オブザーバビリティ for AWS
08月 - AVAハンズオン+re:inforceの復習
09月 - AWS認定試験を受けてみようと思った方へ送る勉強会
10月 - 今改めて「サーバーレス」の価値を理解しよう
11月 - Amazon Bedrock ハンズオン
12月 - 2023年 "AWS re:Invent"の復習（今月開催予定）
```
## 参加人数
### 449名（うちオンラインで42名）
449名ご参加ありがとうございます
来年は500名を目指しますよー！


## 申し込み率
申し込み率：86％（物理開催のみを統計）
ちなみに物理開催だと、当日ドタキャンが少なく参加率は高いです

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/197418/90aade1e-b43a-76dd-ccd2-f0775c7ea959.png)



## JAWS-UG名古屋の名物
JAWS-UG名古屋の名物と言ったら一度はSNSの投稿で目にしたことがあるかもしれませんが楽々さんの名物プリンです
まだJAWS-UG名古屋に来たことがないという方がいれば是非とも足を運んでください
名物プリンで写真を撮りましょう！

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/197418/54db625d-d930-1a97-0b75-f65fb1f98dc2.png)

## 告知
12/18（月）にre:Inventの復習回を開催します
すでに満員ですが、キャンセル待ちで登録すれば繰り上がるかもです

[JAWS-UG 名古屋 2023年 "AWS re:Invent"の復習](https://manage.doorkeeper.jp/groups/jawsug-nagoya/events/165969)
SIFT WorkStationのインストール手順

以下に一応手順は書いてあるが、少々わかりにくかったので、メモ書き。
[https://github.com/teamdfir/sift-cli#installation]()

**0.準備**
Sift Workstationを使用するにはUbuntu20.04LTSが必要。
※それ以上のバージョンで試したが、OSのバージョンに関するエラーが発生した。当たり前ですけど（笑）（Ubuntu22.04LTS）
以下のミラーよりダウンロードを行い、インストールを行う。
[https://www.ubuntulinux.jp/ubuntu/mirrors]()

作業フォルダは/usr/localとする。

```
cd /usr/local
```


**1.SIFTに関するファイルをGithubからダウンロードする。**
ダウンロードするファイルは以下である。バージョンはv1.14.0-rc1。
 * sift-cli-linux
 * sift-cli-linux.sig
 * sift-cli.pub
 
```
sudo wget https://github.com/teamdfir/sift-cli/releases/download/v1.14.0-rc1/sift-cli-linux
sudo wget https://github.com/teamdfir/sift-cli/releases/download/v1.14.0-rc1/sift-cli-linux.sig
sudo wget https://github.com/teamdfir/sift-cli/releases/download/v1.14.0-rc1/sift-cli.pub
```

**2.goをインストールする**
以下より、goのダウンロードを行う。バージョンは1.21.0
```
sudo wget https://go.dev/dl/go1.21.0.linux-amd64.tar.gz
```

ダウンロードが完了したら、goを展開する。
```
sudo tar -xvf go1.21.0.linux-amd64.tar.gz
```

展開後、pathを通す。
```
export PATH=$PATH:/usr/local/go/bin
source ~/.bashrc
```

pathが通ったか確認する。
```
go version
```


**3.cosignをインストールする**

```
go install github.com/sigstore/cosign/cmd/cosign@latest
```

pathが通ったか確認する。
```
cosign version
```


**4.sift-cliで検証を行う**
以下のコマンドを入力し、「Verified OK」が出ればOK。
```
cosign verify-blob --key sift-cli.pub --signature sift-cli-linux.sig sift-cli-linux
```

**5.Siftをインストールする**

```
sudo mv sift-cli-linux /usr/local/bin/sift
sudo chmod 755 /usr/local/bin/sift
sudo sift install --version=v2022.01.22
```

ここからのDLが長い！

途中、「KDE Wallet Service」というウィンドウが出てくる。
classic・・・・と書いてあるやつを選んで、新規のパスワードを促される。

**余談**
「sudo sift install」のように、バージョン指定無しで行うとエラーが発生して、インストールが全く進まない状況だった。公式のissueを見るに、同じエラーを吐いていた人がいて、解決策についても提示されていたが、こちらでは全く解決できず・・・・。


そして、２日かけて見つけた解決策は、バージョン指定だったとさ。
連なったプルリクエストとの戦い

## はじめに
最近、表題のようなプルリクエストと格闘していたことがありました。そこで得た学びを備忘録的にここに書きます。


## 連なったプルリクエストとは？
まず、連なったプルリクエストとは何か？について説明します。ここで言う連なったプルリクエストとは、
mainから生えた子ブランチAがブランチBの親で、ブランチBが親のブランチCがあり...と言った感じで、派生ブランチの連鎖が起きているような状態です。

```mermaid
%%{init: { 'gitGraph': { 'showCommitLabel': false } } }%%
gitGraph:
  commit
  branch branchA
  checkout branchA
  commit
  commit
    branch branchB
  checkout branchB
  commit
  commit
    branch branchC
  checkout branchC
  commit
  commit
    branch branchD
      checkout branchD
      commit
      commit
```
通常ではmainに向けPRを発行すれば問題ないかもしれません。しかし、これらは上流ブランチに依存関係のあるコンポーネントを抱えており、それがmainにまだマージされていない場合に、こう言った事態が発生することがあるかと思います。

## 何が起きるのか
### チームはレビューにかける時間が増大してしまう
レビュアーは順に追って見なければならなかったり、1つのPRあたりのdiffが膨大になっている場合などではレビュアーが全てのPRを見終わるまで時間がかかってしまいます。こうなるとチームのレビューのキャパシティを超えることにもなり、他のPRまで滞留が始まってしまいます。

### PR作成者側はmainにコミットがされた場合、rebaseやコンフリクト対応に追われる
こうなってしまうと、PR作成者側にも大きな負担がかかります。
また、例えばbranchCの親のbranchBのPRで、かつbranchCに影響のあるコンポーネントに修正を依頼するコメントが来た場合でも、修正の必要や、commitをrebaseなどする可能性が出てくることもあるでしょう。その場合でも対応が煩雑になることが考えられます。

## どうすれば防げるか？

### そもそも何故連らせているのか？を考える
実は後になって、親子関係にするほどそこまで依存度の高くないコンポーネントだった、ということがあるかもしれません。
それぞれの機能において影響のあるものを洗い出しておきましょう。

### それでも連なってしまった場合は、最初の1つのPRだけをOpenにして、それ以外のPRはDraftにする
こうすると、レビュアーは最初の１つのPRのレビューに集中することができ、早期のレビュー完了、マージの一助になります。

### mainにまだマージされていない内容に依存するようなタスクを、レビューとマージが完了するまでそのスプリントでは取らない
少々強めの解決策ですが、これも選択肢の1つとしてあるかなと感じます。レビューにかかる時間は1つのPRあたり必ず一定時間ありますし、数が多ければそれに比例して増大していきます。そのため、1つ目がマージされるまで着手しないという手もあります。

## 最後に
チーム開発では、思い通りのフローではいかなくなる時が訪れることがあります。しかしそれを早期に抜け出し、円滑に進めていくことが最終的なベロシティ向上につながっていきます。
PHP Stripe SDK 連結アカウントに口座を登録する（実装コード無し）

## 概要

laravel-cashierというライブラリとstripe-php（SDK）を駆使してStripeの顧客の口座を登録する方法をまとめる。

## 選定

- stripeの登録が完了しており、ブラウザからテスト環境にログインできること。APIキーが確認できていること。筆者は下記の方法で実施済み。

https://qiita.com/miriwo/items/01cac1cab4133ebd0d9a

## 注意

送金先として銀行口座を設定する場合、Stripeの「顧客」に送金用の口座を紐付けることはできない。
送金したい場合はStripeのConnectというサービスを使って、送金対象のユーザーを連結アカウントとしてStripeに登録する必要がある。

## 処理の流れ

下記のような流れで処理を行う。（口座の登録方法は「フロントエンドからStripe.jsを使ってリクエストを投げてもらい、レスポンスの口座情報トークンをlaravelのAPIに投げてもらう方法」と「laravelから平文の口座情報を投げる方法がある。」バックエンドのログに口座情報を残したくないので今回は前者の方法で進める。）

```mermaid
sequenceDiagram
        actor user as ユーザー
		participant front as FrontEnd
		participant back as BackEnd
		participant stripe as Stripe
		user->>front: 口座情報入力<br>登録実行
		front->>stripe: 口座情報送信（Stripe.js使用）
		stripe->>front: 口座情報ID
		front->>back: 口座情報<br>ユーザー紐づけ<br>API実行
		rect rgb(136, 61, 136)
				back->>stripe: 連結アカウント<br>存在確認
				stripe->>back: TRUE / FALSE
				back->>stripe: FALSEの場合<br>連結アカウント<br>作成
				stripe->>back: 連結アカウントID返却
				back->>back: 連結アカウントID保存
				back->>stripe: 口座情報<br>連結アカウント紐づけ<br>リクエスト
				stripe->>back: 成功可否
				back->>front: 200 ok
		end
		front->>user: 正常登録表示
```

※確認前にブラウザからStripeにログインし、左サイドバーで「Connect」をクリックし、テスト環境で使用開始するためのボタンクリックが必要だったかもしれない。（すみません記憶が定かではないです。）

実装後のテストは下記の内容を参考に実施した。

- まず[こちら](https://stripe.com/docs/connect/custom-accounts#create)を参考に連結アカウントを作成した。（最低限の情報があれば連結アカウントは作れる筈なので、国情報、連結アカウントタイプ情報、ケイパビリティ情報だけを指定して連結アカウントを作成した。）
- その後[こちら](https://qiita.com/miriwo/items/e3d6c0b79d836a132767)を参考にテスト用銀行口座情報を使って「口座情報入力登録実行」の部分を実行した。
- 「口座情報連結アカウント紐づけリクエスト」は[こちら](https://stripe.com/docs/api/external_account_bank_accounts/create)を参考に処理を記載した。

## 参考文献

https://stripe.com/docs/api/customer_bank_accounts/create?lang=php

https://stripe.com/docs/api/customers/object
PC上のUnityからAndroidへビルドする方法

# 1. はじめに
こんばんは！！！MYJLab Advent Calendar 2023 12日目を担当させていただきます！

前回の記事は岡田さんのこちらの記事でした。

https://qiita.com/a8nana/items/b71402999a348796d1a4

3Dモデリングとアニメーション制作、夢が広がりますね！！！
<br>
さて、今日はUnityで作成したプロジェクトをAndroidへビルドする手順を解説していきます。

せっかく作ったゲームとか、スマホに実装できたらいいですよね！

ではどうぞ！

# 2. 目標
PC上のUnityで開発したプロジェクトをAndroid版にビルド。

# 3. 必要なもののインストール
まずはUnity Hubがないと始まりません。

Unityを使うためのバージョンとかパッケージとかを管理してくれる優秀な子です。

いつもありがとう。
<br>

まだのひとはこちらから↓↓↓

https://store.unity.com/ja/download?ref=personal

<br>

Unity Hubを利用してUnityをインストールします。

左のタブの『インストール』に移動すると、所有するUnityのバージョンが表示されますね。

次に歯車マークをクリック。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3473652/b7a108a1-25c3-39fd-5b4d-a1baf68e0d2b.png)
<br>
<br>

そうすると『モジュールを加える』という項目があるので、そちらをクリックします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3473652/73c56869-076d-8629-8ce3-e8456621752b.png)
<br>
<br>

ここではUnityで使用したいモジュールを加えることができます。

明らかにAndoidでの開発をサポートしてくれる雰囲気の、

 **Android Build Support(OpenJDK、Android SDK & NDK Tools)**

をダウンロードしましょう。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3473652/1046a9c2-91eb-854c-1d1f-7b0a7457059f.png)
<br><br>

これで必要なモジュールのインストールは終了です。

# 4. プロジェクトの設定

さて、実際にプロジェクトを設定していきましょう。

ビルドしたいプロジェクトを立ち上げたら、左上の『File』タブをクリックします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3473652/2501265c-3040-e411-08e6-edd48e948d80.png)
<br><br>

そして『Build Settings…』をクリックします。

 *Ctrl + Shift + B* でも可能です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3473652/0427c7a1-5548-ca50-fc0c-84d99ee171f6.png)
<br><br>

『Build Setting』内では以下のような項目を選択できます。

まずは『Platform』を今回の目的である『Android』に設定しましょう。

すると、右側にAndroidでビルドする場合の様々な項目が表示されますね。

色々設定できますが、とりあえず最下の『Switch Platform』をクリック。

切り替えに少し時間がかかります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3473652/60a30c69-77f9-87c8-b0a3-dc0b42943d6d.png)
<br><br>


これでプロジェクトの設定は終了です。

うまく行かない場合は、項目を変更してトライしてみてください。

# 5. ビルド
いよいよビルドです！

同様に『Build Setting』を開くと、最下の項目が『Build』に変わっていますね！すごい！！

問題がなければここで『Build』をクリックしビルドは完成です。

最上部『Scenes In Build』で必要なシーンを選択するのを忘れずに！

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3473652/af2470f0-bd0a-447d-0df5-0f9f4d357702.png)
<br><br>

## 5-2. うまくビルドできないとき

ということで終了です。が、そううまくいかない場合だってあります。

そんなときは『Edit』>『Project Setting』>『Player』をチェックしましょう。

なんか色々設定項目があります。

apkの名前はもちろん、パブリッシャーの名前を変更したり様々な設定が可能です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3473652/2f1aff03-9ca6-e4ef-6dd1-acf24044a259.png)

経験上ビルドエラーに影響する項目を以下にまとめました。

* Minimum API Level
* Target API Level
* Scripting Backend
* Target Device

これらは実行端末での動作及びビルドの可否に影響する（気がする）ので、困ったときはここらへんをチェックしましょう！！

# 6 おわりに

ということで、Androidでのビルド方法を紹介しました！

Unityそのものではなく外部端末への実装を焦点に当てた記事、いかがでしたでしょうか。

実際、所有端末の相性とかいろんな要因でビルドが失敗することがあります、つらい。

今回は基本的なことしか扱っていないですが、参考になれば幸いです。

では！！！！
StimulusはどのようにしてDOMの変更を検知しているのか

# はじめに
本記事は錆びかけたRailsの知識を頑張ってアップデートするアドベントカレンダー10日目です。

今日は**MutationObserver**について学んだらRails7(というか、Stimulus)の仕組みが把握できたという話を書きます。

# 背景
筆者は現在、Rails7のHotWireを学んでいます。

HotWireを学ぶ教材として、猫Rails様の書かれた[猫でもわかるHotwire入門 Turbo編](https://zenn.dev/shita1112/books/cat-hotwire-turbo)を読み手を動かしています。

その中で、`Stimulus`というライブラリが登場しました。

:::note info 
stimulusとは？
:::
Railsで利用するJavaScriptのライブラリです。Stimulusを使えば、RailsでJavaScriptを使った動きをつけるとき、より便利にJavaScriptを扱えるようになります。

具体的なStimulusの動作例は以下のページに端的にまとまっているのでぜひご覧ください。

https://zenn.dev/shita1112/books/cat-hotwire-turbo/viewer/tutorial-3

素のJavaScript(ここではバニラJSと呼びます)を利用する場合と比較したStimulusの特徴は以下の通りです。

#### 構造化されたJavaScriptコードの管理
バニラJSもStimulusも、要素に対してイベントをセットして、ユーザーの決まった動作(Clickやフォームの入力)に反応してそのイベントが動く(イベントが発火する)という点は変わりません。

しかし、Stimulusはイベントをセットするためのお作法、レールを用意してくれます。これにより複数人で開発する場合やコードの量が多くなってきた場合でもコードの可読性を保ちやすくなります。

#### DOMの変更に対する自動的な対応
StimulusはDOMの変更を監視します。新しく要素が追加された場合、自動的に適切なイベントをセットする仕組みがあります。

新しい要素がユーザーの操作などによってDOMに追加される場合、その新しいDOMにイベントをセットするようコードを書くのは手間ですし、ミスが起きやすくなります。Stimulusは、これを自動化しているので便利！ということですね。

# 疑問点
ここで1つ疑問が浮かびました。StimulusはどのようにしてDOMの変更を監視しているのでしょうか。

# 結論
Stimulusは、`MutationObserver`というものを使ってDOMの追加・更新を監視しています。

:::note info 
MutationObserverとは？
:::
MutationObserverはWeb標準のAPIです。DOMの変更に反応して発火します。JavaScriptから利用するための書き方が準備されています。おそらく、以下のような形で実装されているはずです。

:::note alert
注意: 以下は筆者の妄想コードです。実際のStimulusの中身のコードではありません。
:::

```javascript:stimulusの例
import { Application } from "stimulus"

const application = Application.start()

// MutationObserverの設定
const observer = new MutationObserver(mutations => {
  mutations.forEach(mutation => {
    if (mutation.type === 'childList') {
      mutation.addedNodes.forEach(node => {
        // 新しいノード（DOM要素）が追加された時にコントローラーを接続
        application.connectControllerForNode(node)
      })

      mutation.removedNodes.forEach(node => {
        // ノードが削除された時にコントローラーを切断
        application.disconnectControllerForNode(node)
      })
    }
  })
})

// ObserverをDOMの変更を監視するように設定
observer.observe(document.body, { childList: true, subtree: true })
```

ここで伝えたいことは、`new MutationObserver`という書き方は特にライブラリを読み込まずともできる、つまり標準で使えるクラスであるということです。

なるほど確かに、このようなAPIがあるのならDOMを監視して何かをするということが容易にできそうですね。

### Stimulusが監視しているイベントまとめ

| イベント    | 説明 |
|-----------|------|
| input     | 入力フィールドに文字が入力された際にトリガーされる。テキストボックスやテキストエリアでのキータイプなどに用いられる。 |
| change    | フォーム要素（例えばテキストボックス、セレクトボックス、チェックボックス）の値が変更されたときにトリガーされる。 |
| submit    | フォームが送信されるときにトリガーされる。フォームの送信ボタンが押された際などに反応する。 |
| mouseover | マウスポインターが要素の上に移動したときにトリガーされる。 |
| mouseout  | マウスポインターが要素を離れたときにトリガーされる。 |
| keydown   | キーボードのキーが押されたときにトリガーされる。 |
| keyup     | キーボードのキーが離されたときにトリガーされる。 |
| focus     | 要素がフォーカスを受けたとき（例えばテキストボックスをクリックしたとき）にトリガーされる。 |
| blur      | 要素がフォーカスを失ったときにトリガーされる。 |

# 終わりに
StimulusはRailsの思想であるCoCを体現するJavaScriptライブラリなんですね。
実行環境が IchigoJam か ORANGE pico かを判定する

[IchigoJam](https://ichigojam.net/) と [ORANGE pico](http://www.picosoft.co.jp/orange/) は、ともにBASIC言語を実行することができ、全く同じコードをそれぞれ実行できることもある。
そこで、環境を判別できれば、共通のコードで書ける部分は共通のコードを用い、配列やI/Oなどの異なる部分は分岐して実行できる可能性が出てくる。

IchigoJam では、ビットオア演算子の優先順位が比較演算子より高い。
(これは[0.9系](https://fukuno.jig.jp/984)でも[1.0系](https://fukuno.jig.jp/1002)でも成り立つ)
一方、ORANGE pico では、ビット論理和演算子の優先順位が比較演算子より低い。
これを利用した、以下のプログラムで環境の判別を行うことができる。

```
10 IF 1|1<0 THEN GOTO 30
20 PRINT "IchigoJam":END
30 PRINT "ORANGE pico"
```

IchigoJam では `1|1<0` は `(1|1)<0` すなわち `1<0` と解釈されるので、これは `0` になる。
一方、ORANGE pico では、`1|1<0` は `1|(1<0)` すなわち `1|0` と解釈されるので、これは `1` になる。

以下に、これを実際に IchigoJam と ORANGE pico でそれぞれ実行してみた結果を示す。

![IchigoJam での実行結果](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/99656/77f46651-3a01-f5d8-eb0f-d711b8b2cb79.png)

![ORANGE pico での実行結果](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/99656/a80e21a6-1f19-cbe2-5765-b04598355430.png)

実際に環境が判別できていることがわかる。

※IchigoJamはjig.jpの登録商標です。
[おすすめ設定]PagerDuty障害情報はSlack連携し迅速に検知しよう！

PagerDuty Advent Calendarの11日目！

https://qiita.com/advent-calendar/2023/pagerduty

本日はPagerDuty障害情報をSlackに連携する方法についてお話しします！

# まえがき
早速ですが、皆さん普段PagerDutyを使っていますか？

PagerDutyはシステム監視やインシデント管理において重要な役割を持っています。
多くの監視ツールとインテグレーションが可能であり、API経由でのインシデント管理なども提供しているため、深夜に発生した障害を即座に検知させ迅速な対応につなげたりサービス監視や運用業務には欠かせないツールです。

そのためPagerDutyの正常性を確認し、障害時に迅速に対応できることは極めて重要です。

PagerDutyでは、24時間365日、ステータスの正常性をモニタリングし、公式ステータスページやX（旧Twitter）などを通じて障害情報を提供しています。
これにより、障害発生の有無について迅速に確認できます。

・[PagerDutyの障害通知](https://support.pagerduty.com/lang-ja/docs/pagerduty-outage-notifications)より抜粋

>当社のステータスページ：[status.pagerduty.com](https://status.pagerduty.com/)
Twitter: [@PagerDutyHelp](https://twitter.com/PagerDutyHelp)

しかし、この情報をより効果的に活用する方法があります。

今回は、**PagerDutyの障害情報をSlackに通知し、日常のチャットツールと連携させる方法についてご紹介します。**
これにより障害をより早く検知し、スピーディーな対応が可能になります。



※設定方法は「[PagerDutyのステータスページを購読する](https://support.pagerduty.com/lang-ja/docs/pagerduty-outage-notifications#subscribe-to-the-pagerduty-status-page)」を参考。

# 手順
## 1. Slackで通知用チャンネルを作成する
・今回は「notify-pagerduty-status」という名前のチャンネルで通知を受ける。

![pd0.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/449720/d59a2a52-8888-d4f9-856d-d7a84104e1d7.png)

・作成できればこれで準備は完了です。
![pd01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/449720/99f3db77-fe36-d029-3f38-f4308a8ba0a6.png)
## 2. PagerDutyステータスページから、Slackチャンネルを連携する。
・[status.pagerduty.com](https://status.pagerduty.com/)へアクセス。
![pd1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/449720/dfa53273-b62f-8632-00d5-1787c7ba71cc.png)
・右上より「Subscribe to Updates」をクリック
![pd2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/449720/91feacf9-d434-c525-4ee7-437b1c0868bd.png)
・タブより「Slack」を選択、「Add to Slack」をクリック
![pd3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/449720/a76cbc9d-85ab-642b-07a5-11fc90b22544.png)
・初回はSlackのワークスペースURLを聞かれるので、Slack画面の左上から確認できるので入力する。
![pd3-1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/449720/e707139d-a76e-abaf-45b6-508ebf83a94f.png)

・通知先チャンネルに先ほど作成した「notify-pagerduty-status」が選択できるので設定し「許可する」をクリック。

![pd02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/449720/ea40166d-39a3-fcfd-5a4c-55f751f81eac.png)

・通知先のSlackチャンネルに以下のようなメッセージが出力されれば完了です。
![pd3-2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/449720/009fec75-c05e-8e25-1af0-4da4a1bf849a.png)

# まとめ
今回ご紹介したPagerDutyとSlackの連携により、障害情報の迅速なキャッチが可能になります。
また、チーム全体での情報共有などもスムーズになるため、障害対応の迅速化にも繋げることもできます。
Slackのほかにもメールへの連携も可能になっています。まだの方はぜひお試しください！

最後まで閲覧いただきありがとうございました。
IBM i アーキテクチャー：ジョブ実行とシステム資源へのアクセスの例

今回はこれまで解説してきたIBM i 実行管理機能の諸動作を5250対話型ジョブの動きの例で振り返ってみたいと思います。

## シナリオ例
シナリオとしては、5250端末がログインして、ある対話型プログラムPGMAを起動して、5250画面を使ってユーザーが入力し、データベースのデータを操作し、結果を5250画面に返す、というようなものです。
 -図中の水色の吹き出し①～⑩がユーザーから見た処理の流れです
 -ピンクの吹き出しが、それぞれの操作時に発生する可能性のあるシステム的な処理の例です

 ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1011394/e574401f-6665-f2a4-ab7b-a3eb43dfe461.png)

### シナリオの説明
①5250画面でユーザーの入力画面待ち（RPGだとEXFMT命令）が発生します。

②このとき初回のプログラム呼出しでメインメモリ上にプログラムが存在しないと、要求されたページをシステムプログラムがマシンプールにロードします。このときマシンプールに空きがないと非データベースページ不在が発生します。

③ベースプールまたはジョブが指定したサブシステム定義のプールの活動レベルに空きがあればジョブは活動状態になります。もし、活動レベルに空きがない場合、ジョブは不適格隊状態になります。

④ジョブが活動状態になるとディスク上に書き出していたPAGがベースプール又はジョブ指定のサブシステム定義のプールにロードされます。

⑤トランザクションを処理するために必要なプログラムがメインメモリ上に無いと非データベースページ不在が発生、ページングが起こります。

⑥必要なデータ、アクセスパスがメインメモリ上に無いと、データベースページ不在が発生し、ページングが起こります。

⑦　④で読み込まれていないPAGが参照されると非データベースページ不在が発生しページングが起きます。

⑧トランザクション処理の間にシステムプログラムへの要求があり、このシステムプログラムがメインメモリ上に存在しない場合は非データベースページ不在が発生しページングが起きます。システムプログラムはマシンプールにロードされるものと、ベースプールを使うものの二種類があります。

⑨トランザクション処理が終わると、データを5250端末に書き出し、ユーザーの次の入力を待ちます。

⑩PAGがストレージ上に書き出されます。（PURGE(*YES)の場合）
Unityで世界一シンプルなDictionaryシリアライズ

> この投稿は「[K3 Advent Calendar 2023](https://adventar.org/calendars/9117)」の10日目の記事です

Unityの標準機能では、`Dictionary`型の変数はシリアライズされません。これは、多くのUnity開発者にとって課題となっています。
本記事では、`SerializedDictionary`を使ってこの問題を解決する方法を紹介します。
# コード
```cs
using System.Collections.Generic;
using UnityEngine;

[System.Serializable]
public class SerializedDictionary<K, V> : Dictionary<K, V>, ISerializationCallbackReceiver
{
    [System.Serializable]
    internal class KeyValue
    {
        public K Key;
        public V Value;

        public KeyValue(K key, V value)
        {
            Key = key;
            Value = value;
        }
    }
    [SerializeField] List<KeyValue> m_list;

    public virtual K DefaultKey => default;
    void ISerializationCallbackReceiver.OnAfterDeserialize()
    {
        Clear();
        foreach (var item in m_list)
        {
            this[ContainsKey(item.Key) ? DefaultKey : item.Key] = item.Value;
        }
    }

    void ISerializationCallbackReceiver.OnBeforeSerialize()
    {
        m_list = new List<KeyValue>(Count);
        foreach (var kvp in this)
        {
            m_list.Add(new KeyValue(kvp.Key, kvp.Value));
        }
    }
}
[System.Serializable]
public class SerializedDictionary<V> : SerializedDictionary<string, V>
{
    public override string DefaultKey => string.Empty;
}
[System.Serializable]
public class SerializedDictionaryC<K, V> : SerializedDictionary<K, V> where K : new()
{
    public override K DefaultKey => new();
}
```
## 使用例
追加でCustomクラスは作る必要はなく、そのまま利用可能です。
```cs
[SerializeField] SerializedDictionary<int, string> m_PrimitiveDic;
[SerializeField] SerializedDictionary<string> m_StringDic;
[SerializeField] SerializedDictionaryC<Vector3, string> m_ClassDid;
```

### Unity Editorでの表示
キーと値のペアが視覚的に編集可能な形式で表示されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/27776/b20e0f47-f66b-9578-808c-6367097bcbb8.png)

## 本クラスの利点
Dictionary<K, V>をベースで継承しているため、Dictionaryに存在しているメソッドがそのまま使えます
また、インスペクターで用意にデータの編集も可能となっています。

# 他との比較

| プロダクト | Dictionary | Inspector | 補足 |
|:-:|:-:|:-:|:-:|
| 本プロダクト  | 継承  | 容易  | コード数少ない  |
| [Core RP(Unity)](https://docs.unity3d.com/Packages/com.unity.render-pipelines.core@17.0/api/UnityEngine.Rendering.SerializedDictionary-2.html)  | IDictionary  | 不可  | 公式  |
|  [neuecc/SerializableDictionary](https://github.com/neuecc/SerializableDictionary) | IDictionary  |  不可 | 高パフォーマンス / クラス別途定義  |
| [baba-s/UniSerializableDictionary](https://github.com/baba-s/UniSerializableDictionary)  | 内部List  |  可能 |  クラス別途定義 |
| [UnityのSerializableFieldで連想配列(Dictinary)を扱いたい](https://rimever.hatenablog.com/entry/2022/05/27/000000)  |  配列 |  可能 |  Dictionary的扱い不可 |
AtCoder Beginners SelectionをGoで解いてみた（前半）

`Go`の基本的な文法に慣れるため、**AtCoder Beginners Selection**を解いてみようと思う

## AtCoder Beginners Selectionとは？
> このコンテストは、「AtCoderに登録したけど何をしていいか分からない・・・！」という人に向けて作られた、初心者向け問題集です。

https://atcoder.jp/contests/abs

### PracticeA	Welcome to AtCoder
https://atcoder.jp/contests/abs/tasks/practice_1

**PracticeA**は`Go`のサンプルコードが問題文の下にある。
`fmt.Scan` 関数で標準入力からデータを読み込み、指定した変数に値を格納できる。

#### ACコード
```go
package main

import (
	"fmt"
)

func main() {
	var a, b, c int
	var s string
	fmt.Scan(&a, &b, &c)
	fmt.Scan(&s)

	result := a + b + c
	fmt.Println(result, s)
}

```

### ABC086A	Product
https://atcoder.jp/contests/abs/tasks/abc086_a
*a*と*b*をかけて`%2`で偶奇判定すれば良い


#### ACコード
```go
package main

import (
	"fmt"
)

func main() {
	var a, b int
	fmt.Scan(&a, &b)

	if a*b%2 == 0 {
		fmt.Println("Even")
	} else {
		fmt.Println("Odd")
	}
}

```

### ABC081A	Placing Marbles
https://atcoder.jp/contests/abs/tasks/abc081_a

`strings.Count`関数で文字列に含まれる特定の文字列をカウントできる

#### ACコード
```go
package main

import (
	"fmt"
	"strings"
)

func main() {
	var s string
	fmt.Scan(&s)
	fmt.Println(strings.Count(s, "1"))
}

```

### ABC081B	Shift only
https://atcoder.jp/contests/abs/tasks/abc081_b

`for`ループの条件部分に何も書かない場合、無限ループになることを利用して解いた

#### ACコード
```go
package main

import "fmt"

func main() {
	var n int
	fmt.Scan(&n)
	a := make([]int, n)
	for i := 0; i < n; i++ {
		fmt.Scan(&a[i])
	}
	ans := 0
	for {
		flg := true
		for i, _ := range a {
			if a[i]%2 == 0 {
				a[i] /= 2
			} else {
				flg = false
			}
		}
		if flg {
			ans += 1
		} else {
			break
		}
	}

	fmt.Println(ans)
}

```

### ABC087B	Coins
https://atcoder.jp/contests/abs/tasks/abc087_b

全探索すれば良い

#### ACコード
```go
package main

import "fmt"

func main() {
	var a, b, c, x int
	fmt.Scan(&a, &b, &c, &x)
	ans := 0
	for ai := 0; ai <= a; ai++ {
		for bi := 0; bi <= b; bi++ {
			for ci := 0; ci <= c; ci++ {
				if x == ai*500+bi*100+ci*50 {
					ans += 1
				}
			}
		}
	}
	fmt.Println(ans)
}

```

### ABC083B	Some Sums
https://atcoder.jp/contests/abs/tasks/abc083_b

`strconv`パッケージを使用して、文字列と整数の変換ができる

#### ACコード
```go
package main

import (
	"fmt"
	"strconv"
)

func main() {
	var n, a, b int
	fmt.Scan(&n, &a, &b)
	ans := 0
	for i := 1; i <= n; i++ {
		str_i := strconv.Itoa(i)
		work := 0
		for _, ele := range str_i {
			digit, _ := strconv.Atoi(string(ele))
			work += digit
		}
		if a <= work && work <= b {
			ans += i
		}
	}
	fmt.Println(ans)
}

```
### ABC088B	Card Game for Two
https://atcoder.jp/contests/abs/tasks/abc088_b

Goで`int`のスライスをソートする方法は
```go
// sはintのスライス
sort.Ints(s) // 昇順
sort.Sort(sort.Reverse(sort.IntSlice(s))) // 降順
```

#### ACコード
```go
package main

import (
	"fmt"
	"sort"
)

func main() {
	var n int
	fmt.Scan(&n)
	a := make([]int, n)
	for i := 0; i < n; i++ {
		fmt.Scan(&a[i])
	}
	sort.Sort(sort.Reverse(sort.IntSlice(a)))
	ans := 0
	for i, num := range a {
		if i%2 == 0 {
			ans += num
		} else {
			ans -= num
		}
	}
	fmt.Println(ans)
}

```

## 後半に続く

https://qiita.com/rapirapi/items/d9fd03927581748b58ab
Stripeのサポートチャットがすごすぎる

## 概要

Stripeのサポートのチャットが非常に便利だったので簡単にまとめる。
筆者はすでに数回お世話になっている。

## サポートを受ける方法

- 下記にアクセスする。

https://support.stripe.com/?locale=ja-JP

- 「サポートにお問い合わせください」をクリックする。

![Stripe__ヘルプ___サポート.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306417/a334ddf5-04e5-1bec-f225-80c56c4bc005.png)

- 問い合わせたい内容のトピックを選択する。

![Stripe__ヘルプ___サポート.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306417/f9890020-b1de-e2f8-83b8-0a09de4f922f.png)

- サポートの種類を選択する。

![Stripe__ヘルプ___サポート.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306417/eefcdb8c-a878-ba20-67f5-54d435dcad10.png)

## 注意

基本日本語での対応は「平日の9時〜18時」だけである。（電話もチャットも）

## サポートの種類

Stripeのサポートは下記の3種類である。

- 電話
- チャット
- メール

筆者はこの中でもチャットを多様してる。
理由は
- 電話だとうまく伝えられる自身がない、聞き取り漏れがあるかもしれない。
- メールだと返事までに時間がかかる。

である。チャットだとリアルタイムではあるが、文字でやり取りできるし焦りがない。
本記事は基本チャットでの問い合わせについて書いている。

## 無料　！ほぼ待ち時間無し！日本人の方の手厚い対応！

平日の9時〜18時限定ではあるが日本人の方に日本語で問い合わせができる。個人的にこれはかなりすごいことだと感じた。
大体待ち時間目安が3分で、基本それより速いスピードで返事が来る。よくあるような「サポートに連絡しているのに繋がらない」
みたいなことを感じたことはない。
オペレーターの方の知識が非常に豊富で基本的にチャットで完結できる。ありがちな「公式ドキュメントのURLだけを送って、ハイ終わり」という感じは一切ない。すぐに答えが出ない内容であっても、社内で調査し、レポートを後々メールで送ってくれる。
そして、チャットでのやり取りも後からメールで送ってくれる。セコセコとチャット終了後に手動でコピーしてメモする必要がない。

## サポートを受けるときに心がけたほうがいいかもしれないこと

### Stripeのアカウントを作っておこう

Stripeのアカウントを作成し、ログインした状態でチャットを開始するとやり取りがスムーズになる。
例えば「チャットですぐに答えが出ない内容」を問い合わせたとして、後からメールを送って貰う場合、ログイン中なら登録済みメールアドレスにメールを送ってくれる。本番環境を契約中だったら、その設定内容なんかもサポート側で確認できるのかもしれない（これは未確認、実際そのようなアプローチがあるかは不明）
自分が楽をする意味でも、オペレーターさんが楽をする意味でもアカウントを作り、ログインした状態で問い合わせるとスムーズだ。

### 数回に分けて問い合わせよう

自分はStripeで「一方のユーザーから徴収したお金を一方のユーザーの銀行口座に振り込む」という動作をStripeを使って実現したかった。下記のように問い合わせた。

1. 「自分が実現したいこと」をまずは問い合わせた。どうやらConnectというサービスを使うことがわかった。
1. 自分でStripe Connectについてドキュメントを読んでみた。
1. 実現方法の認識があっているか問い合わせた。
1. 自身の大枠の認識があっていることが確認できた。
1. 詳細で具体的な実現方法をドキュメントで調べた。
1. 実装方法の不明点が出てきたので問い合わせた。
1. 不明点がクリアになり実装する事ができた。
リモートワークでのチーム作業に！おすすめのZoom機能3選

リモートワークでのチーム作業中、相手の反応が見えにくかったり、微妙な間が生まれてしまったりと、コミュニケーションの取りにくさや作業のしづらさを感じた経験はありませんか？

そこで、私たちのチームが普段使っているZoomの中で、メリハリをつけながら一緒に楽しく作業するためにおすすめの機能をピックアップしてみました。

### Musicアプリ
BGMを流せるZoomアプリです。同じルームの人と共有できて、曲数も豊富！

#### 使い方
1. ツールバー内の「アプリ」をクリックしてAppsウインドウを開く
![アプリボタン](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3513849/c08f9e87-b5a3-9e27-bf82-51a4784ecbca.png)
2. Add Appsタブの検索ウインドウでMusicアプリを検索し、Get→Open
![Musicアプリの取得](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3513849/a99465f6-9b34-da5c-445b-6611aac491d3.png)
3. プレイリストを選択して再生
プレイリストは10種類以上あるので、気分に合わせて選びましょう。Enable/Disable Sharingボタンで、ルーム内の人に共有するかどうかを変えることができます。音楽を再生した状態で画面共有開始/終了すると、音楽が止まってしまうので、画面共有後に曲再生を開始すると良いです。
![Sharingボタン](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3513849/d7089469-bb9b-f805-c322-ea3e8d0bcd57.png)


### Timerアプリ
画面共有とは無関係にルーム内でタイマー共有できるのがgood。モブプロにも重宝します。

#### 使い方
1. ツールバー内の「アプリ」をクリックしてAppsウインドウを開く
![アプリボタン](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3513849/c08f9e87-b5a3-9e27-bf82-51a4784ecbca.png)
2. Add Appsタブの検索ウインドウでTimerアプリを検索し、Get→Open
Timerアプリは複数ありますが、Zoom公式のものがおすすめです。
![Zoom公式Timerアプリ](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3513849/867ccea4-7fb6-0a68-4da4-5cf4b5ef61f8.png)

3. 時間をセットしてタイマー開始
Show timer to allを切り替えると、ルーム内の全員にタイマーを表示するか、自分だけに見えるようにするかを切り替えることができます。また、ビデオをONにすることで、自分のビデオの表示エリア内にタイマーを映すこともできます。
![タイマーセット画面](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3513849/867ccea4-7fb6-0a68-4da4-5cf4b5ef61f8.png)



### アバター機能
会話相手の顔が見えている方が話しやすいけれど、ビデオONには抵抗がある。そんなときはアバターを使いましょう。
アバターの表示や選択はツールバー内の「ビデオの開始/停止」の横をクリックすることで行えます。ビデオOFFの状態でも、喋っている間はアバターの口元が動きます。
![アバターの表示・選択](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3513849/5d177c5f-de02-e454-30d6-98dafefcc1e2.png)
オリジナルアバターを作るのも楽しいです。
![オリジナルアバター](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3513849/446882c8-94e8-cd63-f84a-b39a8d07f30a.png)


今回紹介した機能は、いずれもサインインした状態でないと使えないのでご注意ください。
他にもたくさんのZoomアプリが提供されているようなので、今後試していきたいと思います！
日本語プログラミング言語をモデリング言語としてシステム開発上中流工程に導入（レイヤードアーキテクチャの対応方法）

# はじめに

日本語プログラミング言語をモデリング言語としてシステム開発上中流工程に導入した場合、そのメリット・デメリットについて考察する記事の2回目です。

本記事の内容はいくつかに分割されて記載されます。本記事中の「本記事」とは分割された内容の総体を指す場合があります。

https://qiita.com/advent-calendar/2023/remind

この記事は日本語構造化仕様記述言語 Re:Mind（リマインド）アドベントカレンダー2023の11日向けの記事です。

## 対象読者
とりあえずこの記事の想定読者はシステムエンジニアさんです。とくに日本語で要求仕様や内部設計資料を書いている方向けのお話です。

実装ご担当者の方も引き受けた実装の内部設計書がぐだぐだで完成納期だけが迫られるという体験をされたことあるかと思いますので、そのような方にとっても参考になればと考えております。

# 想定しているシステム開発フロー
[前回の初回の記事](https://qiita.com/mylifewithviolin/items/b7cc85911507cf1a2a55)ではオーソドックスなリレーショナルデータベースを使用している業務システムを想定していると書きましたが、もう少しだけ具体的にその業務システムはレイヤードアーキテクチャを想定して設計・開発されるとします。

よくありうるのは最終的な実装言語が各レイヤーによって異なる場合があることです。本記事ではその点を考慮して進めてまいります。

少し図が複雑化しますが、もっともシンプルな原型については、お手数ですが前回記事をご参照ください。

```mermaid
flowchart 
    subgraph sgA["上流工程"]
    A["ユビキタス言語</br>（日本語業務用語ディクショナリ）"] --> B["日本語モデリング言語"]
    A --> F["概念ER図"]
    style sgA width:700px
    end
    subgraph sgB["中流工程"]
    B --> C["日本語ロジック記述言語"]
    C --> D["日本語トランスコンパイラ言語"]
    F --> G["論理ER図"]
    G --> M["設計検証用DB"]
    G --> H["物理ER図"]
    style sgB width:900px
    end
    subgraph sgC["実現工程"]
    subgraph sgD["フロントエンド"]
    D --> E["実装言語（Ts）"]
    end
    subgraph sgE["バックエンド"]
    D --> J["実装言語（C＃）"]
    D --> K["実装言語（Java）"]
    H --> L["実データベース"]
    end
    style sgC width:940px
    end
```
# 各工程のレイヤーの扱い
上図の概念図では、実装工程だけレイヤーにわかれているようにも見えますが、上中流でそのように見えないのは、モデリング設計言語が一貫しているためです。

レイヤーにわけて設計しないという意味ではなく、同じ言語を使ってそれぞれのレイヤー向けのクラスなどをモデリングします。

トランスコンパイラ層では、実際はターゲット言語によるアノテーションの違いや細かい点での差異は許容するとしています。また、実装言語の差異は細かいので、実装専門の人材が各レイヤーの実装言語をすべて対応できる場合は多くありますが、設計者レベルでは実装言語にそこまで詳しくないので、実装言語の些末さを除いたレベルで適切なロジックを考案設計できる必要があります。

前回で上中流工程での「完成」について前ブレ的に触れておりますが、のちの記事で詳しく説明していくとして、今回の図ではデータベース設計のルートに設計検証用DBというものを記述しています。

# この回のまとめ
この記事のテーマは上中流の設計品質と生産性を向上させる可能性について検討することです。
デザインレビューの判定基準が、各工程の成果物の書き味に立ち入らない場合は、往々にして日程消化の都合上不安定な成果物が後工程の「実現工程」に投入されることにより、「実現工程」の担当者に負荷のしわ寄せがおそいかかるという状況を避けられないものかという問題意識を含んでいます。

# 次回
~~各工程の詳細について検討してきます。~~
レイヤードアーキテクチャ について補足します。
Record<Keys, Type>について

:::note
プロパティのキーが`Keys`、プロパティの値が`Type`であるオブジェクトの型を作るユーティリティ型
:::

- Keys
    - オブジェクトのプロパティキーを指定する
    - 代入できる型は、string, number, symbolとそれぞれのリテラル型
- Type
    - オブジェクトのプロパティの値の型を指定する
    - 任意の型を代入できる

```typescript
// キーがstringで値がnumberのインデックス型を定義する
type StringNumber = Record<string, number>;
const value: StringNumber = { a: 1, b: 2, c: 3 };

// キーがfirstName,middleName,familyNameで、値が文字列であるオブジェクトの型を定義する
type Person = Record<"firstName" | "middleName" | "lastName", string>;
const person: Person = {
  firstName: "Robert",
  middleName: "Cecil",
  lastName: "Martin",
};
```

https://typescriptbook.jp/reference/type-reuse/utility-types/record
React/TypeScriptで関数をpropsに渡すときに美しく書くための基準

## はじめに
日々実務で、React/TypeScriptと戦っているのですが、**どっちの書き方がいいんだろう?🤔**と迷うことがあります。
今回は、Reactには欠かせない親コンポーネントから子コンポーネントにpropsを渡すときに生じた疑問について書きます。

React Navigationを使用して画面遷移する際の具体的なコード例を通じて、Propsの渡し方における選択肢と、それをどのように書き分けるのか、基準を紹介します。綺麗なコードを書くために使える基準だと思います。
同じ初心者エンジニアの方の参考になれば嬉しいです！

### 自己紹介
私は2023年9月1日にフロントエンドエンジニアとして自社開発のSaaS企業に入社しました。
未経験独学で、薬剤師からの転職です。
詳しくはこちらをご覧ください。

https://qiita.com/odendayoko/items/f616b2f1952897a9af5d

## この記事で伝えたいこと
- 関数をPropsとして渡す時は、**その関数になるべく引数を渡さない形で揃える**と美しくなる

## 背景
- React Nativeでスマホアプリの開発をしている
- 複数のコンポーネントで共通のコンポーネント（`ModalComponet`）を呼ぶことになった。
- propsとして`moveTo`に次の画面遷移先を示す関数を渡したい。
- それぞれのコンポーネントで渡す画面遷移先が異なる
- propsの中身をどのように書けばいいのか迷ってしまった

## 疑問点
なにを迷ったのか、疑問点は以下の2つです。

- propsで渡す関数の中身の長さが異なる時、**どこまで関数に切り出せばいいのか？**
- なんとなく長い、見た目が悪いという感覚で書き分けてしまったが、具体的な**基準**はあるのか？


以下、私がなんとなく長い、見た目が悪いかなという感覚に基づいて書いたコードです。
### パターン1. アロー関数を書く
```react:1.アロー関数を書く
<ModalComponent
  setModalData={setModalData}
  moveTo={() => navigation.navigate(pages.userSetting.name)}
/>
```
propsに直接コールバックを書きました。
少し長い気もしますが、一行なのでいいかなと思いました。
### パターン2. 関数を切り出す
```react:2.関数を切り出す
const moveToTop = () => {
    navigation.reset({
      index: 0,
      routes: [{ name: pages.top.name }],
    });
  };
  
<ModalComponent
  modalData={modalData}
  moveTo={moveToTop}
/>
```
propsに渡す関数を切り出しました。
理由はコールバックが複数行に渡るため、propsに書くと行が広がって見えにくいと思ったからです。
### パターン3.関数そのものを渡す
```react:3.関数そのものを渡す
<ModalComponent
  modalData={modalData}
  moveTo={navigation.goBack}
/>
```
propsに関数を直接渡しました。
[`navigation.goBack`](https://reactnavigation.org/docs/navigation-prop/#goback)は、React Navigationライブラリのメソッドの1つで、現在の画面を閉じて前の画面に戻るためのメソッドです。

3パターンをなんとなくの感覚で書いてみました。
このままでも良いのですが、書き方が異なるのは気持ちが悪いし、具体的な書き分けの基準が知りたかったので先輩に聞いてみました。

## ポイント
:::note
#### propsに関数を渡したい時、別で関数として切り出すかどうかの判断基準
**関数に引数を渡すか渡さないか**を１つの目安にする！!
:::
この基準に従うと、他のpropsで変数を渡している部分の書き方と揃う(見栄えが良い)というメリットがあります。
実際に上記をリファクタしてみましょう。

## リファクタ
パターン2、3は引数を渡していないのでこのままで良さそうです。
パターン1のみ修正します。
```diff_jsx:1.アロー関数を書く リファクタ
+ const moveToUserSetting = () => {
+   navigation.navigate(pages.userSetting.name);
+ };

<ModalComponent
  modalData={modalData}
- moveTo={() => navigation.navigate(pages.userSetting.name)}
+ moveTo={moveToUserSetting}
/>
```
引数を渡しているので、アロー関数を切り出します。
最初よりすっきりしました。
これにより、他のpropsで変数(`modalData`)を渡す書き方と揃って見栄えが良くなりました。

今回はpropsの数が少ないのであまりメリットを感じませんが、コンポーネントが大きくなり、propsの数が増えると、揃っていないとガタガタして見えるので、基準を持っておくことは大切だと思います。

## 終わりに
綺麗なコードを書くための1つの基準を教えていただきました。
ただ、あくまで基準の1つなので、他にも状況に応じて判断していく必要があります。

なんとなくで書いていたものに、具体的な基準が見つかると、一気に書きやすくなりますね。
なんとなくで書かずに、基準に基づいて書いていきたいです。
SortedMultiSet として使う BIT

Python は Hash Set 以外の集合データ構造を標準で実装しておらず貧弱なので順序が必要な場合は自前のデータ構造が必要になります。

万能ではありませんが、BIT でいくらか代用可能です。
# BIT (Binary Indexed Tree) の定義
```python
class BIT:
  def __init__(self, n): pass
  def sum(self, i): pass
  def add(self, i, x) pass
  def lowerbound(self, s): pass
```

`sum(i)`: index $0$ から $i$ までの和を返します
`add(i, x)`: index $i$ に $x$ を足します
`lowerbound(s)`: index $0$ から $i$ までの和が $s$ になるような最小の $i$ を返します

いずれの操作も、列の長さ $N$ に対して時間計算量 $\mathcal{O}(\log{N})$ で実現できることが知られています。

# BIT を拡張して BITSortedMultiSet を作る
```python
class BITSortedMultiSet:
  def __init__(self, mx):
    self.mx = mx
    self.fwk = BIT(mx)
  def add(self, x): self.fwk.add(x, 1)
  def discard(self, x):
    if self.fwk.sum(x) - self.fwk.sum(x - 1): self.fwk.add(x, -1)
  def kthmax(self, k):
    n = self.fwk.sum(self.mx)
    return self.fwk.lowerbound(n - k + 1)
```

受け付ける最大の整数をコンストラクタに渡す必要があります。

`add(x)`: 集合に $x$ を追加します
`discard(x)`: 集合から $x$ をひとつ減らします
`kthmax(k)`: $k$ 番目に大きい値を返します

## 制約
BIT の制約から $1$ 未満を受け付けることはできません。また、整数以外受け付けられません。

# おわり
よく使います。問題に特化したデータ構造の拡張をしておくと、脳のリソースをセーブできて良いです。
Road to E資格

JDLAのE資格は、ディープラーニングの実装知識に関する資格試験です。
今年の3月までは、Pythonに興味はあったもののAIを学ぼうとは思ってもいなかった自分が、
GCI、マナビDXを経験して、E資格を受験してみようと決意するに至った経緯を起承転結の流れで思いつくままにまとめます。

０.マナビDXQuestとは
　マナビDXQuestは、経産省と情報処理推進機構が主催する人材育成プログラムです。
  　このプログラムの目的は、デジタル人材の育成と、中小・零細企業のDX化、の二つとされています。
 
 経済産業省　「マナビDX Quest」について
 https://www.meti.go.jp/policy/it_policy/jinzai/manabi-dx-quest.html

  　運営はBCG、学習コンテンツはSignateが提供しています。
   受講生は、最初の１ヶ月でSignateのオンラインコンテンツでAI技術について学ぶことができます。その後の２ヶ月間は、PBLと呼ばれる架空のビジネス課題に対してITコンサルタントの立場でPoC（Proof of Concept）を顧客に提案する、という課題に取り組みます。課題の山場は、顧客課題解決策のためのAIモデル実装と顧客経営者へのプレゼン資料作成です。

１.起
　きっかけは、純粋にPythonへの興味でした。
 
　 大学院で光半導体の電磁界シミュレーションをやっていた時期があるのですが、学部で習っていたC++を使うのかと思いきや、Fortranという古いプログラミング言語を使うことに。FortranもC++も可読性が高いとは感じなかったし、当時のプログラミングの教科書やオンラインの学習コンテンツに良質なものも無く、興味を失った経験があります。
　就職後は、主にexcelやaccessをVBAで動かして100万件程度のデータ分析をする経験をし、データ分析の面白さを知ったのですが、VBAもまた、可読性が高い言語ではなかったので深く学ぼうとは思わなかった。

 表１　各プログラミング言語の特徴比較(ChatGPT4により生成)
![231217_qiita_1st_図1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3624429/3564d536-ca36-bc4d-0b9d-e098ca5a410e.png)


　そんな中、Pythonの可読性の高さ、ライブラリの豊富さ、等をNewsや友人からの情報で知り、好奇心を持ちました。
 
２.承(2023/4~2023/7)
　　東大松尾研のメタバース講座の一つであるGCI２０２３_Summerへの参加について社内公募があり、申し込んだところ参加できることになりました。全15回、４ヶ月間の質の高い講義のおかげで、知的興奮を感じ続けながら学ぶことができ、初級レベルの機械学習を難なく扱えるようになりました。

  GCIの良いところ
 ・中学生〜社会人（含む、育休取得中の方、失業中の方）まで、年齢も10代〜60代まで色々な方が受講している。
 ・年々参加者を倍増させていて、松尾教授はこのまま倍増させる構想のようだった。　　
 ・前年の優秀修了生を中心にしたTA（Teaching Assistant）が１０〜２０人いて、その方達が週数回、slackで1時間程度のオフィスアワーを開催してくれる。そこでは、授業内容に関する質問、お勧めの参考書籍、コンペの攻略方法、最終課題の取り組み方などをQ&A式に回答してくれる。


 あるオフィスアワーで、GCI修了後の学習の進め方について相談したところ、E資格とマナビDXクエストをTAから紹介されました。E資格合格レベルとGCI修了レベルの距離感をTAに聞いてみたところ、GCI修了レベルはE資格出題範囲の2/3をカバーしているので、残り1/3＝深層学習を身につければ合格するという、分かりやすい目安を示してもらえたので、チャレンジすることを決めました。

 マナビDXクエストは、Signateのオンライン講座を無料で受講でき、画像認識に関する深層学習を勉強できる点と、地域の中小企業のDX化のお手伝いができる点が魅力で、参加を決めました。
 
３.転(2023/8~2023/10)
　マナビDXクエストに２０２３年から8月から参加。終えてみた感想としては、PBLが楽しかったです。眠くなってきたので、良いところと改善して欲しいところを箇条書きして、本稿を締めくくりたいと思います。

良いところ
・受講生はほぼ社会人で、住所、職業、年代、性別、動機、が多種多様で興味深かったです。ソフトウェア開発会社のプログラマ、中小企業のSE、自然言語の研究者、などなど。普段の人生では関わることができなかったであろう方達なので、時間が許せば11月からの中小企業のDX化にも参加したかった。
・Signate　Cloudの無料講座は内容が充実しています。デジタルスキル標準別、AI技術の分野別、などの括りで、多様な講座が公開されていて、すべて無料で受講できます。
・PoCの課題については、課題発掘〜AIモデル構築〜中期計画立案までベースラインは提案してもらえるので、時間がなければ、そのベースラインを改善して提出することも可能です。２ヶ月弱でPoCをやるのは時間的にきついので、ベースラインが示された点はすごく助かりました。（GCIの最終課題では基本的に自分で１から考える必要があり、１ヶ月という期間の短さもあり、より厳しかったです。）
・Slack上で受講生の投稿が活発な点。色んな外部イベントのアナウンス、自主的な勉強企画のアナウンスなど。

改善して欲しいところ
・Slackの情報整理をして欲しい。特に初期の頃は新規投稿が多過ぎて、運営のアナウンスを見落としそうになったことが何度もあった。
・受講に関する各種説明会の時間が長時間（4時間とか）が長いものが結構ありました。半日潰れるような説明会はどうかと思いました。長くても2時間くらいに、短くできないでしょうか。

不満に思う点は上記2点ぐらいで、全体としては非常に良くできた学習プログラムだと思います。

４.結
　現在、E資格合格目指して勉強中です。
 仕事しながら100時間/月のペースで勉強していますが、苦になりません。
 E資格に合格したら、来年のマナビDXクエストに参加し、今度は企業のDX化にも参加します！
 
 
以上！
テスト駆動開発をサポートする pytest

## テスト自動化の便利さ

最近、テスト自動化の重要性と便利さを実感しています。特に、Pythonのテストフレームワークであるpytestは非常に使いやすく、素晴らしい機能を備えています。私は最近、オレオレFS（自作ファイルシステム）の動作確認のためにpytestを使ってみました。その結果、とても良い印象を持ちました。

# pytest
pytestの特徴の一つは、fixtureと呼ばれる機能です。fixtureを使うと、テストケースの中で頻繁に行われる面倒な手続きをまとめて実行することができます。例えば、マウント周りの手続きなど、環境構築の一部をfixtureにまとめることで、テストケースのシンプルさと可読性を向上させることができます。

このpytestの使いやすさと他の言語との相性の良さについても考えました。同様の薄いテストツールとしておすすめできるものがあれば知りたいと思っています。

# Sample
以下は、FIFO（named pipe）ファイルをCOW（Copy-On-Write）して読み書きできるかを確認するテストコードの一部です。関数の引数を見てpytestが自動的に値を渡してくれることも、fixtureの一部です。

```python
import pytest

@pytest.fixture
def needs_to_be_root():
    if not is_root_user():
        pytest.skip("Rootユーザーでないため、テストをスキップします")

def test_fifo_file_rw(needs_to_be_root):
    # テストコードの実装
    pass
```

さらに、私は最近、テストを実行するユーザーがrootユーザーである必要がある場合に、テストをスキップするためのfixtureを追加しました（needs_to_be_root）。これにより、rootユーザー以外の場合にテストがスキップされるようになります。とても簡単で便利です。

# テスト自動化のススメ
テスト自動化は開発作業を効率化し、品質を向上させるために欠かせないものです。pytestのような優れたツールを駆使して、テストフローの自動化を進めていきましょう。効果的なテスト自動化は、開発チーム全体の生産性を向上させる一助となることでしょう。

# 最後に
最近の私のテスト自動化の体験および考えでした。これからもテスト自動化に取り組みながら、より優れた開発プロセスを構築していきたいと思います。
ベイビーステップで学ぶマップリストの値の操作④ -Enum.filterの紹介

こんにちは！
プログラミング未経験文系出身、Elixirの国に迷い込んだ？！見習いアルケミストのaliceと申します。
今回はマップリストの要素を検索する方法を学びましたのでまとめます。

# 目次
1.[Ectoスキーマからパターンマッチを使用してパラメータを取り出す](https://qiita.com/Alicesky2127/items/480816252525e9ae45ed)
2.[Ectoスキーマからパラメータを取り出して更新する(iex内のみ)](https://qiita.com/Alicesky2127/items/13a3edbf441256054a3b)
3.[Enum.mapの紹介](https://qiita.com/Alicesky2127/items/34c751267a254522bae6)
4.Enum.filterの紹介(本記事)
5.[String.contains?の紹介](https://qiita.com/Alicesky2127/items/ca81efcf8cca6907364a)
6.[Enum.intoの紹介](https://qiita.com/Alicesky2127/items/b399d2a6dde4f4129ece)
7.[Map.putの紹介](https://qiita.com/Alicesky2127/items/4700d913c6df3b81a1a5)
8.[(番外編)元データがマップ→リスト→マップのもう一段深い入れ子構造だったらどうするか？(Map.getの紹介)](https://qiita.com/Alicesky2127/items/23c8d9ed8d47c22fd6aa)


# 目的
リストの要素がマップ(あるいはその逆)になっている場合に値を取り出して操作できるようになりたい。

## 実行環境
Windows 11 ＋ WSL2 ＋ Ubuntu 22.04
Elixir v1.14.3
Erlang v26.0.2
Phoenix v1.7.10

# 今回やりたいこと
前回、元データからEnum.mapで`:id`と`name`だけを取り出した下記の状態から、検索ができるようになりたい。
```diff_elixir:iex
results = users |> Enum.map(&{&1.id, &1.name})
[{1, "hogehoge"}, {4, "fugafuga"}, {5, "piyopiyo"}]
```

# Enum.filterとは
要素を一つずつ取り出して条件に合ったものだけ取り出す

https://hexdocs.pm/elixir/main/Enum.html#filter/2

```diff_elixir:iex
Enum.filter(results, fn {id, _name} -> id == 5 end) 
[{5, "piyopiyo"}]
```

Enum.filterの中の`fn {id, _name} -> id == 5 end`の部分が検索条件になるので、この部分を文字列検索する関数に置き換えればよいということが分かりますね。

## (途中経過)元データからここまでをパイプでつなげる
```diff_elixir:iex
users
|> Enum.map(&{&1.id, &1.name})
|> Enum.filter(fn {id, _name} -> id == 5 end)          
[{5, "piyopiyo"}]
```

次回はEnum.filterの検索条件に関数を入れて文字列検索をしてみたいと思います。

# ～Elixirの国のご案内～
↓Elixirって何ぞや？と思ったらこちらもどぞ。Elixirは先端のアレコレをだいたい全部できちゃいます:laughing::sparkles::sparkles:

https://qiita.com/piacerex/items/09876caa1e17169ec5e1

↓ゼロからElixirを始めるなら「エリクサーチ」がおすすめ！私もエンジニア未経験から学習中です。

https://elixir-lang.info/topics/entry_column


↓[We Are The Alchemists, my friends!:bouquet:](https://qiita.com/torifukukaiou/items/6bcd5bbb80df9e594e9e "Awesome-san's Awesome article")[^10]
Elixirコミュニティは本当に優しくて温かい人たちばかり！
私が挫折せずにいられるのもこの恵まれた環境のおかげです。
まずは気軽にコミュニティを訪れてみてください。[^11]


https://speakerdeck.com/elijo/elixirkomiyunitei-falsebu-kifang-guo-nei-onrainbian




[^10]: @torifukukaiouさんのAwesomeな名言をお借りしました。Elixirコミュニティを一言で表すと、これに尽きます。


[^11]: @kn339264さんの素敵なスライドをお借りしました。Elixirコミュニティはいろんな形で活動中！
【Qiitaで使用しているルールも紹介】textlintおすすめルールまとめ 

この記事は、[Qiita株式会社のカレンダー | Advent Calendar 2023 - Qiita](https://qiita.com/advent-calendar/2023/qiita-inc)の13日目の記事です。

https://qiita.com/advent-calendar/2023/qiita-inc

---

## はじめに
`textlint`について、皆さんはご存知ですか?
実はQiitaのエディタ機能(ベータ版)でも、使用されています!

今回は、`textlint`のおすすめのルールとQiitaで使用されているものも
一部公開していこうと思います!


### textlintとは?
以下公式より
>textlint is an open source text linting utility written in JavaScript. It is hard to lint natural language texts, but we try to resolve this issue by pluggable approach.

簡単に説明します。
textlint(テキストリント)とは、Javascriptで書かれたOSSのことで校正ルールにもとづいて文章校正を行うことができるライブラリです。

また、**ルールを自作したり**既に **公開されているルール** と組み合わることによって
独自のルールセットを作成することができます!

## 導入方法
今回は設定ファイルを用いた方法を説明します。

1.プロジェクトのディレクトリでnpm の初期化処理を行います。
```
npm init --yes
```

2.初期が完了した後に、textlintのインストールを行います。
```
npm install textlint
```

3.使用するルールのインストール
今回は、同じ助詞が連続して出てくるのか確認するルールを追加します!

```
npm install textlint-rule-no-doubled-joshi
```

4.extlintの設定ファイルの作成

`.textlintrc`という名前の設定ファイルを作成します。

```
npx textlint --init
```

上記のコマンドか直接作成してください。
そして以下のようにルールを追記します。

```json
{
  "rules": {
      "no-doubled-joshi": true,
  }
}
```

5.textlintを実行する

```
npx textlint [ファイルやパス]
```

これで、指定したルールに基づいて文章チェックを行うことができます！


## Qiitaのエディタで使用されているルール

Qiitaのエディタで使用されているルールについて、
一部紹介します！

### [textlint\-rule\-no\-doubled\-joshi](https://github.com/textlint-ja/textlint-rule-no-doubled-joshi)

1つの文中に同じ助詞が連続して出てくるかの確認してくれるルールです。
文中で同じ助詞が連続していると、読み難くなりますがそれをチェックしてくれます!

![スクリーンショット 2023-12-11 23.56.17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/636995/b54e6e35-c584-7696-e0ac-3d03b0db04c7.png)

### [textlint\-rule\-aws\-service\-name](https://github.com/bun913/textlint-rule-aws-service-name)

AWSのサービス名を確認してくれるルールです!
以下のように表記揺れをチェックしてくれます！

![スクリーンショット 2023-12-12 1.33.34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/636995/c33da5a7-f291-8252-6eb1-c68c89ac3bd8.png)

直近でルールを追加したので、何が追加されたか気になる人はこちらを見てください！

https://qiita.com/release-notes/2023-12-08

## おすすめtextlintルール3選!

### [textlint\-rule\-ja\-unnatural\-alphabet](https://github.com/textlint-ja/textlint-rule-ja-unnatural-alphabet)
不自然なアルファベットを検知してくれるルールです！
IMEの入力ミスによるtypoを見つけくれます。

```
OK
リリース
aiueo

NG
リイr−ス
対応でｋない
```

### [textlint\-rule\-ja\-no\-redundant\-expression](https://github.com/textlint-ja/textlint-rule-ja-no-redundant-expression)
冗長な表現を禁止するルールです！
「であると考えている→である」のように無い方が良い、無くても良いものを
省き文章をわかりやすくしてくれます！

```
OK
である
できる

NG
であると考えている
することができる
```


### [textlint-ja/textlint-rule-preset-ja-technical-writing](https://github.com/textlint-ja/textlint-rule-preset-ja-technical-writing)
技術文書向けのtextlintルールプリセットになります。

これは、単一のルールではありませんが複数のルールを組み合わせたもの(プリセット)になります。
エディタ上で固めの技術書を書く方にはおすすめです!


## おわりに
今回はtextlintの導入手順、Qiitaで使用されているルール、自分的なおすすめを紹介していきました！
textlintは開発する際のルールもそうですしQiitaのエディタにように
ユーザーに提供する機能にも活用することができます！

また、提供されているルールに要件を満たすものがなければ**ルールの自作**も行うことができます。

今回の記事が参考になれば幸いです。

## 参考資料
https://textlint.github.io/

https://github.com/textlint/textlint/wiki/Collection-of-textlint-rule