OmniAICreator/Qiita-1.07M huggingface dataset:
Segment Anything

# 1. 概要
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/158742/276fb749-48be-44c9-e4a5-69bc003ee762.png)
画像内の異なる物体や領域を識別し、それぞれに対応するピクセルを分割するタスクのことをセグメンテーションという。提案手法では、プロンプト可能なセグメンテーション手法を提案しており、例えばテキスト・マーカー(点)・矩形・手書き教師(物体の一部を塗ってAIに教える)などの複数のユーザー入力が可能となっている。

*BEST PAPER HONORABLE MENTION

---

# 2. 新規性
- プロンプト可能なモデル：画像認識の分野で初めて複数のプロンプト可能なモデル(promptable model)を提案している。全く未知の画像分布を持つデータに対して、ゼロショットで対応するためにユーザーが複数の教師を与えることで正確に推論できるように設計されている。
- 大規模データセット：これまでのデータセットと比べて圧倒的に大規模なセグメンテーションデータセットを公開している。データセットには10億枚の画像があり、そのうち1100万枚には精緻なマスクアノテーションをつけている。なお、公開データセットはプライバシーやライセンスに考慮してデータ収集されている。
- ゼロショット推論性能：事前のトレーニングデータが無い場合でも推論できるように、10億枚もの画像で汎化性を持ってネットワークがトレーニングされており、従来の完全教師有りのモデルと同等性能を達成している。新しいタスクに対しても事前学習が不要でゼロショット推論できる汎化性がある。

---

# 3. 実現方法
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/158742/14b94adf-bcdd-c0f5-8f3b-69bf4df111b9.png)
モデルは、プロンプトと画像を入力としてマスク結果を出力する。ユーザーからのプロンプト教師を受けてリアルタイムに推論できるようマスクエンコーダーが軽量化されている。Mask/Points/Box/Textなどの異なるプロンプト情報をトランスフォーマーを使ってエンコーディングしており、入力の画像特徴とともに同じ特徴空間で扱うことでマルチモーダルな操作を可能にしている。

---

# 4. 結果
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/158742/d917fcd1-779c-b249-8145-a5842b2834ca.png)
例えば、1点のマーカーを教師としたときにSegmenta Anything Model(SAM)がどの領域を一つの物体と捉えるか実験してみると、3つの異なるレベルの領域を提示しており、ユーザーが所望するセグメンテーション結果を階層別に選択できるようになっている。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/158742/7f1efca7-1a9a-8c0f-0faf-e93d429548d9.png)
テキスト入力による領域推定も可能で、詳細を指示することで複雑なパーツの部位も精緻にセグメンテーションすることが可能。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/158742/e72cd1bb-903c-5d30-db55-11b069b3f235.png)
データセット作成はSAMを使って自動化されており、等間隔にマーカーを置いて自動でセグメンテーションさせた結果を更に教師の学習データに含めるという、自動アノテーションループを実現することで、アノテーションコストを限りなく少なくすることに成功している。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/158742/5299d49d-d241-f498-bb0f-bd0ffa459ab4.png)
データセット内のアノテーションのクオリティは非常に高く、このモデルの汎用性の高さを伺い知ることができる。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/158742/0a60d17d-18f8-62ce-a186-4fe8139e8ff3.png)
従来手法との複数データセット間の比較結果からも、提案手法の汎用性の高さが示されている。

---

Paper URL: <https://openaccess.thecvf.com/content/ICCV2023/html/Kirillov_Segment_Anything_ICCV_2023_paper.html>

last updates: Oct 8 2023
サブタスクが出力される不具合

「リマインダーを検索」アクションで「完了済み」または「完了済みではない」条件を設定すると、サブタスクが出力される。

### 前提条件

リマインダーとサブタスクをそれぞれ１つずつ用意した。

![IMG_5831.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3583885/f33d095e-fff1-5ed2-5cb5-faead53bebec.jpeg)

![IMG_5833.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3583885/0e3a21cf-4897-0fdc-73ac-0aa890147cf4.jpeg)

### 仕様

「リマインダーを検索」アクションで条件を設定しない場合、サブタスクは出力されない。

![IMG_5835.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3583885/1a1daf8d-632d-1dd2-4bbd-86ef10102fe0.jpeg)

### 不具合

ここに「完了済みではない」条件を追加すると、サブタスクが出力されてしまう。

![IMG_5834.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3583885/bd8cff52-37fa-99e2-f2d0-b15e4783a30d.jpeg)

画像は省略するが、「完了済み」条件を追加した際も、同様にサブタスクが出力されてしまう。
PLATEAU VIEW で My データを表示する

PLATEAU VIEW はウェブ GIS で、PLATEAU のデータを簡単に表示することが出来ます。ちなみに OSS としてソースコードも公開されています。

https://plateauview.mlit.go.jp/

https://github.com/Project-PLATEAU/PLATEAU-VIEW-2.0

この PLATEAU VIEW では PLATEAU のデータのほかにプリセットの各種オープンデータを重ね合わせて表示できるのですが、さらに独自に用意した My データも使用できます。ということで、実際どのようになるか試してみました。

## My データの読み込み方

PLATEAU VIEW を立ち上げて「カタログから検索する」をクリックします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/86075/4755b063-0856-0dbc-0931-34c737f0d909.png)

データカタログダイアログが開きますので、「Myデータ」タブをクリックします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/86075/d32346d6-46cd-cb44-86f3-504a08b4372c.png)

「ローカルのデータを追加」もしくは「Web からデータを追加」でデータを追加できます。

ファイルタイプは GeoJSON、KML/KMZ、CSV、CZML、GPX、GeoRSS、ShapeFile(Zip)、GLTF/GLB が選択できます。Web からの場合、さらに Web Map Service(WMS)、3D Tiles、Mapbox Vector Tile(MVT) が選択できます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/86075/a6b4bd86-2f3c-9fb2-7a92-d04bfd476ad8.png)

## CSV を読み込む

個人開発している[カラオケ(仮)](https://karaoke.saoyagi2.net/) で収集しているカラオケボックスのデータを CSV にして読み込んでみました。CSV はこんな感じです。PLATEAU は新宿区の建物モデルを LOD1 で重ねて表示しています。

```csvs
ID,店名,緯度,経度,URL
1,カラオケ ビッグエコー町屋駅前店,35.742468,139.781303,https://karaoke.saoyagi2.net/shops/detail/1
2,カラオケBanBan町屋店,35.743412,139.78034,https://karaoke.saoyagi2.net/shops/detail/2
3,カラオケALL町屋店,35.743328,139.781255,https://karaoke.saoyagi2.net/shops/detail/3
```

新宿駅周辺を表示してみました。歌舞伎町のあたりに白い球としていくつか表示されていますが、建物のかげになってよく見えません。建物を半透明にしてみても、重なりあっているところではちょっと見づらいですね。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/86075/04aac741-37dc-d1d6-2f9c-b192ed681de8.png)


球をクリックすると、CSV の他のフィールドの情報が表示されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/86075/f9d91136-0be7-07f2-d8d0-08840d0ef461.png)

## GeoJSON を読み込む

さきほどの CSV を GeoJSON に変換して読み込んでみました。

CSV の時とは違うマーカーになりましたが、やはり建物のかげに隠れてしまいますね。マーカーはファイルタイプごとに固定なのでしょうか。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/86075/94451a0c-f636-79d9-493a-f21ad78a2595.png)
Passive Ultra-Wideband Single-Photon Imaging

# 1. 概要
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/158742/a7a76c14-19f2-d824-1356-d91f377dfccf.png)
非常に短い極小時間のタイムスケールを考えてみると、秒単位からピコ秒単位まで撮影時間を短くすると、光源から光が物体に反射してカメラに届くよりも速い速度でシャッターを切るため、光がほとんどないため通常のカメラでは撮像できない。この論文では、極小時間の撮影で動的にシーン全体を再構築する技術を提案している。

*BEST PAPER AWARD

---

# 2. 新規性
従来手法で提案されている、単一光子(Single-Photon)を用いた光の強度や単位時間あたりに通過するエネルギーおよび光子の量を推定するフラックス推定手法では、動的なシーンを同時に撮影することができないため、光子を検出したタイムスタンプのストリームからピクセルの時間変動分のフラックスを再構築する、フラックスプロービング理論を提案している。

---

# 3. 実現方法
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/158742/3079a23b-0634-f101-ca5c-b7fe8f80e1ac.png)
提案手法では以下の効果が得られる。
- パッシブな自由走行型カメラ(Single-photon avalanche diode: SPAD)を用いて、低光量条件でDCから31 GHzまでの周波数帯域を持つことを可能にした。
- タイムスタンプデータ内において、統計的に有意な分布を持つ周波数をスキャンする新しいアルゴリズムを提案している。(フーリエドメインフラックス再構築: Fourier-domain flux reconstruction algorithm)
- アルゴリズムのノイズモデルが、非常に低い光子カウントや無視できないデッドタイムの場合でも頑健であることを示している。

---

