OmniAICreator/Qiita-1.07M huggingface dataset:
【JointJS】JointJSのイベント処理

JointJSで描画しているSVGにはイベントを設定することができます。今回はどんなイベントが設定できるのかを紹介していきます。

## 設定単位

JointJSでは、以下の単位でイベント処理を定義できます。

- Graph
- Paper
- Element
- Link

それぞれの設定単位について、どのような設定ができるのかを紹介します。

## Graphに設定できるイベント

GraphではGraphに対しての変更が生じるタイミングをトリガーとしたイベントを設定できます。また、Graph内に存在しているすべてのElement, LinkのイベントはGraphに対しても伝搬されます。

### 使用できるイベント

- `change`：Graph内のすべての変更イベントに対して発火する
- `add`：GraphにCellが追加されたタイミングで発火する
- `remove`：GraphからCellが削除されたタイミングで発火する

```js
graph.on('change', function() {
  console.log('何かしらの変更が発生しました')
});

let cellCounter = 0;

graph.on('add', function() {
  cellCounter++;
});

graph.on('remove', function() {
  cellCounter++;
});
```

## Paperに設定できるイベント

Paperの各種イベントに対して処理を設定することができます。Paperのイベントについては過去の記事で既に触れておりますので、この記事ではこれ以上は触れません。

https://qiita.com/acnaman/items/82207fdbed578b956d9f#%E3%82%A6%E3%82%A3%E3%83%B3%E3%83%89%E3%82%A6%E3%82%A4%E3%83%99%E3%83%B3%E3%83%88%E3%81%AE%E5%87%A6%E7%90%86

## Elementに設定できるイベント

