OmniAICreator/Qiita-1.07M huggingface dataset:
個人開発のOSSで独立・起業した話

# 自己紹介
内田といいます。富士通エフサスという会社に19年ほど勤務していましが、2014年から開発をはじめたOSS [プリザンター](https://pleasanter.org) で2017年に独立起業しました。今はインプリムという会社(7期目)を経営しています。

# プリザンターとは？
個人開発のOSSで、もともとは富士通社内の管理業務の効率化を狙って開発した情報共有ツールです。データベースとしての機能をもっていて、エクセルで管理している仕事を置き換えることができます。OSSなので、フリーソフトとして無料で提供しています。

https://github.com/Implem/Implem.Pleasanter

# なぜ開発したか？
管理業務がとても大変でした。エクセルとメール、そして印刷しての会議は労力が必用でした。こうした業務をWeb化すればよいのですが、管理業務の種類も多いため1つ1つWeb化していっては時間が足りません。そのため、簡単にエクセルで管理しているようなものをWebの操作だけで開発できるツールを作ろうと考えました。今流行の言葉でいうところの業務システムのノーコード開発ツールです。下記は独立・起業する前に Fujitsu Advent Calendar 2016 に投稿した内容です。

https://qiita.com/Implem/items/1d815f93719d4129dc4f

# なぜOSSにしたか？
OSSとして広く普及すれば、私と同じような人たち（特に富士通グループの仲間）が楽になるのではないか、という想いでGitHubで開発を進めていました。開発当初は独立起業の構想はありませんでした。

# なぜ独立起業したか？
富士通グループでも様々な業務やプロジェクトで活用してもらいましたが、金融系の規模の大きい組織では採用されませんでした。理由としては継続性に不安があること。すなわち個人開発のソフトウェアでは、信用が無いということです。規模が大きい組織で使ってほしいという想いで開発したので、このままでは目的を達成できないと思いました。ソフトウェアとして信用を得るためには、組織的にメンテナンスする体制や実績を作る必要がありました。その手段の1つとして、独立・起業を選択しました。

# どうやってマネタイズしたか？
起業した当初はまったく売上がたちませんでしたが、1年が経過したころからサポートサービスを購入してくれる企業が何社か出てきました。プリザンターは数百人、数千人規模で使う業務システムなので、フリーソフトのままで使うのではなくサポートを購入したいという企業ニーズにマネタイズのチャンスがありました。

その後、プリザンターを開発プラットフォームとして、SIビジネスを展開するパートナー企業が増えていきました。現在は大手SIerなども加わり70社を超えるパートナー企業と協業しています。

https://pleasanter.org/partner/

# 信用を作ることができたか？
当初の狙いどおり大企業にニーズがありました。金融機関や大手製造業など大規模な組織で導入が進み、ありがたいことに事例化に協力してくれる企業が増えました。現在は21事例を公開することができ信用をあげることができたと考えています。会社の業績としても売上・利益も順調に伸び信用調査会社の評点も良い点数になったようです。起業はリスキーな選択ですが、個人開発プロダクトの信用をあげる上で1つの選択肢になり得ると思います。

https://pleasanter.org/cases

# 起業して大変だったことは？
私はエンジニアの経験しか無い中で起業したので、エンジニアリング以外の専門性がありません。当初2人で起業しましたが、セールスも会計も採用も資金調達もはじめてのことばかりです。独立すればソフトウェアの開発に専念できるという甘い考えがありましたが、そんなことはありませんでした。あたりまでですね。幸いなことに良い仲間に恵まれて、現在はそれぞれの専門領域をまかせられるようになりましたが、それまでは何もかも自分たちで勉強してクリアしていく必要がありました。もし個人開発のプロダクトで独立・起業を考えている場合には、専門外のことにも果敢に立ち向かう覚悟をもって取り組んでください。

# 起業してよかったことは？
## その1（仲間）
新しい仲間が1人増えるたびに、会社が活気ずくのを目の当たりにしてきました。OSSとして公開していたこともあって、プロダクトのファンがJOINしてくれることも増えています。当初はプロダクトの信用を得るために独立・起業しましたが、今は仲間のために頑張る気持ちが強いです。

## その2（貢献）
ソフトウェア開発を通じて世の中の役に立っているという実感が持てるようになりました。口コミサイトなどで様々なフィードバックがありますが、良いコメントも悪いコメントも全て読んでいます。役に立っているな、期待されているな、と感じると嬉しい気持ちになります。起業する必要はないかもしれませんが、フィードバックがやる気の源泉になっています。

https://www.itreview.jp/products/pleasanter/reviews

## その3（協業）
開発プラットフォームとして、パートナー制度をつくったことがきっかけで70社を超える多くのIT企業と協業することができるようになりました。パートナー企業からのリクエストは難易度が高いものが多いですが、それだけ期待されているということだな、と実感することができます。これからもプリザンターに期待してくださる企業とのつながりをふやして、エコシステムと呼べるような経済圏を創り出していきたいと考えています。

## おわりに
プリザンターは今後も業務に役立つノーコード・ローコード開発ツールとして進化を続けてまいります。よかったら応援してください。皆さん良いクリスマスをお過ごしください。
https://pleasanter.org
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/78230/1764addf-fe7a-b707-0d06-d84ad7899014.png)

:star:GitHubにスターつけてもらえたら嬉しいです。
https://github.com/Implem/Implem.Pleasanter
JSで日付扱うならmoment

## はじめに
私は株式会社qnoteにて、勉強会の幹事を務めております。
2023年度勉強会の珠玉のネタを2023Qiitaアドベントカレンダーに投稿していこうと思います。

## 対象者
この記事は下記のような人を対象にしています。

- 駆け出しエンジニア
- プログラミング初学者

## 結論
JSで日付扱うなら、Dateよりmomentです！

## 解説
フロントエンドで日付を加工して表示させたい時、ありますよね。
Date()とMoment()の手法を比較しました。

## Date()は冗長
```javascript
const date = new Date ()

const year = date.getFullYear()	// 年
const month = date.getMonth() + 1 // 月
const day = date.getDate() // 日
const dayOfWeek = date.getDay() // 曜日(数値)
const dayOfWeekStr = [ "日", "月", "火", "水", "木", "金", "土" ][dayOfWeek] // 曜日(日本語表記)
const hour = date.getHours() //時
const minute = date.getMinutes() // 分

const result = `${year}年${month}月${day}日(${dayOfWeekStr}) ${hour}時${minute}分`
console.log(result)
// 結果
2018年8月22日(水) 04:15
```
上記の例、みていただければわかりますが、長すぎる...

:::note alert
- 月を取得する際、謎の「+1」記述が必要で、可読性DOWN
- 曜日を取得するのが場長の極み
:::

## Moment()は短い！
```javascript
const result = moment().format('llll')
console.log(result)
// 結果
2018年8月22日(水) 04:15
```
短！！！
さまざまなフォーマットを活用することができます。

## おわりに
JSで日付扱うならmoment、についてまとめました。

## 参考記事
https://www.notion.so/JS-moment-9e7a3a6531af4ffe9531797326484cb0?pvs=4