# 4. 結果
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/158742/da35e2a7-5aae-1b1c-5b9c-2aa9082f21df.png)
同期せずに異なる速度で動作する光源(例えば、電球・プロジェクタ・複数のパルスレーザーなど)によって、同時に照らされるシーンを再構築することが可能となった。非同期で超広帯域のビデオの記録ができるようになり、例えば30 Hzで再生して日常の動きを再構築することが可能で、光の伝播を利用しているため、通常の動画と比べて10億倍遅く再生することができる。

---

Paper URL: <https://openaccess.thecvf.com/content/ICCV2023/html/Wei_Passive_Ultra-Wideband_Single-Photon_Imaging_ICCV_2023_paper.html>

last updates: Oct 8 2023
Adding Conditional Control to Text-to-Image Diffusion Models

# 1. 概要
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/158742/d6129c0d-5592-7f03-9019-df981cae4618.png)
Stable DiffusionなどのText-to-Imageタスクを行うための大規模な事前学習済みの拡散モデル(Diffusion models)に対して、空間的な制約条件を追加する”ControlNet”を提案している。Text-to-Imageでは、入力のプロンプトに対して画像が生成されるが、所望の画像をテキストだけから得ることは難しく、例えばエッジ情報・深度マップ・セグメンテーション・人体のポーズ情報などを制約条件として簡単に生成画像をコントロールできる点が評価されている。

*BEST PAPER AWARD

---

# 2. 新規性
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/158742/8ab318f5-a998-4735-7c07-d7dcd0dae7dd.png)
事前学習済みのパラメータを破壊しないように、外部から空間的な制約条件を教師する方法としてZero Convolutionを提案している。Zero Convolution層は、重みとバイアスが0で初期化された1x1の畳み込み層からなる。ここで元のbackboneネットワークは一切再学習せずに、同じネットワークをコピーして前後にZero Convolutionを挿入し元のネットワークとelement-wiseで足し算をして接続する。この演算により、元の特徴マップxを受け取り、空間的な制約cを付与した特徴マップy_cを得る。

---

# 3. 実現方法
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/158742/eb56d145-16c6-5c84-b9bc-758cff7172a2.png)
Stable Diffusionをbackboneにした場合、事前学習済みの拡散モデルは汎用性を持たせるために数十億枚の画像で学習されており、空間的な制約条件を使ってbackboneネットワーク全体をFine-tuningすることは現実的ではない。そこで、この論文ではbackboneネットワークを凍結(freezing)し、"Zero Convolutions"(ゼロで初期化された畳み込み層)で各Unetのレイヤーを接続し、パラメータをゼロから段階的に増やすことで、出力結果に対して制約条件がノイズとならないようにコントロールする手法を提案している。


---

# 4. 結果
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/158742/d5644710-245d-c491-c880-e61de0d8a1dd.png)
深度マップやポーズ情報など複数の制約条件を同時に入力してテキストから画像生成することが可能。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/158742/d88f7aff-11e4-4377-f0a2-d10678096491.png)
あいまいなテキスト入力に対しても、与えられた制約条件を解釈して画像を生成できていることが分かる。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/158742/fa5c54f6-04bf-893d-32b4-e4676fea4852.png)
Stable Diffusionの入力テキストを空にして、制約条件だけを入れて複数画像生成をしてみた結果を見ても、入力の制約条件に従って多様なシーンが再構成されているのが分かる。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/158742/914010f7-c91f-bbaf-d11a-15b0a149e5f9.png)
Zero Convolutionと通常のConvolutionを比較した結果、提案手法では生成結果が安定するのに対し、通常のConvolutionを用いると制約条件がノイズとなって生成結果が安定しないことが分かる。これは、学習可能なパラメータの初期値を0から開始し悪影響を及ぼさない範囲で学習を進めることによる効果だと考えられる。

---

Paper URL: <https://openaccess.thecvf.com/content/ICCV2023/html/Zhang_Adding_Conditional_Control_to_Text-to-Image_Diffusion_Models_ICCV_2023_paper.html>

last updates: Oct 8 2023
Multi-Modal Neural Radiance Field for Monocular Dense SLAM with a Light-Weight ToF Sensor

# 1. 概要
物体までの距離を測定するためのセンサーとして、Time-of-Flight(ToF)が知られる。ToFセンサーでは、発信された光や電磁波・赤外光が対象物体に当たり、反射して戻ってくるまでの時間を計測することで物体までの測距を行う。特に軽量なToFセンサーを用いた深度推定は、モバイルデバイスでのオートフォーカスや障害物検出のタスクによく使われる。一方で、深度測定値が疎でノイズが多く三次元再構成などの正確な測距が必要なタスクには用いることができなかった。この論文では、単眼カメラと軽量なToFセンサーという異なるモダリティ情報を用いて初めてSLAM(Simultaneous Localization and Mapping)を実現した。

---

# 2. 新規性
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/158742/8956ec95-ef50-34cc-31e3-4b7190c057de.png)
軽量なToFセンサーとRGBカメラ情報を用いることでマルチモーダル処理可能な深度推定手法を提案しており、ToFセンサー自体は低解像度で安価なデバイスにもかかわらず、三次元再構成されるシーンは密な情報を補完している。

---

# 3. 実現方法
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/158742/b800b1bc-751d-b7a8-9fc6-1dbd6f00720d.png)
物体の形状や外観(シーン内の環境の詳細な形状・テクスチャなど)を明示的にモデル化するのではなく、物体やシーンに関する情報をニューラルネットワークで学習するImplicit Representation Learningを用いてシーンの特徴や属性を暗黙的にエンコードしている。レンダリングには粒度を持たせており、ラフなシーンから詳細までCoarse-to-Fineで最適化できるようになっている。また、レンダリング結果と入力の生データを比較してロスを設計している。精度を向上させるため、ToFセンサーの信号に含まれるノイズを除去するために時間情報を用いている。

---

# 4. 結果
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/158742/bcaea855-ed84-4c60-64e2-1b9a3c8686ef.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/158742/775f60aa-99b3-b049-6a64-7888565b43bf.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/158742/54410589-a229-b87a-3d1e-13c86775f2c2.png)
カメラトラッキング・シーン再構成共に、既存研究よりも高精度に推論できている。

---

Paper URL: <https://openaccess.thecvf.com/content/ICCV2023/html/Liu_Multi-Modal_Neural_Radiance_Field_for_Monocular_Dense_SLAM_with_a_ICCV_2023_paper.html>

last updates: Oct 8 2023
【Rails】ポリモーフィックが便利〜

どうもこんにちは。

今回はポリモーフィックについてまとめます。

# ポリモーフィックってなんぞや？

ポリモーフィックとは、複数のモデル同士の関連付けの考え方です。

この考え方は、異なるモデルを単一の関連で扱う機能です。

例えば、以下のようにテーブルが存在しているとします。

commentsテーブル
| カラム名 | 型 | 値1 | 値2 | 値3 |
| --- | --- | --- | --- | --- |
| id | integer | 1 | 2 | 3 |
| comment | text | ワンちゃんかわいい！！ | よろしくお願いします。 | この時期寒くね？ |
| article_id | integer | null | 1 | null |
| photo_id | integer | 2 | null | null |
| tweet_id | integer | null | null | 1 |

articlesテーブル
| カラム名 | 型 | 値1 | 値2 |
| --- | --- | --- | --- |
| id | integer | 1 | 2 |
| article_title | string | 私の自己紹介 | 私の会社について |

photosテーブル
| カラム名 | 型 | 値1 | 値2 |
| --- | --- | --- | --- |
| id | integer | 1 | 2 |
| photo_title | string | 山からの景色 | 飼っているペットの写真 |

tweetsテーブル
| カラム名 | 型 | 値1 | 値2 |
| --- | --- | --- | --- |
| id | integer | 1 | 2 |
| tweet_title | string | 海なう | 美味しいご飯なう |

このような状態だと、commentsテーブルでは`article_id`に値が入っているときに`photo_id`と`tweet_id`は`null`になってしまっていますね。

## デメリット

### データベースの容量の無駄

上記のようにデータベースを作成してしまうと、無駄なカラムが出現してしまい、無駄に容量を使用してしまいます。
これは、データベース使用料などのコストがかかってしまうことに繋がってしまいます。

### 拡張性の欠如

上記のデータベースだと、記事,写真,ツイート以外のものに対してコメントできるようになった場合、カラムを増やなければなりません。

これもデータベースの容量の無駄に繋がってしまいますね。。。

### データの整合性

`article_id`カラム,`photo_id`カラム,`tweet_id`カラム全てに値が入っていたり、全てに値が入っていなかったりする可能性があります。

この場合、チェックする機構を作ればいい話ですが、ポリモーフィックを導入するとこのチェックする機構が必要なくなります。

# ポリモーフィックを導入するとどうなる?

Commentテーブルは以下のようになります。