Elementには、[Elementの変更に対するイベント](https://resources.jointjs.com/docs/jointjs/v3.7/joint.html#dia.Element.events)が設定できます。また、[Elementからイベントを発行](https://resources.jointjs.com/docs/jointjs/v3.7/joint.html#dia.attributes.event)することもできます。

Elementの変更に対するイベントは、`change:position`などのイベントを`on()`メソッドに設定します。

Elementの`event`属性に文字列を設定すると、その文字列のカスタムイベントを発行できます。カスタムイベントはPaperやGraphで捕捉できます。
`event`という名前ですがクリックイベント(正確には`mousedown`/`touchstart`イベント)のみしか扱えないことに注意してください。クリックイベント以外のイベントを扱わせるためには別のアプローチが必要になります。

### コード例

```js
var paper = new joint.dia.Paper({
  el: document.getElementById('myholder'),
  model: graph,
  width: 600,
  height: 100,
  drawGrid: "mesh",
  gridSize: 10,
  cellViewNamespace: namespace
});

// 黄色い四角形（移動で変化）
const rectangle1 = new joint.shapes.standard.Rectangle({
  size: { width: 150, height: 40 },
  position: { x: 10, y: 30 },
});
rectangle1.attr('label/text', `テキスト初期値`)
rectangle1.attr('body/fill', 'yellow');
rectangle1.on('change:position', function(ele, position) {
  rectangle1.attr('label/text', `x: ${position.x} y: ${position.y}`)
})

// 青い四角形（クリックで変化）
const rectangle2 = new joint.shapes.standard.Rectangle({
  size: { width: 150, height: 40 },
  position: { x: 10, y: 130 },
  attrs: {
    body: {
      event: 'rect2.click'  
    }
  }
});
rectangle2.attr('label/text', 'テキスト初期値');
rectangle2.attr('body/fill', 'lightblue');

paper.on('rect2.click', function(elementView, evt) {
  elementView.model.attr('label/text', 'クリックされた');
});
```

### 実行結果

![dadlink.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/129526/359d816e-eb12-8d56-d3d6-5d47efa7a785.gif)

## Linkに設定できるイベント

Linkのイベントも、Elementと同様に[Linkの変更に対するイベントの設定](https://resources.jointjs.com/docs/jointjs/v3.7/joint.html#dia.Link.events)と、Linkからのイベント発行ができます。

前者のLink変更に対するイベントについては、Linkの場合`change:source`（起点）,`change:target`（終点）,`change:vertices`（経由点）などのLinkのルート変更に関するイベントが設定できるようになっています。

## まとめ

JointJSでは様々なイベントの設定単位が利用できます。ユーザーの操作に対すて適切なイベントを設定できるように、イベントの種類と動作を把握しておくことが重要です。

※この記事は [JointJS Advent Calendar 2023](https://qiita.com/advent-calendar/2023/jointjs) の記事です。他の記事を読む場合はカレンダーのページを参照してください。

https://qiita.com/advent-calendar/2023/jointjs
AppleシリコンのMacでDocker上にSQL Serverを構築できるようにする

# やりたいこと
Docker上にDBサーバーを立ち上げたい
```docker-compose.yml
version: "3.9"
services: 
  sqlserver:
    image: mcr.microsoft.com/mssql/server:2022-latest
    container_name: sqlserver
    hostname: sqlserver
    ports:
      - 1433:1433
    volumes: 
      - ./sqlserver/startup.sh:/startup.sh
      - mssql-db:/var/opt/mssql
    environment: 
      MSSQL_PID: Express
      MSSQL_LCID: 1041
      MSSQL_COLLATION: Japanese_CI_AS
      ACCEPT_EULA: Y
      TZ: Asia/Tokyo
    command: "sh -c '/startup.sh & /opt/mssql/bin/sqlservr;'"

  azurite:
    ...
      
volumes: 
  mssql-db:
    driver: local
  azurite-data:
    driver: local
```

# 発生したエラー
![スクリーンショット 2023-12-11 23.41.49.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1812049/a9b4c36c-c0a0-f3de-b66b-ff0b5be87e19.png)
![スクリーンショット 2023-12-11 23.43.41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1812049/aa62610f-2d65-822b-763a-ac7ee2a369cc.png)

`docker-compose up`を実行したところ以下のようにsqlserverが立ち上がらない...

# 最近使えるようになったらしい
もともとエラーになってて、つい最近のリリースでAppleシリコンにも対応したそうです。

https://neruko-ha-sodatsu.hatenablog.com/entry/2023/01/15/181936

https://docs.docker.com/desktop/release-notes/#4160

# 設定
![スクリーンショット 2023-12-11 23.44.08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1812049/c04846ee-df95-18ea-89a7-f87422f56d20.png)

Dockerデスクトップの右上の設定ボタンをクリックして、「Features in development」を選択。
「**Use Rosetta for x86/amd64 emulation on Apple Silicon**」にチェックをつけてリスタート。
<br>
...
<br>
![スクリーンショット 2023-12-11 23.53.28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1812049/a64fff06-5834-3531-317b-7381828b856e.png)

![スクリーンショット 2023-12-11 23.45.19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1812049/a1ea9833-bf28-f686-d98f-a8f4b9fd668b.png)
無事立ち上がりました。

# 注意
Macのバージョンも13（Ventura）以上に上げる必要があります。
あげないと「**Use Rosetta for x86/amd64 emulation on Apple Silicon**」というチェック欄が出てこないので、アップデートすることを忘れずに。
【CSS】contentで文字列入れるのだけはやめてください

## はじめに

CSSには`content`というプロパティがあります。

https://developer.mozilla.org/ja/docs/Web/CSS/content

沢山のWebデザイン入門のような本やサイトで、装飾として紹介されています。たとえば、h1タグに適用して、おしゃれなラベルを実現したり、タグの前に記号を入れてちょっとオシャレにできたりします。`::before`や`::after`などの擬似要素と一緒に使うことが多いと思います。サイトをオシャレに、カッコよくするテクニックとしては全然使ってOKだと思います。

<font color="red">**ただし、文字列は入れないでください。**</font>

例えば,
```css
.hoge::before {
    content:"更新"
    ...
}
```
みたいな感じで文字を装飾代わりに使うことです。記号はいいですが、文字はやめてください。

こういうパターンです

<p class="codepen" data-height="300" data-default-tab="html,result" data-slug-hash="eYxogmR" data-editable="true" data-user="mu-tomoya" style="height: 300px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;">
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>

## マークアップでないため、目以外でその文字が判断できない

例えばマークアップで文字を書いた場合
```html:HTML
<span>更新</span>
```

みたいな感じだと、ブラウザ上から調べても「更新」と検索すればヒットします。「更新されているメニューにいきたい」ってときには調べればヒットします。

しかし、CSSの`content`で実現した場合、それはただの装飾なので、検索したところで何もヒットしません。非常に使い勝手が悪いです。コピーすらできません。

## アクセシビリティ的に最悪

スクリーンリーダーの種類によっては読み込まれない可能性もあります。DOMに入っていないので。
例えばこの「更新」みたいなバッジを表す時、スクリーンリーダーで読み込んだところで何もないので、何が更新されているコンテンツなのかが全くわかりません。

「定型的な文字列だから」みたいな理由でcontentに文字いれて表現するなんてもっと最悪です。「車について調べてみた」の「調べてみた」の部分だけ使い回すからcontentで表すなんてしたら、「車について」の部分しか把握できなくてめちゃくちゃ最悪です。

なので文字列をcontentで表すのだけは本当にやめてほしいです。ちゃんとマークアップで表してください。


## HTMLにスタイル当てれば必要ない

どうしてもそれはcontentを入れないと実現できないですか？たとえばオシャレなメニューを作りたい時に、「HOME」を大きく書いてその下に「ホーム」と書く場合です。

![スクリーンショット 2023-12-11 23.31.52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/267174/f2bf3c9f-367b-c958-2a86-edb25a82df28.png)
Figmaで適当につくりましたが、こんな感じです。

こういうのはflexboxで実現してあげたほうが装飾の自由度が高いです。ただ、このままだとスクリーンリーダーで2つ読み上げられてしまうので、「ホーム」の部分は`aria-hidden="true"`を設定してあげれば読み取られません。

<p class="codepen" data-height="300" data-default-tab="html,result" data-slug-hash="LYqvxXv" data-editable="true" data-user="mu-tomoya" 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/mu-tomoya/pen/LYqvxXv">
  Untitled</a>
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>

こうすればcontentを使わずとも実現できます。


## 終わりに

逆にcontentがどこで有用なのかがわからないなと思いました。
CSSのテクニックは調べればかなり出てきますが、HTMLとCSSは正しく使い方を守って使いましょう。

## 追記
2023-12-17追記
スクリーンリーダーの件に関して、一部誤りがあったため訂正しました。MacのVoiceOverではCSSのcontentは読み込まれました。お詫び申し上げます。

しかし、それでもCSSのcontentで文字列を表すべきではないなと思いました。そこに文字としてある以上はマークアップで表されるべきです。
DBのテーブルでNOT NULL制約が課された列項目であっても、クエリ処理結果がNULLになる例

# 1. はじめに
単体テストケースを考える中で、DBのテーブルでNOT NULL制約が課された列項目であっても、クエリ処理結果がNULLになる例が存在することに気づきました。そのため、この記事ではクエリ処理として外部結合を例に紹介します。

# 2. 具体例の紹介
```sql:tableA
CREATE TABLE tableA (
    id INT PRIMARY KEY,
    name VARCHAR(50) NOT NULL
);

INSERT INTO tableA (id, name) VALUES (1, 'John');
INSERT INTO tableA (id, name) VALUES (2, 'Jane');

```

```sql:tableB
CREATE TABLE tableB (
    id INT PRIMARY KEY,
    description VARCHAR(50)
);

INSERT INTO tableB (id, description) VALUES (1, 'Employee');

```
tableAとtableBをid列で外部結合してみましょう

```sql:ID列で外部結合
SELECT tableA.id, tableA.name, tableB.description
FROM tableA
LEFT JOIN tableB ON tableA.id = tableB.id;

| id | name | description |
|----|------|-------------|
| 1  | John | Employee    |
| 2  | Jane | NULL        |
```
この例では、tableAのすべての行が表示されていますが、tableBに対応する id が2の行が存在しないため、description 列には NULL が挿入されています。外部結合は、左側のテーブル（tableA）のすべての行を表示し、右側のテーブル（tableB）とのマッチングができる場合には対応する値を表示し、できない場合には NULL を表示するため、NOT NULL 制約があっても NULL が挿入される可能性があります。

このように、NOT NULL制約はDBのデータベースファイル上に存在する時にチェックされるものであり、クエリ処理結果までに制限を加えるものではありません。

# 3. おわりに
この記事では、単体テストケースを考える中での注目すべきポイントとして、DBのテーブルでNOT NULL制約が課された列項目であっても、クエリ処理結果がNULLになる例を示しました。
iOSアプリのアーキテクチャについて理解する

# なぜ、アーキテクチャに拘る必要があるのか

アーキテクチャとは、アプリを綺麗に開発・継続的に運用していくための設計。
このアーキテクチャに沿わない形で開発すると以下のような障害が発生してくることになる。

- ファイルの肥大化
    - 1000行越えのViewControllerファイルができてしまったり、コードを追うことが困難に
- ロジックの煩雑化
    - 新規機能を付け足していくうちに、状態管理がめちゃくちゃに
        →機能の追加、改修が困難に。
- テストがしにくい
- 属人化が進み、プロジェクトの引き継ぎがし難い

etc...

# 設計一覧
### MVC
![スクリーンショット 2023-12-09 23.31.52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2778525/53bc1bb2-56ea-15d7-4f90-83b62cae46b6.png)


#### 処理流れ
1. `View`がユーザーの入力情報を受け付け、`Controller`にアクションを渡す
2. アクションを受け取った`Controller`が`Model`にデータの更新を依頼する。
3. `Model`が`Controller`に処理の完了を通知し、`Contoller`から`View`へ更新処理が走る

#### それぞれの役割
- `View`：表示、入出力
- `Controller`：入力にもとづく`Model`と`View`の制御
- `Model`：データの保持、通信、ビジネスロジック


:::note info
MVPは入力を受け付けるのが`Controller`ではなく、`View`となる

:::

:::note info
※図を参照する通り、MVCは`Controller`が肥大化しやすい。
→これを回避するために、ビジネスロジックを`Model`に移し替えるということがよく行われている。
:::


### MVP
![スクリーンショット 2023-12-09 23.47.38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2778525/ad05a119-4c6a-3653-2f9a-0a8e2f3c6b75.png)

#### それぞれの役割
- **`Model`:** データの保持、通信、ビジネスロジック
    - Presenterから移譲された処理を実行
        - API使うならAPIクラスを外からもらう
    - 処理完了後にpresenterに通知

- **`View`:** 表示、入出力
    - Modelを直接いじらない
    - Presenterにイベントを移譲
    - Presenterから貰った処理結果をそのまま表示するだけ
- **`Presenter`: `View`と`Model`の間で仲介役
    - Viewから受け取ったイベントをもとにModelに処理を移譲
    - Modelの処理結果を受け取り、Viewに通知

#### Presenterについて

- Viewで表示するために必要なデータをModelから受け取り、Viewへ渡してあげる仲介役。


- ライフサイクルやレイアウトに関する実装は含まない(UIkitに依存しない)。
#### Presenterの利点
:::note info
ViewControllerをPresenterとして分割することができるので、ViewControllerの肥大化を防止できる。
:::

:::note info
ViewControllerとPresenterで役割ごとに分離できた為、テストがし易い
:::

### MVVVM
![スクリーンショット 2023-12-11 16.06.55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2778525/452db3bb-14f0-27b3-5c4b-d1b4f78b6d13.png)
MVVMはModel、View、ViewModelで構成されます。Controllerがなくなり、ViewがView+Controllerの役割をします。そして、ViewModelがViewとModelを繋ぐ形になります。

#### それぞれの役割
- `Model`: データの保持、通信、ビジネスロジック
- `View`: 表示、入出力
- `ViewModel`: ビジネスロジックとUIを結びつける仲介者

#### ViewModelの役割
ViewとViewModelはバインディングという仕組みで繋がっていて、ViewModelがModelから変更点を受け取り、ViewModel自身の状態を更新します。

そのため、状態管理をしているViewModelがModelを監視しているので、条件によってViewやコンテンツを出し分けする処理の見通しが良いです。



#### MVVMの利点
:::note info
モデルを書き換えると自動でViewが更新されるので、更新処理がまとまりやすく、読みやすい
:::
:::note info
MVPと同様、ViewModelにロジックが集中しているため、テストがし易い
:::

## 参考記事
https://qiita.com/navitime_tech/items/602d3286f23952ae0149#mvp-model-view-presenter

https://qiita.com/tattn/items/d4b95af0b60c3849243a#mvp
ブラウザのキャッシュを削除する方法

## 対象の読者
アプリ開発を行っているが、ブラウザのキャッシュが溜まり、それが原因で開発作業がスムーズに進まないと感じている方々。

## キャッシュの消し方
### 1. シークレットブラウザの利用
シークレットモードまたはプライベートブラウジングモードを使用すると、そのセッションでのブラウジング履歴やキャッシュは保存されません。
### 2. スーパーリロードをする
ブラウザ上でページをリロードする際に、通常のリロード(F5またはCtrl+R)ではなく、強制的にキャッシュを無視してページをリロードする方法です。
具体的には、Cmd+Shift+R(Mac)またはCtrl+F5(Windows)を使用します。
### 3. URLの最後にパラメーターを追加
- URLの後ろにクエリパラメータ?cache_delete=Trueをつけてキャッシュを消す。
- URLの最後にランダムなクエリパラメーターを追加することで、ブラウザはそれを新しいリクエストとして認識し、キャッシュを無視します。
例えば、`http://example.com`を`http://example.com?param=1234`のように変更します。
### 4. 開発者ツールの利用
ブラウザの開発者ツール(F12またはCtrl+Shift+Iで開くことができます)を使用してキャッシュをクリアすることも可能です。

- Applicationのlocal storage、cookieに保存された内容を消す
- ネットワークタブで「Disable cache」のチェックし、キャッシュを無効化する


### 5. ブラウザの設定からキャッシュをクリア
ほとんどのブラウザでは、設定メニューから直接キャッシュをクリアするオプションが提供されています。
軽深演習 #11 山本五十六

### 軽深（かるしん　なんちゃって圏論） Advent Calendar 2023 11日目の記事です。

演習形式をとっているので、ぜひ　回答を試みてください。


### 前提知識　山本五十六

圏は、射つまり矢印が重要です。私達は、普段よく矢印をつかっています。グロタンディークのように、射もなんでもいいわけですが、それではわけわからなくなります。矢印は、順序を意味しているとも考えてみましょう。

普段使う言葉も、順序があります。有名な山本五十六の名言もそうです。

**やってみせ、言って聞かせて、させてみせ、ほめてやらねば、人は動かじ**

文を図式書くとこのようになります。
```mermaid
flowchart LR
A[やってみせ]-->B[言って聞かせて]-->C[ほめてやらねば]-->D[人は動かじ]
```
誰もが知っている当たり前の名言ですが。実践している人はいるんでしょうか？

```mermaid
flowchart LR
B[言って聞かせて]-->C[いうこときかないので批判する]
```
実際は、ほとんどがこの図式の行動をしているのではないでしょうか？

さて、演習　**山本五十六**　は順番にかんするものです。

### 演習　山本五十六の名言の順番は、確かにその順番でやるのがいいなと思えるものです。他の非常な名言で、順番を変えてもいいのではと思えるものはなんでしょうか？
jenkinsのsimple themeプラグインによって、実行中のアイコンがダブって回る

# はじめに
https://plugins.jenkins.io/simple-theme-plugin/

Simple Themeというプラグインが、jenkinsにはあります。
インストール直後は真っ黒なんですが、それの色をカスタマイズすることにより、どこのjenkinsマシン触っているのか？などをわかりやすくする目的で使ったりもします。

theme colorを簡単に作ってくれるサイトもありますし。

http://afonsof.com/jenkins-material-theme/


ただねこれ。
jenkinsの更新なのか、pluginの更新なのか、バグが起きるんですね。
それの直し方の話をします。

# 症状
![icon_.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1026740/80d07b76-2788-f0b7-df63-613d1f0cf442.gif)


最初見たとき、なにこれ？！ｗ
と、なったのはいうまでもありません・・・・ｗ

# 直し方

ググったら直し方相談してる外国の方がいらっしゃいました。

https://github.com/afonsof/jenkins-material-theme/issues/183

extra cssに下記を入れると治ります。

```css
svg[class*=anime] { visibility:collapse }
```

厳密には、治るというより、マシになる、って感じですね。

![スクリーンショット 2022-06-01 0.38.34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1026740/b67cc56d-8c82-78fa-c99f-f800b3aafdec.png)

![スクリーンショット 2022-06-01 0.38.38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1026740/a4f8a7ab-e264-1de8-9920-03dd9dad2c89.png)

面白いですね・・・・ｗ
グローバルなgitignoreファイルの置き場所

## これはなに？

一度作ってしまうと、書き換える機会もそんなに多くないという人も少なくはないと思います。
私はめったに変更しないタイプなもので、先日Macの初期設定をするときに、どこに置くんだったか…とすっかり忘れてしまっていました。
この記事では、置き場所はもちろんですが、忘れたときのリファレンスもご紹介できればと思います。

## コンピューター上のすべてのリポジトリについて無視するファイルを設定する

結論はこちらです。

```vim
~/.config/git/ignore
```

もしignoreファイルが存在していなければ作成して配置すればOKです。

## 忘れてしまったときのリファレンス

なにごともやはり公式が一番ではないでしょうか。

https://git-scm.com/docs/gitignore

日本語で読みたい…という方はGitHub Docsを確認しても良いと思います。

https://docs.github.com/ja/get-started/getting-started-with-git/ignoring-files#configuring-ignored-files-for-all-repositories-on-your-computer


この記事が誰かのお役に立てると幸いです。
「分かる」ってこと

「では、今年度のにし研の顔合わせを始めましょう。」

ノートPCの電源を付けて、指輪を外しながら話し始めたのが指導教員だ。恰幅が良く、黒縁の眼鏡をかけて髪は白髪をオールバックにして、チノパンに青の襟付きのシャツにスーツを羽織った、いわゆるビジネスカジュアルという大学教員のイメージとは離れた格好をしている。
研究棟の一室に長机をロの字型に組み、指導教員は下座に座り、向かいには男性と女性の先輩が2人、ロの字の両側を新しく入ったB4の学生2名ずつで囲んでいる。

「今年度は新しく入ってきたB4が4人、先輩はM2の菊池、博士後期の嶋崎で学生は全部で6人です。後で秘書の青木さんがいらっしゃいます。」
「B4は自己紹介をして、先輩は自己紹介と研究テーマを説明して下さい。」

全員初めて会う人たちだった。それぞれが名前ややってきたことや研究室でどんなことをしたいのかといったことを順に話していく。B4の自己紹介が終わると先輩の説明に移る。


「じゃあ、嶋崎から。」
「博士後期課程の嶋崎です。好きなものはチョコレート…」

嶋崎と呼ばれた女性が少し舌っ足らずだが、ハキハキと自己紹介していく。

「嶋崎、研究テーマについてB4に説明して。」
「はい、私はワクワクについての研究をしています。」

なんだそりゃ。

「大学の近くにカフェが2つあるんだけど、北側にあるカフェはすごいおしゃれで店員さんも丁寧に対応してくれるし、そこに行くとすごいワクワクしてハッピーになるんだよね。だけど、南側にあるカフェは同じくらい内装も綺麗だしメニューもおいしいんだけど全然ワクワクしないんだよね。その違いが…」<br>
そんなことも研究テーマになるのか、研究してどんなことになるんだとぼんやり思いながら説明を聞き流していく。<br>
「…それで、ワクワクというのが何かを研究してワクワクできるカフェを設計できるようにするのが私の研究です。」<br>
やってることはよくわからないが、なんか変わった研究テーマもあるんだなと思いながら恙なく説明が終わった。

「分かったか？」
「あ、はい。わかりました。」

指導教員が近くに座っていた僕に質問した。それに対し、嶋崎さんの説明に特に疑問も無かったので答える。直後に部屋の空気が一変する。


「伊藤、じゃあ嶋崎の研究内容を俺に説明しろ。」

突然の言葉に頭が真っ白になる。数秒前まで嶋崎さんからの説明を受けて研究内容をわかったはずなのに、説明しろと言われた瞬間に何から説明して良いのか分からず言葉に詰まる。当然、指導教員も一緒に嶋崎さんの説明を聞いていたし、指導教員なんだから研究内容は俺に説明されるまでもなく当然知っているじゃないか、なんでそんなことしなきゃいけないんだ。そんなことを脳裏に思いながらも返答を考える。

「・・・ワクワク感という感情について研究しています。」
「それで？」

必死に絞り出した説明にすらなっていない言葉は無情にも一言で返される。

「・・・わかりません、説明できないです。」
「じゃあ嶋崎に聞け。」

できないことを伝えて終わりになるかと思いきや、絶望的な事が告げられる。

「嶋崎さん、もう一回研究テーマの説明していただいても良いですか？」

いいよ、と快く研究テーマの説明をしてくれるが、いくら説明されてもさっぱりわからない。断片的に単語の意味は分かるがそれもさることながら、出てくる単語の関係性も研究の目的とどう繋がるのかもわからない。

「分かったか？」

言葉が出ない。わかったと言えば説明を求められるが、部分的な単語しかわからずうまく説明ができないか嶋崎さんが説明したことのオウム返しになるだけだ。しかし、わからないと言って質問をしようにも何がわかっていないかもわからない。

「他に嶋崎の研究内容分かった人は？」
「嶋崎さんはワクワク感を使ってカフェの設計をする研究をしています。」
「カフェを"設計する"って何だ？」
「えっ」

他のB4も挑戦するが、突っ込んだ質問をされて赤子の手をひねるように呆気なく撃沈していった。

「それでは、B4は嶋崎の研究テーマを俺に説明できるようにして下さい。説明ができるようになったら声をかけて下さい。」

そう言うと指導教員は手元のPCに向かい別の作業をし始めた。残された学生たちは嶋崎さんに説明をしてもらいながらあーでもないこーでもないと嶋崎さんの研究テーマの説明をし合った。

「B4は嶋崎の研究テーマ分かったか？」

自己紹介が始まってからかれこれ2時間以上経った。そろそろかと痺れを切らしたように指導教員が口を開いた。しかし、問いかけに対して俯いたまま誰も声をあげることができない。


「じゃあ、来週B4は先輩の研究テーマを説明できるようにしておいてね。」
「いいかい、君たちは分かったの基準が低いんだよ。この研究室では分かったと言ったら説明した内容に関わらず、分かったと言ったそいつが説明する責任がある。安易にわかったと言えば自分の首を絞めることになるよ。一つヒントを言っておくと自分が分かるためには相手の説明を分かってあげようとしてはいけないんだよ。」

この時、僕たちは大変なところに来てしまったと思い知った。


---

今年は正直僕にとってはあまり良い年ではなかったです。
大きな出来事として大学の研究室での指導教員をしていただいた恩師を亡くしました。記事の内容はある程度脚色などありますが、研究室での初めての顔合わせの一面の思い出の一つを書かせていただきました。配属の前からにし先生は怖いという噂や、実は僕はこの前に一悶着などあり、緊張しながら当日を迎えていたことを覚えています。
研究室で過ごした4年間は人生で一番大変でした（特に最初の1年目は）が、技術的にも人としても今までで一番成長できた4年間でした。研究を通して特にものの考え方や記事にも書いた「分かる」といったことに対しては厳しく指導していただきました。仕事や価値観に大きく影響を与えられました。にし先生に出会っていなければ少なくとも今この会社にはいなかったと思います。


にし先生から教えていただいたことは決して忘れることはないです。
R.I.P.

この記事は[グロースエクスパートナーズ Advent Calendar 2023 5日目](https://qiita.com/advent-calendar/2023/gxp)の記事です。


>「トートロジーって分かるか？」
>「水とウォーターみたいな？」
>「菊池、それは翻訳だ。」
Stripe テスト用クレジットカード情報が記載されている場所

## 概要

Stripeが用意してくれているテスト用クレジットカード情報が書いてあるドキュメントの場所をまとめておく。

## 場所

https://stripe.com/docs/testing?testing-method=payment-methods#cards

「アジア太平洋」の部分までスクロールすると情報が記載されている。

![Test_payment_methods___Stripe_のドキュメント.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306417/a2241e81-b815-d6d7-f8fb-78185a9bdf2b.png)
和を取る UnionFind

各頂点に値が振られているグラフで、連結成分内の全頂点の和を管理しながらグラフを連結させられます。

# UnionFind を定義
```python
class UnionFind:
  def __init__(self, n): pass
  def root(self, x): pass
  def unite(self, x, y): pass
```

`root(x)`: `x` の属する UF 木の根を返します
`unite(x, y)`: `x` の UF 木と `y` の UF 木を連結させます


# UnionFind を拡張して和を管理できるようにする
```python
class UFSum:
  def __init__(self, n):
    self.uf = UnionFind(n)
    self.val = [0] * (n + 1)
  def unite(self, x, y):
    rtx = self.uf.root(x)
    rty = self.uf.root(y)
    self.uf.unite(x, y)
    self.val[self.uf.root(x)] = self.val[rtx] + self.val[rty]
  def add(self, x, v):
    rt = self.uf.root(x)
    self.val[rt] += v
  def sum(self, x):
    return self.val[self.uf.root(x)]
```

前項のメソッドを実装している UnionFind データ構造であればこのデータ構造を動かすことができます。（トレイトがほしい！）

`unite(x, y)`: `x` の UF 木と `y` の UF 木を連結させます
`add(x, v)`: 頂点 `x` の値に `v` を足します
`sum(x)`: `x` の属する連結成分の全頂点の和を返します

## 応用
足し算に限らず、可換性・結合性のある演算なら `add(x, v)`, `sum(x)` に使うことができます。

# おわり
よく使います。
Confluenceの表で色違い行にカスタマイズする

# はじめに
Confluenceのカスタマイズ方法についての話です。
会社でやっている人がいたので、調べてやってみました。

# やり方
cssはどこで定義するのか？については、こちらを参照してください。

https://qiita.com/bluelemmon/items/597f5d998563d97073c0


```css
table.confluenceTable th.confluenceTh, td.highlight, div.tablesorter-header-inner, th.confluenceTh p {
    background-color: #5575A0 !important;
    color: #fff !important;
}
 
table.confluenceTable td {
    background: #e9f4f5;
}
table.confluenceTable tr:nth-child(odd) td {
    background: #fff;
}
```

最初に色が適用された後に白点滅する、という症状があるようなので、少し変えました。

参考：

https://community.atlassian.com/t5/Confluence-questions/How-to-change-the-font-color-for-table-headings-using-Space-CSS/qaq-p/1034090


# 結果
![スクリーンショット 2023-12-11 23.21.52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1026740/9e2059c8-a423-f4d0-1e0c-27039c5e5c60.png)


視認性がよくなるので、色々活用すると良いと思います。
ただし、アドオンのテーブルによっては、色が想定外になる可能性があるので、検証してみるのが良いかと思います。
最新のRAG検索？「RegaVAE: A Retrieval-Augmented Gaussian Mixture Variational Auto-Encoder for Language Modeling」

# はじめに
論文「RegaVAE: A Retrieval-Augmented Gaussian Mixture Variational Auto-Encoder for Language Modeling」では、現在の検索機能付き言語モデル2つの主要な課題を概説し、それらに対処するためにRegaVAEを提案しています。検索の方法として、Explicit Aggregation（明示的集約）と、Implicit Aggregation（暗黙的集約）の２つの種類が紹介されています。Explicitな方法として、代表的なものがRAGがあげられます。RAGに関しては、別記事で整理しましたので、興味ある方は[こちら](https://qiita.com/DeepMata/items/3c27394e4475b1b7e7ff)の記事も見ていただけるとうれしいです。

![RegaVAE.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1413258/ceed9abd-dc91-6fa8-6d52-488e85f6d8c0.png)

![RAG.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1413258/9cc82338-58b4-e887-dd96-24b38e4f237d.png)




## コード
https://github.com/TrustedLLM/RegaVAE

## 背景：現在の検索補強言語モデルの2つの主要な課題
- 検索時には、現在の意味情報だけでなく、将来の意味情報も考慮する必要がある
- 検索された文書とソーステキストを明示的に集約することは、モデル入力の長さによって制限され、ノイズが多すぎる

## 課題解決：RegaVAEの提案
RegaVAEは、Retrieval-Augmented Gaussian Mixture Variational Auto-Encoderの略で、言語モデリングのための新しい手法です。RegaVAEは、Variational Auto-Encoder（VAE）をベースにしたリトリーバル拡張言語モデルで、テキストコーパスを潜在空間にエンコードし、ソーステキストとターゲットテキストの現在と未来の情報を捉えます。

- 現在と未来の情報を暗黙的に結合する検索手法を提案する。これは、Query、Key、Valueの部分に未来の情報を同時に導入することで、文書の類似度が高いほど、生成者にとって有益になるようにするものです。
- 変分オートエンコーダ（VAE）と検索生成の確率論的フレームワークを統合し、効率的なアグレグリーメントを行う。
- 実験によれば、RegaVAEは品質、多様性、幻覚の排除において競争力がある。

![table1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1413258/70f54235-fe9e-15d2-6a7b-f5290ff2b619.png)

## モデルのアーキテクチャ

![figure1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1413258/6a2e1b49-09b9-314a-abfe-4555056ba41b.png)

>（ChatGPT4で翻訳）
トレーニングデータに基づいて、まずはVAE（変分オートエンコーダ）をトレーニングして、コンパクトな潜在空間を構築します。これにより、潜在変数zが現在および将来の情報の両方を含むようになります（§ 3.1参照）。次に、検索データベースを構築し、そこから取得した情報をジェネレータに統合します（§ 3.2参照）。VAEのエンコーダとデコーダのパラメータは全てのステップで同じです。公平を確保するために、トレーニングセット内のコーパスデータとソースデータは同じものを使用します。Gはガウス混合分布を表し、πはそれに対応するパラメータです。


# 制約事項
モデルのアーキテクチャから推測できる通り、残念ながら、大規模言語モデル（LLM）での利用今後の課題のようです。

> 現在の大規模な言語モデルは、大規模なコーパスで事前学習されており、計算リソースの制約のために、RegaVAEを大規模なコーパスで事前学習することはできません。これにより、パフォーマンスが低下する可能性があります。さらに、モデルは事後崩壊問題のために安定していないため、トレーニングが困難です。低ランクのテンソル積を採用しても、この問題は完全に解決できません。


# まとめ
RegaVAE自体の利用はまだ難しそうです。が、これからもRAGでの課題を追っていきたいと思います。有効な情報などありましたら、ぜひ情報いただけるとうれしいです。また、記載に誤りなどありましたらご指摘お願いします。
最近のC++

## この記事について
身内向けのアドカレ用に書いた記事です。
久しぶりにC++を触って、結構機能が増えてたのでこの感動を~~押し付ける~~分かち合うために記事書きました。
※C++履修者向けになってます。ごめんね🙇
※かさ増しのために古い機能も入れてます。ごめんね🙇

## 参照型 (C++11)
これまでのC++で参照といえばアドレス参照が一般的でした。
```cpp:pointer.cpp
  void hoge(const std::string* src) {
    // なにかする
  }

  // コピーされるので効率悪い
  void fuga(const std::string src) {
    // なにかする
  }

  int main() {
    std::string src = "文字列";
    hoge(&src);
    fuga(src);
  }
```

参照型が追加されたので、アドレス渡しとか気にしなくてよくなりました。
ぬるぽも起きないね、やったね。
```cpp:reference.cpp
  void hoge(const std::string& src) {
    // なにかする
  }
  
  int main() {
    std::string src = "文字列";
    hoge(src);
  }
```

## コンパイル時計算 (C+11)
`constexpr`を使うとコンパイル時に計算が行われます。
そのため実行時の計算が減りただでさえ速いのがさらに速くなります。やったね。
```cpp:constexpr.cpp
  constexpr int sum(int a, int b) {
    return a + b;
  }

  // sはコンパイル時に計算されて「120」になる 速くなる 正義
  constexpr s = sum(100, 20);
```

## 構造化束縛 (C++17)
モダンな言語によくあるタプルの展開ができるようになりました。
今風でかっこいいね。
```cpp:tuple.cpp
  std::tuple<int, std::string> moge() {
    return { 100, "name" };
  }

  int main() {
    auto [age, name] = moge();
  }
```

ちなみに、ちょっと設定すれば自前で作ったクラスでもできるらしい。

## 名前付きモジュール (C++20)
今まではヘッダー書いてそれを`include`していました。
`include`するたびにヘッダーが展開されるので、100万行のヘッダーなんぞを何度も`include`した日には目も当てられない大惨事になっていました。
```cpp:include.h
namespace hoge {
  void doHoge() {
    // めんどいのでinline
  }
}
```
```cpp:include.cpp
// include.hの中身がここに展開される
#include "include.h"

int main() {
  hoge::doHoge();
}
```
新しく追加された名前付きモジュールでは、翻訳単位がモジュール(.ixx)ごとになっているので、この心配がなくなりました。
```cpp:module.ixx
export module Hoge;

namespace hoge {
  void doHoge() {
    // めんどいのでinline
  }
}
```
```cpp:module.cpp
// Hogeモジュールはコンパイル済み
// includeのように展開されたりしない
import Hoge;

int main() {
  hoge::doHoge();
}
```
## まとめ
Rustとか、C++の代替になりそうな言語も出てきてますが、実はC++26がすでに策定されていたりして、まだまだ長く使われていきそうです。
君もC++使いにならないか？
MacのUSキーボードで簡単に日本語切り替えをする設定 2023年12月ver

## これはなに？

最近USキーボードのMacを再設定する機会があり、日本語・英語の切り替えのキーバインドの設定を見直しました。
この記事はそのときの備忘録です。

## 何の設定をしたいのか

JISキーボードのように、スペースキーの左右の ⌘command で言語の入力モードを切り替えられるようにしたいと思います。

ちなみに以前は[Karabiner](https://karabiner-elements.pqrs.org/)を使っていました。

https://karabiner-elements.pqrs.org/

様々なキーバインドの設定ができて便利ですが、時々反応しなくなることがあったり、現状の私のやりたいことにはオーバースペックになっていたので、もっとシンプルなものに乗り換えようと思いいたりました。

## ⌘英かな

下記のアプリがちょうど欲しい機能のみ提供してくださっていました。

https://ei-kana.appspot.com/

GitHubはこちらです。
上記のページのリンクから遷移可能です。

https://github.com/iMasanari/cmd-eikana

## 設定

上記のアプリのページのキーコンフィグに書いてあるとおりです。

1. 「Preferences..」→「キーリマップ」タブを選択
1. ウィンドウ右下の「+」ボタンで項目を追加
1. input列にキーボードの入力するキーを選択
1. outpuの列にMacで認識させるキーを選択

下記の図のように設定しました。

![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/215239/41838974-5237-aa75-74b7-6dcfcbd52f91.png)


以上で設定完了です。
今のところ快適に利用させていただいております。
更新は止まっているようなので、様子は見ながら使っていこうと思います。
[Python] Vision AIをAPI経由で使えるようにするまで

# 環境
Ubuntu 23.04
Python 3.11.4

venvで仮想環境を作って作業しています。
venvの使い方↓

https://zenn.dev/kotopasi/articles/ebc5758074536f
# はじめに
Vision AIとは、Google Cloud APIs に含まれる、画像処理に特化したAPI経由で使える事前学習済みのデータセットです。

https://cloud.google.com/vision?hl=ja

上記サイトでAPIを試せるので、遊んでみるのをおすすめします。
結構面白いです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3531484/099707eb-b5fc-9415-aa68-df74da0777c9.png)

# 手順
- Google Cloudにログイン

https://cloud.google.com/vision/?hl=ja

最初は90日間無料で利用できます。

- サービスアカウントの作成

タブメニューの「IAMと管理」画面から、「サービスアカウント」を押して作成します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3531484/b02858e0-beba-0495-a22d-9cdac35846e3.png)

アカウントの詳細画面から、「鍵を追加」 > 「新しい鍵を作成」でプライベートキーを含むJSONファイルがダウンロードされます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3531484/08795dd2-d5f3-b9b9-a331-de1dbedaa658.png)

- 環境変数の設定
`export GOOGLE_APPLICATION_CREDENTIALS= "JSONファイルの絶対パス"`

- ライブラリのインストール
`pip install google-cloud-vision`

# 実践
サンプルとして画像からテキストを抽出するコードを書きます。
![profile.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3531484/12319de0-9dae-ef6f-8563-449723c68be6.png)
これがこう↓
```bash
Web, CreativeCoding, ずとまよが好きです。 宮崎
```
```python:test.py
import io
from google.cloud import vision

client=vision.ImageAnnotatorClient()
image_path='./assets/profile.png'
with io.open(image_path,'rb') as image_file:
    content=image_file.read()

image=vision.Image(content=content)
response=client.text_detection(image=image)

texts=response.text_annotations

for text in texts:
    print(text.description)
```
テキスト抽出以外にも、ロゴの特定や、顔の検出なども出来ます。
# おわりに
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3531484/8228e891-7400-202d-5464-40a103f2a16c.png)

何度もこいつが出てきましたが、再試行押したら通った
# 道中で得た知見
## プライベートキーの入ったJSONファイルの管理
- ローカルのディレクトリから参照する、バージョン管理システムに含めないなど色々ある
- 今回は同じ階層に`./config/secrets/`を作って`.gitignore`で管理している

## 環境変数周り
- Unix系で環境変数の設定をするには`export`コマンドを使う。
(Windowsだと`set`)
- 環境変数一覧を見るには`printenv`
    特定の環境変数を参照するには(主にPATH)、`printenv PATH`
- 環境変数を更新したいときは同じコマンドで上書きでいい
- 環境変数を追加した後確認するには、`printenv GOOGLE_APPLICATION_CREDENTIALS`

# 参考

https://reneeds.net/2018/11/26/google-cloud-vision-api/

https://techblog.cartaholdings.co.jp/entry/archives/7801
【Linux】whatisコマンドが使えないときの対処法

## はじめに
Linuxの`whatis`コマンドが使えなかったときに行った対処法を、備忘録として残しておきます。<br>
エラー解消のヒントになれば幸いです。

## whatisコマンドを使えるようにする手順
Linuxの勉強がてらプロンプトにコマンドを打ち込んでいると、以下のようなエラーに遭遇。<br><br>

```
[user@localhost ~]$ whatis passwd
passwd: 適切なものはありませんでした。
```
<br>

`whatis`コマンド自体はあるみたいですが、うまく実行できてないようです。<br>
書籍やネットで色々調べると、どうやらrootユーザーにログインして`mandb`コマンドを実行すればよさげだとわかりました。<br>
ということで実践↓<br><br>

```
[user@localhost ~]$ sudo su -
[sudo] username のパスワード:
[root@localhost ~]# mandb
```
<br>

`mandb`コマンドが無事実行できたら元のユーザーに戻り、`whatis`コマンドを試してみましょう。<br><br>

```
[root@localhost ~]# exit
ログアウト
[user@localhost ~]$ whatis passwd
passwd (1)            - ユーザパスワードを変更する
passwd (5)            - password file
passwd (1ossl)        - OpenSSL application commands
```
<br>

うまく実行できました。めでたしめでたし。<br>
最後まで読んでいただき、ありがとうございました！
やば、iPhone落としたかもと思ったら

# やば、iPhone落としたかもと思ったら

## はじめに
- 人生1度や2度携帯電話を落としてしまうこともあるだろう
- 会社の端末を落としてしまったけど、MDM入ってないぞ…？
    - そんな時は、ちゃんと上司に報告するんやで…
- 会社でMDMなんて入れてないし、情報抜かれたらどうしよう、、、
    - そんなときの大急処置について書きます

:::note alert
この手順は情報漏洩などを抑制するものであり、必ずしもデータを守る術ではございません。
警察への届け出や会社の端末であればちゃんと報告するようにしましょう
:::

## さっそく手段を書いていきましょう！
<font color=red>大事だからもう一回書くぞ</font>

:::note alert
この手順は情報漏洩などを抑制するものであり、必ずしもデータを守る術ではございません。
警察への届け出や会社の端末であればちゃんと報告するようにしましょう
:::
※この手順では、対象のiPhoneで「探す」が有効になっていることが前提です。

1. デバイスを探すにアクセスしてログインします
    - https://www.icloud.com/find
        <img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/266246/de872007-56e5-4344-b762-ed4ff212fa39.png" width="400">
        ログインできるとデバイスを検索し始めます
        <img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/266246/79417232-589f-1bbd-f1cb-21115ec0f138.png" width="400">

2. 紛失してしまったiPhoneを選択して紛失モードにする
    - 選択すると下のような表示に
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/266246/16295a26-1a6c-de1b-9189-ce6f4992c524.png)
    - この中から紛失としてマークをクリックします（クリックすると以下のようなポップアップが出ます）
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/266246/4b763577-69df-d4f4-88ea-b14f42dc24d0.png)
    - (必要に応じて)電話番号やメッセージを入力していきます
    - ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/266246/6339d2ac-8006-96d7-0ca6-86102e3b9059.png)
    - ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/266246/6cc6ec10-b6d5-b88f-c7ef-2e697ef5b8a9.png)
    - 最後に有効にするをクリックします！（絶対忘れないでね）
    - 端末がオフラインの時は保留中に変わります（オンラインになると端末が紛失モードに切り替わります）
        - ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/266246/22ccb867-0212-ecd4-2071-393982f69d65.png)
    - 検出時に通知をONにしましょう
        - もし、拾った人が携帯の電源を入れた際に登録されているメールアドレスに見つかった旨のメールが届きます

