OmniAICreator/Qiita-1.07M huggingface dataset:
Stripe AppsにWebGLを載せてみた

こちらは [JP_Stripes Advent Calendar 2022](https://adventar.org/calendars/7823) の12月18日分のエントリーです。

# はじめに

まずはぜひデモ動画からご覧ください。
![stripe-webgl-demo.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2282314/4b0dce2b-8a6c-6839-e8ab-ae4d0692e386.gif)
キレイなキューブが60fpsでヌルヌル動きます。マウスでも操作が可能です。ソースコードは GitHub に公開しています。

https://github.com/falken42/stripe-apps-webgl

# Stripe Appsとは

Stripeダッシュボードの中で表示されるカスタムUIの拡張機能がStripeアプリです。Stripe APIとWebhookを使用することで、データを可視化したり、独自のサービスと連携したりすることが可能です。

アプリはReactで作られているので、TypeScriptでコードを書きます。

アプリの作り方についてもっと詳しく知りたい方はぜひ @hideokamoto さんの [Stripe Apps を25日間紹介し続ける Advent Calendar 2022](https://qiita.com/advent-calendar/2022/stripe-apps) を読んでみてください。

# WebGLとの連携・仕組み

Stripeアプリはセキュリティのため、サンドボックスされた `iframe` で表示されます。DOMには直接アクセスできず、WebGLのコンテキストでGPUからの出力は表示できません。

ただ、GPUの出力をバッファーにキャプチャーすることは可能（リアルタイムでテクスチャ生成など）なので、キャプチャーされた画像データをCPU側のメモリに戻し、以下のdataURLの様にエンコードすることで静止画像として表示することは可能です。

```php
data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAASAAAAEgCAYAAAAUg66AAAAAAX...
```

そしてみんな大好きThree.jsがこのレンダリング出力からdataURLのエンコードまでの流れを既に対応しています。とてもありがたいことです。

https://github.com/mrdoob/three.js/

Stripeアプリの `Img` の画像表示するコンポーネントは `src` 属性にdataURLをそのまま渡せるので、Reactのstateでレンダリング出力のdataURL文字列を保存することで、基本のレンダリングループが簡単に出来上がります。

```react
const ThreeJS = () => {
	const [renderOutput, setRenderOutput] = useState('');

	useEffect(() => {
		renderer.setAnimationLoop((time) => {
			// ...update scene here...
			renderer.render(scene, camera);
			setRenderOutput(renderer.domElement.toDataURL());
		});
	}, []);

	return (
		<Img width={width} height={height} src={renderOutput} />
	);
}
```

# マウスからの入力

DOMに直接アクセスがないなので、`MouseEvent` にローカル座標の `offsetX` / `offsetY` が無く、`clientX` / `clientY` の絶対座標をコンポーネントのローカル座標にどう変換すればいいかという情報すら取得ができないらしい。

（※ React用の `ref` を使ったり、 `getBoundingClientRect()` などで結構色々と苦労したのですが、もし誰かが解決方法がご存じでしたら、ぜひ教えてください！）

一応仮の解決方法として、画像のサイズ ( `width` と `height` は指定してる）は分かるし、`MouseEvent` を取得する際はマウスが `Img` コンポーネントに確実に入ってる時のみになるので、マウス座標を取得する際はコンポーネントのエリアを自動的に調整し、ユーザーがマウスを動かすことで正確なバウンディングボックスが認識されるようになります。

```react
const mx = evt.clientX;
const my = evt.clientY;

// update sliding bounds window based on input coordinates
if ((mx < bound.x1) || (my < bound.y1)) {
	bound.x1 = Math.min(mx, bound.x1);
	bound.y1 = Math.min(my, bound.y1);
	bound.x2 = bound.x1 + width;
	bound.y2 = bound.y1 + height;
} else if ((mx > bound.x2) || (my > bound.y2)) {
	bound.x2 = Math.max(mx, bound.x2);
	bound.y2 = Math.max(my, bound.y2);
	bound.x1 = bound.x2 - width;
	bound.y1 = bound.y2 - height;
}
```

あとはマウスの座標を正規化することで、X/Yの位置はコンポーネントの中で [0.0 .. 1.0] に変換されます。

```react
// convert mouse coords to local normalized space
const mouseState = {
    pos: {
        x: (mx - bounds.x1) / width,
        y: (my - bounds.y1) / height
    },
    buttons: evt.buttons
};

props.onMouseEvent(mouseState);
```

なお、絶対座標が正確ではなくても、今回のデモのように相対座標を利用すれば、正常の動きは取れます。

# 今後の進展

3Dデータの可視化はWebGLがかなり良いなので、Stripe Appsには結構使えそうですね。

現状は本当にシンプルなプロトタイプなもんですが、あとはキーボード入力とか、もっとクオリティが高いのシーンを表示したりしたいと思います！
この記事を参考にして成績が下がっても私は一切の責任を負いません

# はじめに

これは[鈴鹿高専 Advent Calendar 2022](https://qiita.com/advent-calendar/2022/snct)の18日目の記事です。

# 自己紹介

SNCT電子情報科3年、ぴちぴちのJK(Jouhouka Kousensei)です♡
バレーボール部に所属しています。

# 勉強方法

私がテストを乗り越えるために意識していることは4つです。

- 授業中は授業を受けること。
`理解`が出来ない、つまらない、麻雀など色々な理由で話を聞かなくても結局テスト前に後悔することになるので、授業中にさらっとでも聞いておくことでテスト前の復習が楽になります。高専教員がどれだけ教えるのが下手でも、自分一人で勉強するよりはその道のプロである先生の話を少しでも聞いたほうが`理解`しやすくなると思います。

- 復習をすること。
毎日家に帰ってからその日の`授業`を復習出来ればそれに越したことはないですが、無理なのでとりあえず課題を自分で考えてしたり、`授業`前に前回は何したかを確認したり出来ることをしています。テスト前に総復習をする時は板書などを見て`授業`中に先生が言っていたことを思い出し、その先生が欲しい答え方を考えます。

- 睡眠を取ること。
テスト期間中は魔剤をキメている人をよく見ますが、夜遅くまで勉強しても`睡眠`を取らないと記憶は定着しないとよく聞くので効果は薄いと思います。更に`睡眠`不足が原因で授業中に寝てしまったら本末転倒です。テスト前日は不安になりますがひと通り復習したらしっかりと`睡眠`を取り良いコンディションでテストを受けるようにしています。私の前の人は徹夜して勉強したと言って計算ミスを連発していました。

- 理解すること。
授業や課題で分からない`問題`、自分の中で納得がいかない`問題`があれば放置せずに理解するまで考えるようにしています。調べたり、わかる人に聞いたりして自分で理解できると記憶に残りやすいと思います。解けない`問題`をそのままにしておくとテストで出たとき絶対に後悔するので

ここまで私が意識していることを書きましたが、`勉強`法は人によって合う合わないがあるので自分に合ったものを探してください。`勉強`は正しくすれば点数が上がるので、伸び悩んでいる人は思い切って`勉強`法を変えてみてもいいかもしれませんね。

<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>

`理解` `理解`　`授業` `授業` `授業`　`睡眠` `睡眠` `睡眠`　`問題` `問題` `問題`　`勉強` `勉強` `勉強`


**四暗刻**

# 高専生活

私は3年なので5年間の高専生活の半分がもう終わってしまいました。そんな高専生活で私が見つけた趣味について話そうと思います。
その趣味というのは女装です。昔から「かっこいい」言われるより「かわいい」と言われるほうが多く自分でもそう思っていました。
今年の高専祭でたくさんの人と話して、ジェンダーに対する考え方を変えていこうという流れは確実に来ているんだなと思いました。

**女装は男にしかできないから最も男らしい行為の一つ**


# おわりに

すいませんでした。
部活のことを書くと愚痴になってしまったのでやめました。
拙い文章でしたが、最後まで読んでいただきありがとうございました。
『システム運用アンチパターン』の輪読会が結構うまく回った話

これは [SRE Advent Calendar 2022](https://qiita.com/advent-calendar/2022/sre) 18日目のエントリです。

## はじめに

どうも、SREをしている@toro_ponzです。今回は今年オライリーから発売された『[システム運用アンチパターン](https://www.oreilly.co.jp/books/9784873119847/)』がとても良書だったのでその紹介も兼ねて、実施した輪読会について触れられればと思います。
4月発売なので今更、という感じかもしれませんが今年を振り返ると言う意味も込めて。

## 形式

本書は発売する前から気になっていたのですが、発売後にも良書らしいとの噂を伺ったので、目次だけざっと見て所属するSREチームでの輪読会を提案しました。
私自身ちゃんとした輪読会というものを今まで経験したことがなかったということもあり、かなり探り探りの実施でしたが、できるだけ意味のあるものにすることを意識していました。
ざっくり形式は下記の通りです。

- 隔週開催、30分
- 1回につき一つの章
- 各人好きな章を選び、実施までにスライドにまとめておく
- 前半はLT、後半はそれを聞いての議論
- 可能であれば具体的なアクションに落とし込む

輪読会と言っていますが、実際の実施時間には全員で黙って読む時間は取りませんでした。書籍をぱらぱらとめくりながらLTを聞く形式です。

## 良かった点

### 1. チームの現状にマッチした内容だった

輪読会実施においていくつかの書籍候補があったのですが、この本を選んで良かったなと感じています。一言で表すと **チームの現在の状態にマッチした内容だったから** です。

本書は各章ごとにシステム開発および運用に関係するアンチパターンを上げながら、それを解決する手法としてDevOpsの観点を織り交ぜて言及しています。GoogleのSRE本などが **理想論** 的な本であるとするならば、この本はかなり **足元の泥臭い点** に目を向けた書籍です。わたしたちSREチームも各種理想論・ベストプラクティスを追い求め日々業務をしていますが、足元の課題が見えてないことに輪読会を通じて気づくこともいくつかありました。

具体的には **第10章「情報のため込み：ブレントだけが知っている」** を読んで、「確かに誰が何に詳しいか正確にわかっていない部分もあるので、可視化しよう」となったりしました。メルカリではスキルマップと呼ばれるものがあるみたいです。参考にしたい。
https://engineering.mercari.com/blog/entry/20221104-souzoh-skill-map/

理想論的な書籍でも悪くないとは思うのですが、実際の業務内容や目標に則していた方が業務時間を割く意義も高いですし、初回の選定書籍としてはとても良かったと思っています。

### 2. 各章ごとに独立した構成だった

本書は基本的にどの章から読んでもある程度内容がわかるようになっていて、1章から順番に読み進めなくても良い形式になっています。各人が好きな章を選び好きな順番で話すことができました。特に今回は担当者が事前に読んで資料化する輪読会だったため、この構成はかなり相性が良かったです。輪読会向きの書籍でした。

むしろ連続した書籍の場合はどのように進めるのが良いのでしょう。コメントお待ちしています。

### 3. SREチーム外にも共有できる章があった

我々のSREチームはいわゆる **プロダクトSRE** 的な側面が強いチームで、サーバーサイドエンジニアやWeb/アプリエンジニアに各種DevOpsの知見共有をし、組織全体の文化醸成を推し進めることも重要な業務の一つです。本書はSREに特化した書籍ではないため、私たちSREチームだけの知見にするには勿体無い章および資料もいくつかありました。そういった内容についてはより広い会議体でLTをし、知見共有することができました。

具体的には **第2章「パターナリスト症候群」** の「2-1. 安全装置ではなく障壁を作ってしまう」で言及されている **歴史的経緯によって承認プロセスは増え続けるがそのほとんどは形骸化して意味を成していない** 点などについて開発責任者を含めて議論をし、実際に無駄な承認プロセスを減らすことに繋がりました。

それ以外にも、テストについて書かれた **第5章「最後の味付けとしての品質」** やデプロイ頻度等に言及した **第8章「業務時間外のデプロイ」** などもチーム外に共有し議論に役立てました。

### 4. ネクストアクションに落とし込むまでを輪読会にした

全ての会ではありませんが、議論を踏まえて実際に改善が行われたものもありました。輪読会がただの自己満足で終わらないようにちゃんと議論から集約する時間も必要だと感じました。
担当者が事前に「議論したい点」を議事録に書いていたり、参加者LTを聞きながら追記したりして議論したのち、実際の業務で改善できる箇所がないか顧みました。足元のケーススタディが多い本書だからこそうまく回ったと考えていますが、次回以降にもうまく活かせるようにしたいです。

## 改善点

ここからは改善点ですがあまり大した内容でもないので箇条書きで。

- 実施時間
  - 30分だと短い場合があった、特にネクストアクションを話し合う時間が少ない
  - とはいえ1時間だと時間が余ること必死な気もするので要検討
- 実施されないネクストアクション
  - これしたいね、で終わっているものもちらほらあった
  - ポストモーテムのアクションと同じように、タスクトラッキングツールで継続的に追うことを検討

## 総評

『システム運用アンチパターン』自体は多くのエンジニアに読んでほしいものですが、文化醸成を担うSRE、特に私と同じ **プロダクトSRE** の皆様には是非読んでほしい一冊です。特に **第11章「命じられた文化」** は必読です。組織における価値観・指針の重要性のみならず文化醸成のための採用にまで言及されており、目から鱗と感じるのと同時に文化醸成は一筋縄ではいかないという現実も知ることができます。

また、輪読会についてはかなり初回にしてはうまく回ったかな、と思っています。改善点もいろいろ見つかりましたので、それを踏まえて次回につなげて輪読会文化を醸成したいところです。次の輪読会で読む本はまだ決まっていませんが、『SREの探求』や『チームトポロジー』なども視野に検討中です。もしオススメの書籍などござましたらコメントいただけると幸いです。
Azure Site Recovery

●Azure Site Recovery
レプリケーションサービス。

・あるリージョンのAzure仮想マシンをベルのリージョンへ
・オンプレミスで実行されるVMware仮想マシン、Hyper-V仮想マシン、物理サーバーをAzureへ
・AWSで実行されるWindowsインスタンスをAzureへ

「あるリージョンのAzure仮想マシンを別のリージョンへ：というシナリオが最も一般的なシナリオ。

●Azure BackupとAzure Site Recoveryの違い
Azure Backupでも、あるリージョンにバックアップしたデータを別のリージョンにコピーすること自体は可能、だがバックアップデータからの復元には時間がかかる。
つまり、Azure BackupはRTO(目標復旧時間)が長い。また、Azure BackupはAzure仮想マシンのバックアップを1日1回しか実行できない。タイミングが悪いとRPO(目標復旧時点)も長くなる。
Azure Site Recoveryでは、フェールオーバーにより、セカンダリリージョンにレプリケーションされたデータから仮想マシンを作成して速やかに再開できる。また、5分ごとにクラッシュ性合成復旧ポイントが自動的に作成されるため、障害の直前の状態まで復旧することができる。
社内システムでDXCriteriaを一部取り入れてみた

早くも2022年も12月に入りましたね。
SLAM DUNKの劇場版を見ました。当時の想いがこみ上げてきて大興奮。本当に良かったです。
見ていない方は是非！もう一度見てみたいと思ってます。

さてこれまで社内システムに関して記事を投稿してきましたが、今回は日本CTO協会が監修している企業のデジタル化及びソフトウェア活用のためのガイドラインである **DX Criteria** のシステムの一部を取り組んでみたので紹介します。

過去の社内システムでの記事はこちらです

https://qiita.com/nogu-rin/items/301ee04a9d5b4244e8c0

https://qiita.com/nogu-rin/items/b1b657449fd33ee1e666

# DX Criteriaとは？

以下DX Criteriaより抜粋したものです。
絶対的なものではなく、各組織やプロジェクトに併せてどのテーマのクライテリアから実施していくのかを進めていくほうが良いかと思います。

**本基準は、デジタル技術を企業が活用するために必要な要素を多角的かつ具体的に体系化したものです。ソフトウェアエンジニアリング組織の健全な成長・経営目標の可視化・パートナーとのコミュニケーションなどに使っていただくことを目的に作成されています。**

**また、本基準は絶対ではありません。誰かを攻撃したり、アセスメント結果の数字のみに注目して本質的な改善をおろそかにするためのものではありません。極めて実践的で具体的な項目で構成されているため、定期的に最新動向に併せてCTO協会のWG内で議論をおこないながら、適宜アップデートをしていくものです。**

# 取り組むことになったきっかけ

弊社が日本CTO協会の法人会員となっており、弊社CTOからの紹介で取り組むことになりました。
特に**システム**というテーマの中でも取り組むべき項目が色々あり、
社内システムのプロジェクトでも取り組むべきものがいっぱいあるので1つずつ潰していこうということになりました。

# 取り組んだ内容

取り組むとなっても、5つもテーマがあり、1つのテーマにも64項目もあるためまずは何からすればよいのか。。。

### 現状を知る！
まずは、DXCriteriaのアセスメントシートから**システム**というテーマ内のクライテリアを
社内システムの各メンバーに回答してもらい、現状を知るということから始めました。
各メンバーでクライテリアの項目ごとに感じていることが異なっていました。

### 改善項目を開発チームで合意する！
各メンバーに回答してもらったものから、開発チーム内で改善すべき項目を投票、合意した上で進めることになりました。
通常のタスクもある中なので、2項目に絞り込み、それぞれの改善項目のオーナーを決めました。
また期限は2ヶ月とし、2ヶ月後に改善項目
以下が改善項目の2つです。

- [SYSTEM-2-2 デッドコードを四半期以上のサイクルで定期的に棚卸しし、削除や分解をしているか。](https://dxcriteria.cto-a.org/da91d9c5fd894fe78243412ca7624adb)
- [SYSTEM-4-6 デプロイされたコードに問題が発生した際に、前のバージョンへの切り戻しを意思決定してから5分以内に切り戻すことができない。](https://dxcriteria.cto-a.org/17943d79c21842c2877065251a1e68c1)

### 改善項目の取り組み
期間は約2ヶ月とし、取り組む内容のオーナー含めて週次で進捗MTGを重ねて進めました。

改善項目の内容は以下となります。

- SYSTEM-2-2 デッドコードを四半期以上のサイクルで定期的に棚卸しし、削除や分解をしているか。
    - フォルダやファイルのステップ数の測定をIntelliJのプラグインの[Statistic](https://plugins.jetbrains.com/plugin/4509-statistic)で行う
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/605889/07d44482-ecfa-f870-3305-0e515bf45068.png)
    - デッドコードの検出方法は、IntelliJのインスペクションを利用し洗い出すを行う
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/605889/c213833d-b645-3364-d064-a9753df7f651.png)
    - 検出したものを**Unused declaration**で確認し、デッドコードを削除する
    - デッドコードの削除後、ローカルで動作確認する

- SYSTEM-4-6 デプロイされたコードに問題が発生した際に、前のバージョンへの切り戻しを意思決定してから5分以内に切り戻すことができない。
    - 検討した結果、社内システム上では5分以内にすることはできませんでした（以降の課題として認識）
        - 不具合発生時に不具合切り分けに時間がかかる
        - 前回バージョンへのデプロイにステージング環境などでの動作確認など含めて5分以上かかってしまう
    - 5分以内への切り戻しに近づけるため、以下のルールを決めた
        - リリース切り戻し時の意思決定のルールをリリース手順書に記載する
        - ロールバック用のSQLを毎リリース毎に作成し、切り戻し対応にいち早く実施可能とする
    - 以降のリリースで出てきた課題から改善を行っていく

# 取り組み後

デッドコードの削除に関しては第1四半期に少し遅れた実施し、リリース待ちの状態となりました。
まずは、影響の少ない画面・機能から実施することで、デッドコード削除後のリスクを極力へらすことにした。

リリース不具合の切り戻し対応は、5分以内にすることは難しいため、社内システムのアーキテクトやクラウド基盤のサービスなどの検証などを行い、即時切り戻しなどの対応を行っていく必要があると思います。
ただ今回の取り組みで、リリースまで、リリース時のルールを見直し、取りまとめることで大きくリスクを減らし、開発者とリリース担当者の認識をあわせることができました。

# まとめ

DXCriteriaの**システム**の中には他にも取り組むべき項目がまだまだあります。
すべてを改善することは難しいですが、ガイドラインにも記載されているとおり、デジタル技術を企業が活用するために体系化されたもので、システムの構造上必須の有無はわかれますが、とても重要な項目で様々な企業が活用できればと思っています。

社内システムだけではなく、弊社内の他案件にも横展開し、会社としてテンプレート化していければと考えています。まだまだ先は長いですが、継続して取り組むことが大切だなと思いました！
MATLAB グラフ 関連 Tips

[<B>MATLAB/Simulink Advent Calendar 2022</B>](https://qiita.com/advent-calendar/2022/matlab)に参加しました。


・使用ツール
<dt>　MATLAB</dt>
<br>

<H4><a href="https://note.com/leftbank/n/nbea5fb8193bf"</a> [<B>note</B>]にUpしました。</H4>
【フロントエンド】GraphQLを導入する時はGlobal Object Identificationを理解しよう

## はじめに

GraphQLを用いたフロントエンド開発は多くなってきているように思います。
フロントエンドから柔軟にデータを取ってくることができるということは、今までバックエンドが担保してきていた部分をフロントエンドが担わないといけなくなった

ということを意味します。
保守性をちゃんと考えないといけない。

ということですね。

今回はその中でも結構重要な、スキーマ定義についての話。

採用する、しないはどちらを選んでも大きな判断になるかと思いますが、知っておく必要はある知識かなと思います。

## スキーマとは？

スキーマというのはQuery（データの取得）やMutation（データの更新や削除）といったものを定義したものです。

この定義にそってフロントエンドから以下のようにクエリを書き、データの取得や更新を行っていく訳ですね。

```graphql
query {
  albums(limit:20) {
    title
    tracks (limit:2) {
      name
    }
  }
}
```

この定義ですが、適当に作り始める前に知っておいた方が良いことがあります。

`Global Object Identification`という概念です。

## `Global Object Identification`とは？

https://graphql.org/learn/global-object-identification/

全テーブルにおいてグローバルなID（NodeID）を発行し、キャッシュするようにしましょう。
と言う話です。

意味がわかりませんね。一つ一つ解説します。

### GraphQLのキャッシュとは？

RESTfulなAPIの場合、`https://smaple.com/api/items/5`のようにURLベースでデータに問い合わせにいったりしますね。

なので、このGETリクエストをURLベースでキャッシュをすることができたりします。
CDNにGETリクエストごとキャッシュしたりすることで、ユーザーに高速にレスポンスを返すんですね。

しかし、GraphQLはエンドポイントを一つしか持たないため、キャッシュを行うことができません。
なので、なんとかして別の方法でキャッシュしたい

という話です。

### どうやってやるのか？

URLベースでのキャッシュができないのであればどうするのか？

一度、アクセスしてくれたデータを何かをキーにしてオンメモリキャッシュに突っ込むことができればいい気がしますね。

その「**何かのキー**」というのに**全テーブルにおいてグローバルユニークなIDを使おう**ということです。

DBのレコードIDでいいじゃないか。と思われるかもしれませんが、usersテーブルとpostsテーブル、両方にid: 1は存在すると思います。
なので、全テーブルにおいてユニークなIDが必要なんです。

これを`Global Object Identification`ではNodeIDと表現しています。
全てのテーブル型定義において、`Node`というインターフェースを継承します。

```graphql
interface Node {
  # The ID of the object.
  id: ID!
}

type User implements Node {
  id: ID!
  # Full name
  name: String!
}
```

こうしておくことで、フロントエンドからすると、Userデータをフェッチした時にidが全テーブルにおいてユニークなIDが返ってくるので、データをリフェッチするときは以下のようにnodeIDでとって来ればキャッシュから返ってくる。
といった仕組みですね。

```graphql
query {
  node(id: nodeID) {
    users (limit:2) {
      name
    }
  }
}
```

### どう作るのか？

簡単に考えると`テーブル名:ID`みたいな形にすればいけそうですね。
ちゃんとやるのであれば、全テーブルでユニークなUUIDを振るみたいな方法もあります。

実はこれは結構大変。

だって、データを作成する時に全テーブルにおいてユニークな何かを保存しておかないといけないのだから、、

micro serviceみたいな構成にしていてデータベースが分かれている。
みたいな人たちはより大変ですね。

GraphQL Serverのレイヤーでうまく処理できるようにしていく必要があるかなと思います。

## まとめ

最初にもいった通り、Global Object Identificationの概念を取り入れるとリフェッチが効率化できたりします。

でも、作るのめちゃくちゃ大変だと思います。

チームで話し合ってやるのがいいかなと思います。
array_slice() で配列の一部を取得する(PHP)

## 概要
配列の一部が取得できます。
戻り値は取得した配列になります。

## 文法
```php
array_slice(array, offset, length, preserve_keys)
```
 [必須] array：入力配列
 [必須] offset：開始位置の指定
 [任意] length：開始位置からいくつ値を取得するか
 [任意] preserve_keys：キーを保存するか

## 使い方

```php
<?php

$input = ["a", "b", "c", "d", "e"];

$slicedList = array_slice($input, 2); 
print_r($slicedList); // Array ( [0] => c [1] => d [2] => e )

$slicedList = array_slice($input, 2, 2);
print_r($slicedList); // Array ( [0] => c [1] => d )

// 連想配列でも利用可能。
$input2 = [
    "input" => "test1",
    "input2" => "test2",
    "input3" => "test3",
];

$slicedList2 = array_slice($input2, 1);
print_r($slicedList2); // Array ( [input2] => test2 [input3] => test3 )
```

## 参考
https://www.php.net/manual/ja/function.array-slice.php
今更のContainer/Presentational Pattern

# 歴史を学ぼう

今更ながらContainer/PresentationalPatternに触れる機会がありまして、実際に触れていく中で色々とお気持ちなどなどを語りたく、記事にしてみました。

# 今更ながら学ぶContainer/Presentational Pattern

業務の中で、Container/Presentational Patternのデザインパターンで実装をしていたのですが、そもそもこのパターンが何なのか、何をモチベーションで使われているのかがいまいち理解できなかったのでちゃんと学んでみました。

# Container/Presentational Patternとは何か

1行で説明すると、**UI/ロジックの関心の分離をする**ことを目標にしたデザインパターンです。
UIを担う**Presentational**、UIを表示するために必要な要素を渡すための**Container**を置くことで、それぞれの関心を少なくすることができます。
詳しく説明していきましょう。

## Presentational

UIに関わるものに対しての機能を持ちます。
UIに関わらないことについては何も持ちません。データも自身では持たず、Propsで値をもらい、その値を加工することなく表示します。
※UIに関する状態、例えば開閉状態などであれば持つこともあります。

## Container

コンテナはアプリケーションのロジックを担当して、最終的にPresentationalコンポーネントで描画するためのデータを渡すことを目標にしています。

- APIの呼び出し
- 状態管理、例えばstoreへのアクセスなど
- Presentational層で使いやすいデータへの加工

などなど、ロジックに関わることであれば全てこの層で行います。
一方でUIについては何もしません。Presentationalコンポーネントをレンダリングするのみで、Containerではスタイルを含めてUIに関係するものを何も持ちません。

# Container/Presentational Patternは結局何を解決したのか

Container/Presentational　Patternが解決したのは責務を完全に切り分けるというところです。
FEで使われるフレームワークではUIとロジックを同一のファイルに配置することが可能です。
1ファイルでUI/ロジックについて書くことができる利便性がある一方、どちらも書けてしまうことで混沌としたコンポーネントともなりえます。
責務を完全に分けることで、デザイン面の修正であればPresentationalをいじれば良い、かつ、ロジックを含まないため誰でも変えうることができる。
ロジックであればContainerを修正すればよいとはっきりと責務が分かれることで実装などがスッキリします。
また、PresentationalはUIだけを示すので、再利用性も高めやすい（ロジックがContainerに依存するので、同様のUIであればContainerがデータを加工することで対応ができる）のも嬉しいです。

# 個人的に感じたポイント

ここからは個人的に感じたポイントについてお話しします。

## PresentationalとContainerを1対1にするべきかと言う問題

PresentationalとContainerを1つのコンポーネントに対して両方とも作るか、それともどちらかの分類とするかが難しいと思っています。
ロジックを綺麗に剥がせるのが1つ目のパターンです。そのUIに依存するロジックや状態がContainerを配置することで必ず全て剥がせるようになります。
ですが半端なContainerが生まれるため、UI層に当たるPresenterの再利用性は低まります。
では後者のコンポーネントを分類する方はどうかとなりますが、こちらはこちらでHooksがなければContainerがPresentationalに完全依存する実装を複数することになってしまったり、また、そもそも分類するのが難しいといった問題もあります。

## Hooksとの取り回しをどうするか

そもそも前提としてContainer/Presentational PatternはHooks前に生まれたパターンなのですが、HooksでもロジックとUIの関心の分離はできます。
ので、モチベーションがロジックとUIの関心の分離であればContainerはいらず、このデザインパターンにする必要はないです（とりわけ個人でやるプロジェクトなど小さい場合はファイル数を肥大させるだけかもしれないです）。
HooksでロジックとPrensentationalコンポーネントを分けることができるようになった一方で、HooksをPresentationalコンポーネントで呼び出すと、UIの再利用性が下がります（Propsとして受け取る方が再利用性が高まるので）。
うまい塩梅を考えないと、HooksとPresentationalコンポーネントが乱立し、ひたすらファイル数が肥大化する危険性もあります。

# まとめ

個人的には現代のFE、例えばReact/NextであればHooks、Vue/NuxtであればComposableのようにロジックの切り出し、再利用をできる状況なので、このパターンに囚われすぎる必要はないのかなと思っています。
（提唱者も「このパターンに固執するな」と言及していたりします。）
ですが、再利用性や疎結合といった概念を考えると、このデザインパターン自体はうまく使えば非常に優れる作りにできそうだなと思います。

# 最後に

こちらは[TLB Enjoy Developers Advent Calendar 2022](https://qiita.com/advent-calendar/2022/tlb-enjoy)の１７日目の記事になります。

明日は[@magatakohei](https://qiita.com/magatakohei)さんの記事になります。


## 参考
[参考：Presentational and Container Components](https://medium.com/@dan_abramov/smart-and-dumb-components-7ca2f9a7c7d0)
展示会や案件で役立つ！Nreal Lightを接続するだけでアプリを自動起動させる方法

:::note alert
本記事ではスマートグラスNreal Lightで使用する専用アプリNebulaのDeveloper Optionsについて言及します。このDeveloper Optionsは公式サポートの対象外であり、本記事の内容を実行した結果について筆者は一切サポートいたしかねます。また、筆者は本記事の内容を実施した事により発生したあらゆる損害についても、その責任を負う事をいたしません。本記事は、Nrealアプリケーション開発の知識を持ち、問題が発生した場合でも開発者サイトのドキュメントやフォーラム等を参照し自己解決できる方のみ、参考としてお読みください。
:::
# はじめに
Nreal Lightのアプリを開発をしていると、よく「スマホにNreal Lightを接続したらアプリを自動起動させたい！」という声を聞きます。確かに、展示会などでNreal Lightを初めて触る方に、Nebulaからアプリを立ち上げてもらうのは敷居が高いかもしれません。
そこでこの記事では、Nreal Lightを接続するだけでアプリが自動起動するようになる設定方法を解説します。
※Nebulaのインストールまでは割愛します。

# Developer Optionsの有効化方法
アプリを自動起動をさせるためには、Developer Optionsを有効にする必要があります。
まず、Nebulaを起動します。（今回はバージョン3.2.1を対象とします）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2961786/de57805d-5be6-bdac-9acf-68d16a418c33.png)
「自分」をタップしてアカウント画面に移動します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2961786/d179735e-a0f2-1eae-059d-fb4afc36ce37.png)
「もっと見る」をタップしてバージョン情報の画面に移動します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2961786/70e496c7-84de-fa20-b15e-cfa9dbbe5edf.png)
ここでNebulaのアイコンを10回連続で素早くタップすると、Developer Optionsが有効になります。
Androidの「開発者向けオプション」によく似ていますね。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2961786/cc4b01ec-9481-abc6-4d29-5b370238edec.png)

# 自動起動の設定
再びアカウント画面に戻ったら、今度は「設定」をタップして設定の画面に移動します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2961786/d179735e-a0f2-1eae-059d-fb4afc36ce37.png)
すると、一番下にDeveloper Optionsが表示されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2961786/488c493c-51eb-d32f-7bbb-d10180a9c919.png)
このDeveloper Optionsをタップすると、以下のような画面になります。
一番下の「Enter the MR package name and click Save」のテキストボックスに、自動起動させたいアプリのパッケージ名（例：com.hogehoge.app）を入力して、Saveボタンを押してください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2961786/6db4352f-bb3f-06b6-9e49-7bbf54e4767e.png)
設定を有効にするためには、Nebulaを一旦終了させて再起動してください。
これでスマートフォンにNreal Lightを接続すると、指定したアプリが自動起動するようになります。
もし自動起動が不要になった場合は、このテキストボックスを元のように空欄にしてSaveボタンを押せば、アプリは起動されなくなります。

# 最後に
どうか楽しいNrealライフを！
Unityにおけるnullチェック(4) - メモリリークを防ぐ

以下の続きの記事になります。

https://qiita.com/tanikura/items/b57f6b92371026307c0b?1

https://qiita.com/tanikura/items/69a5ac3b1491723e756b?1

https://qiita.com/tanikura/items/5debeb83530ea97508a1?1

# おさらい

* `UnityEngine.Object`では等値演算子`==`(及び非等値演算子`!=`)がオーバーロードされている
* オーバーロードされた等値演算子では`Object.CompareBaseObjects`メソッドに判定処理を委譲している

```CS
public static bool operator ==(Object x, Object y) => Object.CompareBaseObjects(x, y);

public static bool operator !=(Object x, Object y) => !Object.CompareBaseObjects(x, y);
```

* `Object.CompareBaseObjects`メソッド内では純粋な`null`チェックや`InstanceID`の等値判定に加えて、渡されたオブジェクトが「破棄」されていないか(Unityフレームワーク上で生存しているか)をチェックする`Object.IsNativeObjectAlive`メソッドが実行されている

* Destroy実行前後で、検証対象メソッドの戻り値は以下のように変化した(`UnityEngine.Object`に生えている静的な非公開メソッド)

|  | IsNativeObjectAlive | DoesObjectWithInstanceIDExist | GetCachedPtr |
| :-: | :-: | :-: | :-: |
| 破棄前 | true | true | インスタンス固有の値 |
| 破棄後 | false | false | 0 |

* 等値演算子`==`と`is`演算子は挙動が異なる

* `[UnityEngine.Objectを継承したクラスのインスタンス] is null`のように書いた場合、`is`演算子はそのインスタンスに本当に`null`が代入されているかを判断するため、既に破棄済みのインスタンスでも実際に`null`が代入されていなければ`false`を返す

# ガベージコレクション
Unityがスクリプト用の言語として標準的にサポートしているこのC#は、メモリ管理をガベージコレクション(GC)に任せるという仕様を持つ言語です。
GCの存在によって、私たちプログラマはメモリ管理に煩わされることが少なくなっています。
一方で、プログラマ(C#のユーザ)が任意のタイミングでメモリを解放することは仕様上できなくなっています。

## 参考
岩永さんという方が運営されているブログ「++C++;」の以下の記事は、C#のメモリ管理の基本的な概念を知る上でとても参考になります。

https://ufcpp.net/study/computer/MemoryManagement.html#garbage-collection

# メモリリーク

これまで検証した内容やC#のメモリ管理の仕様を踏まえて考えると、どのような場合にメモリリークを起こすか見当がつきます。
ポイントとしては、オブジェクトの破棄を行う`Destroy`が、C#のユーザ側がメモリ解放を自由にできないという仕様上、メモリ解放などは行わずにいわば破棄フラグを立てるような挙動を取るということです。

以下のようなテストコードを考えます。
```CS:SampleTest.cs
using UnityEngine;

public class SampleTest : MonoBehaviour
{
    private readonly SampleMonoBehaviour[] sampleMonoBehaviours = new SampleMonoBehaviour[10000];

    private void Start()
    {
        for (int i = 0; i < sampleMonoBehaviours.Length; i++)
        {
            sampleMonoBehaviours[i] = new GameObject($"Game Object {i}").AddComponent<SampleMonoBehaviour>();
            Destroy(sampleMonoBehaviours[i]);
        }
    }

    private void Update()
    {
        foreach (var sample in sampleMonoBehaviours)
        {
            Debug.Log(sample.GetName());
        }
    }
}
```

これは、破棄されたインスタンスの参照を保持して継続的にアクセスするというコードです。
使用した`SampleMonoBehaviour`の実装は特に関係はありませんが、以下に示しておきます。

```CS:SampleMonoBehaviour.cs
using UnityEngine;

public class SampleMonoBehaviour : MonoBehaviour
{
    private GameObject go;

    private void Awake()
    {
        // 破棄された後にgameObjectプロパティにアクセスするとMissingReferenceExceptionが発生するが
        // 破棄されるより前に参照をコピーしておけば例外は発生しない
        go = gameObject;
    }

    public string GetName()
    {
        return go.name;
    }
}
```

このコードを実行すると、SampleMonoBehaviourが破棄された後も参照が保持されて、`GetName`メソッドが呼び出され続けているということが確認できます。

![スクリーンショット 2022-12-17 235723.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2987563/f45ab0f4-4d75-e2ad-c284-aeb3ff4337a7.png)

このように破棄後も誰かが参照を保持し続けているとGCの収集対象にならずにインスタンスが生存し続けて、実質的なメモリリークを起こしてしまいます。
これを回避するには、`null`チェックを行った後は実際に`null`を代入するなどの対策が必要になります。
初めてのLua製Neovimプラグイン開発〜uhooi.nvim〜

## はじめに

本記事は [Vim Advent Calendar 2022](https://qiita.com/advent-calendar/2022/vim) の17日目の記事です。
昨日は @NI57721 さんで [Vimで古代ギリシア語【自作プラグインのすすめ】](https://qiita.com/NI57721/items/06fc78227faaea9bce90) でした。

初めてLua製のNeovimプラグインを開発したので紹介します。

## 環境

- OS：macOS Ventura 13.0.1
- Neovim：v0.8.1

## プラグインを開発したきっかけ

[社内のとあるVimmerがとある猫を回転させていた](https://github.com/delphinus/nekokak.nvim) のを見て、「これパクればウホーイも回転させられるんじゃね？」と思ったからです。（雑）

https://twitter.com/the_uhooi/status/1544264820827963392

当時はNeovimを使い始めたばかりで、Luaも全然わからなかった（今もあまりわかりませんが）ので、勉強がてら作ってみることにしました。

## 開発手順

### 参考にするリポジトリをフォークする

まず参考にするリポジトリをフォークしました。
基本的には画像を差し替えるだけなので、そのほうが手っ取り早かったからです。

### XPMファイルを作成する

回転させる画像は、XPMというフォーマットが採用されていました。

https://ja.wikipedia.org/wiki/XPM

作成方法がわからなかったのですが、調べたらImageMagickでGIFをXPMに変換できることがわかりました。

https://twitter.com/the_uhooi/status/1544283481454563328

無事にXPMファイルを作成できたので、手順を忘れないようにImageMagickの記事に追記しました。

https://qiita.com/uhooi/items/26b944f6908351d41bf2#convert-gif-to-xpm

いいね数は少ないですが、私はImageMagickを使うときによく見返します。

### 画像などを差し替える

文言や画像をとある猫からウホーイに差し替えます。

https://github.com/uhooi/uhooi.nvim/pull/1

### エラーを修正する

ビルドエラーが発生したので修正しました。

https://github.com/uhooi/uhooi.nvim/pull/2

本家でも発生するエラーだったので、PRを作成し、マージもされました。

https://github.com/delphinus/nekokak.nvim/pull/8

### 色を追加する

XPMファイルは色をカラーコードまたはカラーネームで指定するのですが、 `gray1` や `gray2` など、一部のカラーネームはそのままだと色が付きませんでした。
そのためカラーネームを手動でカラーコードに変換する処理を仕込みました。

https://github.com/uhooi/uhooi.nvim/pull/3

### 完成！

ウホーイがNeovim上で踊りました ₍₍⁽⁽└|▼▼|┐₎₎⁾⁾

https://twitter.com/the_uhooi/status/1544333476039901184

## おわりに

画像を差し替えてちょっとソースコードをいじっただけなので、そこまでLuaやNeovimプラグイン開発の勉強にはなりませんでしたが、楽しかったのでよかったです。

作ったのが半年くらい前なので、また何かしらLua製のNeovimプラグインを作りたいです。

以上 [Vim Advent Calendar 2022](https://qiita.com/advent-calendar/2022/vim) の17日目の記事でした。
明日は @uga-rosa さんで「えっ！NimでNeovim用プラグインを！？」です。
ipyleafletでbasemapの変更方法

foliumよりもインタラクティブな操作ができるけど、
ipyleaflet ドキュメントが探しにくい。

航空写真にするのにbasemapの変更方法がわかりにくいのでメモ。
(APIの一覧があっても使い方があまり書いてない気がする)

```python
import ipyleaflet
m = ipyleaflet.Map(center=(35.693406,139.749839), zoom=18, basemap=ipyleaflet.TileLayer(
    url="https://mt1.google.com/vt/lyrs=y&x={x}&y={y}&z={z}",
    name="Google Satellite",
    attribution="Google",
    max_zoom=22,
))
m
```

これ調べる過程で見つけた、[leafmap](https://leafmap.org/notebooks/00_key_features/) も気になる。デフォルトでたくさん機能がある。つくづく思う、便利な時代。
テストコードから書き始める

この記事は[エンジニアと人生コミュニティのアドベントカレンダー（#1）](https://adventar.org/calendars/7577)の18日目です。

#2は[こちら](https://adventar.org/calendars/7632)

## はじめに

ここ半年〜1年ほど、部分的にテストコードから実装するようにしています。  

「テスト駆動」というほどテスト中心じゃないな〜と思ったので、TDDという言葉は使っていないです。  

もちろんその時々でやり方は調整しますが、
一番よく使う実装パターンとともに、「テストコードから書き始めること・テストコードを書くこと」のメリット・デメリットをまとめようと思います。

## 筆者の状況

- 開発の割合はバックエンド8割、フロントエンド2割

- チームではなく一人で実装することが多い

- 保守担当で、機能追加が多い(「SNS連携したいからAPIとデータ連携バッチ作って！」みたいな)

- テスト駆動開発は気になるところを拾い読みした(第1部が中心)

## やり方(メソッド単位のテストを書く場合)

- メソッドの設計をする

    - 入力・出力・処理過程の考慮点を決める

- そのメソッドが一番使われそうな入力でテストコードを1つ作成する

- 設計した通りにメソッド本体を書く

    - 基本的にこの時点でメソッドは完成する

- テストコードを追加していく

- 考慮漏れが発覚したら随時メソッドを修正する

## メリット

### テストコードが揃えやすい

1つテストコードを書いておくと、2パターン目以降のテストコードが増やしやすくなります。

理由としては、2パターン目以降は入力のバリエーションを増やすだけで済む場合が多いからです。

特に入力としてレコードをセットアップする場合は、
1つ目を書く時にセットアップを書けば、2パターン目以降は格段に楽になります。

パラメタライズドテスト化しておくのもいいですね。

たまに1パターン目のセットアップを再利用しづらい時もありますが、
その場合は関数の責務が重すぎることが多いです。

一度腰を上げてしまえば、その後はテストコードを揃えやすくなります。

### 変更しやすい

テストコードが揃うので、変更がしやすいです。

自分が行った変更が前書いたコードを壊していないか、コマンド一つで確認できます。

開発中の仕様追加によりガード節を追加した場合などに、よく恩恵を感じますね。

テスト結果のアサーションに漏れがあるとそもそも意味がなくなるので、
そこは慎重に書く必要がありますが。

実装中のメンタルも安定しますし、一度この変更のしやすさを味わってからは、自然とテストコードを書くことが多くなりました。

## デメリット

### テストコードを書く分時間がかかる

テストコード無しの実装より時間がかかります。

理由としては、思考時間とコード量が増えるからです。

テストコードでも可読性や実行速度を気にする必要があるので、
設計・実装にそれなりに時間がかかります。

ただこれまでの経験だと、「コード変更時の時間・不具合の削減」によって開発全体では時間を節約できているような。

初期開発やスピードが必要な不具合修正などでは、この時間がネックになるかもしれませんね。

### チームの文化によってはそもそもテストを書けない

チームのルールで「テストコードは書かない」となっていたら、勝手に書くわけにはいきません。

自分は現在一人で開発しているので、
PMに相談しつつ開発スタイルは自由に選べます。

ただ新規開発で、納期の都合から途中でテストコードの実装をやめたプロジェクトを見たこともあるので、そこは要相談ですね。

## 終わりに

自分の場合、以下の流れで実装することが多いので、テストコードの「変更しやすい」という恩恵をより大きく感じるのかなと思います。

- 要件が固まりきってない状態で降りてくる

- お客様に質問をして、その回答待ちの間に実装

- 回答を得られ次第、適宜コードを変更していく

テストコード利用の一例として、参考になったら嬉しいです。

読んでいただき、ありがとうございました。
アジャイル・スクラムのダークサイド

# はじめに

- 個人的な観測範囲のダークサイド
- 何事もそうだけど、賛否あるもので、この記事はアジャイル・スクラムの「否」の面を集めてるよ。
- 記事書いてる人間はスクラムが好きだよ。

# いろんな対立
## Don't just Do Agile, Be Agile
「Do Agile」ってのはアジャイルプラクティスを実践することに重きを置いているイメージ。
「Be Agile」ってのはプラクティスの実践に拘るのではなく、アジャイルの本質を目指せという立場。

正直、導入初期などのスクラムがいまいちわかってない内は「Do Agile」になりがち。
そこに対して「それってBe Agileじゃないよね」みたいな批判が飛んでくるケースがある。

これ、自分の中でもいまだに呪いとして残ってるかもしれない。
いまだにバランス見つけられない。


## 形を変えてはいけない vs 形を変えざるを得ない
「スクラムやアジャイルを自社の都合に合わせて変えるな」という話があります。
でも、何かしら変えないとそもそも導入できないとう状況もある。

「変えないと導入できないなら、何かしらの組織課題があるのだから、その組織課題を解決するまでは導入するべきではない」という理由もわからなくはない。
個人的には形を変えてでも少しずつでも組織内にアジャイルを徐々に浸透させて、徐々に組織課題を解決していくのが良いと思ってる。
よっぽど権限持ってる立場にいない限りは、組織はそんなにすぐ変えられない。

他にも言いたいことは以下に書いてる。

https://qiita.com/nh321/items/c62f07b98d74957af506

## 失敗したやつはアジャイルとは呼べない？
[Be Agile]のスタンスに近いんですが、アジャイルプラクティスを導入したとしても、成功に寄与しなかったのであれば、「アジャイルの本質を理解できてなかったから失敗した。だからあれはアジャイルではない。」と主張できなくはない。
みたいな話。

そういう屁理屈があるから嫌だ！みたいな話をたまに聞く。
個人的にはアジャイルかどうかなんてどうでもよくて、成功するかが大事じゃない？とは思う。
アジャイルじゃなくても成功すれば成功だし、アジャイルでも失敗すれば失敗じゃない？

まぁ、成功をアジャイルだけの功績にするのは少し違うとも思ってるので、この言説に共感する部分はある。

## 現場の状況全然違うのに「アジャイル」という一言で同じ扱いになる
ベンチャー開発文脈でのアジャイルと、受託開発文脈でのアジャイルって話が違うと思ってる。
というか、現場ごとに形が大きく変わってくるのがアジャイルだと思ってる。
現場ごとに個別最適化していく印象。
なので「アジャイルは〜だ！」みたいな言い切り系の記事はいつも違和感持って読んでる。
そっちで効果あったことが、こっちで効果あるとは限らんべ。

## 見積もりはすべき？
（ちょっと古いかもですけど）海外では「no estimates」と言って見積もらないムーブメントみたいなのもあったりしました。
当然これ賛否ありました。
詳しくはググってもらうのが良いと思いますが、こういった言説もやっぱり現場ごとに判断すべきで、「アジャイルなら一律で見積もり不要」みたいな言い切りはなんか違うよなぁ、という印象。

## アジャイルは「開発者体験を上げる手段」なのか「事業成功の手段」なのか
開発者体験というキーワードが最近よく見かけるんですが、大事だとは思うんですが、違和感あるのよね。
「事業ないしはPJの成功が重要で、そのために開発者体験をあげていこう」はわかる。
「PJの成功を見ずに、開発者体験だけ上げていこう」は違うと思ってる。
「PJさえ成功すれば開発者体験は不要」というのが昔の考え方だとは思うけど、PJの成功がなければ開発者は雇えない事実もあるので、一概に否定しきれないなぁ・・・とも思ってる。

## スクラム　嫌い
「スクラム 嫌い」とかで検索すると出てくる。

抜粋

- マイクロマネジメントな形になる：確かにスプリントといった感じで、チームに毎回全力を求めるスタンスはあるし、管理単位も小さくなるので、指摘されてる側面はあるように感じる。
- POとDEVの線引きが強くなりやすい：確かに。特に契約関係や権力の差などもあって、発生しやすい気がする。
- SMが悪影響：学習をリードするという役割もあれど、SMがいないと学習できないみたいな空気にもなり得る。
- なんちゃってスクラム：これが意味するところは人によって異なりすぎるので総括はできないんだけど、きっと何も解決しない形ばかりのスクラム何だろうなとは思う。
- うさんくさい：わかる。

# まとめ

- 都合の良い情報だけに包まれていると偏りやすいので、反対派の意見にもたまには耳を傾けた方が良い。
- ここにあげてる話はどれも一理あると個人的には思ってる。
- とはいえ、最終的には現場ごとに筋道立ててやってけばいいんじゃないかな、と思ってる。

# 次回予告

https://qiita.com/advent-calendar/2022/jutakuagile

本記事は、2022アドベントカレンダー「受託アジャイル」の記事です！他にも興味あれば見てってください。
次回は、受託アジャイルな現場で個人的に取り組んでいることです。
whereメソッドの基本的な使い方

## はじめに
Qiita初投稿になります。
学んでいる内容で以下の記述の意味が全然わかりませんでした。
なので、今回は「whereメソッド」の使い方をメモします。

```ruby
    @todays_date = Date.today
    plans = Plan.where(date: @todays_date..@todays_date + 6)
```
ちなみに「..」は”~”を指します。
つまり、 @todays_date..@todays_date + 6は「今日の日付（@todays_date) ~ 6日後までということらしいです。
## 基本の使い方
__モデル名.wher(カラム名: 条件)__
```ruby
User.where(name: "ショウ")
```
これで「ショウ」という名前のユーザーのレコードを全て取得します。

引数が一つの場合は他にも書き方があるそうですが、以下の２つの理由で上記のハッシュで記述するのが良いそうです。
1. 「SQLインジェクション」という悪意のある攻撃を防ぐため
2. 　記述が楽なため

## whereの他の使い方
__配列で指定する方法__
```ruby
User.where(tweet_id: [1,2])
```
tweet_id が１か２のユーザーの全てのレコードを取得できます。
____
__〜以外で指定する方法__
```ruby
User.where.not(name: "ショウ")
```
nameが「ショウ」以外のユーザーのレコードを全て取得できます。
___

## あとがき
他にもwhereには比較演算子を使用した使い方があるみたいですね。
少しずつ覚えていこうと思います！


参考サイトです！
https://www.sejuku.net/blog/13363
Excelよく使う便利操作

個人的に仕事でよく使う操作なのに毎回忘れてしまう操作をまとめた
随時追加していく予定

# 「Ctrl + Shift + ↓」
その列で文字が入力されている行まで文字を選択する

例）A1～A12で文字が入力済の場合、A1にポインタがある状態で「Ctrl + Shift + ↓」するとA1～A12までが選択中となる
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2955416/354493fd-e472-5214-6326-f521f3143aec.png)

# オートフィル機能をダブルクリック
オートフィル機能って便利だけど、カーソルをあてて「＋」を出して下までマウスで持っていくの面倒臭いっていうときにダブルクリックは便利
例）
①生徒ごとに数学と英語の合計金額を算出する場合で、D2セルの計算式をD6までコピーしたい場合

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2955416/7918744e-7247-9ca3-d76a-ed661649f343.png)

②D2セルにフォーカスをあてた状態でセル右下にカーソル（？）をあてて「＋」を表示する
画像の「＋」はイメージです
その「＋」の状態でダブルクリックするとD6セルまで数式が反映される

![矢印はイメージ.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2955416/3e1c1ba8-b425-ab88-0340-d5bea8bf3985.png)
SassのインストールとCSSのおまけ知識

### Dart Sass

https://sass-lang.com/dart-sass

### インストール

```bash
brew install sass/sass/sass
```

### バージョン確認

```bash
sass --version
```

```bash
1.50.0
```

### Sassの詳細

```bash
sass --version
```

```bash
sass/sass/sass: stable 1.50.0
Stylesheet Preprocessor
https://sass-lang.com
/usr/local/Cellar/sass/1.50.0 (7 files, 8.5MB) *
  Built from source on 2022-04-14 at 10:58:53
From: https://github.com/sass/homebrew-sass/blob/HEAD/sass.rb
==> Dependencies
Build: dart-lang/dart/dart ✔
```

### フォルダ構成

```
folder
├-css
│	└─style.scss
└-index.html
```

```html
<!DOCTYPE html>
<html lang="ja">
<head>
中略
  <link rel="stylesheet" href="css/style.css">
  <title>Document</title>
</head>
<body>
  <h1>Dart Sass Test</h1>
  <p>sample text</p>
</body>
</html>
```

```scss
$theme_color: green;

h1, p {
  color: $theme_color;
}
```

CSSのディレクトリで以下のコマンドを実行

```
sass style.scss style.css
```

style.cssとstyle.css.mapが生成される

```
folder
├-css
│	├-style.css
│	├-style.css.map
│	└─style.scss
└-index.html
```

![スクリーンショット 2022-04-14 17.33.15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1051129/2dd81547-58bb-f619-c07d-cfa26a96383a.png)


参照サイト
[Sass のインストールと設定（Dart Sass）](https://www.webdesignleaves.com/pr/css/sass_installation.html)

https://www.webdesignleaves.com/pr/css/sass_installation.html

## スーパリロードなしでもCSSや画像の更新する方法

`?v=`任意の文字列(日付とか)をファイル名の後ろに追記

```html
?v=20220727
```

使用例：

```html
<img src="img/book02.jpg?v=20220727">
```
【Alpine.js使用者必見】コンポーネントサンプルサイト2選

# 使いたいコンポーネントはこのサイトから探せばOK
## AlpineToolbox
物によってはCodepenで実際のコードと動きを確認できるの良い。
バリエーションも豊富でよきよき。

https://www.alpinetoolbox.com/examples/


## Codebase
AlpineToolboxと違ってこちらはすべてのコンポーネントのデザインに統一性があるので、統一されたデザインで使いたいならこちら。

<b>超シンプルでカスタマイズもしやすそう。</b>

https://codebase-frontend-library.github.io/codebase-4/docs/8-alpinejs-components/about-alpinejs-components/

# まとめ
色々なデザインを探したいならAlpineToolbox
シンプルなデザインで統一されたコンポーネントを使いたいならCodebaseを使えばよいぞ。
GraphViewのノードをプログラムで繋げる

GraphViewのノードをプログラムで繋げる
=============

皆さんUnityでグラフ描いていますか？
最近のUnityに追加された機能でGraphViewがあります。
コレ、結構使えそうで、色々紹介記事を見るのですが、ノードを繋げて色々遊べますよーみたいなのでこのノードをマウスで繋げると便利ですよみたいなのが多いと思います。
それはそれで面白いのですが、なんか、デザイナーからボーンのツリー構造を表示したいとか、今あるゲームのデータの状態遷移を表示したい
とか、なんかデータ読み込んでツリー表示させてほしいリクエストが有った時に結構ハマったのでなんか書こうかと思っていたらアドベントカレンダー来たのでちょっと書こうかなと思います。
そんなデカい記事じゃないですが許してください
ちなみに自分の手元ではUnity2021.3.9f1で確認しています。


プログラム的にノードを作成するときには
```C#:HogeNode.cs
    public class HogeNode : Node
```


みたいなノードを宣言して

```C#:FugaGraphView.cs
	public class FugaGraphView : GraphView
	{
	    public FugaGraphView(EditorWindow editorWindow)
	    {

			var node1 = new HogeNode();
			var node2 = new HogeNode();

	        AddElement(node1);
	        AddElement(node2);
```


みたいなこと書いてノードを作成すると思います(変数名は便宜的なもので適宜読み替えてください）
コレでノードがノードエディタで表示されると思うのですが
ノードのinputポート、outputポートを
        
```C#:FugaGraphView.cs
        var inputPort = node1.inputContainer.Q<Port>();
        var outputPort = node2.outputContainer.Q<Port>();
```
        
で入力出力ポートも出てくるしPortのメソッドにConnectToがあるので、そのままこれ呼べばいーじゃんと思って
        
```C#:FugaGraphView.cs
       outputPort.ConnectTo(inputPort);
```
       
とか書けばちゃんと接続されるぞと書いて実行しても全く接続を表示してくれません

```C#:FugaGraphView.cs
       Add(outputPort.ConnectTo(inputPort));
```
       
と書くと接続されたノードが作成されます。
AddElementでもなく、Addです。AddElementでも文法違反にならないので判りづらいですよね
なんか出ないなーと悩んでしまったので同じ失敗をしない様にここに書き込んでおきます。ついでにアドベントカレンダーのネタにします。
ディスクがいっぱいで保存できませんでした。

先日、Dockerでエラーが出て、docker hubに保存できませんでした。　


# 悪循環　

ディスクが足りなくなり、ディスクにファイルが保存できなくなると悪循環が始まります。　


## ごみばこに入れればいい
いらないファイルを削ればいいじゃないかとお思いでしょう。　
いらないファイルが、ゴミ箱にはいらなくなります。　

## ごみばこの内容が消せない　

ディスクがいっぱいなら、ごみばこを消せばいいだろうと思うかもしれません。　
ディスクがいっぱいになると、ごみばこのごみが消せなくなります。　


## ごみばこの整理ができなくなったら　

コマンドプロンプトで、rmコマンドでファイルを消します。　

ファイルを消しても、ファイルシステムのキャッシュが更新できないと、　
ごみばこに入れることも、ゴミ箱の内容が消せないのもそのままです。　

## 再起動　

無理やりファイルを削ったら、再起動すれば、秋領域ができます。
アクティビティの見出しを超簡単に入力する方法

アクティビティの見出しを超簡単に入力する方法を紹介します

アクティビティなど、後で確認するときのためにも注釈はよく使うと思います。
でも、コーディングしているときに注釈を入れるときって、
#### 右クリック → 「注釈」 → 「注釈を追加」
や
#### Shift＋F2 → [ドッキングマーク]をクリック
などで入力すると思いますが、もっと簡単な方法があります。

アクティビティの上部をクリックし
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3046355/7f373c85-02bb-6d80-13c8-7631675b7050.png)
Shift+F2　を入力
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3046355/2f641b3a-beb4-d3b4-c60d-026d2bf2aa58.png)
周りのどこか（アクティビティ上部とか、どこでもOK）をクリック！！
すると・・・
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3046355/15449c5b-9fc1-744a-449a-f3b7dd7bf7a7.png)
のように、
超簡単に注釈欄が挿入されます。

ショートカットキーと１クリックだけなんて、とても楽ちん！です。


#### 感　想
この方法を知ってからは、注釈の入力がとても楽になりました。
分かりやすいソースコードにするためにも、注釈やコメントは大切ですよね。
美しいコードを心掛けたいと思います。
[SQL]アンビギュアスグループ

最近素のＰＨＰを使ったプロジェクトにアサインしＳＱＬを実装するようになったため「ＳＱＬアンチパターン」を読んだ

その中で地味に衝撃だった「アンビギュアスグループ」についてサクッとアウトプット

参考：[https://www.oreilly.co.jp/books/9784873115894/](https://www.oreilly.co.jp/books/9784873115894/)

https://www.oreilly.co.jp/books/9784873115894/

# 概要

## テーブル構成

### Bugs

| bug_id | bug_name |
| --- | --- |
| 1 | Yabaiバグ |
| 2 | Kituiバグ |
| 3 | Iyanaバグ |
| 4 | Kanashiiバグ |
| 5 | Rakunaバグ |

### BugProducts

| product_id | date_reported | bug_id |
| --- | --- | --- |
| 101 | 2022-12-12 12:00 | 1 |
| 101 | 2022-12-09 10:00 | 2 |
| 102 | 2021-02-03 07:00 | 3 |
| 102 | 2020-03-04 05:00 | 4 |
| 103 | 1992-01-15 01:00 | 5 |

### Products

| product_id | product_name |
| --- | --- |
| 101 | AAAサービス |
| 102 | BBBサービス |
| 103 | CCCサービス |

## クエリ
- 「サービスごとに、直近発生した、バグ」を取得したかったので以下クエリを実行した
```sql
SELECT product_id, MAX(date_reported) AS latest, bug_id
FROM Bugs
INNER JOIN BugsProducts USING (bug_id)
GROUP BY product_id;
```

## 想定する結果

| product_id | latest | bug_id |
| --- | --- | --- |
| 101 | 2022-12-12 12:00 | 1 |
| 102 | 2021-02-03 07:00 | 3 |
| 103 | 1992-01-15 01:00 | 5 |

## 実際の結果

| product_id | latest | bug_id |
| --- | --- | --- |
| 101 | 2022-12-12 12:00 | 2(！？) |
| 102 | 2021-02-03 07:00 | 3 |
| 103 | 1992-01-15 01:00 | 5 |

問題：`bug_id`が`MAX(date_reported)`の値を取得していない（`！？`の箇所）

→必ずしもSQLでいい感じに`MAX(date_reported)`である`bug_id`を取得するわけではない

# 原因

**`GROUP BY`で指定したカラムの値ごとにそれぞれ1つの行グループが存在するため（単一値の原則）**

＝`GROUP BY`使用時の`SELECT`文で指定したカラムはすべて一意の値となることが原則

今回、`GROUP BY`で指定した`product_id`はbug_idを２つ持つため、単一値の原則に反するため想定外の挙動になった

# 対策

### 1, 単一ではないカラムを使わない

```sql
SELECT product_id, MAX(date_reported) AS latest  // bug_idを指定しない
INNER JOIN BugsProducts USING (bug_id)
GROUP BY product_id;
```

### 2, 他の列に対しても集約関数を使用する

```sql
SELECT product_id, MAX(date_reported) AS latest, MAX(bug_id) as latest_bug_id // bug_idに対してもMAX()を使う
FROM Bugs
INNER JOIN BugsProducts USING (bug_id)
GROUP BY product_id;
```

### 3, グループごとにすべての値を連結する（MySQL、SQLiteのみ）

```sql
SELECT product_id, MAX(date_reported) AS latest, GROUP_CONCAT(bug_id) as bug_id_list // MAX(date_reported)のbug_idを全て取得
FROM Bugs
INNER JOIN BugsProducts USING (bug_id)
GROUP BY product_id;
```

SET型がサポートされているので使用可能。↓の感じになる

| product_id | latest | bug_id |
| --- | --- | --- |
| 101 | 2022-12-12 12:00 | 1, 2 |
| 102 | 2021-02-03 07:00 | 3, 4 |
| 103 | 1992-01-15 01:00 | 5 |

１レコードの値に複数の値が取得できる

# 所感

- 「アンビギュアスグループ」が発生するクエリを実行すると、基本エラーとなるが、MySQL, SQLiteについてはエラーが吐かれず、間違った値が取得できてしまうのでバグの温床になりえて怖い。。。
- 対策としてはいくつかあるが現実的なのは欲しい値が取得できる「2, 他の列に対しても集約関数を使用する」なのかなと思う
    - 他にも相関サブクエリを使用したり導出テーブルを使用したりする方法もあったが、取得したい結果のわりに複雑なクエリを準備する必要があるのは現実的じゃないかなあ
Next.jsでDynamic Routes（動的ルーティング）を試してみる

# はじめに
こんにちは、都内でソフトウェアエンジニアをしている[YSasago](https://qiita.com/YSasago)と申します。
今回は、Next.jsの特徴の１つであるDynamic Routes（動的ルーティング）についてまとめたいと思います。

# Dynamic Routesを試してみる
ファイル名に```[]```を使うとDynamic Routesになります。
つまり、
http://localhost:3000/posts/ssg-ssr
http://localhost:3000/posts/pre-rendering
といったように、```http://localhost:3000/posts/任意のURL```を作ることができます。
ファイル名に```[]```を使うだけでDynamic Routesになるので簡単ですね。

```zsh:ファイル名の参考
pages/posts/[id].js
```

# getStaticPaths()を使おう
getStaticPaths関数は、Dynamic RoutesをNext.jsで設定する際に使用するものです。

* 本番環境ではビルド時に実行される関数
* 開発環境では、リクエスト毎に実行される
* pathsとfallbackを返す
* pathsは事前ビルドするパス対象を指定するパラメータ
* fallbackは事前ビルドしたパス以外にアクセスした時の動作


```javascript
export async function getStaticPaths() {
  const paths = getAllPostIds();
  return {
    paths,
    // pathsの中身
    // [
    //     {params: {id: 'ssg-ssr'}},
    //     {params: {id: 'pre-rendering'}}
    // ]
    fallback: false, // 指定パス以外なら404を返す
  };
}
```

上記のコードの場合、[http://localhost:3000/posts/pre-rendering](http://localhost:3000/posts/pre-rendering)と[http://localhost:3000/posts/ssg-ssr](http://localhost:3000/posts/ssg-ssr)はアクセスできますが、指定パス以外の場合404を返します。


```javascript
export async function getStaticPaths() {
  const paths = getAllPostIds();
  return {
    paths,
    // pathsの中身
    // [
    //     {params: {id: 'ssg-ssr'}},
    //     {params: {id: 'pre-rendering'}}
    // ]
    fallback: true, // どんなpathでもOK
  };
}
```

上記のコードの場合、どんなpathでも表示できますが、表示する側で対応していないとエラーになっていまいます。

![スクリーンショット 2022-12-03 23.59.30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/95954/52bffd32-6d43-94e8-9fc0-427e5af534df.png)



# おわりに
今回は、Next.jsでDynamic Routesを設定する方法をまとめました。
Next.jsはDynamic Routesを簡単に実装できるのでとても便利ですね！
最後まで読んでくださりありがとうございました。

# 参考
https://nextjs.org/learn/basics/dynamic-routes
CSSだけでモーダルを使用してみる

# まえおき
12月といえばアドベントカレンダー。
アドベントカレンダーといえばこの業界にいると記事を書かなくては！となりますよね。
本来はイエス・キリストの降誕を待ち望む期間に1日ずつ開けていくカレンダーですが、海外では紅茶やお菓子のアドベントカレンダーもたくさんあります。

今回はティータイムにぴったりなアドベントカレンダーをCSSだけで描いてみました。

紅茶についてはあまり詳しくはなく、少し嗜む程度ですがおすすめを載せましたので、足を運べそうなお店がありましたらぜひ行ってみてください。（~~CSS書くよりリストまとめるのに時間がかかったかもしれない😿~~ ）

## なんちゃってアドベントカレンダー

<p class="codepen" data-height="500" data-slug-hash="KKerOdG" data-user="96usa_koi" style="height: 300px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;">
  <span>See the Pen <a href="https://codepen.io/96usa_koi/pen/KKerOdG">
  Le Calendrier de l'Avent</a> by いおり🔯 (<a href="https://codepen.io/96usa_koi">@96usa_koi</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>


## 今回使用してみたかったこと
- チェックボックスのアニメーション
- 擬似クラス:targetだけでモーダル

※気になってたCSSを触れてみただけですので、アクセシビリティーの考慮はしておりません。

## チェックボックスのアニメーション

`input`が`:checked` になったら`input`と兄弟関係にあるクラスがアニメーションします。

```html
    <label>
      <input type="checkbox" name="" value="">
      <div class="open-door">
      <div class="doorArea">
        <div class="door">Le Calendrier de l'Avent</div>

    〜

```


```css
input[type=checkbox]:checked ~ .doorArea .door {
  animation: doorOpen 1s linear 0s;
  animation-fill-mode: forwards;
}

@keyframes doorOpen{
  0% {
    transform: translate(-50%, -50%) rotateY(0deg);
  }

  100% {
    transform: translate(-56.5%, -50%) rotateY(85deg) skewY(-10deg);
    opacity: 0;
    display: none;
    z-index: -1;
  }
}

```

## 擬似要素:targetのモーダル
MDNを見た方がわかりやすいのでコードは割愛します。

https://developer.mozilla.org/en-US/docs/Web/CSS/:target

MDNに載っているdemoが滑らかで綺麗です。
JavaScriptを使用していないとは思えないくらいナチュラルですね。

https://madmurphy.github.io/takefive.css/#nowhere


## まとめ
CSSだけでマリ●を再現している方を見かけてから、気になってたCSSを触ってみました。
ラジオボタンでの複数アニメーションも触ってみたいです。

以上
Kintoneで筋斗雲を呼ぶアプリを作ってみよう！

# はじめに
電車の広告やCMで数年前からよく見かける**Kintone**
CMをみると、正直ちょっと何がなんだかよくわからないと思っているのは自分だけではないはず・・・笑

数年前に会社で「Kintone」を使う機会があり、ついでに筋斗雲を呼ぶアプリを作ってみたので、まとめてみたいと思います！

# kintoneって何ができるの？
> Webデータベース型の業務アプリ構築クラウドサービスである

wikiによるとこんな感じで記載されています。
実際に触ってみた印象は、GUIで色々とカラムを作れるデータベースであり、サンプルアプリがいくつもあって、技術がない方でも気軽に業務アプリを作成できるツールといった感じでした。

そして面白いのは、Javascriptでカスタマイズできること！
イベントを取得できるAPIも完備されているので、Javascriptで実現できることは、ほぼできちゃいます！

# ライセンスを取得しよう
簡単に説明を書いてみましたが、実際に触ってみたほうが分かりやすいです。
そして、制限はありますが以下の公式サイトから無料で利用できます！
[kintone 開発者ライセンス（開発環境）
](https://developer.cybozu.io/hc/ja/articles/200720464-kintone)


# さっそくアプリを作ってみよう
ライセンスを申し込むと、期間限定ではありますが、無料でKintoneをお試し利用できるようになります！
ログインしてみると、画面はこんな感じです！
![その１.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/201860/4cdf4f98-4cd9-b4fa-d147-f94476997875.png)

ここからアプリを作成していきます！
作成方法はいくつかあり、よく業務で使いそうなアプリはテンプレートとしてすでにかなりの量が登録されています。

また、ExcelやCSVファイルを読み込んで作成できたりもします！すごい！！

下の例は新規でアプリを作成し、データ登録して一覧表示させるイメージ動画です。
基本的にドラッグアンドドロップでできちゃいました。
![Animation1.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/201860/fc2a5a53-4b0c-22da-d8d4-adbcd88dcfec.gif)

# KintoneのAPIを使ってJSでカスタマイズしてみよう
先ほども触れましたが、Kintoneの面白いところはJavascriptを読み込ませることができるため、細かいカスタマイズを自分でできることです。
kintoneJavaScriptAPIを使うことで、画面表示時やレコード追加時などのイベントを取得できます。
詳しくは[公式サイト](https://developer.cybozu.io/hc/ja/articles/201755040)に分かりやすくまとめられています！

# 筋斗雲を呼んでみよう！
はい。ここまででなんとなーく、Kintoneってなんだろうっていうのを理解していただけましたか？
本来は、案件管理や顧客管理、日報やファイル管理などで使うのが一般的のように感じました。

ただ、今回はJavaScriptを埋め込めるということで、JavaScriptでWebアプリを作成して、筋斗雲を呼んでみようと思います！
理由はkintoneと聞いて一番最初に思い浮かんだのが「きんとーーーん！」と叫ぶと、どこからともなく現れて、心がきれいな人だけが乗れる、かの有名な漫画にでてくる筋斗雲だったからです・・・。

というわけで、筋斗雲に乗せたい人をKintoneで登録し、そのデータを使ってみました。あとはJSで無理やり作ってみました！

この記事内ではJavascriptについての説明は省きますが、ソースは公開しています。
※Kintone以外でも動かせるようにしてあるため、イベント発火のタイミングやボタン設置などは、KintoneAPIで書き直す必要があります。
[公開ソース](https://github.com/ryuji-i3/kintone)

そして実際に動かすと、こんな感じです！！
![Animation2.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/201860/aebf64ea-002f-d578-c8fe-71813890210d.gif)


うん、作ってみたはいいものの、このアプリはいったい何の意味があるんだろう・・・・・。

# まとめ 
・GUIで作れてかんたん
・色々サンプルアプリがあるので、さらに敷居が低そう
・Javascriptが使えるので、細かいカスタマイズができちゃう
・外部のAPIとも連携できるみたいで、極めていけば何でもできて楽しそう！
orelangのdart版を作って拡張しました

## なんだこれは

みなさんはorelangを知ってますか？
[プログラミング言語を作る。１時間で。](https://qiita.com/shuetsu@github/items/ac21e597265d6bb906dc)という素晴らしい記事で実際に作られている言語です。

今回はdartを使って勝手にorelangを実装してみました。

## できたもの

これが完成品を置いているリポジトリです。
だいぶテキトーだしエラー処理も甘いし抽象化も雑魚いので大目に見てやって下さい。

[https://github.com/Uchijo/orelang_dart](https://github.com/Uchijo/orelang_dart)

## 工夫を試みた箇所

### `Object`をなるべく使わない

Javaの実装では`Object`型が多用されています。どうせなので型に守られてプログラミングしたいなぁと思い、できるだけ`Object`型を使わないようにしました。
その結果、`EvalResult`とかいう謎のresultクラスが完成しました。

orelangでは全てが式であり、式を評価していくと最終的に以下の3つにたどり着きます。

- 整数
- ブール
- 値なし

これらを全てObjectでまとめるよりは、ということでEvalResultというクラスを作成しました。
int, bool, EvalResultTypeのフィールドを持ち、EvalResultTypeで保存されている型が何なのかを確認することができます。
整数ならintのフィールドに値が入り、ブールならboolのフィールドに値が入り‥という感じです。
（dartにユニオンがあればもっときれいに実装できるんだけどなぁ‥）

また、`IOperator#call`の第二引数の型を`List<IExpression>`に変更しました。結果から書くと、**これは大きな間違いでした**。
`IOperator`の実装には、変数のset, getなどの処理も含まれています。その際、set, getに渡される引数は変数の識別子なのです。
これを式（つまりIExpression）にするとなにかがおかしい感じになってしまいます。
今回はあまり時間をかけて作る気分ではなかったので、しょうがなく`IExpression`を実装した`Identifier`型をつくり、渋々それを使うという形を取りました。

### 何個か機能を追加してみた

orelang元記事では1時間で完成させるという制約がある関係上、機能は非常に限られています。（その制約のお陰でお手軽さと充実感の両立が実現できているはずなので本当にありがたいことです。決して機能が少ないことをディスりたい訳では無いです。）
しかし私には時間的制約はありません。ということで、最後楽しくなって追加したいくつかの機能をご紹介します。

#### `if`式

皆さんご存知の`if`式です。`["if", cond, exp1, exp2]`という形で書くことができ、`cond`が`true`なら`exp1`の評価結果が、`false`なら`exp2`の評価結果が返るというだけの式です。

#### `and`, `or`

これもだいたいどの言語でもある機能ですね。`["and", exp1, exp2]`みたいな感じで書けます。

#### `>`, `<`

大小比較です。ないよりあったほうが良いかな～と。

#### `skip`

何もしない命令です。値としては`novalue`、つまり値なしが返ります。
`if`が式である以上`else`句の実装は強制したかったのですが、どうせなので命令型言語的にskipもできたほうが良いかな、と思いこれを追加しました。軸ブレブレですね‥

## 今後やる気が続けばやること

そういえばwhileを作って満足したせいでuntilを作ってなかったので、それの実装はしたいですね。
識別子のところは納得いってないので、いつかリファクタリングしたいなと思っております。
あとは構文解析バチバチにしたやつとかも作りたいかも‥
最先端時系列データ分析モデルETSformerを使ってみた

# 概要
本記事は、Salesforceが2022年に発表した最先端の時系列データ分析モデルである[ETSformer](https://arxiv.org/pdf/2202.01381.pdf)の紹介です。多くの時系列タスクでSOTAを達成したと論文には書かれています。まだQiitaやKaggleにはETSformerについての記載が無いので記事を書いてみようと思いました。
また、Streamlitを用いてウェブアプリ化し、ETSformerを手軽に体験できるようにしました！

# ETSformerとは
ETSformerの論文についてChatGPT先生に聞いてみました。ChatGPT先生は論文の解説も端的でわかりやすいですね！
※ただし、たまに間違ったことを言うこともあるので注意が必要です。
***
You:「ETSformer: Exponential Smoothing Transformers for Time-Series Forecasting」という論文について解説してください。

ChatGPT:「ETSformer: Exponential Smoothing Transformers for Time-Series Forecasting」という論文では、時系列データ分析において、Transformers アーキテクチャを採用したモデルを提案しています。
このモデルは、時系列データを処理するために、Exponential Smoothing (指数平滑) という手法を組み合わせています。指数平滑は、過去のデータを加重平均して、未来のデータを予測する手法です。このモデルでは、指数平滑を行う部分を、Transformers のエンコーダー部分に対応させています。
また、このモデルでは、指数平滑では表現できないような複雑な時系列パターンも処理できるように、複数の Transformes ブロックを組み合わせることで、より複雑な時系列データを処理することができるようになっています。
このモデルは、様々な時系列データセットを用いて評価されており、他のモデルよりも優れた精度を発揮することが示されています。
***

# 手軽にETSformerを体験できるウェブアプリをつくりました！
Streamlitを用いてウェブアプリ化し、ETSformerを体験できるようにしました。
[こちら](https://isaka-code-etsformer-practice.streamlit.app/)からアプリを体験できます。
ETSformerは、Exponential Smoothing (指数平滑)とTransformerの合せ技です。パラメータチューニングが少し大変かもしれません。今回は論文のパラメータをそのまま用いています。

アプリのスクショ
![アプリのスクショ.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2627015/ebb3806a-f12b-6625-2307-16f3b5945b8a.png)

# Kaggleで使うには？
実際に使う際は、[ETSformer-pytorch](https://github.com/lucidrains/ETSformer-pytorch)を使用するのが簡単です。ただし、Pythonのバージョンが3.8以上である必要があるので、Kaggleのノートブック環境ではPythonのバージョンが足りずインストールできないです。GCPを使うか、ローカルで動かす必要があります。
※2022年12月現在KaggleのPythonのバージョンは3.7.12でダウングレードもアップグレードもできないです。

# まとめ
この記事では、最先端の時系列データ分析モデルであるETSformerの紹介を行いました。また、それを体感できるウェブアプリを実装しました。
画像認識や自然言語処理ではディープラーニングがデファクトスタンダードですが、時系列タスクにおいては勾配ブースティング系のLightGBMなどがKaggleにおいては猛威を振るっています。近い将来に時系列タスクにおいても、ディープラーニングがデファクトスタンダードになるのか楽しみにしています。


## ソースコード
ソースコードはGitHubで公開しています。参考になれば嬉しいです。
https://github.com/Isaka-code/ETSFormer-practice

## 参考文献

この記事は以下の情報を参考にして執筆しました。

- [ETSformer](https://arxiv.org/abs/2202.01381)
- [ETSformer-pytorch](https://github.com/lucidrains/ETSformer-pytorch)
- [Streamlitで時系列予測アプリを作る](https://rarejob-tech-dept.hatenablog.com/entry/2022/06/10/190000)
```
@misc{woo2022etsformer,
    title   = {ETSformer: Exponential Smoothing Transformers for Time-series Forecasting}, 
    author  = {Gerald Woo and Chenghao Liu and Doyen Sahoo and Akshat Kumar and Steven Hoi},
    year    = {2022},
    eprint  = {2202.01381},
    archivePrefix = {arXiv},
    primaryClass = {cs.LG}
}
```
numpyのaxis = i で迷わない

# はじめに

ニューラルネットワークの学習をしていてコードを書いていると必ず出てくるnumpyのコード

```
numpy.sum(x, axis=i)
```
列方向に演算する場合は、axis=0
行方向に演算する場合は、axis=1　

だと思い込み学習を進めていると全く意味が分からなくなり混乱してしまいました。

## 混乱していた理由
行、列みたいに理解をしようとしていたのが混乱の原因でした。
しかも行列方向の意味がどっち向きのことをいっているのか分からなくなり、さらにチャンネル次元が追加されるともう意味がわかりません。

axisの指定に迷っていてはそもそも学習に支障がでます。
もう二度と迷わないように自分なりの考え方を整理しました。

## このように考えてみる
そもそものコードのあり方に立ち返り
axis=0,1,2,3・・・
はリストのインデックスと同じように演算したい次元の順番を指定していると考えて

ex:
(N,M)でNを演算したいときは、axis=0
(C,N,M)でCを演算したいときは、axis=0
(N,T,H)でHを演算したいときは、axis=2

# これでひとまず
あとはその変数の次元がどうなっているのか。
そのモデルや関数はどうしたいのかを理解していれば大丈夫です。

はい、これからが本番です。