commentsテーブル
| カラム名 | 型 | 値1 | 値2 | 値3 |
| --- | --- | --- | --- | --- |
| id | integer | 1 | 2 | 3 |
| comment | text | ワンちゃんかわいい！！ | よろしくお願いします。 | この時期寒くね？ |
| commentable_type | string | Photo | Article | Tweet |
| commentable_id | integer | 2 | 1 | 1 |

nullがなくなってカラムも減ります！

では実際に実装してみましょう。

# 実装手順

## 手順1. Commentテーブルを作成する

以下のコマンドでマイグレーションファイルを作成する。

```
rails g migration CreateCommentTable
```

以下のようにマイグレーションファイルを編集します。

```ruby
create_table :comments do |t|
  t.string :content
  t.references :commentable, polymorphic: true, index: true
  t.timestamps
end
```

## 手順2. Commentモデルに設定する

```ruby
class Comment < ApplicationRecord
  belongs_to :commentable, polymorphic: true
end
```

## 手順3. 関連させたいモデルに設定する

```ruby
class Article < ApplicationRecord
  has_many :comments, as: :commentable
end
```

```ruby
class Photo < ApplicationRecord
  has_many :comments, as: :commentable
end
```

```ruby
class Event < ApplicationRecord
  has_many :comments, as: :commentable
end
```

## 手順4. コントローラに処理を記述

```ruby
class ArticlesController < ApplicationController
    before_action :set_article, only: %i[comment_create]
    
    def comment_create
        @comment = Comment.new(comment_params)
        @comment.commentable_type = 'Article'
        @comment.commentable_id = @article.id
        if @comment.save
            redirect_to articles_path
        else
            render :new
        end
    end
    
    private

    def set_article
        @article = Article.find(params[:id])
    end
    
    def comment_params
        params.require(:comment).permit(:comment)
    end
end
```

Photo,Tweetのコントローラに対しても同様にコードを記述すればOKです！

うまくやれば、Commentsコントローラに一括で実装できます！

# まとめ

ポリモーフィックはデータベース使用料などのコストを抑えるなどの目的のために実装すべき仕組みだと思います。

以上
ScanNet++: A High-Fidelity Dataset of 3D Indoor Scenes

# 1. 概要
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/158742/a0f9974c-98a6-4d91-ff1a-5547e3ba1660.png)
2017年に提案されたScanNetは室内の3次元シーンのデータセットとして有効であったが、物体を個別に識別するFine-Grained Segmentationなどのタスクに用いるにはあまりにもノイズが多く低品質であった。そこで、この論文では高品質かつ高精度なジオメトリ情報(High-Fidelity Geometry)を考慮して、室内の3次元ジオメトリと色情報を結び付けた大規模なデータセットを公開している。

---

# 2. 新規性
室内を高品質なレーザースキャナーでキャプチャし、サブミリメートル級の解像度でジオメトリ情報を取得している。また、デジタル一眼レフカメラから3300万画素の画像とiPhoneを用いたRGB-Dストリームも同時に録画している。データ規模は、460のシーンに対して28万枚以上の画像と370万以上のRGBDフレームから成る。

---

# 3. 実現方法
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/158742/b93800d2-7335-d16e-dd2c-88f12a79629d.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/158742/95fd9033-dea4-2724-290f-da8df1782e06.png)
3Dセマンティックセグメンテーション・インスタンスセグメンテーション用のアノテーションデータも提供しており、3次元のシーン理解の様々なタスクに適用できるようになっている。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/158742/e08f01f3-5888-0cc1-a3e8-73304100172a.png)
また、NeRFを用いた多視点画像再構成技術のベンチマークにも使用できデータセットの有効性を示している。

---

# 4. 結果
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/158742/97c508b5-5528-fe3e-a677-4955e5690b36.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/158742/22b14ea3-cf96-4775-6009-31a346a5e861.png)
従来のデータセットより高解像度で密なデータを提供している。

---

Paper URL: <https://openaccess.thecvf.com/content/ICCV2023/html/Yeshwanth_ScanNet_A_High-Fidelity_Dataset_of_3D_Indoor_Scenes_ICCV_2023_paper.html>

last updates: Oct 8 2023
VitePressでTailwind CSSを使う

# VitePressでTailwind CSSを使う
VitePressでTailwind CSSを利用するための設定方法です。
## 確認環境
- Tailwind CSS 3.3.5
- VitePress 1.0.0-rc.29
- autoprefixer 10.4.16
- PostCSS 8.4.31
## Tailwind CSSのインストールと設定
### 前提条件
- VitePressはインストール済みとします。
- VitePressのテーマはデフォルトテーマを利用します。
### Tailwind CSSをインストールする
Tailwind CSSのインストールをします。
[公式サイト](https://tailwindcss.com/docs/installation/using-postcss)
```sh
npm install -D tailwindcss postcss autoprefixer
npx tailwindcss init
```
### PostCSSを設定する
PostCSSの設定ファイル(postcss.config.js)にTailwindを追記します。postcss.config.jsはVitePressプロジェクトディレクトリの直下に作成します。
```js
// postcss.config.js
export default {
  plugins: {
    tailwindcss: {},
    autoprefixer: {},
  }
}
```
### Tailwind CSSを設定する
Tailwindの設定ファイル(tailwind.config.js)にTailwindを適用するファイルのパスを設定します。以下はdocsディレクトリにマークダウンファイルを格納している場合の例です。
```js
//tailwind.config.js
/** @type {import('tailwindcss').Config} */
export default {
  content: ["./docs/**/*.{html,js,md}"],
  theme: {
    extend: {},
  },
  plugins: [],
}
```
### カスタムCSSを追加する
VitePressのデフォルトテーマにCSSを追加します。
```js
// docs/.vitepress/theme/index.js
import DefaultTheme from 'vitepress/theme'
import './custom.css'

export default DefaultTheme
```
カスタムCSSを追加します。
```css
/* .vitepress/theme/custom.css */
@tailwind base;
@tailwind components;
@tailwind utilities;
```
### 稼働確認
ローカル開発サーバを起動して確認をします。
```sh
npm run docs:dev
```
[Drupal] Develモジュールを使って、効率よくデバッグする方法



今回は、DrupalのDevelモジュールについて紹介します。

DrupalのDevelモジュールは、Drupalウェブサイトの開発およびデバッグプロセスを支援するための非常に便利なツールセットです。Develモジュールを使用すると、デバッグ情報の表示、パフォーマンスプロファイリング、データベースクエリのログ記録など、さまざまな開発タスクを効率的に実行できるようになります。

本記事は、Develモジュールでできることの紹介と、セットアップの手順をまとめました。

# 対象読者

本記事は、Drupalウェブサイトの開発者、またはDrupalに興味を持つ以下のような読者を対象としています。

* Develモジュールを使用してウェブサイトの開発プロセスを改善する方法に関心がある
* Develモジュールの機能や利点を知りたい
* サイト管理者や運用チームが、Develモジュールを使用してサイトの問題を特定する方法に関心がある


# Develモジュールでできること

Develモジュールは、様々な開発タスクをサポートする機能を提供しています。以下では、Develモジュールがもたらす主な利点について3つ紹介します。

## 1. デバッグ出力
Develモジュールは、`dpm()`関数を提供し、変数の内容やデバッグメッセージを表示するためのシンプルな方法を提供します。これは、カスタムコードのデバッグや問題のトラブルシューティングに役立ちます。ウェブページの上部にデバッグメッセージを表示することができるので、変数の値やクエリの実行などの情報をリアルタイムで確認できます。


```php
// 変数の値をデバッグメッセージとして表示する
$variable = 'Hello, Drupal!';
dpm($variable);

// ページの上部にデバッグメッセージが表示される
```
![dpm-message.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2187910/e8e038ee-c9cd-3f69-0f27-4232769c738b.png)



## 2. デバッグ情報の表示
Develモジュールは、Drupalの内部情報を表示するためのヘルパー関数を提供します。たとえば、`dpm()`関数を使用すると、オブジェクトや配列の内容を階層的に表示できます。

#### データ構造を`dpm()`関数で表示する
```php5
  public function buildForm(array $form, FormStateInterface $form_state) {
    // フォームの定義
    // ...

    // $formの内容をデバッグメッセージとして表示する
    dpm($form);

    return $form;
  }
```

この場合、`dpm()`関数は配列の内容を階層的に表示して、見やすい形式でデバッグ情報を提供します。以下の画像のように出力されます。
![dpm-form.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2187910/719dc756-5d14-955d-1b03-d105bd9d348f.png)


## 3. データベースクエリのログ
Develモジュールは、データベースクエリのログを記録し、実行されたSQLクエリを確認できるようにします。Drupalでは通常databaseクラスでクエリを発行して実行します。それによってクエリ文は隠蔽されてしまうため、実際に実行されるクエリ文を知ることができません。Develモジュールのdpq()を使うことで、クエリ文を知ることができるようになりデバッグ等の解析を効率良く進めることができます。

```php
$query = \Drupal::database()->select('users_field_data', 'u')
  ->fields('u', ['name', 'mail'])
  ->condition('u.uid', '1');
// クエリ文をデバッグ出力
dpq($query);
// クエリ実行
$result = $query->execute();
```

上のようにdpq()を使うと、以下の画像のようにページ上部にクエリ文を表示させることができます。
![dpq.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2187910/e1a68f62-0460-0a8d-b3ae-9cff639e8ab0.png)



# Develモジュールのセットアップ

次に、Develモジュールのセットアップ手順について紹介します。

## 0. 事前準備
Develモジュールのセットアップにあたり、ComposerとDrushをインストールしておく必要があります。
Composerの概要やインストール方法は、以下のURLを参照ください。
https://qiita.com/akira-hagi/items/553da1e122f7c300d6ac

Drushのインストールについては公式ドキュメントを参照ください。
https://www.drush.org/12.x/install/


## 1. Develモジュールのインストール

まず最初に、DevelモジュールをComposerを使用してインストールします。以下のコマンドを実行してください。なお、この手順を進める前に、Composerがインストールされていることを確認してください。

```bash
composer require 'drupal/devel:^5.1'
```

## 2. モジュールの有効化
Develモジュールを有効化するために、以下のDrushコマンドを実行します。Drushがインストールされていない場合は、先にDrushをインストールしてください。

```bash
drush en devel
```

これでDevelモジュールがDrupalに正常に統合され、利用できるようになります。
Translating Images to Road Network: A Non-Autoregressive Sequence-to-Sequence Approach

# 1. 概要
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/158742/20069109-9da3-95fc-dfa8-09f8ee37d08d.png)
カメラから360°の多視点画像を撮影し、これを入力として道路の俯瞰地図を自動生成する手法を提案している。高精度な地図を生成するためには、道路の目印となるランドマーク間の接続情報を正確に特定する必要があるが、俯瞰地図を生成させるネットワークを学習させるうえで、ユークリッド構造(例えば、道路の位置)と非ユークリッド構造(例えば、どの道路とT字路や道がつながっているかという道路のトポロジカルな接続情報)の複雑な組み合わせを考慮しなければならなかった。従来手法ではこの2つのデータドメインをうまく統合できなかったため、生成クオリティが低かった。