## さいごに
いかがでしたでしょうか？
知っているだけで、紛失時にちょっと安心できますね（安心してはいけないですが）
もし、どこかに携帯を落としてしまったときに役に立つことを祈っております
が、落とさないようにしましょうね（大前提）
AIによる東方風な音楽生成：Google Music Transformerを活用した「Super Piano 3」

## はじめに

このコードは、Google Music Transformerを利用して長期構造を持つ音楽を生成するためのもので、「Super Piano 3」というプロジェクトの一部です。以下、コードの各セクションについて詳細な解説をします。

---

こちらの記事もおすすめ

https://hamaruki.com/composer-ai-create-songs-using-ai-suno-ai/

https://hamaruki.com/cg-production-is-also-possible-with-chatgpt/


## 環境設定と依存関係のインストール

まず、Google Colabでの作業を開始するためにGoogle Driveをマウントします。

```python

from google.colab import drive
drive.mount('/content/drive')
```



次に、必要なライブラリ（PyTorch、TorchVisionなど）をインストールし、GPUが利用可能かを確認します。また、必要なリポジトリをクローンします。

```python

!pip install torch==1.13.1+cu117 torchvision==0.14.1+cu117 torchtext==0.14.1 torchaudio==0.13.1 torchdata==0.5.1 --extra-index-url https://download.pytorch.org/whl/cu117
!nvcc --version
!nvidia-smi
!git clone https://github.com/asigalov61/midi-neural-processor
!git clone https://github.com/asigalov61/MusicTransformer-Pytorch
# その他必要なライブラリのインストール
```