- [全61件！Moment.js日付フォーマット実例](https://blog.capilano-fw.com/?p=908#_2018822_0812-2)
- [Vite使っていて moment.locale('ja') が効かないときは - Qiita](https://qiita.com/oedkty/items/61837af79d05f2794ad9)
- [JavaScriptで日時、曜日を取得する方法](https://lab.syncer.jp/Web/JavaScript/Snippet/3/)
Realmのエラー解決法:Thread 1: Fatal error: 'try!' expression unexpectedly raised an error: Error Domain=io.realm Code=10 "Migration is required due to the following errors:

# Realmのデータ構造を変更した際に起こったエラー
:::note alert
Thread 1: Fatal error: 'try!' expression unexpectedly raised an error: Error Domain=io.realm Code=10 "Migration is required due to the following errors:

- Property 'Item.name' has been added." UserInfo={Error Name=SchemaMismatch, NSLocalizedDescription=Migration is required due to the following errors:
- Property 'Item.name' has been added., Error Code=10}
:::
内容としては、後からデータ構造にプロパティ「Item.name」が追加されたのに、マイグレーション処理ができてませんというエラーです！
# 原因
変更前のデータ構造
```swift: Item.swift
import Foundation
import RealmSwift

class Item: Object {
    @Persisted var title: String = ""
    @Persisted var done: Bool = false
    @Persisted var order = 0
}
```
変更後のデータ構造
```swift: Item.swift
import Foundation
import RealmSwift

class Item: Object {
    @Persisted var title: String = ""
    @Persisted var done: Bool = false
    @Persisted var order = 0
    @Persisted var name: String = ""
}
```
後からデータ構造にプロパティ「Item.name」が追加されたのにマイグレーション処理ができていないことが原因でエラーが起こりました！
既に保存されている情報と新規で操作しようとしている情報が違いますよというエラーです！

# 解決方法
Realmのデータ構造を変更したらマイグレーション処理が必要になる！
まだAppStoreにリリースしていないアプリのRealmのデータ構造を変更した後、シミレータで確認したい場合であれば、下記の方法で解決できます！

command + shift + H で下記の画像のホームに行き、アプリのアイコンを長押しすることで、削除ボタンが出てきます！削除ボタンを押して一度アプリを削除します！
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3090887/93dfda91-0dc6-e885-8d24-b39cf561b48b.png" width=300>

シミュレータを実行したらエラーが解消しました！
<font color="red">**※既にリリースしたアプリは、ユーザーにアプリを削除して入れ直してということにはいかないので、マイグレーション処理を書く必要があるので注意が必要です！**</font>

# 参考文献

https://ios-docs.dev/realm-migration/

https://qiita.com/airy_flutter/items/218c900a5d4214a6bde1
AWS個人利用ならLightsail

## はじめに
私は株式会社qnoteにて、勉強会の幹事を務めております。
2023年度勉強会の珠玉のネタを2023Qiitaアドベントカレンダーに投稿していこうと思います。

## 対象者
この記事は下記のような人を対象にしています。

- 駆け出しエンジニア
- プログラミング初学者

## 結論
AWS個人利用ならLightsail一択です。
マジで安い+セットアップ簡単です。

## 解説
個人開発でAWSを利用したく、価格を調べたのですが、EC2+RDSの構成、高すぎない？(1~2万/月)
特にRDSが個人で利用するには高すぎます。
EC2だけにしても5000円/月くらいで、気軽に個人開発をデプロイできる...とは言えませんね。

他にAWSで安いサービスないか探したら、**Lightsail**が見つかりました！
最安で400円/月。とても安い！

しかも、実際に使ってみたところ、セッティングも圧倒的に簡単で、初心者のポートフォリオであれば充分ではないかと思いました。

実際にAWS LightSailを利用したポートフォリオが下記になります。

https://github.com/YutaManaka/patisserieLara

## おわりに
AWS個人利用ならLightsailについてまとめました。

## 参考記事
https://www.notion.so/AWS-Lightsail-9b91eff4d153410ebadc7925de8274d1?pvs=4

- [【AWS】Laravelアプリを公開【Lightsail】](https://chigusa-web.com/blog/aws-laravel-lightsail/)
- [GitHubの既存プロジェクトをlightsailにインストール](https://juno-engineer.com/article/amazon-lightsail-lamp-php8-laravel/#autoid-6)
- [「"storage/logs/laravel.log" could not be opened: failed to open stream: ...」が出た時の対処方法](https://akizora.tech/laravel-log-error-4495)
- [SQLSTATE[HY000] [1045] Access denied for user](https://inouelog.com/access-denied-user/)
- [Connect to a WordPress Lightsail Database from a GUI](https://mead.io/2022/06/30/connect-to-a-wordpress-lightsail-database-from-a-gui/)
LaravelでSeederを定期実行したい時

## はじめに
私は株式会社qnoteにて、勉強会の幹事を務めております。
2023年度勉強会の珠玉のネタを2023Qiitaアドベントカレンダーに投稿していこうと思います。

## 対象者
この記事は下記のような人を対象にしています。

- 駆け出しエンジニア
- プログラミング初学者

## 結論
定期実行する際に記述する場所はプロジェクトごとに決めましょう！

## Laravelのタスク定期実行の仕組み

> /var/spool/cron/crontabs/apache(←1.crontabに書く)
↓
app/Console/Kernel.php(←2.kernerl.phpに書く)
↓
app/Console/Commands/XXX.php(←3.コマンド化)
↓
app/Actions/YYY.php(←3.コマンド化)
>

## それぞれの手法のメリット・デメリット
|  | メリット | デメリット |
| --- | --- | --- |
| crontab | 簡単(1行) | git管理できない |
| kernel.php | git管理できる | テスト書けない |
| コマンド化+kernel.php | テスト書ける・git管理できる | 実装量多い |

## crontabに書く手法
```
* * * * * cd /path-to-your-project && php artisan schedule:run >> /dev/null 2>&1
```
参考：[crontabの書き方](https://www.notion.so/crontab-da329bacede84bdea9c511a493e76bd5?pvs=21)

## おわりに
LaravelでSeederを定期実行したい時についてまとめました。

## 参考記事
https://www.notion.so/Laravel-Seeder-4d3e35562ae34238b8b4a00320361e20?pvs=4

- [kernel.phpのスケジュールを実行するためにcrontabに書かなきゃいけないこと](https://reffect.co.jp/laravel/laravel-task-schedule-cron/)
- [公式ドキュメント](https://laravel.com/docs/10.x/scheduling#running-the-scheduler)
- [>> /dev/null 2>&1って何？](https://qiita.com/ritukiii/items/b3d91e97b71ecd41d4ea)
2023年に読んでよかった本

# はじめに
2023年に読んでよかった本の紹介記事。

本を同時に読み進める癖があり、読み途中な本もありますがおすすめな本を紹介してみる。
本屋さんに並んでいたら手に取ってくれると嬉しいです。振り返ってみると、資格本ばかり読んでいたので紹介する本は少なめですが、どれもおすすめな本です。
資格勉強と並行して読んでいました。

# 大学4年間のデータサイエンスが10時間でざっと学べる
データサイエンス系、ちょっと迷走しているところがあったためわかりやすくまとめられている本を探していてみつけた本。大学の授業で統計学は取りましたが、進んでいているので
データサイエンスやり直す意味でもいい感じ。
[大学4年間のデータサイエンスが10時間でざっと学べる](https://www.amazon.co.jp/%E5%A4%A7%E5%AD%A64%E5%B9%B4%E9%96%93%E3%81%AE%E3%83%87%E3%83%BC%E3%82%BF%E3%82%B5%E3%82%A4%E3%82%A8%E3%83%B3%E3%82%B9%E3%81%8C10%E6%99%82%E9%96%93%E3%81%A7%E3%81%96%E3%81%A3%E3%81%A8%E5%AD%A6%E3%81%B9%E3%82%8B-%E8%A7%92%E5%B7%9D%E6%96%87%E5%BA%AB-%E4%B9%85%E9%87%8E-%E9%81%BC%E5%B9%B3-ebook/dp/B0BP6C31K8/ref=sr_1_1?__mk_ja_JP=%E3%82%AB%E3%82%BF%E3%82%AB%E3%83%8A&crid=EE4PCLHETKIB&keywords=%E5%A4%A7%E5%AD%A64%E5%B9%B4%E9%96%93%E3%81%AE%E3%83%87%E3%83%BC%E3%82%BF%E3%82%B5%E3%82%A4%E3%82%A8%E3%83%B3%E3%82%B9%E3%81%8C10%E6%99%82%E9%96%93%E3%81%A7%E3%81%96%E3%81%A3%E3%81%A8%E5%AD%A6%E3%81%B9%E3%82%8B&qid=1702804821&sprefix=%E5%A4%A7%E5%AD%A64%E5%B9%B4%E9%96%93%E3%81%AE%E3%83%87%E3%83%BC%E3%82%BF%E3%82%B5%E3%82%A4%E3%82%A8%E3%83%B3%E3%82%B9%E3%81%8C10%E6%99%82%E9%96%93%E3%81%A7%E3%81%96%E3%81%A3%E3%81%A8%E5%AD%A6%E3%81%B9%E3%82%8B%2Caps%2C153&sr=8-1)

# 問題解決力を鍛える!アルゴリズムとデータ構造 (KS情報科学専門書)
コーディング力を上げるため読んでみた本になります。自己流でプログラミングしている
ところがあり、参考書的に読み進めました。なかなかの良著作。
[問題解決力を鍛える!アルゴリズムとデータ構造 (KS情報科学専門書)](https://www.amazon.co.jp/%E5%95%8F%E9%A1%8C%E8%A7%A3%E6%B1%BA%E5%8A%9B%E3%82%92%E9%8D%9B%E3%81%88%E3%82%8B%EF%BC%81%E3%82%A2%E3%83%AB%E3%82%B4%E3%83%AA%E3%82%BA%E3%83%A0%E3%81%A8%E3%83%87%E3%83%BC%E3%82%BF%E6%A7%8B%E9%80%A0-%EF%BC%AB%EF%BC%B3%E6%83%85%E5%A0%B1%E7%A7%91%E5%AD%A6%E5%B0%82%E9%96%80%E6%9B%B8-%E5%A4%A7%E6%A7%BB%E5%85%BC%E8%B3%87-ebook/dp/B08PV83L3N/ref=sr_1_1?__mk_ja_JP=%E3%82%AB%E3%82%BF%E3%82%AB%E3%83%8A&crid=2WVTDF1HO1FE1&keywords=%E3%82%A2%E3%83%AB%E3%82%B4%E3%83%AA%E3%82%BA%E3%83%A0%E3%81%A8%E3%83%87%E3%83%BC%E3%82%BF%E6%A7%8B%E9%80%A0+%E5%95%8F%E9%A1%8C%E8%A7%A3%E6%B1%BA&qid=1702804760&s=books&sprefix=%E3%82%A2%E3%83%AB%E3%82%B4%E3%83%AA%E3%82%BA%E3%83%A0%E3%81%A8%E3%83%87%E3%83%BC%E3%82%BF%E6%A7%8B%E9%80%A0+%E5%95%8F%E9%A1%8C%E8%A7%A3%E6%B1%BA%2Cstripbooks%2C151&sr=1-1)

# 数学の世界地図
最先端の数学研究分野をわかりやすく紹介している書籍。ＳＮＳで流れてきた本であり、ちょっと気になって読んでみると面白い面白い。
Ｅ資格で大学数学に触れる機会があり、数学に少し興味がでてきた分野。読んでいて色んな視点が変わってよかったです。何かこの知見を活かせるといいなーと。
[数学の世界地図](https://www.amazon.co.jp/%E6%95%B0%E5%AD%A6%E3%81%AE%E4%B8%96%E7%95%8C%E5%9C%B0%E5%9B%B3-%E5%8F%A4%E8%B3%80-%E7%9C%9F%E8%BC%9D-ebook/dp/B0C6X1KKSS/ref=sr_1_1?adgrpid=146163103865&hvadid=650599407092&hvdev=c&hvqmt=e&hvtargid=kwd-2013401183201&hydadcr=12796_13472373&jp-ad-ap=0&keywords=%E6%95%B0%E5%AD%A6%E3%81%AE%E4%B8%96%E7%95%8C%E5%9C%B0%E5%9B%B3&qid=1702804706&sr=8-1)

# ライブラリ新数学大系 基礎　情報数学
コーディング力やプログラミング力をもっと上げたいなと思い読み進めています。
ちなみに１段階上の書籍として　応用　の本もあります。
これもコーディング力での考え方が変わり読んでよかったです。
基本からやりなおす、少し古めな本ですがおすすめです。
[ライブラリ新数学大系 基礎　情報数学](https://www.kinokuniya.co.jp/f/dsg-01-9784781912073)

# まとめ
今年は、資格が4つ取れ、目標を達成できました。来年もよい本に巡り合えますように。
来年はなんの資格を目指そうかな。
ONYX 触ってみた

この記事は、 [大阪工業大学 Advent Calendar 2023](https://adventar.org/calendars/9108)の18日目の記事です。

# onyxとは
wasmへのコンパイルに特化したプログラミング言語
[公式ドキュメント](https://docs.onyxlang.io/book/Overview.html)

# Hello World
```onyx
use core {*}

main :: () {
    println("Hello, World!");
}
```
# 実行方法

```
onyx run main.onyx
```

# ファイル分割
foo.onyx
```onyx
// There can be comments before the package declaration.

package foo

func :: () {}

Struct :: struct {}
```

main.onyx
```onyx
package main

use foo

main :: () {
    foo.func();
}
```

# 演算子
普通の四則演算と同様
比較演算子は, c言語と同様

# ポインタ
c言語と同様

# 感想
まだ, 触ったばっかりなのでメリットがよくわからｎ
Carbon::parse(null);は現在時刻を返す

## はじめに
私は株式会社qnoteにて、勉強会の幹事を務めております。
2023年度勉強会の珠玉のネタを2023Qiitaアドベントカレンダーに投稿していこうと思います。

## 対象者
この記事は下記のような人を対象にしています。

- 駆け出しエンジニア
- プログラミング初学者

## 結論
PHPのCarbonの引数が空文字やnullの場合、現在時刻が返されてしまう…気をつけなはれや！

## 解説
PHPではタイムスタンプを扱うのに重宝するCarbonですが、初心者が陥りやすい罠について、解説します。

引数に空文字やnullがはいると、現在時刻を返してしまいます！
この挙動を知らずにじっそうすると、思わぬ結果になることもありますので、要注意です。
引数が空文字やnullになる場合はcarbonを実行しないなどの記述が必要か、ご検討ください。

```php
>>> Carbon\Carbon::parse('')->format('H:i');
=> "11:20"

>>> Carbon\Carbon::parse(null)->format('H:i');
=> "11:20"
```

## おわりに
Carbon::parse(null);は現在時刻を返す、についてまとめました。



## 参考記事
https://www.notion.so/Carbon-parse-null-31709e2c51854e87bdb2f5b5be62789b?pvs=4
Lightning Experience のタブアイコンを確認する

小ネタです。カスタムタブを作るときに選択するアイコン、未だに Classic のままで、選んだ後に Lightning Experience のアプリケーションに戻るとなんだか思っていたのと違う、という経験をした人は少なくないのではないでしょうか。PDA やブラウン管テレビ等、そもそもアイコン自体が古すぎたりもしますが。

![タブ設定に表示されるアイコン](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/184624/fdb0db7f-3d24-579c-862c-09d7e5b8b9da.png)

既存の設定画面にはなかなか投資される気配がないため、以下のような、 Classic のアイコンと Lightning Experience (SLDS) のアイコンの対応表を作りました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/184624/5b25a170-3058-5094-20ca-83e9173acf41.png)

全量はこちらから。

https://github.com/shunkosa/salesforce-tab-icons/

一覧で眺めると今まで試したことのないアイコンに出会えるかもしれません。楽しいカスタムタブ・カスタムアプリケーション作成ライフをお送りください。
PrismaでSQLの作成や管理、反映の手間を削減する

# Prismaのインストールと初期設定
- 下記コマンドを実行
```
npm init -y
npm install prisma
npx prisma init
```

- 「.env」ファイルにDBの接続情報を記載
  - [DockerでMySQLとDB管理ツールのAdminer or phpMyAdminを実行する](https://qiita.com/teradatk/items/1a31a9c6f18015e1518f)で作成したDBを使用
```.env
DATABASE_URL="mysql://root:mysql@localhost:33306/test_db"
```

# テーブルの作成と反映
- 「schema.prisma」ファイルにテーブル情報を作成します
```schema.prisma
model User {
  id    Int     @id @default(autoincrement())
  email String  @unique
  name  String
  nickname  String?
}
```
- 下記コマンドを実行するとテーブルが作成されます
```
npx prisma migrate dev
```

- 作成されたテーブルの内容
![1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/361770/7f88124c-f4f3-fffd-ef9d-d7d6913f84d3.jpeg)

# テーブルの変更と反映
- 文字列長の変更と項目を追加します
```schema.prisma
model User {
  id    Int     @id @default(autoincrement())
  email String  @unique
  name  String @db.VarChar(60)
  nickname  String? @db.VarChar(60)
  remarks1 String? @db.VarChar(250)
  remarks2 String? @db.VarChar(250)
}
```
- 下記コマンドを実行するとテーブルが変更されます
```
npx prisma migrate dev
```

- 変更されたテーブルの内容
![3.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/361770/cd45e50a-247b-1116-3b4f-ed4112ad68aa.jpeg)

# コマンド実行時にmigration.sqlファイルに差分が保存されます
- migration.sqlファイルの中身はcreate文やalter文になります
```
migrations
   │  migration_lock.toml
   ├─20231211003530_init
   │      migration.sql
   └─20231211015124_
          migration.sql
```
```20231211003530_init/migration.sql
-- CreateTable
CREATE TABLE `User` (
    `id` INTEGER NOT NULL AUTO_INCREMENT,
    `email` VARCHAR(191) NOT NULL,
    `name` VARCHAR(191) NOT NULL,
    `nickname` VARCHAR(191) NULL,

    UNIQUE INDEX `User_email_key`(`email`),
    PRIMARY KEY (`id`)
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
```
```220231211015124_/migration.sql
-- AlterTable
ALTER TABLE `User` ADD COLUMN `remarks1` VARCHAR(250) NULL,
    ADD COLUMN `remarks2` VARCHAR(250) NULL,
    MODIFY `name` VARCHAR(60) NOT NULL,
    MODIFY `nickname` VARCHAR(60) NULL;

```

# DBの接続先を変更したい場合
- dotenvを使用する必要があるため、下記コマンドでインストールする
```
npm install dotenv --save
```
- 接続先の設定ファイル名が「.evn.test」の場合の例
```
dotenv -e .evn.test -- yarn prisma migrate dev
```
流行りのGenerative AIを動かすのにも、Nutanixはいいぞという話

これは[Nutanix Advent Calendar 2023](https://adventar.org/calendars/8538) の17日目のエントリーです。師走ですなあ。30分で書くぞ！

## ライブ告知
いきなりそれかよ。[TECK x ROCK Festival 2023](https://trf.connpass.com/event/293949/)というライブイベントを12月23日にやります。出演者38人全員エンジニアというお祭りです。[ヤギの人](https://smzklab.net/)も出るよ！みんなきてね。

https://trf.connpass.com/event/293949/

## Nutanixに入社してそろそろ半年になりますが
なかなか楽しいです。いろいろカオスだったりもしますが、まだまだスタートアップっぽい雰囲気も強く、私のロールもわりとやりたい放題でいい感じです。
製品の内部実装を見ていくとこれまたなかなかのカオスだったりもしますが、多種多様なコンポーネントが複雑に連携して表面的には非常にシンプルにスケールするのを眺めていると、クラウドネイティブってこういうことだよなあ。と思ったりもします。
みたいなことを、先日のCloud Native Days Tokyo 2023で [NutanixなんもわからんクラウドネイティブおじさんがNutanixの中の人になってみたら想像以上にクラウドネイティブ文字数](https://event.cloudnativedays.jp/cndt2023/talks/2080) というお題でお話ししました。

https://event.cloudnativedays.jp/cndt2023/talks/2080

## 流行りのGenerative AI
CNDTのセッションでも触れたのですが、Generative AIがもうね。これをバズってると言わずになんと言おう。Nutanixも、**GPT-in-a-Box** という、それ明らかに釣りタイトルでしょみたいなのを出してきましたが、そのへんの背景は昨日の[@tknrszkさんの記事](https://qiita.com/tknrszk/items/70d83c96bf0e0ab53c27)を読んでいただくとして。

https://qiita.com/tknrszk/items/70d83c96bf0e0ab53c27

## AIの本質って
要はデータプロセッシングなわけです。70億パラメーターとかのLLMだとしても、やってることは超巨大な行列計算。
インフラおじさんたちはなぜかAIといえばGPU、みたいな方向に走りがちです。まあモデルをチューニングするとか、推論サーバーを立てるとかであればGPUも必要になったりはするのですが、そもそも一般企業のえらい人が株主向けに言ってる「AIの活用」って、本質的には「データの活用」なんですよね。
まあそのへんも昨日の[@tknrszkさんの記事](https://qiita.com/tknrszk/items/70d83c96bf0e0ab53c27)でまとめてくれているので、

## で、Nutanixだとどうなるのよ
というのをめちゃめちゃ簡単に見せるデモを作ったので、そちらの紹介をもって本日のネタとしたいと思います。手抜き言うな。
CNDTのセッションでもちらっとお見せしたやつです。社内向けに書いてたざっくり構築手順とサンプルコードがあったのですが、べつに隠すもんでもないやろ。ということで公開してしまいます。こちら。 

https://github.com/jyoshise/GenAI-Demo-on-Nutanix

たとえばこんなことがやりたいとします。絵が雑ですまんな。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/103746/61684a38-f303-8480-ca6e-d86b75ad45dd.png)
いわゆるRAGです。日本語でうまいことが言えるだけの~~ひろゆき~~LLMに単に質問するのではなく、社内の機密情報からの類似性検索結果を一緒に与えることにより、「社内の機密情報を調べたうえで答えてくれる」ちょっと使える~~ひろゆき~~LLMにしようというわけです。
で、これをビジネスでやろうとすると、大事なのが左側の、青い矢印のところ。
- データはナマモノなので、スケーラビリティや世代管理が必要になります。
- もちろん機密文書なのでセキュリティも最優先で考えなければなりません。
- 元データの追加・更新に追従して類似性検索DBもアップデートしていきたいので、この部分はServerlessでイベントドリブンに回したいところです。

というわけでざっくり、こんな置き方になるだろうなあと想像します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/103746/7664191d-9d6b-86bd-899d-83ba656ab039.png)

イベントドリブンなパイプラインや、推論のサービングのところは、KubeFlowで一通り揃います。
ちゃんとNutanix版のKubeFlowもあります。

https://nutanix.github.io/kubeflow-manifests/

つまり、Nutanix+Kubernetes+KubeFlowなら、すぐに作り始められますね、と。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/103746/c40f53d9-9055-f562-4c85-a780d0d7b0f8.png)

実際、私がこのデモ作るのに要した時間は半日程度です。まあもともと家のPCで似たようなことやってたからではあるんですが。
つまり、下回りにNutanixがあれば、2日目からはゴリゴリコード書いてRAGなりチューニングなりに集中できますよ、と。

## 良くない？
Nutanix社員であるということを抜きにしても、私は個人的に良いと思いました。いや、ちゃんとしたストレージサービスが備わってるってのはめちゃめちゃ楽ですよ。

というわけでメリークリスマス！
「学び」とは、他の場面にも応用できる「スキル」を身につけること

「なぜ学ぶのか」って問われたら、いいことがあるし楽しいから答えるけど、
実際の「勉強は好き？」って問いには否定もある。

なぜなら、「勉強」は目的が不明確で、知識やスキルの獲得に結びつくイメージがあるためだ。
でも、学ぶことは個別の経験を他の場面にも生かせるようにすること。

例えば、テストでの経験から得た「問題の全体像を把握し、優先順位をつける」ことは、仕事でも役立つ。

学べる人は経験を次に活かせるし、学べない人は都度新たな経験に対処しなければならず、労力がかかる。
学ぶためには基本的な知識とスキルが必要で、それを他の場面にも応用できる「スキル」を身につけることが大切。

勉強で得る知識とスキルは学ぶ基礎であり、省エネできるだけでなく、新たな発見ももたらす。結局、学ぶことは楽しさと同時に、成長と柔軟性を生むものなのだ。
gitlabで「マージ4週間前」→「マージ2023/07/12 12:34」に変更

## はじめに
私は株式会社qnoteにて、勉強会の幹事を務めております。
2023年度勉強会の珠玉のネタを2023Qiitaアドベントカレンダーに投稿していこうと思います。

## 対象者
この記事は下記のような人を対象にしています。

- 駆け出しエンジニア
- プログラミング初学者

## 結論
`https://＜GitLabサーバー＞/-/profile/preferences`の「相対時間を使用」のチェックボックスを外すだけ！

## 解説
GitLabのマージリクエストのマージ日時ですが、「4週間前」「2日前」のように表示されていると思います。
これはこれで便利なんですが、正確な年月日が表示させたい！と思って調べてみました。

https://qiita.com/ynott/items/5d8af56131cce2cbed64

`https://＜GitLabサーバー＞/-/profile/preferences`の「相対時間を使用」のチェックボックスを外すと...

「2023/12/17 17:49」のような表記になりました！
これで、同日にマージされたものの順番が分かるようになりましたね。

## おわりに
gitlabで「マージ4週間前」→「マージ2023/07/12 12:34」に変更する方法についてまとめました。

## 参考記事
https://www.notion.so/gitlab-4-2023-07-12-12-34-41349ef9d7d540f0aaf3d412ba5dcbd2?pvs=4

https://qiita.com/ynott/items/5d8af56131cce2cbed64
トラブルの幕引き〜ITサービスマネージャーとしてのお作法〜

前回、システムトラブルが発生したときのITサービスマネージャーがとるべき振る舞いについて記事を書きました。
なんとかシステム復旧できお客様への報告もひと段落、トラブル対応はクロージングに持っていけそうだ…そんなときにもITサービスマネージャーの出番です。

# ダラダラ引っ張らない。トラブル体制の解散を宣言しましょう。
目の前のトラブル対応が終わったあと、早々に帰ってしまったり普段の業務に戻ったりしていませんか？

ぜひITサービスマネージャーとして、トラブル対応のための体制は解散し通常体制にもどることを関係者に宣言しましょう。
つい念のためで特別対応を続けてしまったりしがちですが、暫定であってもトラブルからの復旧ポイントを明確にすることが重要です。

# 戦友にお礼を言うことを忘れずに。
ともにシステムトラブルに対応したメンバは、役職や役割の違いはあっても言わば戦友のようなものです。
限られた時間で復旧を急ぐ場面では、つい語気が荒くなったり命令口調になるなど、きつい言い方になってしまうこともあるかもしれません。

システムトラブルが落ち着いたタイミングで必ず、お礼とねぎらいの言葉を（ときにはお詫びも）かけ合うことが、良いチーム作りに繋がります。

# 経験を糧にする。
システムトラブル対応のなかで得た気づきはチームの資産です。

例えば、他チームのメンバから知らない用語がでたら、あとで調べて自分やチームの知識にしておくこと。
システム復旧へもっと最短距離で進めるアクションは無かったか？
メンバ各自がひとつ上のポジションで成果をだすためにはどんな行動が必要だったか？
また、このトラブルを未然に防ぐにはどうしたら良かったか？

このような観点で振り返り、ITサービスマネージャーとしてトラブル対応の流れを多角的に分析し、改善していくことが必要なのです。

# 最後に
ITサービスマネージャーは「お客様やユーザの隅々にまでサービスを送り届けシステムの持つ価値を最大化するにはどうしたらよいか」を常に考え、継続的に取り組んでいくことが重要です。

私自身は丸10年システム運用界隈の仕事をしてきたなかで大小さまざまなトラブルを経験してきましたが、
システムトラブルが発生したときに「出番がきた！！」と腕がなるようになればITサービスマネージャーとして本物と言い切れる気がしています。
（まだその域には到達できていません、、）
自社のマスコットキャラクターをゲームに追加実装

# 続ノベルゲーム作成
去年もノベルゲームを作成して記事を書いた↓。
[Webサーバの構築とゲーム実装](https://qiita.com/yus-harada/items/0260f2ed192b15f7fc13)

今年は去年作ったものを発展させていった形となる。
そのため引き続きRen’pyを使っていく。

## 新・マスコットキャラクターの追加実装
弊社エニプラはマスコットキャラクターが存在する。えにぃとプラ子だ。
今年2023年には新規マスコットキャラクターが誕生した。その名は「ニィ子」
![nyiko normal.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/525892/71b55690-30ad-4f9c-8a92-2d88b00112c7.png)

せっかく新キャラが出来たので、じゃあゲームに実装しよう、となった。
Ren’pyの使い方は公式サイトやチュートリアルゲームをやればある程度ゲーム作成には困らない。
今回はキャラクターの追加なのでimagesフォルダに画像を格納。
見た目通りピンク系統のキャラクターのため、ゲームに表示される名前もピンク系統にしたいのでカラーコードをググって下記のように設定
```
define n = Character(_("ニィ子"), color="#ff7fbf")`
```

次に画像を画面上のどこに表示させるかをTransformでいい感じに設定してあげるだけでよい。
```
transform slightright:
    xalign 0.975
    yalign 1.5
```

あとは画像の呼び出し。「nyiko smile」はimagesフォルダに格納した画像のファイル名。
```
show nyiko smile at slightright
```
実際のゲーム画面が下記。

![b52b3c371627cee6.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/525892/85763dc9-11db-18f6-5704-9a8d5181abbe.jpeg)

# 今後の活動
ゲーム作りは最初難しいかなと思ったが、いざ初めて見るとRen’pyはドキュメントが豊富でひとまずの形にするだけであれば簡単だ。そして作っていて楽しい。
次はぷよぷよプログラミングをやってみたいと個人的に思っている。
実際に実務で使った管理パネル2つ

## 概要
実際に実務で使った管理画面パッケージ2つを紹介します。
- システムの管理画面
- 業務システム

に利用しました。

## Laravel-AdminLTE
https://github.com/jeroennoten/Laravel-AdminLTE

bootstrapベースで作られている管理画面パッケージ、3案件これで戦いました。
内2案件はlivewire、alpine.jsと組み合わせて開発しました。


結構有名な管理パッケージで、[bladeコンポーネント](https://github.com/jeroennoten/Laravel-AdminLTE/wiki/Components-Categories)が多数用意されているので少ないコードでUIが作れます。
専用のconfigファイルがあり、サイドメニューやヘッダーに関する色んな融通が利きます。



### 過去書いた記事
https://qiita.com/sgrs38/items/c3eec061f0850046443d

https://qiita.com/sgrs38/items/89a6a59b896669dfd725



## filament

https://filamentphp.com/

https://github.com/filamentphp/filament

tailwind・livewire・alpine.jsで作られているモダンな見た目の管理画面パッケージ（最強）

基本的に手作りでhtmlを書く事はありません、メタメタプログラミングでフォームやテーブルを生成します。
こちらは管理画面を作成する時に採用しました。
予め色んな仕組みが用意されているので、短い納期の中早い速度で不具合も少なく開発できました。
どういうものか説明するのがちょっと難しいですが、
- テーブルを作成する仕組み(テーブルビルダー)
    - 簡単に検索機能を持ったテーブルが作成できる
- フォームの作成する仕組み（フォームビルダー）
    - 簡単にフォームが作成できる
- ウィジェットの作成する仕組み
    - ダッシュボードで使うカードやグラフ

などが備わっています。[デモはこちら](https://demo.filamentphp.com/login)

### 過去書いた記事
https://qiita.com/sgrs38/items/149c2b7ff3a251f72a32

https://qiita.com/sgrs38/items/f4f5cb86fad38c4c1117
シェルプログラミング

# zipコマンド
圧縮対象をzipでファイルを圧縮
zip 圧縮ファイル名.zip 圧縮対象
オプション　-r: ディレクトリは以下のファイルも圧縮


# mktempコマンド
mktemp xxx.tsv
一時ディレクトリ作成
オプション -d: ディレクトリ作成

# cp コマンド
コピー元をコピー先にコピーする
cp コピー元1.tsv コピー元2.tsv コピー先ディレクトリ名
オプション: 
-r サブディレクトリも含めてコピーする
-p: 元のファイルのオーナー、グループ、パーミッション、タイムスタンプ保持

# >　リダイレクション
入力先、出力先を変更させる
## command > /dev/null
/dev/nullとは、ゴミ箱のようなもの。なので、標準出力やエラーメッセージは>によりゴミ箱行きになる、

# trapコマンド
trap action signal
signal に指定されたシグナルを受けると、actionに指定された動作が起動する。signalにはシグナル名称またはシグナル番号を指定する。シグナル名称の場合、INTを指定する

## trap コマンド Exit
正常終了時にコマンドが動作する、

## trap コマンド ERR
異常終了時にコマンドが起動する

# If 
条件分岐
オプション -e: -が存在するtrueを返す

# スペース
シェルスクリプトの原則の1つが、コマンド列を連結したものであることである。

## 空けない場合
### i=0のような変数の代入文
仮にi = 0とスペースを空けてしまうと、iコマンドの引数は=と0であると見なされて、誤った動作になってしまう。

## 空白を開ける場合
### if [ $i != 0 ]のような条件分岐や制御構造
ifはifコマンドであり、ifコマンドの後に続く[]はifコマンドの構成の一部ではない。[]は[コマンドというものである。$i != 0は[コマンドの引数として見られる。

#### 参考
https://qiita.com/piroor/items/0cb44663430bfc66c204
【Kaggle】初心者こそイベントに参加/発表してみよう


# この記事で言いたいこと


Kaggleは機械学習コンペでありプラットフォームである。
一方で**コミュニティとしての側面**も持っており、Kaggleを愛し、日常的にコンペに参加する人は"Kaggler"などと呼ばれる。
この記事では「**そのようなコミュニティに参加し、時に発表することは初心者にこそ有意義であるよ**」ということを使えたい。

なお、ここでは「初心者」を明確に定義はしないが、Kaggleに興味はあるもののなかなか成果が出せない、メダルが取れないといったような層をなんとなく想定している。

ちなみに私は[@tetsuro731](https://www.kaggle.com/tetsuro731) と申します。
都内在住のKaggle Expertです。



# どんなイベントがある？

### 関東Kaggler会 (自分が参加したのはこれ)

- 参加者は合計数百人にのぼった
- 現地参加の抽選に落ちても、Zoom参加、Youtube配信などもあった
- GM (GrandMaster)による特別講演+LTいくつか

https://connpass.com/event/290248/

### Kaggle Tokyo Meetup 2023 
- 今年4年ぶりに開催 
- Kaggler Expert以上と以下で参加のための抽選区分が分かれている
- こちらも招待講演+LT  

https://connpass.com/event/292810/

### 関西Kaggler会
- 関東に比べると頻繁に開かれており、よりカジュアルな印象
- 自分は参加したとこないが、より「コミュニティ感」が強いのはこっちかも

https://kansaikaggler.connpass.com/event/288677/

他にも小さいものを含めるといろいろあるかもしれないが、有名ないのはこのあたりだろう。

# Kaggleは孤独だ

Kaggleはよくマラソンに例えられることがある。
競技プログラミングなどは数時間ですべての決着がつくが、**Kaggleのような機械学習コンペは2~3ヵ月かけて取り組まなくてはならない**ことが多い。
そのためモチベーションを保ち続けるのが極めて難しい。

チームで参加すればまだ相談できる人もいるかもしれないが、僕のような基本ソロで参加している人間は**基本孤独**である。
特に方向性を見失ったりなかなか良い成績が取れないときはつらい。

そんなときの一つの手段はDiscussionに投稿したり議論に参加することであるが、
基本すべて英語であるのとテキストベースのコミュニケーションとなるので「**コミュニティに属してる感覚**」を得るのはある程度限界があるかもしれない。

そんな場合こそ上記のようなイベント参加を進める。
以下に
- 参加することのメリット
- 発表することのメリット

を書いていく。


# 参加することのメリット

イベントにもよるが、普段普通に生活していてなかなかお目にかかることのできないGMの話が聞けることも珍しくなく、懇親会などで話しかければ直接話を聞くことが可能だ。

（懇親会で実際に話すと「**あ、GMの人も普通の人間で会話するんだ**」という不思議な感覚を得ることができる（？））

現行コンペに直接関係することでなければ何かを相談することも可能だし、Kaggleというコミュニティに属することによってモチベーションも上がる。

発表内容もバラエティに富んでいることが多い。

コンペで勝った手法の紹介だとテクニカルな説明がメインになることもあるが、「**初心者がコンペに取り組む上でどうするか？**」といった取っつきやすいトピックが発表されることも多い。
例えば自分が参加したイベントだとmakotuさんのコンペの取り組み方の紹介が非常にためになった。

https://speakerdeck.com/makotu/n-equals-1no-teburudetakonpenoqu-rizu-mifang



# 発表することのメリット
さて、参加に比べて発表となるとさらに敷居が高く聞こえる。
というのもイベントで招待講演をするのはいわゆる"つよつよGM Kaggler"のような人が多く、
「**自分なんかが発表していいんだろうか？**」
と恐縮してしまうのも自然である。
ただ、自分が主催者などと話をした感覚では「**一部の強い人ばかりが発表するのではなく初心者も含めて広く情報発信をする場があったほうがコミュニティ全体にとって有益である**」というのも真なのではと思った。

例えば本当の初心者にとっては「10年間Kaggle一筋で頑張ってる人のアイディア」よりも「最近Kaggleを始めた人がどうやってメダルを取ったか」のような話のほうがためになるかもしれない。

イベントでは10分弱のLT枠が容易されていることも多く、この枠であれば自分で自由にテーマを決めることができる。
自分の場合は業務でレコメンドに関わっている and 参加したコンペのレコメンドコンペが多かったのでそこに絞って発表した。

https://speakerdeck.com/tetsuro731/20230923-jin-nian-norekomendokonpenituite-at-tetsuro731

自分はKaggle Expertで他の参加者に比べるとたいした実績もなかったが、これをきっかけにいろんな人と話すことができたので発表してよかったなーと思えた。

また、発表者になれば優先的に抽選に選んでもらえることも多く、
「現地行きたいけど抽選当たるかな...Zoom枠だったら当たるかな？」
などとそわそわする心配もない。



# まとめ

人によって何に心地よさを感じるかは異なるため、このようなイベントへの参加、発表は
万人におすすめできるものではないかもしれない。
しかし、もしあなたがKaggleに取り組む上で孤独に戦い苦しんでいるのであれば、このようなコミュニティに顔を出してみるといいのではないかと思う。

最後に、このような素晴らしいイベントを定期的に開催してくださっている方々、日々有益な情報を惜しみなく発信してくださる素晴らしきKagglerの方々に感謝を捧げたい。
save()とcreate()の挙動の違い

## はじめに
私は株式会社qnoteにて、勉強会の幹事を務めております。
2023年度勉強会の珠玉のネタを2023Qiitaアドベントカレンダーに投稿していこうと思います。

## 対象者
この記事は下記のような人を対象にしています。

- 駆け出しエンジニア
- プログラミング初学者

## 結論
- save()は保存だけ。(変更がない場合、updated_atは更新されない)
- create()はインスタンス化+データ挿入+保存まで一括で実行

## save()
saveメソッドは保存するだけです。
インスタンス化+データ挿入は事前に行う必要があります。
```php
$user = new User();
$user->name = $request->name;
$user->save();
```
また、カラムの内容を更新する際に、挿入されるデータが更新前と同じものであれば、updated_atのカラムが更新されません！

## create()
createメソッドはインスタンス化+データ挿入+データ保存を一括で行います。
```php
$user = App\Model\User::create(['name' => $request->name]);
```

## おわりに
save()とcreate()の挙動の違いについてまとめました。

## 参考記事
https://www.notion.so/save-create-c7d62ea7b8be4c56addf0c13c84348aa?pvs=4

https://qiita.com/gomaaa/items/91e5cbd319279a2db6ec

https://qiita.com/adgjmptwgw/items/7cdbf0e097fae7bd0ecd
PHP学習～繰り返し構文～


学習したことのまとめ。

参考サイト：paiza

## 繰返し構文
```
<?php
for ($i = 0; $ < 5; $i++) {
    繰返ししたい処理内容
}
?>

// $i=0; →初期値
// $i < 5; →繰返し条件
// $i++ →変化文
```

## 条件分岐との組み合わせ
if文との組み合わせ。

```
<?php
    $count = trim(fgets(STDIN));

    for ($i = 0; $i < $count; $i++){
        $number = trim(fgets(STDIN));

        if ($number == 10) {
            echo $number . "は10に等しい\n";
        } elseif ($number > 10) {
            echo $number . "は10より大きい\n";
        } else {
            echo $number . "は10未満\n";
        }
    }
?>    
```
アクセサー(ゲッター)に引数を入れる

## はじめに
私は株式会社qnoteにて、勉強会の幹事を務めております。
2023年度勉強会の珠玉のネタを2023Qiitaアドベントカレンダーに投稿していこうと思います。

## 対象者
この記事は下記のような人を対象にしています。

- 駆け出しエンジニア
- プログラミング初学者

## 結論
無限ループを防いでアクセサーを活用しましょう。

## 解説
条件次第で値をそのまま返す可能性がある場合に、無限ループを防ぐ。

```php
// NG
public function getQuantityAttribute()
{
	return $this->quantity > 0
		?	$this->quantity	
		: 0; 
}

// OK
public function getQuantityAttribute($quantity)
{
	return $quantity > 0
		?	$quantity	
		: 0; 
}
```

上記の書き方は古いので、最新のアクセサー(ゲッター)の書き方はこちら。

[【Laravel9対応】Eloquent の Accessors / Mutators](https://kobatech-blog.com/laravel-accessors-mutators/)

## おわりに
アクセサー(ゲッター)に引数を入れる方法についてまとめました。

## 参考記事
https://www.notion.so/ee2f0a560e0e454e8ae78a3769210bbb?pvs=4
iPadの画面収録で、音声を入れる / Macの画面にiPadの画面を共有する

## はじめに
私は株式会社qnoteにて、勉強会の幹事を務めております。
2023年度勉強会の珠玉のネタを2023Qiitaアドベントカレンダーに投稿していこうと思います。

## 対象者
この記事は下記のような人を対象にしています。

- 駆け出しエンジニア
- プログラミング初学者

## 結論
Macの画面にiPad/iPhoneの画面が共有できると、開発効率が爆上がりするのでおすすめ！

## iPadの画面収録に音声を入れる方法

[iPadで画面収録・録画(動画キャプチャ)する方法 | iPad Wave](https://www.ipodwave.com/ipad/howto/screen_recording.html#:~:text=停止できます-,iPadの画面収録で音声も録音する,収録(録画)できます。)

- 操作解説動画取りやすそう。

## MacとiPadの画面を同画面に表示+音声を収録する方法

- 結論：QuickPlayerでiPadの画面をmacに表示し、teamsのレコーディング機能を使って全画面で収録する

chatGPTに聞いたら一瞬だった

```
iPadの画面をMacに移す方法はいくつかあります。以下は、一般的な方法の一つである「QuickTime Player」を使用した方法です。

**QuickTime Playerを使用してiPad画面をMacに移す方法:**

1. **Lightningケーブルを使用してiPadとMacを接続します。** iPadのLightningポートとMacのUSBポートにケーブルを接続します。

2. **QuickTime Playerを起動します。** Mac上でQuickTime Playerを開きます。アプリケーションフォルダにあるか、Spotlight検索で見つけることができます。

3. **ファイルメニューから新しいキャプチャを開始します。** QuickTime Playerを開いたら、「ファイル」メニューから「新しいキャプチャ」または「新しい画面収録」を選択します。

4. **iPadを選択します。** キャプチャデバイスの設定画面が開くので、キャプチャデバイスのドロップダウンメニューから「iPad」を選択します。

5. **画面収録を開始します。** QuickTime PlayerはiPadの画面を表示し、画面収録を開始できるオプションを提供します。必要に応じて、オプションを調整してから収録を開始します。

6. **iPadの画面を表示し、録画します。** QuickTime PlayerがiPadの画面をMacに表示し、あなたが選んだオプションに従って録画を開始します。画面上で何かを行うと、その操作も録画されます。

7. **画面収録を停止します。** 画面収録を停止するには、QuickTime Playerの制御パネルに戻り、録画ボタンをクリックまたはタップします。録画を停止すると、録画ファイルが自動的に保存されます。

この方法を使用すると、iPadの画面をMacに表示し、録画することができます。ただし、QuickTime Playerの画面収録機能を使用するには、iPadとMacを接続する必要があります。また、QuickTime Player以外の方法も存在するため、使用状況に応じて選択肢を検討してください。
```
## 活用方法
- 社内教育動画
    - xcodeとiPhone/iPad画面を両方表示
    - Chromeブラウザに管理画面を表示+iPhone/iPad画面を表示
    - ゲーム実況風に作れそう

## おわりに
iPadの画面収録で、音声を入れる / Macの画面にiPadの画面を共有する方法についてまとめました。

## 参考記事
https://www.notion.so/iPad-Mac-iPad-9238e0f6e81c430b8cf67872a6f3767b?pvs=4

[[解決] iPhone/iPadの画面をmacで録画する簡単な方法](https://recorder.easeus.com/jp/screen-recording-tips/record-iphone-screen-on-mac.html)
ABC333回答メモ

# 0.はじめに
　今日はABCを正解で一個飛ばしてEを正解できました。
　Dは木の問題で粘ってみましたが無理でした。
　結果レート+27で780となりました。
　再緑まであと1歩！


# 1.A - Three Threes 
　やけに簡単な問題と思ったら333回目のABCだからの模様。
　自分なりに丁寧にfor文を回して解答文字列を作り
　出力して終了。

　https://atcoder.jp/contests/abc333/submissions/48537100


# 2.B - Pentagon
　2問目から歯ごたえが段違いに。
　早く回答しないと。と思い愚直にA~Eの全組み合わせについて
　愚直に距離が1(となりあう組)と2(1個飛ばしの組)で
　辞書登録して、距離が一致するかを表示。

　https://atcoder.jp/contests/abc333/submissions/48547546


# 3.C - Repunit Trio
　さすがトヨタコンテストというくらいCの難易度が爆上がり・・・。
　と、思いつつ冷静に見るとそれほどでもなかったでした。
　何種類かの1を連続した数から3つを選んで足し合わせたものを
　ソートして頭から数えていくと考えれば、あとは3つを選ぶ種類だけ。
　最大Nが最大333ということで、12種類から3種類選ぶパターンで
　リストを作ってあげれば、小さい方から333番目までいける！
　と、実装を始めました。

　B問題と同じく実装に使った、1を連結したリストは
　手作りで、[1,11,111,・・・,111111111111]と、愚直な政策でした。
　あとはitertoolsのcombinations_with_replacementを使って
　3個の組合わせを作り、合計をリストに足していき
　最後にリストをソートして、N番目を表示。でAC頂きました。

　https://atcoder.jp/contests/abc333/submissions/48563853


# 4.D - Erase Leaves
　E問題を解いた後戻ってきて頑張りましたが、時間切れとなりました。
　解説を見たら問題を誤解していて、ずうっと1から生えている枝に紐づく頂点が
　一番少ない枝を選ぶ実装をしていましたが、実際は、紐づく頂点が一番大きい
　枝分は残してそれ以外を消していかないことが分かり、納得しました。

 　https://atcoder.jp/contests/abc333/submissions/48604452


# 5.E - Takahashi Quest
　後ろから敵を見ていき、敵にあうポーションだけ拾うシミュレーションをして
　拾う必要があるポーションに印をつけて置き、最後にまた
　先頭から見ていき、印がついたポーションを拾って適切な敵に
　使った場合のKminをメモリつつ、ひろう拾わないをリストにメモっていき
　最後にKminとリストを出力してAC頂けました。
　バッチ処理好きの私とは相性がいい問題でした。

　https://atcoder.jp/contests/abc333/submissions/48582524


以上
好きな言語でシェルスクリプトを書く

## はじめに
私は株式会社qnoteにて、勉強会の幹事を務めております。
2023年度勉強会の珠玉のネタを2023Qiitaアドベントカレンダーに投稿していこうと思います。

## 対象者
この記事は下記のような人を対象にしています。

- 駆け出しエンジニア
- プログラミング初学者

## 結論
好きな言語でシェルスクリプトを書いて、作業を自動化しましょう！

## PHPでシェルスクリプトを書く
```php
#!/usr/bin/env php

<?php
    print('Hello PHP');
```

## JS(node?)でシェルスクリプトを書く
```jsx
#!/bin/sh 
":" //# comment; exec /usr/bin/env node --noharmony "$0" "$@"

console.log('Hello JS');
```

## Swiftでシェルスクリプトを書く
```swift
#!/usr/bin/swift

print("Hello Swift")
```

## おわりに
好きな言語でシェルスクリプトを書く方法についてまとめました。

## 参考記事
https://www.notion.so/67040e245f154d3eae099c082f865926?pvs=4

[PHPを直接実行する（#!/usr/bin/php -q） - Qiita](https://qiita.com/tksnino/items/d64863b92d65a54bae14)
[PHPでシェルコマンドを実行する - inappeのぶろぐ](https://hosikuzu.hatenablog.com/entry/2014/06/18/124214)
[shebangからNode.jsのオプションを指定する - Qiita](https://qiita.com/hnw/items/0eb94e804a674c75a825)
[JavaScriptでシェルを書こう ——zxのご紹介 - GMOインターネットグループ グループ研究開発本部](https://recruit.gmo.jp/engineer/jisedai/blog/javascript-zx-introduction/)
[Swiftでシェルスクリプトを書く - Qiita](https://qiita.com/caesar_cat/items/71903c7155319030b658)
オブジェクトの任意の場所に条件次第で入れたり入れなかったりできるようにしたい

## はじめに
私は株式会社qnoteにて、勉強会の幹事を務めております。
2023年度勉強会の珠玉のネタを2023Qiitaアドベントカレンダーに投稿していこうと思います。

## 対象者
この記事は下記のような人を対象にしています。

- 駆け出しエンジニア
- プログラミング初学者

## 結論
オブジェクトの任意の場所に条件次第で入れたり入れなかったりできるようにするには、スプレッド構文を使いましょう！

## 解説
オブジェクトの任意の場所に条件次第で入れたり入れなかったりできるようにしたい場合、下記のようにしましょう！

```jsx
const obj = {
	a: 'aaaa',
	...(condition && { b: 'bbbb' }),
	c: 'cccc',
}

// condition === true
{
	a: 'aaaa',
	b: 'bbbb',
	c: 'cccc',
}

// condition === false
{
	a: 'aaaa',
	c: 'cccc',
}
```

## おわりに
オブジェクトの任意の場所に条件次第で入れたり入れなかったりする手法についてまとめました。



## 参考記事
https://www.notion.so/fd6b189b01ac4b3ab90cb8167bb72e77?pvs=4

https://qiita.com/sin9270/items/5f892aa25602194b79c7
JetpackCompose縦幅の最大幅、最小幅を設定する方法

この前にCompose横幅の最大幅、最小幅を設定する方法を紹介しました。

# Compose横幅の最大幅、最小幅を設定する方法
https://qiita.com/yuta317/items/57ad03d986d718d9bf36


縦幅の最大幅、最小幅を設定することもできます！

# 最大幅、最小幅を設定する方法 
`Modifier.heightIn(0.dp, 40.dp)`
`Modifier`に`heightIn`を設定すると実装できます。

便利なので覚えておくと良いかもしれません。
PHPで先頭の文字列を取得する方法

## はじめに
私は株式会社qnoteにて、勉強会の幹事を務めております。
2023年度勉強会の珠玉のネタを2023Qiitaアドベントカレンダーに投稿していこうと思います。

## 対象者
この記事は下記のような人を対象にしています。

- 駆け出しエンジニア
- プログラミング初学者

## 結論
[0]で簡単に先頭の文字を取得できます。

## 解説

```php
$text = 'Hello World!!!'
print $text[0]; // [0]で先頭の文字にアクセスできる！

// 結果
H
```

## おわりに
PHPで先頭の文字列を取得する方法についてまとめました。



## 参考記事
https://www.notion.so/42ddea647df74c12b81e2e5dce1519eb?pvs=4

https://www.choge-blog.com/programming/phpstringgetfirstcharacter/
CloudflareWorkersに入門してみる

## 参考

公式のチュートリアルを読みながら、Workersに入門してみます。

https://developers.cloudflare.com/workers/get-started/guide/


## プロジェクトを作成する。

ターミナルで下記を叩きます。

```sh
$ npm create cloudflare@latest
```

アプリケーションを作成する場所を指定して、新しいWorkerディレクトリに名前をつけます。

```sh
Create an application with Cloudflare Step 1 of 3
│ 
├ In which directory do you want to create your application?
│ dir ./test
│
```

作成するアプリケーションの種類を`Hello World script`を選択します。

```sh
├ What type of application do you want to create?
│ type "Hello World" Worker
```

TypeScriptを使うかどうかを選択します。

```sh
├ Do you want to use TypeScript?
│ yes typescript
```

```sh
├ Do you want to use git for version control?
│ yes git
```

Cloudflareにデプロイするかどうかを尋ねられます。
ログインしていない場合、ブラウザでCloudflareが開くのでログインします。


```sh
╭ Deploy with Cloudflare Step 3 of 3
│ 
├ Do you want to deploy your application?
│ yes deploy via `npm run deploy`
├ Deploying your application 
│ deployed via `npm run deploy`
│ 
├  SUCCESS  View your deployed application at https://プロダクト名.アカウント名.workers.dev
│ 
│ Navigate to the new directory cd dlscraping
│ Run the development server npm run start
│ Deploy your application npm run deploy
│ Read the documentation https://developers.cloudflare.com/workers
│ Stuck? Join us at https://discord.gg/cloudflaredev
│ 
```

無事プロジェクトディレクトリが作成されると、下記が生成されます。

```
.
├── node_modules 
├── package-lock.json
├── package.json
├── src
├── tsconfig.json
└── wrangler.toml
```


##　ローカルサーバーの起動

下記のコマンドを叩くことで、開発するためのローカルサーバーを起動します。
開発中にローカルでWorkerをテストすることができます。
```sh
$ npx wrangler dev

 ⛅️ wrangler 3.21.0
-------------------
⎔ Starting local server...
[wrangler:inf] Ready on http://localhost:8787
```

表示されている、http://localhost:8787 にブラウザでアクセスしてみましょう。
HelloWorldが表示されているはずです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3589058/02a97f98-90fe-bdf1-0155-7f676bd444f5.png)


## コードを書く。

`src/index.js`

```js:src/index.js
export default {
	async fetch(request, env, ctx) {
		return new Response('Hello World!');
	},
};
```

### export default
export default は、JavaScriptモジュールを定義するために必要なJavaScriptの構文です。あなたのWorkerには、Workerが処理するべきイベントに対応するプロパティを持つオブジェクトのデフォルトエクスポートが必要です。

### async fetch(request)
このイベントハンドラは、Workerがfetchイベントを受け取ったときに呼び出されます。
エクスポートされたオブジェクトに追加のイベントハンドラを定義して、異なるタイプのイベントに対応できます。
例えば、スケジュールされたイベントに対応するために `async scheduled(event) {}` などを追加もできます。 

### request, env, context
fetchイベントハンドラには常に3つのパラメータが渡されます：request、env、context。

### Responseオブジェクト
Workersランタイムは、fetchイベントがResponseオブジェクトを返すことを期待しています。
この例では、文字列 "Hello World!" を含む新しいResponseを返します。
jsで連想配列を操作するときに気をつけること

## はじめに
私は株式会社qnoteにて、勉強会の幹事を務めております。
2023年度勉強会の珠玉のネタを2023Qiitaアドベントカレンダーに投稿していこうと思います。

## 対象者
この記事は下記のような人を対象にしています。

- 駆け出しエンジニア
- プログラミング初学者

## 結論
- JavaScriptで配列or連想配列を扱う際には、他言語と異なる挙動をする場合があるので要注意！

## 解説
```jsx
const a = []
a.push('aaa')

const b = []
b['b'] = 'bbb'

const c = {}
c.c = 'ccc'

// 添字が数字の配列
console.log(a)
console.log('typeof(a)       :' + typeof(a))
console.log('Array.isArray(a):' + Array.isArray(a))
console.log('a.length        :' + a.length)

// 添字が文字列の配列(連想配列...ではない？)
console.log(b)
console.log('typeof(b)            :' + typeof(b))
console.log('Array.isArray(b)     :' + Array.isArray(b))
console.log('b.length             :' + b.length)
console.log('Object.keys(b).length:' + Object.keys(b).length)

// JSの連想配列(=実質、オブジェクト)
console.log(c)
console.log('typeof(c)            :' + typeof(c))
console.log('Array.isArray(c)     :' + Array.isArray(c))
console.log('c.length             :' + c.length)
console.log('Object.keys(c).length:' + Object.keys(c).length)
```

### 出力結果
![スクリーンショット 2023-07-20 22.15.27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2157342/cae616a0-54f6-11db-5be5-333efab450a2.png)


## おわりに
jsで連想配列を操作するときに気をつけることについてまとめました。



## 参考記事
https://www.notion.so/js-37674030a6514df8a65cb249155372fe?pvs=4

https://zenn.dev/cryptobox/articles/2dc6fe0951eeca
with()の正しい使い方

## はじめに
私は株式会社qnoteにて、勉強会の幹事を務めております。
2023年度勉強会の珠玉のネタを2023Qiitaアドベントカレンダーに投稿していこうと思います。

## 対象者
この記事は下記のような人を対象にしています。

- 駆け出しエンジニア
- プログラミング初学者

## 結論
- find()とfirst()は動的プロパティがスマート
- get()やall()で取得したコレクションをforeach()で処理する場合はwith()を使う

## 解説
（例） User に複数の Post が紐づく「1対多」のリレーションを考えます。

```php
use Illuminate\Database\Eloquent\Relations\HasMany;

class User extends Model
{
    public function posts(): HasMany
    {
        return $this->hasMany(Post::class);
    }
}
```

```php
use Illuminate\Database\Eloquent\Relations\BelongsTo;

class Post extends Model
{
    public function user(): BelongsTo
    {
        return $this->belongsTo(User::class);
    }
}
```

|  | 返り値 | $q->posts()->get() | $q->posts()->first() | $q->posts | $q->with(’posts’) |
| --- | --- | --- | --- | --- | --- |
| find() | 単一モデル・オブジェクト | ○ | ○ | ◎ | △(with()の有無でクエリ数変化なし) |
| first() | 単一モデル・オブジェクト | ○ | ○ | ◎ | △(with()の有無でクエリ数変化なし) |
| get() | コレクション | ×(ｺﾚｸｼｮﾝにpostsが存在しない) | ×(ｺﾚｸｼｮﾝにpostsが存在しない) | ×(ｺﾚｸｼｮﾝにpostsが存在しない) | ○(foreachの外側で使うべし) |
| all() | コレクション | ×(ｺﾚｸｼｮﾝにpostsが存在しない) | ×(ｺﾚｸｼｮﾝにpostsが存在しない) | ×(ｺﾚｸｼｮﾝにpostsが存在しない) | ○(foreachの外側で使うべし) |
| 上記4種を使わない | ビルダー | ×(ｺﾚｸｼｮﾝにpostsが存在しない) | ×(ｺﾚｸｼｮﾝにpostsが存在しない) | ×(ｺﾚｸｼｮﾝにpostsが存在しない) | ○(foreachの外側で使うべし) |


```php
// find()とfirst()は動的プロパティを使うのがスマート。
$user1  = User::find(1);
$posts1 = $user1->posts;

$user2  = User::first();
$posts2 = $user2->posts;

// find()とfirst()はwith()使ってもいいが、クエリ発行数は一緒。
$user1  = User::with('posts')->find(1);
$posts1 = $user1->posts;

$user2  = User::with('posts')->first();
$posts2 = $user2->posts;

// find()とfirst()はwith()の記述位置に注意。
$user1  = User::find(1)->with('posts'); // 返り値がBuilder!!!
$user2  = User::first(1)->with('posts'); // 返り値がBuilder!!!

// get()とall()の場合はN+1問題解決のためにwith()を使用すること。
$users3 = User::with('posts')->get();
foreach ($users3 as $user3) {
	$posts3 = $user3->posts;
}

$users4 = User::with('posts')->all();
foreach ($users4 as $user4) {
	$posts4 = $user4->posts;
}

// get()とall()のNGケース
$users3 = User::get();
foreach ($users3 as $user3) {
	$posts3 = $user3->posts; // N+1発生！！！
}

$users4 = User::all();
foreach ($users4 as $user4) {
	$posts4 = $user4->posts; // N+1発生！！！
}
```

## おわりに
with()の正しい使い方についてまとめました。



## 参考記事
https://www.notion.so/with-6a47d63620d34b61a47c28446ca862dd?pvs=4

[【Laravel】データ取得 find・first・get・all  の違いをしっかり理解 【比較】 - エンジニ屋.com(エンジニヤドットコム)](https://enginiya.com/entry/laravel-get-data-methods)
[[Laravel] 動的プロパティと Eager Loading - Qiita](https://qiita.com/nekohan/items/f909ef78d1cd83d58817)
私たちは Entra ID と オンプレAD に自由にユーザーを作成したいんだ！  (API駆動型インバウンド プロビジョニング)

この記事は [Microsoft 365 Advent Calendar 2023](https://adventar.org/calendars/8908) に参加しています。17日の記事です。

# はじめに
この記事は Microsoft Entra ID に現在 Preview 機能として実装されている **API 駆動型インバウンド** プロビジョニングを**短時間で理解**していただくことを目的とします。

# API 駆動型インバウンド プロビジョニングとは
この機能は Entra ID に**対して**(インバウンド)データをプロビジョニング(書き込む[^1])ものです。

[^1]:書き込むと書くと Identity 界隈の方から怒られそうですがわかりやすさを重視しています*

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/84516/68369770-78db-89c2-8049-ed5b8de7505c.png)
データソースは自由な形式を選択可能であり、例えばスプレッドシートや CSV、 SQL データベースや独自で作成している人事システムとの連携もこのエンドポイントを利用することで実装が可能です。

# これまでとの違いを通じて特徴を認知する
Microsoft Entra ID に対しては Graph User API エンドポイントを通じてオブジェクトの操作を行うことが可能ですし SCIM を通じたプロビジョニングもサポートされています。それらとの違いを見ることで API駆動型インバウンドプロビジョニングの特徴が見えてきます。

1. Graph Users API との違い
    * 大量のデータを投入可能(1秒毎に 2,000 レコード)
    * 投入時にデータの変換が可能(Entra ID 側の GUI で設定しておく)
    * キー属性を指定しておけば更新・削除の処理分岐は Entra ID 側が判断する
    * なんと Entra ID Connect 経由でオンプレミス AD のユーザーも作成可能
    * 操作は非同期で実行され Audit に加えて Provisionig ログも記録される
    * OData 形式ではなく SCIM 形式のフォーマットを利用
2. SCIM プロビジョニングとの違い
    * これまでは**アウトバウンド**プロビジョニングと一部の Cloud HR サービスのみをサポートしていたが自由度の高い**インバウンド**プロビジョニングをサポートした
    * SCIM スキーマを利用するが SCIM の操作である 作成、読み取り、更新、削除(CRUD)をサポートしている訳ではなく一括投入(/bulkUpload)のみをサポートしていて新規なのか更新なのかは Entra ID が自動的に判断する仕組み

# 要するにこの機能はなんなのか？(まとめ)
この機能は **ID の起点をオンプレミスの Active Directory から、クラウドの IdP である Microsoft Entra ID へ切り替えを可能にする大きな変化点** であると考えます。

多くの組織で現在はオンプレミスの ID 管理製品とオンプレミスの Active Directory や LDAP サポートする Directory サービスが同期連携されていると想像しますが、これらのシステムを更改するタイミングで Microsoft Entra ID にデータを直接同期する構成も検討に含めることをお勧めいたします。

# 参照先
https://learn.microsoft.com/ja-jp/entra/identity/app-provisioning/inbound-provisioning-api-concepts

https://jpazureid.github.io/blog/azure-active-directory/introducing-a-new-flexible-way-of-bringing-identities-from-any/

https://qiita.com/murasamelabo/items/beb7b11b68342794ac8d
【UEFN】Verseのインターフェース使ってみた

## 背景
最近は設定の多いタイクーンゲームの制作を始めていてバグがところどころ散見され始めました。設計がごちゃごちゃで一つの部分を修正するのにそれ以外のところまで修正しなきゃならない状況が多々ありました。そこでしっかりと整理しそれぞれの機能の責任を分散する必要があると感じました。その第一歩？であるインターフェースの書き方を理解していきたいと思います。

## やること
- Verseの``creative_device``クラスにインターフェースを実装
- そのクラスの関数をインターフェース経由で呼んでみる

という感じになります。

## 全体コード
#### sample_interface
```
sample_interface := interface():
    GetScore() : int
    GetScore2() : int
```
これが本日の主役となります。いつものクラスの部分をインターフェースに変えて宣言していますね。中身は関数名とその引数のみを書いておく感じになります。（処理は記述しません。）

#### sample_model_device
```
using { /Fortnite.com/Devices }
using { /Verse.org/Simulation }
using { /UnrealEngine.com/Temporary/Diagnostics }

sample_model_device := class(creative_device,sample_interface):

    var score : int =10000
    var score2 : int =99999

    GetScore<override>() : int =
        Print("Model GetScore:{score}")
        return score

    GetScore2<override>() : int =
        Print("Model GetScore2:{score2}")
        return score2
```
インターフェースを実装しているクラスになります。
クラスの実装は一つだけですが、**インターフェースの実装は複数できるようになっています。**

インターフェースが持っている関数は``<override>``を付けて確実に実装しましょう！

#### sample_model_controller_device
```
using { /Fortnite.com/Devices }
using { /Verse.org/Simulation }
using { /UnrealEngine.com/Temporary/Diagnostics }


sample_model_controller_device := class(creative_device):

    @editable
    Model: sample_model_device = sample_model_device{}

    OnBegin<override>()<suspends>:void=
        InterfaceHandle(Model)

    InterfaceHandle(model : sample_interface):void=
        score := model.GetScore()
        score2 := model.GetScore2()

        Print("Controller Score: {score}")
        Print("Controller Score2: {score2}")
```
ここでは``sample_model_device``を取得して``InterfaceHandle``ではインターフェス経由で関数を呼ばせています。

### 実行結果
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/692976/1f606664-1293-0a3a-cbcb-18cbc1c3bbf3.png)

## まとめ
インターフェースを実装させインターフェース経由で呼び出すときにもしそのクラスの内部処理の修正したとしても呼び出し側の影響が少なくなるというところがよいですよね。ただチームで制作している場合にはVerseを触るメンバーがしっかりとそれについて理解していないと大変なことになります。使う場所使わない場所をしっかりと読み取っていきたいです。

## 余談
この度UEFN/Verseに関するオープンコミュニティサーバーを建ち上げました。ちょっとでも興味があれば奮ってご参加くださいませ。

https://discord.gg/MehcNhyxdq
Melos を利用したデザインシステム構築のことはじめ

この記事は YUMEMI Flutter Advent Calendar 2023 の 17 日目の記事です。

https://qiita.com/advent-calendar/2023/yumemi-flutter

# はじめに

こんにちは、たっつー ( [@tatsutakein][Twitter] ) です。

ネイティブアプリ開発ではよく採用されるマルチモジュールですが、 Flutter 開発では意外とマルチパッケージの採用事例を聞かない気がするので、私の事例を紹介できればと思います。

※ あくまでも個人の意見です。 Android アプリ開発でのマルチモジュールと異なり、パフォーマンス面でのアプローチにはなり得ない点にはご注意ください。

# Melos

マルチパッケージは Dart のパッケージとして標準で利用できますが、 Melos を利用すると便利な機能があるので私は基本的に Melos を採用しています。
もしよければ以前 LT で発表した際の資料もご確認いただけると幸いです。

https://speakerdeck.com/tatsutakein/melos-deshi-merumarutipatukezigou-cheng-nakai-fa

[3.2.0][melos#320] では FEAT: support syncing common dependency versions が追加され、外部パッケージのバージョン管理が楽になりました 🎉

## マルチパッケージの構成

今回は以下のパッケージ構成を想定しています。

```text
.
├── apps
│   ├── catalog
│   └── frontend
└── packages
    ├── core
    │   ├── ...
    │   ├── designsystem # 今回はこのパッケージが対象
    │   └── ...
    └── feature
        ├── ...
        └── top
```

`packages/core/designsystem` の `icons` ディレクトリ構成は以下の感じです。

```text
.
├── ...
└── designsystem
    ├── assets
    └── lib
        ├── gen
        ├── l10n
        ├── src
        │   ├── components
        │   ├── ...
        │   ├── icons
        │   │   ├── hoge_icons.dart # 今回はここを対象としています
        │   │   └── index.dart
        │   └── themes
        └── core_designsystem.dart
```

## designsystem パッケージの定義

`packages/core/designsystem` 側での手順を記載します。

### アイコンクラスの定義

各 feature パッケージで利用するアイコンを共通で定義します。

```dart:packages/core/designsystem/lib/src/icons/hoge_icons.dart
import 'package:flutter/material.dart';

final class HogeIcons {
  const HogeIcons._();

  ...

  static const IconData favorite = Icons.favorite;

  ...
}

```

余談ですが, IntelliJ 系の IDE を利用していると使用するアイコンがパッと確認できていいですね。
VSCode にも同様の拡張機能はあるのでしょうか？ 👀

![IntelliJ](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/184644/9d9db162-ccd5-f19e-1c34-b3db099c94bb.png)

### バレルの定義

バレルを記載します。

```dart:packages/core/designsystem/lib/src/icons/index.dart
export 'hoge_icons.dart';
```

### パッケージとしてのエクスポート

こちらも忘れずに記載します。

```dart:packages/core/designsystem/lib/core_designsystem.dart
library core_designsystem;

...
export 'src/icons/index.dart';
...
```

## 使用例

`packages/feature/top` を例に記載します。

### pubspec.yaml の記載

依存に `core_designsystem` を追加します。

```diff_yaml:packages/feature/top/pubspec.yaml
name: feature_top

...

dependencies:
  flutter:
    sdk: flutter
  flutter_localizations:
    sdk: flutter

  ...

+ core_designsystem:
+   path: ../../core/designsystem
...
```

### `core_designsystem` で定義したアイコンを利用する

普段のライブラリのようにパッケージを import し、定義したアイコンを利用できます 🙌

```dart
import 'package:core_designsystem/core_designsystem.dart';
import 'package:flutter/material.dart';

final class FavoriteIconButton extends StatelessWidget {
  const FavoriteIconButton({super.key});

  @override
  Widget build(BuildContext context) {
    return IconButton(
      onPressed: () { /** do nothing. */ },
      icon: Icon(HogeIcons.favorite),
    );
  }
}
```

# おわりに

いかがでしたでしょうか。マルチパッケージをうまく活用して、見通しの良いコードで開発が進められると良いですね 🙌

次は @takashimelon さんです。


[Twitter]: https://twitter.com/tatsutakein
[melos#320]: https://pub.dev/packages/melos/changelog#320