---

# 2. 新規性
この研究では、ユークリッド構造と非ユークリッド構造のデータを両方一遍に同じ空間に射影することでドメイン間の垣根を超えた特徴空間にマッピングし、さらに自己回帰型のトランスフォーマー(auto-regressive sequence-to-sequence Transformer)でモデル構築を行っている。

---

# 3. 実現方法
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/158742/34aca06e-86be-b186-81e6-c2fc557fa347.png)
アーキテクチャはエンコーダー・デコーダーになっている。エンコーダーでは複数のオンボードカメラ(Lift-Splat-Shoot)から俯瞰画像の特徴を抽出しており、現在自分がいる位置の周囲を俯瞰した特徴が得られる。デコーダーではいくつかの層を含み、自己注意層(self-attention layer)と交差注意層(cross-attention layer)、およびMLP層(Multi-Layer Perceptron Layer)から成る。自己注意層と交差注意層は、異なるタイプの情報を結合または処理するための注意メカニズムで、MLP層は情報の変換や最終的な出力を生成するのに使用される。

ここで、RoadNet Sequenceは統合した俯瞰画像特徴の左上からグリッドで区切り順にシーケンスに渡される。後段のSynthetic noisesはMasked Autoencorderのようにモデルに汎化性を持たせるのに効果的である。

---

# 4. 結果
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/158742/63fcec0a-9377-56ab-fdfb-7ecf7d7d018c.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/158742/31ef5450-2450-16e8-590a-1c01c99a07e1.png)
大規模な自動運転用データセットとしてしられるnuScenesで評価実験を行っており、提案手法が従来手法と比べて高速かつ高精度に俯瞰地図の自動生成に成功していることが分かる。

---

Paper URL: <https://openaccess.thecvf.com/content/ICCV2023/html/Lu_Translating_Images_to_Road_Network_A_Non-Autoregressive_Sequence-to-Sequence_Approach_ICCV_2023_paper.html>

last updates: Oct 8 2023
positionを使わないでFlexboxでデザイン配置する（最近よくやる）

この記事は アイスタイル <a href="https://qiita.com/advent-calendar/2023/istyle">Advent Calendar 2023 3日目</a>の記事です。
## potisionではなくFlexboxで実装する小技
よく使うわりに記述内容を忘れてしまうので備忘録を兼ねて:writing_hand_tone1:

例えばビジュアルや画像内で文字列などの要素を天地中央に配置したいとかpositionプロパティを使ってレイアウトを組むと思いますが、最近はFlexboxを使うのにハマってます。
positionを使用することで要素の高さが担保できなく、レイアウトが崩れることがある…など困ったときにとても便利だなと思いました。
## 特定の要素内で天地中央に配置する例
例）画像の中にテキストを天地中央に配置
▼position
<p class="codepen" data-height="300" data-default-tab="html,result" data-slug-hash="QWYmdoa" data-user="rnzdywgn-the-flexboxer" 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/rnzdywgn-the-flexboxer/pen/QWYmdoa">
  positionを使わないでflexでデザイン配置する（position）</a> by か。 (<a href="https://codepen.io/rnzdywgn-the-flexboxer">@rnzdywgn-the-flexboxer</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>

▼Flexbox
<p class="codepen" data-height="300" data-default-tab="html,result" data-slug-hash="WNPzRLX" data-user="rnzdywgn-the-flexboxer" 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/rnzdywgn-the-flexboxer/pen/WNPzRLX">
  positionを使わないでflexでデザイン配置（flex）</a> by か。 (<a href="https://codepen.io/rnzdywgn-the-flexboxer">@rnzdywgn-the-flexboxer</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>

`justify-content:center`で中央寄せにし、`align-items:center`で中央揃えにすることで天地中央にすることができます。
## 要素同士を上下で配置したい
例）イメージ図
![a.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3625328/4c20390d-7fb8-c173-c261-0d38733c8422.png)

<p class="codepen" data-height="300" data-default-tab="html,result" data-slug-hash="rNPdyqa" data-user="rnzdywgn-the-flexboxer" 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/rnzdywgn-the-flexboxer/pen/rNPdyqa">
  要素同士を上下に配置する（position）</a> by か。 (<a href="https://codepen.io/rnzdywgn-the-flexboxer">@rnzdywgn-the-flexboxer</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>

`flex-direction:column`で起点を垂直に変更し`justify-content:space-between`で両端揃えで均等にすることで上下に配置できます。

こういったレイアウトを組む場合、positionを使用するとabsoluteされた要素の高さを担保できなくなるのでレイアウトの組み方を考慮する必要がありますがFlexboxならあまり難しく考えずに実装できます。（要素の大きさが変化した際に崩れるという心配事が減りますね～）
【ChatGPTのお膝元OpenAIその後】こればかり？


　どうも、カーブミラーです。

　今回もOpenAI関連のニュースを継続していきます。

:::note info
本記事は、ChatGPTのニュースは
ありますが、基本OpenAIのことを
扱います。あしからず。
:::

　まずは、
　　昨日の続きから。

チャエン | 重要AIニュースを毎日発信⚡️さん（@masahirochaen）が1:33 午後 on 火, 11月 21, 2023にポストしました:
【続編：OpenAI騒動に新たな黒幕説が浮上】
https://x.com/masahirochaen/status/1726821008089460862?t=UfAQQ8BcyZbDC6S6UIekdQ&s=03
内容
「ずっと今回のクーデターの首謀者のと言われていたのはイリヤ氏ですが、ここに来てChatGPTの競合PoeのCEOであり、OpenAIの取締役でもあったアダム氏説が浮上した。」

　どうやら、
　　Poe CEOのアダム氏が、
　　　OpenAIを潰したいがために
　　　　起こしたものらしい。
　　そこで、イリヤ氏が生け贄に
　　　使われた。
　　彼はそこまでの意図はなく、
　　　少しサムを諌めて
　　　　欲しいだけだった。

　さて、
　　いまだにサムとグレッグは
　　　Microsoftには入社しておらず
　　　　取締役会総辞職もまだ。
　　　　　従業員総辞職もしかり。

　本記事を書いている時点では、
　　サムたちは、取締役会との
　　　交渉を継続しているらしい。

　どうなる、OpenAI。

***
　こっちは、
　　心配しているというのに
　　　OpenAIは、こんなことしてる。
2023/11/22【X-Twitter】
「ChatGPT with voice is now available to all free users. Download the app on your phone and tap the headphones icon to start a conversation.
」
https://x.com/OpenAI/status/1727065166188274145?t=7bajiE8F5flOxTSiBW5u5w&s=03
DeepL翻訳
「音声付きChatGPTがすべての無料ユーザーに提供されました。 携帯電話にアプリをダウンロードし、ヘッドフォンのアイコンをタップして会話を始めてください。」

　グレッグもミラも
　　どうぞ、って言ってる。

　8:00くらい時点では
　　アクセスできず、
　　　確認取れず。
　　（アクセス集中か、ど思ってた）

　これと並行して、
　　APIもダウン状態が
　　　あちこちで報告されている。

　こりゃ、
　　従業員側の抗議行動かな？

　おっ、バグだって。
![Screenshot_20231122-102708.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3457238/2d3e7230-6dd9-c4d7-3035-09ace8b934e1.png)


　2023/11/22の10:30に
　　ALL復活。

　アプリ（無料版）での
　　会話についても
　　　確認が取れました。
***
　その裏では、
　　Anthropicが
2023/11/22【X-Twitter】
Our new model Claude 2.1 offers an industry-leading 200K token context window, a 2x decrease in hallucination rates, system prompts, tool use, and updated pricing.
https://x.com/AnthropicAI/status/1727001773888659753?t=bmVQ_g7sROiyTZt1eNbUUQ&s=03
DeepL翻訳
「私たちの新しいモデルClaude 2.1は、業界をリードする200Kトークンコンテキストウィンドウ、幻覚率の2倍の減少、システムプロンプト、ツールの使用、および更新された価格を提供します。

Claude 2.1は私たちのコンソールでAPIを介して利用可能であり、私たちのclaude.aiチャット体験に力を与えています。」
***
　しかし、今日のX-Twitterは、
　　なんだかレイヤーさんが
　　　次々、アップしてくれてる。
　　　　何かの日？
　　　　　健康的な格好なので
　　　　　　人が近くをとおるたびに
　　　　　　　画面を隠してる
　　　　　　　　不審人物w

　ありゃ、
　　コミケだって。
　　　どこかはわからず。

　落合陽一さんも
　　アップ率が高い。
***
　早く決着して欲しい。

　まぁ、いつもの記事は
　　たいした内容ではないですけど。

　今回は、ここまで。
【ネットワーク】初心者のためのTCP/IPモデル説明

## 概要
前回の記事はカプセル化と非カプセル化について説明をしました。
今回はTCP/IPモデルについて説明をしていきます。
前回の記事は下記のものになります。
こちらの記事を読んでからの方が理解しやすいと思います。
是非、こちらも読んでみてください。

https://qiita.com/nakamura_slj/items/297a55f295b5191c010f

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

# TCI/IPモデル
TCI/IPモデルとは現在インターネットで利用されている通信プロトコル群のことで、
TCP/IPは**TCP**（Transmission Control Protocol）と**IP**(Internet Protocol)
という２つのプロトコルを中心に複数のプロトコルから構成されます。

## OSI参照モデルとTCP/IPモデルを比較
TCP/IPモデルはOSI参照モデルに合わせる形で作られているわけではないため、
各階層を正確に紐付けることは出来ないが、大まかに比較すると下の図１のようになります。
TCP/IPモデルはOSI参照モデルとは違い、図２のように階層が７階層ではなく４階層となっています

図１
![スクリーンショット 2023-11-22 10.45.56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3524075/2d375ad5-7588-0103-a613-390da0b92979.png)

図２
![スクリーンショット 2023-11-22 10.46.12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3524075/4db56831-4c02-620b-dfff-dbdaaad84cf8.png)


## 流れるデータ
続いてはTCI/IPモデルで流れるデータについて説明します。
まず、簡単に図で表したものが下の図となります。
ここでは、アプリケーション層でHTTP、トランスポート層でTCP、インターネット層でIP、リンク層でイーサネットの各プロトコルを使うことを想定しています。
![スクリーンショット 2023-11-22 11.01.47.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3524075/de42b8f7-6c7a-fea4-f292-99350b4619a4.png)

送信元では、上の層（アプリケーション層）から順番に送信するデータをカプセル化して下の階層に渡していきます
OSI参照モデルと同様に、各階層でその階層に必要なデータをヘッドとして付加していきます。

流れを簡単に説明をすると
1\.アプリケーション層でHTTPヘッダ付加してトランポート層に渡す
2\.トランスポート層でTCPヘッダを付加してインターネット層に渡す
3\.インターネット層でIPヘッダを付加してリンク層に渡す
4\.リンク層でイーサネットヘッダとトレーラを付加して、電気信号に変換しケーブル上に流す
といった流れになります。

ここで、トランスポート層でTCPヘッダが付加されたデータを**セグメント**、
インターネット層でIPヘッダが付加されたデータを**パケットまたはIPデータグラム**、
リンク層でイーサネットヘッダとトレーラが付加されたデータを**フレーム**と言います。
※トレーラ：誤り検出のための情報（後ろに付加する）

受信側の流れとしては送信側の逆の処理をしていきます。（非カプセル化）
これらの一通りの流れが完了したら送信完了ということにいなります。

# 最後に
以上となります
今回はTCI/IPモデルの大まかな流れを説明いたしました。
次回は各階層の役割と使われるプロトコルについて説明をしようと思います。
記事は下記のものとなります！

https://qiita.com/nakamura_slj/items/4693c34d30621b87e5be
次世代のコードエディターCursorのメリデメ

## 初めに
最近になって、コードエディターのcursorが話題になってきています。
自分は、１ヶ月前ほどから実際に開発環境で使い始めました。
そして、今まで使ってきた使用感をGitHub Copilotと比較して述べていきたいと思います。
そもそもvscode Likeに作られているため、vscodeの拡張機能はほとんどそのまま使えます。
うちの開発環境で使っている、ASP.NET Coreのdebuggerだけ使えませんでしたが...。

## メリット
1\. コード生成能力が高い

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2576293/800b10a1-8be1-d379-2c0a-95c9e310d879.png)

cursorは、Command Kを用いて会話ベースでコードの生成を行うことができます。
GPT4ベースのコード生成は、copilotよりも明らかに生成能力が高いです。
そもそも、copilotはチャットベースでコード生成はできないですが...。

例
命令：ファイルを読みこむコードを書いて下さい。認めるファイルは、pdf,wordのみにして下さい。
```
<input type="file" id="myFile" name="filename" accept=".doc,.docx,.pdf">
<script>
document.getElementById('myFile').addEventListener('change', function(e) {
  var file = this.files[0];
  var fileType = file.name.split('.').pop();
  if (fileType !== 'doc' && fileType !== 'docx' && fileType !== 'pdf') {
    alert('許可されていないファイル形式です。PDFまたはWordファイルのみをアップロードしてください。');
    this.value = '';
  }
});
</script>
```
上記の命令から、コードを生成してくれます。
自社の開発環境がsvelteであるため、svelteで使えるようにコードを生成しています。
その精度はGPT4ベースであるため、かなり高い精度になっています。

2\. デバッグ精度の高さ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2576293/73519a9d-d963-108a-df0c-81555162c005.png)

Command+Shift+Lを用いると、バグがあるかどうか、どのように変更するべきかを答えてくれます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2576293/f455cb8a-f5a9-3246-54e9-4348909fad85.png)

試しにid属性をなくして、bug fixを頼むとbugをしっかり直してくれます。
この精度は、GitHub Copilot Chatと比べると高い印象です。

全体的に、会話ベースでのコード生成能力はかなり高いと思います。

## デメリット
1\. コード補完はない
GitHub Copilotでは対応しているコード補完が、cursorではありません。
コード補完を使える人は、GitHub Copilotを普段から使っている人で、cursorの機能ではないです。
個人的に、コード補完がないのは痛いと思います。
会話ベースでコードを生成することがないので、痒いところに手が届くコード補完の方が使い勝手がいいと思っています。

2\. 価格設定
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2576293/e9bd5209-32b6-27a5-f963-28a7dd409944.png)

free枠でも普通に使うことができます。
しかし、GPT4を用いたChatは月に50回しか使うことができません。
つまり、今まで述べてきたメリットを受けるためには、pro枠の契約が必要ということです。
価格を考えると、GitHub Copilotかcursor proにするのかの選択に迫られると思います。

## 最後に
Cursorのメリデメを今回の記事では見てきました。
Cursorのコード生成能力は、個人開発の人にとっては大いに役立つと思います。
また、自分でサイトを作ってみたい人にとっては非常に有益です。

しかし、開発環境のために月に$20程しか使えない場合、
GitHub Copilotにするのか、Cursor Proにするのかは考えどころかなと思います。

個人的には、コード生成よりもコード補完をしてくれた方がいいので、
どちらかを取るならGitHub Copilotを使うと思います。

Cursorは無料で試せるので、一度自分で試してみて欲しいです。
Boxを使った電子帳簿保存法対応への対応

**１．本ページの概要**
電子帳簿保存法対応により、企業は様々な対応を求められていますね。
本ページでは、Box　Consulting松浦より、これまでのお客様との対応した経験を元に、Boxを使った電子帳簿保存法への対応について説明させていただきます。

<details><summary>この法律の目的（第一条）は長いので省略:airplane:</summary>
この法律の目的は、情報化社会に対応し、国税の納税義務の適正な履行を確保しつつ、納税者等の国税関係帳簿書類の保存に係る負担を軽減する等のため、電子計算機を使用して作成する国税関係帳簿書類の保存方法等について、所得税法、法人税法、その他の国税に関する法律の特例を定めるものとする。（第一条）
</details>