## データセットの準備

MAESTROデータセットをダウンロードし、解凍します。また、カスタムMIDIデータセットの準備も可能です。

```python

!wget 'https://storage.googleapis.com/magentadata/datasets/maestro/v2.0.0/maestro-v2.0.0-midi.zip'
!unzip maestro-v2.0.0-midi.zip
# カスタムMIDIデータセットの準備
```

今回は東方のMIDIデータセットを使用しました。

こちらの方々のデータをお借りしました。

https://ryoya1295.web.fc2.com/midi.html

http://touhougennsouiri.web.fc2.com/midifolder.html


## モデルのトレーニング

トレーニングのパラメータを設定し、モデルのトレーニングを開始します。

パラメータは下記のようにUIで設定できるようにしました。解説もそちらをご覧ください。

![file](https://hamaruki.com/wp-content/uploads/2023/12/image-1702303790907.png)

```python

# トレーニングパラメータの設定
input_dir = "./dataset/e_piano"
output_dir = "/content/drive/MyDrive/MusicTransformer-Pytorch/rpr"
# その他のパラメータ設定
!python3 train.py -input_dir "./dataset/e_piano" -output_dir "/content/drive/MyDrive/MusicTransformer-Pytorch/rpr" -weight_modulus 5 -print_modulus 5 -n_workers 10 -batch_size 4 -epochs 100 -max_sequence 2048 -n_layers 6 -num_heads 8 -d_model 512 -dim_feedforward 1024 -dropout 0.1 --rpr
```


## モデルの評価と結果の可視化

トレーニングされたモデルを評価し、結果をグラフで可視化します。

```python

!python3 evaluate.py -model_weights /content/MusicTransformer-Pytorch/rpr/results/best_acc_weights.pickle --rpr
# 精度と損失のグラフ表示
```

![file](https://hamaruki.com/wp-content/uploads/2023/12/image-1702303352911.png)

## 音楽生成

トレーニングされたモデルを使用して、新しいMIDI音楽を生成します。

```python

!python generate.py -output_dir output -model_weights=$select_model --rpr -target_seq_length=$number_of_tokens_to_generate -num_prime=$priming_sequence_length -max_sequence=$maximum_possible_output_sequence $custom_MIDI
```


## 結果の保存とGoogle Driveへのアップロード

生成されたMIDIファイルを保存し、必要に応じてGoogle Driveにアップロードします。

このコードは、音楽生成において先進的なアプローチを用いており、長期的な音楽構造の生成に焦点を当てています。また、カスタムMIDIデータセットを使用する柔軟性も提供しています。

## Google Colab

https://colab.research.google.com/drive/1v7yxGNdw4DiJGYM1G-LnMxbMcMm0ElTR
【Flutter】今年触れた技術について〜table_calender〜

今回は、簡単にカレンダーの表示ができるtable_calenderについて紹介したいと思います。

### 環境
Mac OS:Sonoma14.1.2
Android:33
Android Studio:Android Studio Giraffe | 2022.3.1 Patch 4

## table_calender

https://pub.dev/packages/table_calendar

現在(2023/12/11)時点で、pub.defでLike 2492件とかなり有名なライブラリーです。
こちらはとても簡単にカレンダーの表示ができることが特徴の一つになります。

```Dart
// もっとも基本的なカレンダーの表示
TableCalendar(
  firstDay: DateTime.utc(2010, 10, 16),
  lastDay: DateTime.utc(2030, 3, 14),
  focusedDay: DateTime.now(),
);
```

上記だけでカレンダーの表示ができます。すごいですよね！
他にもカレンダーのフォーカスの色などもカスタムすることが可能です。

では、また明日〜！！
【R】read.csvでcsvを読み込むときのエンコーディング指定について


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/61492/ba0c1046-ac5f-c3df-c017-b0dff2ab8df6.png)
上記のようなcsvファイルをread.csvで開こうとしたら以下のようなメッセージが返ってきて、読み込めなかったときの対策
元ファイルは

e-Stat国勢調査、統計データ小地域を使用。

https://www.e-stat.go.jp/gis/statmap-search?page=1&type=1&toukeiCode=00200521&toukeiYear=2020&aggregateUnit=A&serveyId=A002005212020&statsId=T001081

まずはシンプルにread.csvで読み込んでみる。
- 実行内容
```
read.csv(csvfile.csv)
```

- 結果
```
Error in type.convert.default(data[[i]], as.is = as.is[i], dec = dec,  : 
  invalid multibyte string at '<8e>D<96>y<8e>s<92><86><89><9b><8b><e6>'
  ```

  ナンケラーが返ってきて、読み込み失敗

# shift-jis指定で開く
データの値に日本語が入っているので、エンコーディングを指定すれば良いと思い`fileEncoding="shift-jis"`を追加してみる。

- 実行内容
```
read.csv(csvfile.csv,fileEncoding="shift-jis")
```


- 結果
一応、ファイルは読み込めるものの以下のようなWarning messageが。
```
Warning message:
In scan(file = file, what = what, sep = sep, quote = quote, dec = dec,  :
  invalid input found on input connection csvfile.csv'
```

さらに元のcsvの列数は25700もあったのに、R上で列数を確認すると24245に減っていた。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/61492/a9010389-9728-e05a-426e-85bca2d40039.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/61492/d7ed71c6-3854-3a9b-7fcc-d7689863ea23.png)