ざっくり言うと「取引相手に交付する書類（紙、電子データ）をちゃんと管理しようねって」話です


対象になるのは帳簿や書類など、取引に利用する書類になります。

帳簿や決算書類等は専用システムで管理している事がほとんどとは思いますが、取引相手に交付する書類の写し（取引書類）　例えば、「見積書、請求書、納品書、領収書、契約書など」はシステム化されていないケースがあると思います。

そのようなシステム管理外の書類管理にBoxがお役に立てる機能があるので、紹介させていただきます。

**２．取引書類に対して電帳法でやらなくてはいけない事**
電子帳簿保存法では下記の対応が求められます。
・真実性の確保　ー書類が改ざんされていないと証明する
・可視性の確保　ー誰でも視認・確認ができるようにすることです
・保管期間　　　ー7年、場合によって10年保管

もう少し詳しく要件を紐解くと、下記になります。
■真実性の確保：タイムスタンプの付与や、データ訂正や削除の履歴の確保

■可視性の確保：誰でもすぐに閲覧できる「見読可能性の確保」と取引年月日や金額など、所定の要件を満たした検索ができる「検索機能の確保」

■保管期間：電子取引を実施した事業年度の確定申告書提出期限の翌日から７年保管

![電子1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3622775/9b97fad2-6344-2cf0-6639-5ab3933e5c58.png)


**３．Boxで要件を満たせるか？**
ではBoxをつかってどのように２章の要件を満たせるか説明しましょう:laughing:

■真実性の確保：Boxではログ（レポート）による操作履歴や、修正履歴が確認可能であり、書類の改ざんがわからない状態は回避できます。

■可視性の確保（見読可能性の確保）：Boxには共有リンクや招待といった、閲覧希望者に対してセキュアに情報共有できる機能があり、プレビューのみでダウンロードさせない、編集させないような制御も可能ですので、安全に見読性が確保できます。

■可視性の確保（検索性の確保）：ここは少し運用を考える必要がありますが、Boxの機能にはメタデータという機能があります。書類をBoxに保管する際に、メタデータに取引年月日、取引金額、取引先、書類をやり取りした方のメールアドレスを付与すると、メタデータで検索が可能ですので、必要な書類を検索できるようになります。

■保管期間：こちらはBoxのオプション機能であるBox Governanceを利用いただく事で、保管期間を定め、指定期間中は指定した書類はBox上から完全削除ができなくなるように設定が可能です。

![電子2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3622775/60443a97-620a-3211-eea7-58aadfa9d52d.png)

という感じで、Boxでは電子帳簿保存法への対応として必要な機能は揃っております。ただ、メタデータ付与方法など少し運用を検討する必要がある部分もありますので、最終章で少し具体的な運用例を示します。


**４．メタデータの付与方法**
Boxの機能でフォルダ単位で作成できるファイルリクエストという機能があります。
ファイルリクエストの細かい内容は下記を参照してください
https://support.box.com/hc/ja/articles/360045304613-%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB%E3%83%AA%E3%82%AF%E3%82%A8%E3%82%B9%E3%83%88%E3%81%AE%E6%A6%82%E8%A6%81

この機能を使うと、フォルダにアップロードされるコンテンツにメタデータを必須で入力させる事が可能になります。

![電子3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3622775/b1177117-e97c-3acb-4c48-976e666608c7.png)

書類保存する際に利用する事で、うっかり検索要件を入れ忘れる事もなくなります！


さて、４章に渡り、Boxでの電子帳簿保存法対応についてご説明させていただきましたが、いかがでしたでしょうか？
今回は非常にシンプルな対応方法をご紹介させていただきましたが、BoxConsultingではお客様の要件にあった形でのご提案も実施させていただいております。お客様内でより複雑な対応要件や、こんな事できるかなどお悩みがあれば、お声がけいただければと思います。

以上
今更ネタ：VBAで一気に書きこむ最適な方法。

最近はVBAを使って色々やってる貴姫です。このエントリーは備忘録ですよー？

## セルへの値の書き込みが猛烈に遅いスクリプト
シートが2つあり、それぞれのシートに記載された値を元に、星取表に星を入れる必要があります。

あなたはどんなスクリプトを書きますか？

私の場合はこんな感じでした。

1. Sheet1（下記1）にある指定の値をArray1に（一次元配列）
1. Sheet2（下記2）にある指定の値をArray2に（一次元配列）
1. それぞれの値を比較
1. 一致したらSheet2（下記2）にある、Array2の値に対応する星取表の値をSheet1（下記1）に書き込む
* Array1 には **重複あり** で **2000** くらいの値
* Array2 には **重複なし** で **100** くらいの値

```VB:Original
For i = 0 To UBound(Array1)
        For ii = 0 To UBound(Array2)
            If Array1(i) = Array2(ii) Then
                Worksheets("1").Cells(i + 1, 1).Value = Worksheets("2").Cells(ii + 1, 1).Value
                Worksheets("1").Cells(i + 1, 2).Value = Worksheets("2").Cells(ii + 1, 2).Value
                Worksheets("1").Cells(i + 1, 3).Value = Worksheets("2").Cells(ii + 1, 3).Value
                Worksheets("1").Cells(i + 1, 4).Value = Worksheets("2").Cells(ii + 1, 4).Value
                Worksheets("1").Cells(i + 1, 5).Value = Worksheets("2").Cells(ii + 1, 5).Value
                Worksheets("1").Cells(i + 1, 6).Value = Worksheets("2").Cells(ii + 1, 6).Value
            End If
        Next
    Next
```

結構べたな書き方ですよね。

ただしArray内の値の数によっては激しく処理に時間が掛かってしまうわけです。当然ですよね！　だって、1行に6個の値があって、それが2000行続くんですから。
「さすがに時間かかりすぎ」だし「仕事があんまり忙しくない」って事もあり、高速な処理を色々調べてみました！　と言っても、全部書いたりはしないです。

## 最適化されたよ！
さて、答えにすぐ辿り着いてしまった訳ですが・・・　それは以下のような感じでした。
```VB:Amelioration
' セルから配列に入れる
For i = 0 To UBound(Array1)
    For ii = 0 To UBound(Array2)
        If Array1(i) = Array2(ii) Then
            
            ' 配列に書き込む
            With Worksheets("2")
                Array3(i, 0) = .Cells(ii + 3, 2).Value
                Array3(i, 1) = .Cells(ii + 3, 3).Value
                Array3(i, 2) = .Cells(ii + 3, 4).Value
                Array3(i, 3) = .Cells(ii + 3, 5).Value
                Array3(i, 4) = .Cells(ii + 3, 6).Value
                Array3(i, 5) = .Cells(ii + 3, 7).Value
            End With
            Exit For
        
        End If
    Next
Next

' 配列をセルに戻す
Worksheets("1").Range(Cells(1, 1), Cells(LastRow, 5)) = Array3
```

話はすごい単純。
セルから読んだ該当する星取表の値を直に目的のセルに入れるのではなく一旦配列（Array3）に入れます。
そうしたらその配列をセル範囲を指定して一気に書きこむだけです。

ちなみに貴姫が実際にテストした範囲だと、前者のスクリプトでは途中でExcelが応答なしになったりしつつ、2450行のデータ処理に約8分くらいかかりました。まあ正確な時間は計ってなくて、完全な体感ではありますが（2回も3回もやりたくなかった）。
そして後者の配列を一気に書きこむ方法だとなんとびっくり数秒で終わりました。

配列万歳！
音楽生成AIのWEBサービスまとめ(2023年11月版)

# 概要

音楽を生成するAIを調べました。


# 音楽生成AIとは
曲の雰囲気やテンポや長さなどを指定すると、自動的にいくつも曲を作ってくれるAI-WEBサービスです。


# 音楽生成AI-WEBサービス

自分でオリジナルの楽曲を作れるサービスとして、
「AIVA(エイヴァ)」と「SOUNDRAW(サウンドロー)」「SongR」などがあります。






## AIVA(エイヴァ)
https://www.aiva.ai/

### 特徴
- メロディー／ベース／打楽器などの単位で編集できる
- MIDIファイルをアップロードでき、それを元に編曲できる


### 良い点
- プランによっては、自分が著作権者になれる
- MIDIファイルでもダウンロードできる
- デスクトップアプリがあり、利用しやすい


### 気になる点
- 変更できるパラメタが多すぎて使いこなせない


## SOUNDRAW(サウンドロー)
https://soundraw.io/ja



### 特徴
- 操作がしやすい

### 良い点
- アカウントを作成しなくても楽曲が作れる（ただしサーバの反応が遅く生成途中でエラーになる事があるので、アカウントを作ったほうがよい）
- 小節単位で移動や削除や複製ができ、自分の望んだ楽曲に近づけやすい


### 気になる点
- 有料プランでも、楽曲に手を加えずに販売・配布することは禁止
- 小節と小節のつなぎ目が不自然なことがある


## songR
https://app.songr.ai/

### 特徴
- ジャンルとキーワードを入れると、歌詞（英語）と曲を両方作ってくれる
- ボーカル入りの楽曲にしてくれる

### 良い点 
- ユーザー登録不要で作れる(ダウンロードにはユーザー登録が必要)
- 女性ボーカルのみだが、声が鮮明で生成とは思えないほど自然

### 気になる点
- ボーカル無しにはできない
- 英語のみ



## Ecrett Music
https://ecrettmusic.com/ja/play
- 「SCENE」「MOOD」「GENRE」を指定して曲が作れる
- 「EcrettはSOUNDRAWに生まれ変わりました！」との記載あり。アカウント作成しようとするとSOUNDRAWに行くようにという表示が出る。


# その他のサービス
## amper music
https://www.shutterstock.com/discover/ampermusic
- shutterstockという画像素材の販売サイトに吸収？されたようです。
- 登録済みの楽曲の購入だけで、自分で楽曲を作る方法が分かりませんでした。

## musicLM
https://google-research.github.io/seanet/musiclm/examples/
- Googleのプロジェクトの１つ。
- サンプル楽曲のみで、自分では作れない。

## JukeBox
https://openai.com/research/jukebox
- OpenAI社が提供している
- 論文が掲載されているが、サービスとしては公開されていない？


## Amadeus Topline
Amadeus Code：https://amadeuscode.ai/ja (リンク切れ)
Evoke Music：https://evokemusic.ai/ja/music
- 生成済みの楽曲を検索してダウンロードできる


## Humtap
https://www.humtap.com/
- AppleのAppStoreでアプリをダウンロードする必要がある。未確認。

## Computoser
https://computoser.com/ (リンク切れ)

## styleSeq
https://styleseq.mamenone.com/
- 自動作曲できるWindowsアプリ。未確認。



# 画像生成AIと音楽生成AIの比較

音楽生成AIは、画像生成AIと比べて以下の点が異なります。
- プロンプトや自然言語で指示を与えるのが難しい。そもそも音楽を言語化するのか難しい。
- 生成後の音楽を、パートごとに分離するのが難しい。ノイズカットやボーカルキャンセル(弱くする)はできる。

# まとめ

音楽生成AI-WEBサービスを2つ紹介しました。
他にもご存じの方がいらっしゃいましたら、コメントをお願いします。
英小文字の出現率 (paizaランク C 相当)

https://paiza.jp/works/mondai/data_structure/data_structure__dict_step2