# CP932指定で開く

- 実行内容
```
read.csv(file_list[1],fileEncoding="CP932")
```

- 結果
warning messageも出ずに、列数も正しく読み込んでくれました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/61492/2093ae9c-2da0-6027-da2b-97bf612f8d16.png)



# 結論
shift-jisとcp932の詳しい違いは以下を参照
https://qiita.com/kasei-san/items/cfb993786153231e5413

shift-jisのcp932拡張版と言うことで、`shift-jis`ではなく`CP932`で指定する方が安心。
Windowsのバッチファイル・Powershellの結果をSplunkに取り込む

この記事は[Splunk Advent Calendar 2023](https://qiita.com/advent-calendar/2023/splunk) 11日目です。



SplunkのUniversal ForwarderはWindowsの場合、任意のバッチファイル（.bat）やPowershell（.ps1）の実行結果も取り込めます！という機能があって、実はこれすごいんじゃない？と最近個人的にブームだったのでメモです。

※この機能自体は大昔からあります

## 何ができるの？

要はWindowsのバッチファイル・Powershellで見られるものなら何でも取れるんですが、例えば：

- Wifi接続状況の確認（netsh）
- 接続監視、Web/APIコンテンツ取得（curl）
- ドライブ利用状況（Powershell）
- その他コマンドプロンプト経由で標準出力できる.exeの結果

その他にも色々あります。
そして、ChatGPTに聞いたらスクリプトの内容まで作ってくれるので、Windowsで取りたいものは何でも簡単に取ってSplunkで分析できると言っても過言ではありません。
便利な世の中になりました。


## バッチファイル用inputs.conf

### フォルダ構造

$SPLUNK_HOME\etc\app\配下に以下のように作成。

```text: フォルダ構造
- <任意のadd-on名>
  - bin
    - <任意の名前>.bat
  - default
    - inputs.conf
  - local
    - inputs.conf
```


### .batファイル

好きな.batファイルを作成します。

```sh: .batファイル例
@echo off
chcp 65001 >nul
echo name=%1, result="Hello %1!"
```

`@echo off`: コマンドの一行結果のみ出力する。
`chcp 65001 >nul`: utf8（英語）で出力する。>nulがなければ実行結果として「Active code page: 65001」と出力されてしまう。
※日本語がよければ不要だが、sourcetype側の文字コードはSJISにしておく。
`echo name=%1, result="Hello %1!"`: 標準出力。`%1`は引数でinputs.confから渡す。Splunkで取り込んだ後のフィールド抽出はname=valueで自動抽出にお任せ。もっと複雑だったりしたらJSONにしても。（雑に取り込んでrexとかで抽出してもいいけど）


### inputs.confファイル

こんな感じで作ります。

```text: inputs.conf例
[script://.\bin\hello.bat Splunker]
interval = 60 
sourcetype = hello:bat
index = sandbox
disabled = 0
```

`[script://.\bin\hello.bat Splunker]`: 同一Add-onフォルダのbin内の「hello.bat」に引数「Splunker」を渡している。
`interval = 60`: 60秒おきに実行。cron式でも良い。
その他はいつもの。

### 実行結果

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1218403/6546216d-b96a-9d89-6843-873d3a6cff1e.png)