今度はアルファベット版。
アルファベットを配列に入れないといけないのだけどpythonでそんなのあったっけ？
と調べてみると、結構使う人がいるらしいですね、うまくまとまっているのがあったので
こちらで。(ありがとうございます！）

https://qiita.com/okkn/items/3aef4458ed2269a59d63

たしかにVBAのときもchrつかったなー。
あのときは呪文のようにしか聞こえなかったです（まだVBAはじめて2年目ぐらいのとき）

とはいえ。
97 ＋26文字ですね、覚えておこう。たしかによく使いそうです。

```py
[chr(i) for i in range(97, 97+26)]

```

あとはこうですね。
前回の方法をつかってやります。
今回は私が使った方法がよかった。

```py
N = int(input())
S = list(input())
A = [chr(i) for i in range(97, 97+26)]

counts =[]
for i in A:
    count = 0
    for j in S:
        if i == j:
            count += 1
    counts.append(count)
print(*counts)
```

答えを見ると

```py
N = int(input())
S = input()

count = {chr(x): 0 for x in range(ord("a"), ord("z")+1)}
for char in S:
    count[char] += 1

print(" ".join(map(str, count.values())))

```
Sを配列にいれず文字列そのまま。（驚き）

```py
count = {chr(x): 0 for x in range(ord("a"), ord("z")+1)}
```
なんか新しい書き方が出てきたな。
`ord()`は文字をUnicode値に変換する関数。
97という値を覚えるよりはこっちのほうがいいか。。。
それにしてもrangeわかりやすいな。
｛｝は何の内包表記だっけ。。。そうそう、辞書だ。
VBAでもdictionaryでたしかあったはず。。。
辞書については理解があやふやなのでこの機会に覚える。
わかりやすいのがあった(ありがとうございます！）
https://aiacademy.jp/texts/show/?id=570

さて、ここから解読すると
まあやってることはカウントが0のa~zの辞書を作っている感じ。
で、ここでcount[char]で、文字で辞書にアクセスができるので、カウントできる感じ。
で、Sに入っているのは文字列なので、<b>for文にいれると1文字ずつループできることがわかった。</b>

```py
S = input()
print(S)
for char in S:
    print(char)
```
結果下のようになるので1文字ずつループしていることがわかる

```
aaabbbccdddde
a
a
a
b
b
b
c
c
d
d
d
d
e
```
LINE Botに持ち物のストック場所を教えてもらいたい！開発記録

# 忘れっぽい自分を助けるシリーズ第二弾！
前回、忘れっぽい自分のために宅配ボックスの暗証番号などを教えてくれるLINE Botを作ってみました。
↓前回記事はこちら！ぜひ見てね:relaxed:

https://qiita.com/nishimo3/items/34fc394998798e1e4151

今回はTeachable MachineというAI(人工知能)の機械学習ツールを使って、忘れっぽい自分を助けるLINE Botを作ってみたいと思います！

# さっそく作ってみる！
今回は何を作るかな…:thinking:
Teachable Machineは画像や音声、身体の姿勢(ポーズ)などを学習させることができるけど、手軽に使うならやっぱり画像かなー
買ったはずのストックをどこに保管したか忘れちゃうから、画像をLINE Botで送ったらどこに保管したか教えてくれるツールとかいいかも！

# 作成に必要なもの！
- [LINE Developers](https://developers.line.biz/ja/)
- [Teachable Machine](https://teachablemachine.withgoogle.com/)
- [FlowFuse](https://flowfuse.com/)(Node-RED利用のために登録)

# できたのがコチラ！
https://x.com/NRie363584/status/1727141760605028765?s=20


# 作成手順！
### [Teachable Machine](https://teachablemachine.withgoogle.com/)で独自のモデルを作る
Teachable Machineでクラス名を入力し、画像サンプルを追加します。
モデルをトレーニングした後、エクスポートして共有可能なリンクを発行します。
<details><summary><font color="Green"><b>設定の詳細を確認したい方はここをクリック！</font></b></summary>
 Teachable Machineの画像プロジェクトから下記画像の⓵～⓻を実施します。
 
 ![2-8.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3583099/063f8917-b7b8-e49b-d849-374d1e9a54ea.jpeg)

![2-9.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3583099/e76e9f47-c9c6-7b33-34fd-4a26577cb9e3.jpeg)

</details>

### Node-REDとTeachable Machine、LINE Botを連携させる。
Node-REDのフロー内に必要なノード配置し、連携させます。
ちなみに今回のフローはこんな感じ！
![2-4.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3583099/4a1fdb96-f65d-dca0-6e5c-fbe18efa0038.jpeg)
<details><summary><font color="Green"><b>設定の詳細を確認したい方はここをクリック！</font></b></summary>

![2-10.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3583099/e0e0dde7-2fc1-b5db-42b2-ab6b00eba553.jpeg)

![2-11.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3583099/63d75868-b69a-2055-d600-e8a97a7e6da1.jpeg)

![2-12.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3583099/4cc2ec08-a401-2932-6478-4feece997a29.jpeg)
⓷のURLは`https://api-data.line.me/v2/bot/message/{{{line.event.message.id}}}/content`
トークンはLINE Developersのチャネルアクセストークンをコピー＆ペースト

⓸のURLはTeachable Machineの手順⓻でコピーした共有可能なリンクをペースト

![2-13.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3583099/bf51a36e-9384-56b6-9241-ca5f964d64dd.jpeg)
⓺のSecretはLINE Developersのチャネルシークレット、
AccessTokenはLINE Developersのチャネルアクセストークンをコピー＆ペースト

</details>

### [LINE Developers](https://developers.line.biz/ja/)のWebhook設定を行う

「Messaging API設定」ページの「Webhook設定」→「Webhook URL」にNode-REDページのアドレスバーにあるURLをコピー＆ペーストします。
cloud/の後ろは削除し、webhookノードのPath欄に入力したを文字を入力します。（今回はwebhook）

![2-7.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3583099/671c6178-9ed9-786a-7bea-d91f11b922ad.jpeg)

**これにて完成！！！**

# 最後に！
本当は自身の業務課題を解決するようなものを作りたかったけど、いつもExcelをポチポチやっているので画像や音声の機械学習では何にも思いつかなかったー:sweat_smile:
もしTeachable MachineにExcelのデータを読み込んで、今後どう推移していくのか予測してくれる機能とかがあったら私の収支管理業務に役立つのになーとか思いました。

機械学習と聞くととっても難しくてすっごく遠い存在と思っていたけど、こんな風にお試し感覚で楽しめちゃうものなんだなぁというのは発見でした！
自分の知らない技術を知るのは、視野が広がる感じがあってとても楽しいなと思います！
これからも色々新しいことに挑戦するぞー:laughing:
NginxコンテナをIngressで公開する

## 初めに
 IngressはKubernetesクラスター内のServiceに対する外部からのアクセスを管理するオブジェクトです．URIベースで複数のサービスに割り振ることができるので便利です．


## 実装の概要図

実装の概要図は以下に示します．
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/690612/2cae6aed-a9a6-2105-3942-279180084d9b.png)


Kubernetes Clusterはrke2で実装します．
[この記事](https://qiita.com/C0118272/items/a3d0e40cc92439407433)に従うと組み立てられます．

クラスタに配置するものは以下です．
- Ingress
- Nginx Service (Cluster IP)
- Nginx Pod


## 実装

rke2で組み立てたKubernetesクラスタ内に実装するもののYAMLファイルをそれぞれ示します．

**Step1**：
testという名前のNameSpaceを作成
```
$ kubectl create namespace test
```
**Step2**
NginXの構築を行います．

作業ディレクトリの作成
```
$ mkdir nginx
```

デプロイメントの作成
```
$ vi nginx/nginx-deployment.yaml
```
Nginxのデプロイメントが以下です．
```yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
  labels:
    component: nginx
spec:
  replicas: 3
  selector:
    matchLabels:
      component: nginx
  template:
    metadata:
      labels:
        component: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.20
```
移動
```
$ cd nginx
```

testのNameSpaceに作成
```
$ kubectl apply -f nginx-deployment.yaml -n test
```

次はServiceの作成です．Cluster IPで公開するNginxのServiceは以下です．

```
$ vi nginx/nginx-service.yaml
```
ファイルサービスの名前はmy-first-serviceとします．
```yaml
apiVersion: v1
kind: Service
metadata:
  name: my-first-service
spec:
  selector:
    component: nginx
  ports:
  - protocol: TCP
    port: 80
    targetPort: 80
  type: ClusterIP
```


移動
```
$ cd nginx
```

Serviceの作成
```
$ kubectl apply -f nginx-service.yaml -n test
```
**Step3**
作業ディレクトリの作成
```
$ mkdir ingress
```
移動
```
$ cd ingress
```

ファイルの作成
```
$ vi ingress.yaml
```
metadate/namespaceはNginxを作成したtestに作成します．
service/nameは先ほど作成したmy-first-serviceというservice名にします．
Ingressの設定は以下になります．
```yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: test-ingress
  namespace: test
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /
spec:
  ingressClassName: nginx
  rules:
  - http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: my-first-service
            port:
              number: 80
```

Nginxを作成したNameSpaceにIngressを作成します．
```
$ kubectl apply -f ingress.yaml -n test
```

Ingressができているか確認します．
ADDRESSに192.168.150.1と192.168.150.2と192.168.150.3のIPアドレスが振られているためできています．
```
$ kubectl get ingress -n test
```
```
NAME               CLASS   HOSTS   ADDRESS                                         PORTS   AGE
test-ingress   nginx   *       192.168.150.1,192.168.150.2,192.168.150.3   80      8h
```

**Step4**
アクセスができるかどうかを確認します．
ブラウザでhttp://IPアドレス:80 と入力しましょう！以下の画面が出ればOKです！

## 参考
https://kubernetes.io/ja/docs/concepts/services-networking/ingress/
Vector画像を設定したIconがPreviewだと色が変わる理由

Iconを使用して以下のようにVector画像を表示するとPreviewで画像の色が変わってしまいます

```kotlin
    Icon(
        modifier = modifier,
        painter = painterResource(id = R.drawable.vector_image),
        contentDescription = "icon"
    )
```

これはIconのパラメータでデフォルトでTintColorが設定されているため、塗りつぶしが変わってしまうからです。

```kotlin
@Composable
fun Icon(
    painter: Painter,
    contentDescription: String?,
    modifier: Modifier = Modifier,
    tint: Color = LocalContentColor.current.copy(alpha = LocalContentAlpha.current)
) {
```

tintがnonNullのパラメータとして設定されているということは、Androidでは塗りつぶして使う想定ということで、塗りつぶしを指定せずに使うのであればImageを使うのが良いのかもしれません。

どうしてもIconを使いたいよって場合は、パラメータのコメントに改定ある通り、 `Color.Unspecified` を使うと良いでしょう。

> tint - tint to be applied to painter. If Color.Unspecified is provided, then no tint is applied

ちょっとハマったのでメモ程度に。
なにかあればコメントで教えてくだしあ！
[ES6] オブジェクトリテラルの省略記法

## Reactで頻出するこれ

```jsx
// id, name, email がpropsで渡ってきているとして
const　userData = {
  id,
  name,
  email,
  ........
}
```
こういう書きかた。
よくわからないがkeyとvalueが同じであれば省略できるという理解でいる。
詳しく理解せずに1年以上もReactを書いている。
よくない。調べようと思う。

## 「オブジェクトリテラルの省略記法」と言うらしい

前述のuserDataオブジェクトは、昔ながらの書きかたではこうなる。

```jsx
// id, name, email がpropsで渡ってきているとして
const　userData = {
  id = id,
  name = name,
  email = email,
  ........
}
```

しかしReactでは**propsで持ってきた変数にデータを代入すること**が頻発するため、さすがに冗長に感じてしまう。

そのときにES6で加わったオブジェクトリテラルの省略記法という新しい書きかたをしているのが、一番上のコードだったのだ。


同じくES6で加わった**デフォルト引数**とも相性がよい。

```js
function fn ( options = {} ) {
  let id = options.id;
  let name = options.name;
  let email = options.email;
  // 以下同じような定義
}
```

引数のオプションはこうやってだらだら書いてしまいがち。というか、今まではこう書くほかはなかった。

↑これを、↓こう書くことができる。
```js
function fn(options = {}){
  let {id, name, email, 以下続く} = options;
}
```

見通しがよくなる。


## スクラムチームでは

省略記法は糖衣構文ではないので独断で採用して怒られるということはないが、使う必要のないところ（例：keyが2、3の少ないデータ）で使うのは初見の開発者にとって見づらいかもしれない。

一番大切なのはセキュリティで、次点は処理速度、三番目はメンバーにとって読みやすいことだと常々思っている。
GASで時間指定でイベントを発火させる方法について

# GASで時間指定でイベントを発火させる方法について

スプレッドシートに記載したタスクリストを取得し、ステータスが「未着手」「処理中」のタスクをSlackのメッセージで指定時間に送付するアプリをGASで書きたい時に、「○時○分」と時間指定ぴったりに送付させる方法について記載します。

## 前提
まずはGASでイベント発火を設定する方法について説明します。
![キャプチャ0.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2028933/17121765-137c-4b2f-2187-5de47ce18f2e.png)

- 左側にあるサイドメニューから目覚まし時計のマーク（トリガー）をクリックする。
- 右下にある「トリガーを追加」ボタンをクリックする。
![キャプチャ1.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2028933/d0ea7b9e-6517-185c-7b17-886d2ffed305.png)

- 実行する関数を選択の項目で「実行したい関数」を選択する。
- 時間ベースのトリガーのタイプを選択の項目で「日付ベースのタイマー」を選択する。
- 時刻を選択する項目で「実行したい時刻」を選択する。

## 問題
GASで用意されているトリガーは１時間単位でしか指定できないので、上記の例だと9時00分から9時59分の間に実行されてしまう。

例えば9時30分ちょうどにメッセージを送信したい……というような、時間指定ができない。

## 解決策
- 指定の1時間内に実行される用の関数を作成する。
- 作成した関数の中で下記の処理を書く。
  - 指定する時刻をセットする
  - 新規トリガーの設定と実際に行いたい処理（メッセージを送付するための関数）


```
// トリガー設定
function execute(){
  // 実行時刻格納用の定数
  const date = new Date();

  // 実行したい時刻を指定する
 // setHoursで時間を指定する
  date.setHours(09);
 // setMinutesで分を指定する
  date.setMinutes(30);

  // 新規トリガーの設定
 // slackにメッセージを送信するための関数を指定する
  ScriptApp.newTrigger('mainFunction').timeBased().at(date).create();
}
```
GAS内で新規トリガーを作成する構文に下記を代入する。
```
ScriptApp.newTrigger('関数名').timeBased().at(時刻をしていた変数).create();
```

**ポイント**
GASのトリガーは実行したい時間より早い時間を設定しておく。
9時30分にメッセージを送信したい場合、午前8~9時など指定時間より早い時間帯を指定する。
**理由**
例えば午前9~10時を指定してしまうと、9時45分にトリガーが実行されてしまう可能性があるので、早めの時間帯を設定する必要があるから。


![キャプチャ2.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2028933/25a9070c-1227-6d3d-ef32-5989ca354735.png)


無事に指定した時刻にメッセージが送信されました！

今回は例としてスプレッドシートの内容をSlackにメッセージを送信してみましたが、GASのイベント発火全般に利用できるので是非お試しください！