## Powershell用inputs.conf


### フォルダ構造

$SPLUNK_HOME\etc\app\配下に以下のように作成。バッチファイルの時と同じです。

```text: フォルダ構造
- <任意のadd-on名>
  - bin
    - <任意の名前>.ps1
  - default
    - inputs.conf
  - local
    - inputs.conf
```


### .ps1ファイル

好きなPowershell（.ps1）ファイルを作成します。

```powershell: .ps1ファイル例
Param( [string]$Name )
Write-Output "name=$Name, result=`"Hello $Name!`""
```

`Param( [string]$Name )`: 「Name」というパラメーター名で文字列型の値を受け取る。
`Write-Output "name=$Name, result="Hello $Name!""`: Write-Hostで標準出力。


### inputs.confファイル

こんな感じで作ります。

```text: inputs.conf例
[powershell://hello_powershell]
script = ."$SplunkHome\etc\apps\hello_ps\bin\hello.ps1" -Name "Splunker"
schedule = 60
sourcetype = hello:ps1
index = sandbox
disabled = 0
```

`[powershell://hello_powershell]`: 任意のタイトル。バッチファイルと違い、ファイルパスではないので注意。
`script = ."$SplunkHome\etc\apps\hello_ps\bin\hello.ps1" -Name "Splunker"`: script = [**.**（ピリオド）] [$SplunkHomeから始まるファイルパス]という独特な書式。ファイルパスではなく、直接Powershellスクリプトを書いても良い。
`schedule = 60`: 60秒おきに実行。cron式でも良い。バッチファイルの「interval」とは違うので注意。
その他はいつもの。

### 実行結果

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1218403/039b57fc-85da-5b39-8a00-170b19860b19.png)


### 備考
- 詳しくは[こちら](https://docs.splunk.com/Documentation/Splunk/latest/Data/MonitorWindowsdatawithPowerShellscripts)。

- Powershellに関するログは特別にここにも出る。`$SplunkHome\var\log\splunk\splunk-powershell.ps1.log`



## おまけ（ChatGPTがあればなんでもできる）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1218403/ce0fb03c-d764-b5d5-7c95-4d5440405362.png)
シンプルなインメモリキャッシュ go-cache

# go-cache
キャッシュというと、Redisやmemcachedなどが有名所ですが、Goではインメモリなキャッシュを扱うことができます。アイテムごとにTTLを設定でき、取り扱いがシンプルな`go-cache`を紹介します。

https://github.com/patrickmn/go-cache


## インストール
```bash
go get github.com/patrickmn/go-cache
```

```go:main.go
package main

import (
	"fmt"
	"time"

	"github.com/patrickmn/go-cache"
)

func main() {
    // TTL設定
    c := cache.New(30*time.Second, 2*time.Minute)
    c.Set("key", "value", cache.DefaultExpiration)

    val, found := c.Get("key")
    if found {
        fmt.Println("Found key:", val)
    } else {
        fmt.Println("key not found")
    }
    // 揮発しているか確認
	time.Sleep(1 * time.Minute)
	fmt.Println("1分経過")
	_, found = c.Get("key")
	if found {
		fmt.Println("Found key:", val)
	} else {
		fmt.Println("key not found")
	}
}
```


実行してみます。
```
go run main.go
Found key: value
1分経過
key not found
```
【Flutter】今年触れた技術について〜logger〜

今回は、Flutterでのロガーライブラリの一つloggerを紹介したいと思います。

### 環境
Mac OS:Sonoma14.1.2
Android:33
Android Studio:Android Studio Giraffe | 2022.3.1 Patch 4

## loggerについて

https://pub.dev/packages/logger

現在(2023/12/11)時点で、pub.defでLike 2631件とかなり有名なライブラリーです。
前提としてロガーライブラリについての必要性などに関しては過去にQiitaに書きましたので、そちらをご確認いただけると幸いです。

https://qiita.com/minomusi/items/51c4c877c09f763bbe1b

loggerの特徴としては以下があります。
1. PrettyPrinterに対応している。(めっちゃ見やすくて助かる。)
1. ログレベルを設定できる。

## 使い方
簡単に使用できます。

```Dart
var logger = Logger();

logger.d("Logger is working!");
```
上記だけで、簡単にデバッグログが出力できます。
以下は公式の各種ログの出力例です。

https://pub.dev/packages/logger#output

簡単に利用でき、見た目も綺麗で開発効率が上がるライブラリの一つだと思っています！
では、また明日〜〜
Apache POIを使用してExcelのセルの色を取得する



```java
import org.apache.poi.ss.usermodel.*;

import java.io.FileInputStream;
import java.io.IOException;

public class ExcelCellColorReader {
    public static void main(String[] args) {
        try {
            FileInputStream file = new FileInputStream("path/to/your/excel/file.xlsx");
            Workbook workbook = WorkbookFactory.create(file);

            // シートのインデックスを指定
            Sheet sheet = workbook.getSheetAt(0);

            // セルの座標を指定 (例: B3セル)
            int rowNumber = 2; // 0から始まる行番号
            int columnNumber = 1; // 0から始まる列番号

            Row row = sheet.getRow(rowNumber);
            if (row != null) {
                Cell cell = row.getCell(columnNumber);
                if (cell != null) {
                    CellStyle cellStyle = cell.getCellStyle();
                    Color color = cellStyle.getFillForegroundColorColor();

                    if (color != null) {
                        System.out.println("セルの色: " + color.toString());
                    } else {
                        System.out.println("セルの色は設定されていません。");
                    }
                } else {
                    System.out.println("セルが存在しません。");
                }
            } else {
                System.out.println("行が存在しません。");
            }

            workbook.close();
            file.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
短縮URLを自作する

# はじめに
短縮URL、使っていますか？[にわのわ](https://twitter.com/niwa_nowa)です。

自分は端末間でURLを共有するときに、短縮URLを使うことが多いです。
しかし、短縮URLを作るサービスはたくさんありますが、自分にとってとても難しい問題があります。
それは自分にはURLが覚えられないということです。

参考：
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/590707/94251bb2-d4d2-dc28-4e33-04601d91244e.png)

ということで。今回は以下の要件で短縮URLを作るサービスを作ってみました。
- （主に）自分のみが使う前提
- URLは数字のみにして覚えやすいものにする

# 今回みなかったことにしたもの
OSSで短縮URLをホストできるもの
自分で作ることにも意味があったと思っています

https://polrproject.org/

https://yourls.org/

# 作ったもの
今回作ったものはのソースはこちらで公開しています。

https://github.com/niwanowa/omit_url

# ソース
以下の2つのファイルをlambdaにアップロードして使います。
```登録用.py
import json
import boto3

def lambda_handler(event, context):

    table_name = "omit_url"

    #リクエスト情報のログ出力 
    print("===event===")
    print(event)

    print("===context===")
    print(context)

    # eventからurlを取得
    url = json.loads(event.get('body')).get('url')
    print("===url===")
    print(url)

    # DynamoDBからid(プライマリキー)の最大値を取得
    client = boto3.client('dynamodb')
    response = client.scan(
        TableName=table_name,
        Select='COUNT'
    )

    print("===response===")
    print(response)

    count = int(response.get('Count'))+1

    # DynamoDBにデータを登録
    response = client.put_item(
        TableName=table_name,
        Item={
            'id': {
                'N': str(count)
            },
            'url': {
                'S': url
            }
        }
    )

    # CORS対応
    headers = {
        'Access-Control-Allow-Headers': 'Content-Type',
        'Access-Control-Allow-Origin': '*',
        'Access-Control-Allow-Methods': 'OPTIONS,POST,GET'
    }

    return {
        'statusCode': 200,
        'headers': headers,
        'body': json.dumps(count)
    }
```

```リダイレクト用.py
import json
import boto3
import os

def lambda_handler(event, context):

    table_name = "omit_url"

    #リクエスト情報のログ出力 
    print("===event===")
    print(event)

    print("===context===")
    print(context)

    # eventからidを取得
    id = int(event.get('pathParameters').get('id'))

    # DynamoDBからidをキーにしてデータを取得
    client = boto3.client('dynamodb')
    response = client.get_item(
        TableName=table_name,
        Key={
            'id': {
                'N': str(id)
            }
        }
    )

    print("===response===")
    print(response)

    url = response.get('Item').get('url').get('S')

    # urlへリダイレクトするhtmlを生成する
    html = f"""
    <html>
    <head>
    <meta http-equiv="refresh" content="0;URL={url}">
    </head>
    <body>
    </body>
    </html>
    """

    return {
        'statusCode': 200,
        "headers": {"Content-Type": "text/html"},
        'body': html
    }
```
# おわりに
今回は短縮URLをホストするサービスを作ってみました。
作ってから少し時間が経っていますが、そこそこ使っているので満足さんです。
matplotlib ３次元グラフ（アスペクト比調整と多角形塗りつぶし−２）

## はじめに
久しぶりの投稿となった。

最近また３次元グラフの必要性に迫られて、昔の投稿を見直したり、新しい情報がないかさぐっていたところ、３次元でもアスペクト比を３軸で揃えることができるようになったようなので、自分用のテンプレートとしてコードを載せておく。


[自分の投稿](https://qiita.com/damyarou/items/e85d72f6e6513ff81fb0)

[アスペクト比に関する記事](https://sabopy.com/py/matplotlib-3d-61/)

[視点の変更関係](https://python.atelierkobato.com/elevation_azimuth/)



## テストコード
```python
import numpy as np
import matplotlib.pyplot as plt 
from mpl_toolkits.mplot3d.art3d import Poly3DCollection


def main():
    fsz=12
    xmin,xmax=-5,20
    ymin,ymax=-5,50
    zmin,zmax=-10,20
    iw,ih=12,10
    fig = plt.figure(figsize=(iw,ih))
    plt.rcParams['font.size']=fsz
    plt.rcParams['font.family']='monospace'

    elevs=[30,30,30,30]
    azims=[-60,-60,-135,-135]
    aspects=['auto','equal','auto','equal']

    for iii in range(0,4):
        nplt=221+iii
        ax = fig.add_subplot(nplt, projection='3d')
        ax.set_xlim3d(xmin, xmax)
        ax.set_ylim3d(ymin, ymax)
        ax.set_zlim3d(zmin, zmax)
        ax.set_xlabel('x-axis')
        ax.set_ylabel('y-axis')
        ax.set_zlabel('z-axis')
        ax.set_aspect(aspects[iii])
        ax.view_init(elev=elevs[iii], azim=azims[iii])
        # plot square shape
        x1,y1,z1=np.array([2,7,7,2,2]),np.array([2,2,7,7,2]),np.array([0,0,0,0,0])
        x2,y2,z2=np.array([0,0,0,0,0]),np.array([2,7,7,2,2]),np.array([2,2,7,7,2])
        x3,y3,z3=np.array([12,17,17,12,12]),np.array([0,0,0,0,0]),np.array([2,2,7,7,2])
        ax.plot(x1,y1,z1,'-',color='#ff0000')
        ax.plot(x2,y2,z2,'-',color='#0000ff')
        ax.plot(x3,y3,z3,'-',color='#00ff00')
        ax.plot(x1,y1+20,z1,'-',color='#ff0000')
        ax.plot(x2,y2+20,z2,'-',color='#0000ff')
        ax.plot(x3,y3+20,z3,'-',color='#00ff00')
        # colored polygon
        xx=np.array([0,5,5,0,0])
        yy=np.array([0,0,5,5,0])
        zz=np.array([20,20,20,20,20])
        verts = [list(zip(xx,yy,zz))]
        ax.add_collection3d(Poly3DCollection(verts,facecolor='#000080',alpha=0.3))

        ls1='ax.view_init(elev={0:.0f}, azim={1:.0f})'.format(elevs[iii],azims[iii])
        ls2="ax.set_aspect('{0}')".format(aspects[iii])
        ls3='xmin,xmax={0:.0f},{1:.0f}'.format(xmin,xmax)
        ls4='ymin,ymax={0:.0f},{1:.0f}'.format(ymin,ymax)
        ls5='zmin,zmax={0:.0f},{1:.0f}'.format(zmin,zmax)
        ls=ls1+'\n'+ls2+'\n'+ls3+'\n'+ls4+'\n'+ls5
        ax.text2D(0, 1, ls, va='top',ha='left',transform=ax.transAxes,fontsize=fsz)

    plt.tight_layout()
    plt.savefig('fig_1.jpg',dpi=100)
    #plt.show()


#---------------
# Execute
#---------------
if __name__ == '__main__': main()
```

## 上記コードの作図結果
 いくつかの正方形を描画しているが、```ax.set_aspect('equal')``` を指定することで、３軸とも同じスケールで描画してくれている（右上と右下の図）。

![fig_1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/129300/31065af8-e61b-ff3a-7d4a-637fba69381c.jpeg)



## 応用作図例
簡単な３次元骨組構造解析結果から断面力図を出力したもの。

![fig_ds_secf.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/129300/671586d1-e0bb-a762-05cd-f9506e91fa12.jpeg)

以　上
【小ネタ】riverpod_lintのassist紹介

[YUMEMI Flutter Advent Calendar 2023](https://qiita.com/advent-calendar/2023/yumemi-flutter) 11日目の記事です。

## はじめに

特にriverpod_generatorと併用すると便利なriverpod_lintですが、lintの他にいくつかのassistが含まれているので紹介します。

https://pub.dev/packages/riverpod_lint

## assist紹介

### Widgetの変換
StatelessWidgetやStatefulWidgetなどを相互に変換できます。
この機能はriverpod_generatorを使っていなくても恩恵を受けられます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2542067/11a80035-a563-e577-7910-72c9df83a286.png)

HookWidgetなどはflutter_hooksの依存があるときしか候補に表示されないようになってます。

https://github.com/rrousselGit/riverpod/blob/386e0de2fab7ca91f6709f43be348000e0563a69/packages/riverpod_lint/lib/src/assists/convert_to_stateless_base_widget.dart#L32-L36

### ProviderScope、Consumerでのラップ

ScopedProviderのoverrideなどに使うProviderScope、リビルド範囲を制御するときなどに使うConsumerをすぐに使えます。
この機能もriverpod_generatorを使っていなくても恩恵を受けられます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2542067/da4f9f8f-38d1-2045-36aa-40fd45820d63.png)

### 関数ProviderとクラスベースProviderの変換

関数ProviderとクラスベースのProviderを変換できます。
これまでと違い、riverpod_generator向けの機能です。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2542067/f08534a1-59d1-a317-e89b-080f6fa1a12b.png" width=50%><img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2542067/dcb2459e-6df7-2167-6aae-01eff571dc6b.png" width=50%>

## 導入方法
ここまで見てriverpod_lintを使いたくなった人向けの導入方法の紹介です。
（といっても公式ままですが）

riverpod_lintとcustom_lintをdev_dependenciesに追加する
```yaml:pubspec.yaml
dev_dependencies:
  custom_lint:
  riverpod_lint:
```

analysis_options.yamlでcustom_lintを有効化する
結構忘れがちです。custom_lintを入れてるつもりなのにassistが出てない場合は漏れてるかも？
```yaml:analysis_options.yaml
analyzer:
  plugins:
    - custom_lint
```

### Riverpodを初めて導入するとき

同僚の記事をおすすめしておきます😎

https://qiita.com/Yo2_engineer/items/566d0bd392d071cbeab8

## まとめ
riverpod_lintのassistを紹介しました。

### 余談

Widgetの変換に自分の実装も入ってるんですが、あまり使われてないのでは？と気になって記事書きました😂

https://github.com/rrousselGit/riverpod/pull/2306