OmniAICreator/Qiita-1.07M huggingface dataset:
【flutter】TextFormFieldでバリデーションを実装するには？

こんにちは！
今回はTextFormFieldでバリデーションを実装する方法について紹介したいと思います！
今回も最後まで読んでいただけたら嬉しいです。

## 1,　バリデーションの実装方法
### TextFormFieldを作成
TextFormFieldを作成し、バリデーター関数を指定します。このウィジェットは、ユーザーにテキスト入力を促し、入力されたテキストを検証します。
```php
TextFormField(
  decoration: InputDecoration(
    labelText: '入力テスト',
  ),
  validator: バリデーター関数,
)

```

### エラーメッセージの表示: 
バリデーションエラーメッセージがある場合は、それをユーザーに表示します。Formウィジェット内にTextFormFieldを配置し、FormのautovalidateModeプロパティをAutovalidateMode.alwaysに設定することで、エラーメッセージを自動的に表示できます。
```php
Form(
  autovalidateMode: AutovalidateMode.always,
  child: TextFormField(
    decoration: InputDecoration(
      labelText: '入力テスト',
    ),
    validator: (value) {
      if (value.isEmpty) {
        return 'メールアドレスを入力してください';
      }
      if (!EmailValidator.validate(value)) {
        return '有効なメールアドレスを入力してください';
      }
      return null; // バリデーションが成功した場合はnullを返す
    },
  ),
)

```
バリデーター関数の例として、入力値が空である場合や、有効なメールアドレスの形式でない場合にエラーメッセージを返す処理を記述しています。EmailValidator.validate()は、入力値が有効なメールアドレスの形式であるかどうかを判定するためのヘルパーメソッドです。

## 2,　バリデーションの種類

### 数値の範囲チェック
入力された数値が特定の範囲内にあることを確認するために利用します。例えば、特定の範囲外の数値が入力された場合にエラーを返します。
```php
validator: (value) {
  if (value < 0 || value > 100) {
    return '0から100の間の値を入力してください';
  }
  return null;
},
```

### 正規表現によるチェック
入力された値が特定のパターンに一致するかどうかを確認するために利用します。例えば、メールアドレスや電話番号の形式をチェックする際によく使用されます。
```php
import 'package:flutter/services.dart';

validator: (value) {
  final RegExp emailRegex =
      RegExp(r'^[\w-\.]+@([\w-]+\.)+[\w-]{2,4}$');
  if (!emailRegex.hasMatch(value)) {
    return '有効なメールアドレスを入力してください';
  }
  return null;
},
```

![タイトルなし.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3524127/ebb59df3-badc-d9f1-06ee-4ca5b3187bdc.gif)


## 終わりに
今回の記事は以上になります！
では、また次の記事で〜！
運営しているWebサービスをリアーキテクチャした話

## はじめに
運営しているWebサービスが複雑化してきたので、リアーキテクチャやリファクタリングをしました。まだまだな伸び代は多いですが、一旦整理したのでやったことなとまとめてみました。

## 背景

自分が作ったWebサービスは、元々メディア的な属性が強かったのですが、認証機能やCRUDする機能など動的な機能が増えてきて、ロジック部分が多くなり複雑化してきました。

また、サーバーレスということもありフロントでのコード量が増え、なんとかアーキテクチャを見直さないと大変そうな感じがしていました。

そして一番の理由としてテストが書きづらいかったところです。元々メディア的な運営で静的化していたこともあり、デプロイ前のgenerateがテスト代わりのようになっていました。

しかし、動的な機能が増えるとSSGでは検知できないため、テストを書く必要があり、いざ書こうと思うと非常に書きにく設計となっていました。

今後の運用性・拡張性を考えてもリアーキテクチャは急務であり、非常に優先度の高い重要なタスクとして取り掛かりました。

## 色々考えたことを整理する

・フレームワークに依存した作りをやめたい

・レイヤリングしてUT導入したい

・ライブラリに依存したドメインを使わないようにしたい

・共通化したい

・型エラー直したい

ざっくりこんなことを考えており、1つ1つこなしていきました。感覚的な意識の部分としては、「依存性をなくして抽象的かつ中長期的に開発生産性の高いものにしたい」ということをぼんやり考えてました。

そんな中で、Nuxt3 + TypeScriptで開発しているのですが、ロジック部分などなるべくフレームワークに依存するような書き方はやめたいと考え、テストの書きにくさだったり、汎用性だったりを考えたときに、なるべく抽象性の高い書き方にしたく、素のTypeScriptで書くようにしました。

また、ドメインに関する情報の増加や複雑性もあり、DDD + Clean Architectureを導入することにしました。一部Firebaseライブラリのドメインを使っていましたが、そこへの依存度が高くなってしまい、Firebaseを辞めたときやバージョンアップで気付かぬうちに使えなくなってたというのをなくしたい気持ちがありました。

その上で、JestによるUTを導入し、安全かつ見通しの良い、開発していて楽しい開発体験を目指しました。

今回は、DDD + Clean Architectureを導入したリアーキテクチャのところを一部まとめておきたいと思います。

## DDD + Clean Architectureの導入してリアーキテクチャする

![dc4f8255a9399360fa44bb0d6c10bdf5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/242816/9c1b8e0e-e564-2482-2fe0-8d1347e4ab87.png)

構成としてはこんな感じで、srcの下にそれぞれレイヤリングして配置しています。modules.tsに依存関係を書いています。

依存関係としてはusecaseはgatewayとpresenterに依存しており、gatewaはdriverに依存しているといった形です。

本当はportなどのインターフェイスを作って依存性逆転して綺麗な形にしたいのですが、一旦このような形になっています。

usecaseではビジネスロジックを記述しており、garewayを通してデータの取得や登録などをしています。また、presenterを経由してstateの管理をしています。

gatewayではusecaseとdriverの橋渡しとして、driverからのデータをdomainに変換したりしています。データの取得・登録の実装部分はdriverで書いています。DBやAPIなど変更したとしても、driverを変えれば影響がないようにdriverからentityに詰めてgatewayに返し、gatewayでdomainに詰め替えています。

ここまでレイヤリングすると、あとはusecaseを呼び出すだけで済むので、だいぶスッキリしました。

今後はTDDで進めたいと思っていますが、既存の部分に関してはガッとリアーキテクチャしてから、テスト書きました。テストはJestを使っており、jest-whenライブラリを活用しつつ書いています。

## おわりに

一旦基盤はできたので、今後は適宜リファクタリングしながら、保守性の高い設計に向けて改善を続けたいと思っています。

ドメインも全部は用意できてなかったりとまだ伸び代もあるので、常に改善する気持ちで開発し続けることが大事です。

あとはSSGベースでやってますが、SSRにしていきたいと思っています。ちょっとコスト的にどれだけ高くなるのか心配ですが、チャレンジしたいと思っています。

あとE2Eも書きたいと思っています。Cypressでちょっとやりましたが、放置してしまってるので、どこかで本腰入れてやりたいと思っています。やはりテストで担保されていないと、いつ壊れるかわからないですし、そうした状況下で開発するのは結構しんどいです。

品質の担保かつ生産性の向上のためにも、よりより開発・設計を追求していきたいです。

## JISOUのメンバー募集中
プログラミングコーチングJISOUではメンバーを募集しています。
日本一のアウトプットコミュニティでキャリアアップしませんか？

気になる方はぜひHPからライン登録お願いします👇

https://projisou.jp/
【コツコツ学習】StringBuilderとStringBufferの比較（スレッドセーフも）

# 背景
以下でStringBuilderとStringBufferについて以下を学びました
StringBuilderの方がパフォーマンスが良い
・StringBuilder：スレッドセーフじゃない
・StringBuffer：スレッドセーフ

https://qiita.com/gksdyd88/items/d3873600829337bebedd


# スレッドセーフとは何ぞや

複数のスレッドが同時に同一のデータやリソースにアクセスしたとき、予期せぬ問題やデータの不整合が発生しないように設計されたコードのことを指します。
「並行処理を行っても安全」という意味らしいです。

並行処理というのは、コンピュータが複数の処理を同時に行うことです。

つまり複数のスレッドが同時に同じデータを読み書きすると、データが予期せず上書きされたり、一部のデータが更新されないまま使われたりする可能性があり、スレッドセーフなコードは、このような競合状態を防ぐために重要であるということなんだなー

https://qiita.com/yamazaki_25/items/19d5165e529c5ca2ec97

# 文字列に関してはスレッドセーフであるべきか

ローカル変数で用いるのであればスレッドセーフでなくても問題なさそうなのでStringBuilderでよいと思いました

>ローカル変数以外は複数のスレッドから共有され得る
>Javaの変数は，ローカル変数だけがスレッドセーフ（複数のスレッドが同時に動作しても異常をきたさないこと）で>ある。その理由は，ローカル変数はスレッドごとに割り振られる「Javaスタック」と呼ぶメモリー領域に格納される>からだ。これに対して共有メモリーである「ヒープ領域」に格納されるインスタンス変数やクラス変数は，複数のス>レッドが共有する可能性があり，スレッドセーフではない。そのため，参照または更新するときにはロック（更新メ>ソッドにsynchronizedキーワードを指定する）などを検討しなければならない

https://xtech.nikkei.com/it/article/COLUMN/20070820/279950/

# 感想
StringBuilderを自然と使っていたけどこんな背景があるんだなーと
面白い
FullCalendarのカスタマイズ：月表示で余分な翌週の行を消す

FullCalendarの仕様なのかわかりませんが、
月表示の時に、翌月の日にちが1週間分表示されます。(下図参照)
![fullcalendar.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3332453/6bd8215f-8434-219a-5f55-f7f7810b56e0.png)

これを消したかったのですが、公式のドキュメントに消すためのオプションが見つからなかったため、
自分で消す方法を考えてみました。

## 結論
このコードを一番下あたりに追加してください。

```javascript
        /*
            FullCalendar表示カスタマイズ:
            翌週分の週が余計に1行表示されている部分を消す
        */
        //【load】レンダリング、静的ファイルなど全ての読み込みが完了したタイミングで処理を開始する
        window.addEventListener('load', function() {
            
            // カレンダー<tabble class="fc-scrollgrid-sync-table">の最後の<tr>要素を取得
            var lastRow = document.querySelector('.fc-scrollgrid-sync-table tr:last-child');

            //エラー対策:<tr>要素の取得できた時だけ実行
            if(lastRow){
                // 取得した<tr>要素(翌週1週間に該当する部分)を非表示にする
                lastRow.style.display = 'none';            
            }
        });
```

　tableの　子要素のtr要素を全て取得し、一番最後のtr要素(余分な翌週1週間の日付の行)を
 display=noneで非表示にしています。
Gradioにssh tunnel経由でアクセス

# 概要
某クラウドML Platform上で実行しているGaradioへsshプロキシサーバを介して安定的にアクセスを試みた記録。

# 経緯
趣味でNVIDIA GPUが利用可能な開発環境インスタンス上で[Gradio](https://www.gradio.app/)を使用している。
ローカルアクセスが不可のためアクセスにはGradio share optionを使用していた。以下オプションの説明の翻訳。

:::note info
gradioアプリの公開共有リンクを作成するかどうか。SSHトンネルを作成し、どこからでもUIにアクセスできるようにします。提供されない場合、Google Colabで実行する場合を除き、毎回デフォルトでFalseに設定されます。localhostがアクセスできない場合（Google Colabなど）、share=Falseの設定はサポートされません。
:::

仕組みとしては上記の説明の通り実行環境からどこかのサーバーにssh tunnelを掘ってそのtunnel先にアクセスするための公開共有リンクをいい感じに勝手に用意してくれるものと理解していた。（あやふや）

# 問題：Gradioのshare linkが切れる
shareオプションは便利ではあったのだがいつの間にかhttpセッションが切れて？止まってしまうという現象が度々発生していた。
切れたタイミングの大半はGradio Statusで障害が発生しているタイミングだった。おそらくtunnnel先のサーバーが安定していないのかと想像。
https://status.gradio.app/

# 対策:自前のssh tunnel先を構築
現象が発生するとGradioが使用できず結構なストレス&時間を無駄にしていたので対策を決意。
構想としては自前でssh tunnel先としてssh serverを用意してそこにアクセスすればGradio側の障害に巻き込まれずに済むだろうと考えていた。今回は自宅のraspberrypiをssh serverとしたがインターネットからアクセスできるssh serverならこの方法が適応できるはず。


# 前提条件
1. 外部からcloudのVM環境上へのssh接続は不可。
1. cloudのVM環境上から外部ssh接続は可能。
1. cloudのVM環境上から外部ssh serverに安全にsshできる（公開鍵認証推奨）
1. PCからssh serverに安全にsshできる（公開鍵認証推奨）

# 最終的な接続図
```plantuml
@startuml
skinparam component {
  ArrowColor #FF6655
  ArrowFontColor #777777
}


package "自宅" {

node "raspberry pi" {
[ssh server:22]-[port8888]
}

node "PC" {
  [browser:http://127.0.0.1:8888]
  [ssh client(PC)]
note right 
ssh -L 8888:127.0.0.1:8888 user@raspberrypi -N -f -v
end note
  
}

}
cloud "cloud" {
  [gradio:7860]
  note right
  gradio-debug no-gradio-queue
  end note
  [ssh client(cloud)]
note right 
ssh -R  8888:127.0.0.1:7860 user@raspberrypi -N -f -v
end note

}

[ssh client(cloud)]-->[ssh server:22]:ssh 
[ssh client(PC)]-->[ssh server:22]:ssh
[browser:http://127.0.0.1:8888]-[#blue,thickness=4]->[port8888]:http via ssh tunnel
[port8888]-[#blue,thickness=4]->[gradio:7860]:http via ssh tunnel
@enduml
```
# クライアント(PC)側
```bash
$ssh -L 8888:127.0.0.1:8888 user@raspberrypi -N -f -v
```

# クラウド側
```bash
クラウドの7860ポートをraspberrypiの8888ポートに
ssh -R  8888:127.0.0.1:7860 user@raspberrypi -N -f -v
```


図の通りのssh tunnelを確立してPCから http://127.0.0.1:8888 にアクセスすることでGradioが安定的に使用できた。
Gradioに起動時に　gradio-debug　と　no-gradio-queueオプションをつける事。
私が利用しているML Platformサービスではngrokなどのssh tunnelingサービスは禁止されている（banされる）とネット上の情報があったが利用規約には明文化されておらずまた今のところこの方法を使用してbanされていない。（念のためsshポートはデフォルト２２から変更してる）
疑似分割キーボードのすすめ

# 疑似分割キーボードのすすめ

分割キーボードに興味があるけれども、導入に躊躇している方や、分割キーボードを試してみたいと考えている方に向けて、入門として試していただける方法をご紹介します。

---

## 分割キーボードについて

### メリット

#### 姿勢の改善

左右分割キーボードを使用することで、自分の肩幅に合わせてキーボードを配置できるため、自然な姿勢でタイピングが可能になります。これにより、長時間の作業でも疲れにくくなります。

#### 手首の負担軽減

一般的なキーボードの使用では手首が内側に曲がることが多いですが、分割キーボードを使用することで手首が自然な位置を保てるため、手首への負担が軽減されます。

#### 効率的な入力

左右が分割されていることにより、自由なキーマッピングが可能になり、より効率的なキーアサインが可能になります。これにより、入力作業が効率的に行えるようになります。

---

# 分割キーボードの現状

## 問題点

### 高価格帯

分割キーボードは、一般的なキーボードに比べて高価な傾向にあります。特に、カスタマイズ性が高いモデルや、高品質な素材を使用しているものは、価格がさらに上昇します。

### 選択肢の少なさ

通常のキーボードに比べて、分割キーボードの種類は格段に少ないです。選択肢が少ないと、自分に合うものを見つけるのが難しくなります。

私の印象では、65%以下のもので、親指部分が複数キーで特殊マッピングされており、キーおよびキースイッチ上部がむき出しのようなものが多いです。

私の好みは以下の通りです。

- 75%サイズ
- 通常レイアウト
- アルミフレーム系の硬い音
- RGB バックライト

しかし、これらの条件を満たす製品を見つけるのは困難です。

### 入手の難しさ

市場に出回っている分割キーボードの数は限られており、特定のモデルを入手するのが難しい場合があります。また、人気のモデルはすぐに売り切れてしまうこともあります。

### 慣れるまでの時間

分割キーボードに切り替えた後、従来のキーボードとは異なるタイピング感覚に慣れるまでに時間がかかることがあります。特に、キーの配置が大きく異なるモデルを選んだ場合、タイピング速度が一時的に低下することもあります。

---

# 疑似分割キーボードのご提案

そこで、おすすめするのが通常のキーボードを二台使った疑似分割キーボードです。2 つのキーボードを左右に並べて同時に使うことで、効率的な入力以外の体への負担を軽減しようという試みです。実際にはキーボードが分割されていないため、疑似的なものになります。

まずは体験してみて、肩を開いた状態での入力の心地よさを体験してみましょう。

## メリット

### 導入のしやすさ

既に持っているキーボードにもう一つキーボードを追加するだけです。家に余っているキーボードがあれば、今日からでも始められます。高額な投資をした後に、実は自分にはこのスタイルは合わなかったということが減ります。

### 入手の容易さ

左右のキーボードが同じものである必要はなく、自由に選択できます。特に日本語キーボードも選択肢として加わるのは大きなメリットです。分割キーボードでは非常に少ない存在です。

## デメリット

### Fn キーが使えない

#### 問題点

多くのキーボードには Fn という特殊なキーがあり、そのボタンと同時に他のキーを押すと、キーにアサインされている別レイヤーのキーが送信されます。この Fn + キーの組み合わせは、キーボード内で処理され、信号としては変換後のキーとして送信されます。同一のキーボードであれば問題ありませんが、別々のキーボードを使っている場合、右の Fn は左のキーボードには効きません。実質的に Fn が使えない状態になってしまいます。

#### 解決策

VIA などで Fn のキーアサインが変更できる場合は、Fn を F20 などの通常は使わないけれどもキーの信号として存在するキーに割り当てて、OS 側で AutoHotKey などを使ってキーのコンビネーションを作ることで解決します。65% キーボードなど F1 などの独立ファンクションキーがない場合は Fn が必須なので、これができないと疑似分割キーボード案は使えないことになります。Fn キーを使う側のキーボードだけでもキーマップの再割り当てができるキーボードをおすすめします。

### ホームポジションの誤認

#### 問題点

左右で通常のキーボードを使用する場合、ホームポジションの F と J が右と左にそれぞれ存在します。頻繁ではありませんが、間違って右で F を、左で J をホームポジションとして認識してしまい、誤入力することがあります。これは地味にストレスになります。

#### 解決策 1

キーキャップを特徴的なものに変更することで、指で正しいホームポジションを見つけることができます。ただし、わかりやすいものはタイプ感が変わるものが多いため、慣れが必要です。

#### 解決策 2

分割されたパームレストを使用することで、指だけではなく手首で場所を認識し、間違った場所を入力しにくくすることができます。

#### 解決策 3

キーボードの使わない部分に台を置いて物理的に押せないようにすることができます。現在、私はこの方法を採用しており、新しくできたスペースにポモドーロタイマーなどを置いて使用しています。

私が使用しているものはこちらです。 https://www.amazon.co.jp/gp/product/B09GLHZN53/

### スペース問題

通常の分割キーボードでは、中央部分が空いており、タッチパッドを置いたりノートパソコンを手前に配置したりできますが、通常のキーボードを使用する場合、おおよそ一つのキーボード分のスペースが埋まってしまいます。

#### 解決策

これに関しては回避する方法がありません。本物の分割キーボードを購入しましょう。

## 変遷

1. 日本語キーボード x 2
2. 日本語キーボード x 2 + 特殊キーキャップ x 2
3. US キーボード x 2 + 特殊キーキャップ x 2
4. US キーボード x 2 + パームレスト x 2
5. US キーボード x 2 + 台

---

# まとめ

キーボードを二台使った疑似分割キーボードの利用について説明してきました。
疑似分割キーボードを 3 年ほど使用していますが、大きな不満はありません。
しかし、やはり本物の分割キーボードを求めて定期的に市場を探しています。

# 付録

### AutoHotKey 設定例

最後に、AutoHotKey の設定例を紹介します。参考にしてください。これは色々な情報を参考にしながら作成したものです。

https://gist.github.com/unok/a6226df7b323f17bcc67460e7b2ff384
Cohere For AI Command R+について

Hugging Face でトレンドトップに出てきた、Command R+についてまとめてみました。

ネットを調べる中で、noteでnpaka氏がMLXでCommand R+を試すという記事を見つけ、MLXて何だ？ということも調べました。

4月4日にXにリリースのアナウンスが出ています。

https://twitter.com/CohereForAI/status/1775878631715217522?ref_src=twsrc%5Etfw%7Ctwcamp%5Etweetembed%7Ctwterm%5E1775878631715217522%7Ctwgr%5E8fb260f32a845d5b715a5f37edbe01a1209dc52b%7Ctwcon%5Es1_&ref_url=https%3A%2F%2Fweel.co.jp%2Fmedia%2Ftech%2Fcommand-r-plus%2F

基盤としているという35Bのモデルというのは、先月リリースされている、Command Rを指しており、そこから３倍に拡張されているということになります。

## 特徴
- 104Bパラメーター
- RAGと生成手順の自動化のためのツールを含んでいる
- 日本語を含む、１０カ国語をサポート
- 多くの用途で使用できるが、特に推論、要約、Q＆Aに最適化されている。
- コンテキストの長さは128Kをサポート

1040億パラメーターということは、GPT-3の1250憶に迫るものですが、4bitモデルだとハイスペックなPCなら動きます。LLMの進化は驚くべきものですね。

性能的には、132BのDBRX-instructを超えているようです。

## 利用方法

　Hugging Faceにホストされているので、お試しであればそこを利用することが可能。

 https://huggingface.co/spaces/CohereForAI/c4ai-command-r-plus

　ローカルでの使用も可能だが、DRAMやVRAMがかなり必要なので、普通の家庭では無理。

## ローカルで動かすために

4ビットで動かせるquantized versionがある。

 https://huggingface.co/CohereForAI/c4ai-command-r-plus-4bit

これなら、以下の条件で動作可能と思われる。

　GPUメモリが46GB以上
　システムの空きメモリが64GB以上
　モデルファイルは、１３ファイルで約64GBの容量

自分の環境では動作させることが出来ないが、手順としては、

### transformersモジュールのインストール

```
pip install 'git+https://github.com/huggingface/transformers.git' bitsandbytes accelerate
```
サンプルコードは以下のとおり。
以下のコードを実行すると、モデルファイルのダウンロードが始まる。

```
from transformers import AutoTokenizer, AutoModelForCausalLM

model_id = "CohereForAI/c4ai-command-r-plus-4bit"
tokenizer = AutoTokenizer.from_pretrained(model_id)
model = AutoModelForCausalLM.from_pretrained(model_id)

# Format message with the command-r-plus chat template
messages = [{"role": "user", "content": "Hello, how are you?"}]
input_ids = tokenizer.apply_chat_template(messages, tokenize=True, add_generation_prompt=True, return_tensors="pt")
## <BOS_TOKEN>

Hello, how are you?




gen_tokens = model.generate(
    input_ids, 
    max_new_tokens=100, 
    do_sample=True, 
    temperature=0.3,
    )

gen_text = tokenizer.decode(gen_tokens[0])
print(gen_text)
```

Hugging Face上で同じ質問(Hello, How are you?)をしたら、以下の回答が返ってきた。


> Hello! I’m an AI chatbot, so I don’t have feelings or emotions, but I’m here to assist you in any way I can. How can I help you today?

どう思う、どう感じる、という質問に関しては、I’m an AI chatbot, so I don’t have feelings or emotions,（私はAIアシスタントなので、個人的な意見や感情はありません。）と必ず答えるようだ。

## Apple MLXでの動作

noteの記事で、MLXで動作させている例があった。

 https://note.com/npaka/n/n9635d55773ef

MLXはAppleのM1/M2/M3で動くので、DRAMの空きが64GBあれば動作すると思われる。

MLXについて
- Apple版NumPyと考えていいが、Apple siliconでのみ動作するフレームワークである。
- unified memory modelというのが他のフレームワークとの違いで、CPUメモリからGPUメモリに転送しなくても動作する。
- 動作が遅い（自分で言ってます）。配列を実体化させるのは必要があるときということなので、メモリの使用効率はいいが、動作が遅延するということらしい。

MLXについては、詳しい情報はほとんどない。GitHub上のドキュメント

 https://ml-explore.github.io/mlx/build/html/index.html

が一番詳しい情報源だった。

既にローカルで動作させている方がQiitaに記事をあげていたので、参照ください。

 https://qiita.com/isanakamishiro2/items/954247ef7baf7db69548

 https://gigazine.net/news/20240408-command-r-plus-cohere-llm
UbuntuでUnboundを動かす

船井総合研究所のよもぎたです。

この記事は検証用ネットワークのネームサーバーとしてUnboundを動かして検証用ドメインの名前解決が出来るところまでをご紹介します。

# 環境

Ubuntu 22.04を使います。

# インストール

パッケージがありますので、それを利用します。

```bash
$ sudo apt update
$ sudo apt install -y unbound
```

インストールするとSystemdのサービスとしてUnboundが登録されて、起動してくれました。

# 設定

日本Unboundユーザー会さんが設定ファイルの日本語リファレンスを公開してくださっています。

https://unbound.jp/unbound/unbound-conf/

## お作法

設定ファイルは ```/etc/unbound``` に配置されました。
```/etc/unbound/unbound.conf``` は ```/etc/unbound/unbound.conf.d/*.conf``` をincludeするよう記述されていますので、それに合わせて自分の設定ファイルを作成していきます。

## 基本的なサーバーの設定

```
server:
        interface: 192.168.**.**
        access-control: 192.168.0.0/16 allow
        log-queries: yes
        
forward-zone:
        name: "."
        forward-addr: 1.1.1.1
        forward-addr: 9.9.9.9
```

```interface``` のIPアドレスと利用を許可するIPアドレスレンジは適宜設定してください。

要求されたクエリを記録したいので、 ```log-queries: yes``` を追加しています。

必要に応じて ```verbosity``` を上げるのもアリだと思います。

## 名前解決の設定

```
server:
        local-data: "www.example.local. IN A 172.16.1.1"
        local-data-ptr: "172.16.1.1 www.example.local"
```

正引きの名前の最後のピリオドを忘れずに。

# 動作確認

```bash
$ host www.example.local 192.168.**.**
Using domain server:
Name: 192.168.**.**
Address: 192.168.**.**#53
Aliases:

www.example.local has address 172.16.1.1
```

無事、検証用の名前が引けるようになりました。

```
ubuntu unbound: [1690:0] info: 192.168.**.** www.example.local. A IN
```

ログはSyslogに出力されます。

簡単ですが以上です、最後までお読みいただきありがとうございました。
備忘: Railsで古い日付を JST の TimeWithZoneに変換すると時刻がずれる

# 追記
https://qiita.com/vivid_muimui/items/876d89f8bdc0a35c4fb5#comment-96533a49b7d45a748ead

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/26310/518d80f7-da5c-fc0c-555f-92f95e641442.png)

コメントで教えていただきました！

---

# 以下、元記事

:memo: ふかぼりきれておらず事象だけのメモ

# 環境

ruby: ruby 3.3.0 (2023-12-25 revision 5124f9ac75) [arm64-darwin22]
rails: 7.1.2

# 現象

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/26310/af57e6c1-d3d5-e39b-72d4-2136a63f4e7f.png)

```rb
❯ TZ=UTC rails c
Loading development environment (Rails 7.1.2)
irb(main):001> Rails.application.config.time_zone
=> "UTC"
irb(main):002> Time.now.zone
=> "UTC"
irb(main):003> Time.zone.parse("1800/01/01 00:00:00").iso8601
=> "1800-01-01T00:00:00Z"
irb(main):004> Time.zone.parse("1800/01/01 00:00:00").utc.iso8601
=> "1800-01-01T00:00:00Z"
irb(main):005> Time.zone.parse("1800/01/01 00:00:00").in_time_zone("UTC").iso8601
=> "1800-01-01T00:00:00Z"
irb(main):006> Time.zone.parse("1800/01/01 00:00:00").in_time_zone("Tokyo").iso8601
=> "1800-01-01T09:18:59+09:18"
irb(main):007> Time.parse("1800/01/01 00:00:00").iso8601
=> "1800-01-01T00:00:00+00:00"
irb(main):008> Time.parse("1800/01/01 00:00:00").utc.iso8601
=> "1800-01-01T00:00:00Z"
irb(main):009> Time.parse("1800/01/01 00:00:00").in_time_zone("UTC").iso8601
=> "1800-01-01T00:00:00Z"
irb(main):010> Time.parse("1800/01/01 00:00:00").in_time_zone("Tokyo").iso8601
=> "1800-01-01T09:18:59+09:18"
```

---

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/26310/4b08186d-8c5b-0313-cc84-4f9d95cc6b43.png)

```rb
❯ rails c
Loading development environment (Rails 7.1.2)
irb(main):001> Rails.application.config.time_zone
=> "Tokyo"
irb(main):002> Time.now.zone
=> "JST"
irb(main):003> Time.zone.parse("1800/01/01 00:00:00").iso8601
=> "1800-01-01T00:00:00+09:18"
irb(main):004> Time.zone.parse("1800/01/01 00:00:00").utc.iso8601
=> "1799-12-31T14:41:01Z"
irb(main):005> Time.zone.parse("1800/01/01 00:00:00").in_time_zone("UTC").iso8601
=> "1799-12-31T14:41:01Z"
irb(main):006> Time.zone.parse("1800/01/01 00:00:00").in_time_zone("Tokyo").iso8601
=> "1800-01-01T00:00:00+09:18"
irb(main):007> Time.parse("1800/01/01 00:00:00").iso8601
=> "1800-01-01T00:00:00+09:00"
irb(main):008> Time.parse("1800/01/01 00:00:00").utc.iso8601
=> "1799-12-31T15:00:00Z"
irb(main):009> Time.parse("1800/01/01 00:00:00").in_time_zone("UTC").iso8601
=> "1799-12-31T15:00:00Z"
irb(main):010> Time.parse("1800/01/01 00:00:00").in_time_zone("Tokyo").iso8601
=> "1800-01-01T00:18:59+09:18"
```
Discord の BOT で音楽を流したい (w/Ruby)

## 概要

Discord の BOT でボイスチャンネル (以下 VC) に接続して音楽を流す．言語は Ruby．

当記事で BOT の作り方には触れないので[私の過去の記事](https://qiita.com/RabbitAATS/items/31c98b0896f57194ef6b
)を，Discordrb に関する詳しい内容は [Discordrb の GitHub](https://github.com/shardlab/discordrb) を参照されたい．

https://qiita.com/RabbitAATS/items/31c98b0896f57194ef6b

https://github.com/shardlab/discordrb

## 環境

- OS: Rocky Linux 9.3
- 言語: Ruby 3.0.4

## ライブラリの準備

Discord の BOT が VC に接続するには，以下のライブラリが必要．

- libsodium: 暗号処理ライブラリ
- libopus (Opus): 音声圧縮ライブラリ (FFmpeg が使用)
- FFmpeg: メディア処理ライブラリ

以下にライブラリのインストール手順を記載するが，環境によって異なるので注意されたい．

### libsodium をインストール

```bash
# EPEL をインストールして，拡張パッケージを利用可能にする
sudo dnf config-manager --set-enabled crb
sudo dnf install epel-release
# libsodium をインストールする
sudo yum install libsodium
```

### libopus をインストール

```bash
# パッケージ名を確認する
yum list available | grep opus
# Opus をインストールする
sudo yum install opus
sudo yum install opus-devel
sudo gem install opus-ruby
```

### FFmpeg をインストール

```bash
# パッケージ名を確認する
yum list available | grep ffmpeg
# FFmpeg をインストールする
sudo yum install ffmpeg-free
```

## 音声ファイルの準備

再生したい音声ファイルを設置する．

今回は BOT 本体のファイル名を `run.rb` とし，同階層にディレクトリ `music/` を作成する．再生する音楽のファイル名を `test.mp3` とし，`music/` 配下に置く．

```bash
.
├── music
│   └── test.mp3
└── run.rb
```

## 実装

```ruby
require 'discordrb'

client_id = ... # 用意したクライアント ID を添付
token = '...' # 用意したトークンを添付
bot = Discordrb::Commands::CommandBot.new(client_id: client_id, token: token, prefix: '/')

# 音楽を再生する
bot.command :play do |event|
  # イベントを発火させたユーザーが接続している VC (Discordrb::Channel) を取得する
  channel = event.user.voice_channel
  # VC に接続する
  event.bot.voice_connect(channel)
  # Voice Bot (Discordrb::Voice::VoiceBot) を取得する
  voice_bot = event.bot.voice(event.channel)
  # 音量を設定する (0 以上の実数，1 で 100%)
  voice_bot.volume = 1
  # 音楽を再生する
  voice_bot.play_file("music/test.mp3")
end

# 音楽を停止する
bot.command :stop do |event|
  # Voice Bot (Discordrb::Voice::VoiceBot) を取得する
  voice_bot = event.bot.voice(event.channel)
  # 音楽の再生を停止する
  voice_bot.stop_playing()
  # VC から切断する
  event.bot.voice_destroy(event.server)
end
```

## 使用

1. Discord の任意の Server に BOT を招待
1. VC に接続する
1. テキストチャンネルで `/play` と送信すると，音楽が再生される
1. テキストチャンネルで `/stop` と送信すると，音楽が停止する
JavaScriptで長い配列を長さnの小さい配列に分割するワンライナー

# やりたいこと
例えば長さ12の配列を、
```JavaScript:変換前
const src = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']
```
このように、
```JavaScript:変換前
[
  ['Jan', 'Feb', 'Mar'], 
  ['Apr', 'May', 'Jun'], 
  ['Jul', 'Aug', 'Sep'], 
  ['Oct', 'Nov', 'Dec']
]
```
長さ3など短い複数の配列に分割したいとします。これを実現するワンライナーを紹介します。

# 答え（ワンライナー）
```JavaScript:答え
const dst = Array(Math.ceil(src.length/n)).fill().map((_, i) => src.slice(n*i, n*(i+1)));
```
- まず、`Math.ceil(src.length/n)`で分割数を求めます。例えば、長さ12を長さ3で分けるならちょうど4ですが、繰り上げが入るので長さ12を長さで5で分けた場合は2でなく3が導かれます。
- `Array(分割数).fill()`で`fill()`を呼んでいるのは、単に配列を初期化しただけだとインデックス（オブジェクトのキー）がなく次に説明する`map()`が無効となってしまうためです。
- `map()`でループします。インデックス`i`が取る値は0から分割数-1までとなります。
- `slice()`で元の配列から部分配列を切り取ります。`slice(start, end)`の`end`は`end >= src.length` の場合でも`src.length`が使用され、`n`で割り切れないケースでも安全です。

# 実行例
## サンプルコード
```JavaScript:arrsplit.js
process.stdin.resume();
process.stdin.setEncoding("utf8");

const lines = [];
const reader = require("readline").createInterface({
    input: process.stdin,
    output: process.stdout
});
reader.on("line", (line) => {
    lines.push(line);
});
reader.on("close", () => {
    // Change left-hand side dependent on input
    const [n, ...src] = lines.map(e => e.split(/[,\s]/).filter(e => e != "")).flat().map(e => isFinite(e) ? +e : e);
    const dst = Array(Math.ceil(src.length/n)).fill().map((_, i) => src.slice(n*i, n*(i+1)));
    console.log(dst);
});
```

## 実行例1 (nで割り切れるとき)
```
$ node arrsplit.js
3
Jan, Feb, Mar, Apr, May, Jun, Jul, Aug, Sep, Oct, Nov, Dec
(press Ctrl+d)
[
  [ 'Jan', 'Feb', 'Mar' ],
  [ 'Apr', 'May', 'Jun' ],
  [ 'Jul', 'Aug', 'Sep' ],
  [ 'Oct', 'Nov', 'Dec' ]
]
```

## 実行例2 (nで割り切れないとき)
```
$ node arrsplit.js
5
Jan, Feb, Mar, Apr, May, Jun, Jul, Aug, Sep, Oct, Nov, Dec
(press Ctrl+d)
[
  [ 'Jan', 'Feb', 'Mar', 'Apr', 'May' ],
  [ 'Jun', 'Jul', 'Aug', 'Sep', 'Oct' ],
  [ 'Nov', 'Dec' ]
]
```

# 所感
他にも余りがあるか判定を挟む方法や、`reduce()`を使った方法など様々ありますが、上記が個人的には直感的で覚えやすく、かつ簡潔なのでバランスが良いと思っております。
オンラインのコーディング問題を解くときなどに、[JavaScriptで標準入力から数値や文字列を一発で受け取る #JavaScript - Qiita](https://qiita.com/nakatahr/items/138b5cfe1c451c84b68d) と組み合わせて使っていただくと便利ではないかと思います。

# 参考
- JavaScriptで標準入力から数値や文字列を一発で受け取る 
  https://qiita.com/nakatahr/items/138b5cfe1c451c84b68d
- JavaScriptでn個ずつ配列を分割する
  https://yucatio.hatenablog.com/entry/2019/12/10/222311
- JavaScriptのnew Array(n)をmapしたいとき fillをはさむ理由
  https://yucatio.hatenablog.com/entry/2019/04/07/110721
- JSで配列をn個ずつに分割
  https://qiita.com/guttyar2213/items/46230300c5100a06198c
- Array.prototype.slice()
https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array/slice
How to Grow Taller at 17: Tips and Techniques

As you step into your teenage years, you might find yourself wondering how to maximize your growth potential, especially if you're eager to add a few inches to your height. While genetics play a significant role, there are several strategies you can adopt to support healthy growth during your adolescence. Here are some tips and techniques on how to grow taller at 17.

![how-to-grow-taller-at-17.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3757007/bdc0cde5-ba5e-c626-b937-0b92f4e13a7a.jpeg)


1. Balanced Nutrition

A well-balanced diet is essential for promoting growth and development. Make sure your meals include a variety of nutrients, including proteins, carbohydrates, vitamins, and minerals. Calcium and vitamin D are particularly important for bone health, so incorporate dairy products, leafy greens, and fortified foods into your diet.

2. Regular Exercise

Engage in regular physical activity to support healthy growth. Focus on exercises that promote stretching and flexibility, such as yoga, Pilates, and swimming. Additionally, high-intensity exercises like sprinting and jumping can stimulate the release of growth hormones.

3. Proper Sleep

Quality sleep is crucial for growth and overall health. Aim for 8-10 hours of uninterrupted sleep each night. During sleep, the body releases growth hormones that aid in tissue repair and regeneration. Create a relaxing bedtime routine and ensure your sleep environment is comfortable and conducive to rest.

4. Good Posture

Maintaining good posture can create the illusion of height and prevent spinal curvature. Practice standing and sitting up straight, keeping your shoulders back and your head held high. Avoid slouching, especially when sitting for extended periods.

5. Avoid Growth Inhibitors

Certain factors can hinder growth during adolescence. These include smoking, excessive caffeine consumption, and inadequate nutrition. Avoiding these habits can help optimize your growth potential.

6. Stay Hydrated

Drink plenty of water throughout the day to support overall health and growth. Proper hydration is essential for maintaining the body's functions, including the growth process.

7. Consult a Healthcare Professional

If you have concerns about your height or growth trajectory, consider consulting a healthcare professional. They can assess your individual circumstances and provide personalized advice and recommendations.

Xem tại: https://doctortaller.com/blog/how-to-grow-taller-at-17/

Conclusion

While genetics largely determine your ultimate height, adopting healthy habits can help you reach your maximum potential during adolescence. By focusing on nutrition, exercise, sleep, and posture, you can support optimal growth and development. Remember to be patient and consistent, as growth takes time and dedication. With the right approach, you can embrace your journey towards reaching your full height potential at 17 and beyond.
🧶作った CTF🎍低レイヤの勉強にも！

お正月にCTFを作って友達や親戚、先生などに配ったものを、4/9である今日に(?)、(少し変えて)Qiitaにポストします。
低レイヤの勉強にもなると思いますので、解いていただければ幸いです。

問題です！の前に、機械語を簡単に解説します。
よく見るように、機械語は0と1から出来ています。
例えば8ビット固定長のCPUを考えてみます。
ここでは、レジスタ(intの変数のような)は16個です。
この記事ではint8だとします。
「インストラクション」(コマンドのようなもの)は以下のようになっているとします（スペースは見やすさのために書いています）:
0000 xxxx：レジスタxxxx(2進法でレジスタの番号0000から1111までの数が入る)をインクリメント
0001 xxxx：レジスタxxxxの中身が0だったらexit
0010 xxxx：xxxxに二進法で書いてある絶対アドレスまでジャンプ(goto)（ビット単位、例えば0001だと最初のインストラクションの途中にジャンプする）
これを使えば、256回ループしてexitするプログラムなどが書けます（int8がオーバーフローして0に戻って来る）：
000000000001000000100000
（0000 0000　0001 0000　0010 0000）
問題です！
Webサービスを想像してください。
このサービスは、機械語を送ると実行してくれます。
このサービスで使われているマシンは変わっています。
このマシンは、16個の8ビットレジスタを持つ8ビット固定長のCPUです。
インストラクション：
0000 xxxx：レジスタxxxxをインクリメント（+= 1）
0001 xxxx：レジスタxxxxの中身が0だったらexit
0010 xxxx：xxxxに二進法で書いてある絶対アドレスまでジャンプ(goto)（ビット単位、例えば0001だと最初のインストラクションの途中にジャンプする）
0011 0000：秘密のメッセージを送信（下位4ビットが0000でなければエラー）
0100 0000：「🧶」を送信（下位4ビットが0000でなければエラー）
このサービスから秘密のメッセージを取得するのはこのままなら簡単です。00110000
ですが、このサービスは送った機械語を実行する前に以下のコードでスキャンします：
```python
def scan(x: List[bool]) -> bool:
  # xは機械語です(boolでビットを表しています)。
  # 安全と判断すればTrue、危険だと判断すればFalseを返します。
  for i in range(0, len(x), 8):
    f, t = False, True
    if x[i:i+8] == [f, f, t, t, f, f, f, f]:
      return False
  return True
```
どのような機械語を入力すれば、秘密のメッセージを送信してもらえるでしょうか？
答えは64個の「🧶」のあとで！(スクロールしないと見えなくするために)
🧶
🧶
🧶
🧶
🧶
🧶
🧶
🧶
🧶
🧶
🧶
🧶
🧶
🧶
🧶
🧶
🧶
🧶
🧶
🧶
🧶
🧶
🧶
🧶
🧶
🧶
🧶
🧶
🧶
🧶
🧶
🧶
🧶
🧶
🧶
🧶
🧶
🧶
🧶
🧶
🧶
🧶
🧶
🧶
🧶
🧶
🧶
🧶
🧶
🧶
🧶
🧶
🧶
🧶
🧶
🧶
🧶
🧶
🧶
🧶
🧶
🧶
🧶
🧶
答えは、
0010 0101 0 0100 0000
です！
アラインされていないところへジャンプすることで、スキャンをかいくぐり、実行するという仕掛けでした！
この問題は、NaCl（NACL • x86で信頼できないプログラムを安全に実行するためのシステム • Native Client: A sandbox for Portable, Untrusted x86 Native Code）がコンセプトになっています。
お楽しみいただけたらうれしいです！
VSCodeでpythonのLinter+Formatterを設定する

## はじめに

今回は以下を設定する手順をご紹介します！
- Linter
    - [flake8](https://github.com/PyCQA/flake8)
    - [mypy](https://github.com/python/mypy)
- Formatter
    - [autopep8](https://github.com/hhatto/autopep8)

また今回紹介する設定では、ローカルでの`pip install`は一切不要となっていてそこも気に入っております！

## 0. pythonの設定
pythonの拡張をインストールしておいてください。

https://marketplace.visualstudio.com/items?itemName=ms-python.python

## 1. Linterの設定
VSCの拡張から「flake8」「Mypy Type Checker」をインストールします。

https://marketplace.visualstudio.com/items?itemName=ms-python.flake8

https://marketplace.visualstudio.com/items?itemName=ms-python.mypy-type-checker

以上です。
この時点でpythonファイルに警告が出るようになっていると思います。(なってなかったらコマンドパレットからReload Windowとかしてみてください）

![スクリーンショット 2024-04-09 18.30.35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2947418/ed7bbba3-5e6c-37ab-1149-b9213179b6dd.png)

## 2. Formatterの設定
VSCの拡張から「autopep8」をインストールします。

https://marketplace.visualstudio.com/items?itemName=ms-python.autopep8

VSCのsettings.jsonに以下を追加します。
VSCのユーザ設定を汚したくない方はプロジェクトルートに`.vscode/settings.json`を追加してそちらに記載してください。

```json
{
  "[python]": {
    "editor.defaultFormatter": "ms-python.autopep8",
    "editor.formatOnSave": true
  },
  "autopep8.args": [
    "--ignore=E501"
  ]
}
```

以上です。
この時点でpythonファイルを上書きすると勝手にautopep8が走るようになっていると思います。(なってなかったらコマンドパレットからReload Windowとかしてみてください）

## 3. おまけ
今回の設定をチームで共有したい場合は、`.vscode`フォルダを以下のようにしてgit管理するのがお勧めです。

- extensions.json
```json
{
    "recommendations": [
        "ms-python.python",
        "ms-python.flake8",
        "ms-python.mypy-type-checker",
        "ms-python.autopep8"
    ]
}
```

- settings.json
```json
{
  "[python]": {
    "editor.defaultFormatter": "ms-python.autopep8",
    "editor.formatOnSave": true
  },
  "autopep8.args": [
    "--ignore=E501"
  ]
}
```
GASで環境変数(スプレッドシートのID）を設定する

# はじめに　

GASを使ってGoogleのスプレッドシートを使った開発を最近行っているのですが、gasのコードをgithubにあげたいとなった時に、「スプレッドシートのID直書きは良くないな、envファイルとか作って環境変数として設定できないのだろうか」と思い、やり方を調べてみました。

# スクリプトプロパティの設定

まずGAS上で左側にある歯車マークを押して、設定画面へ行きます。
![スクリーンショット 2024-04-09 17.39.03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3766230/b4a69999-fa28-7dc8-b466-57c91797fd5f.png)

そこから下の方にスクロールするとスクリプトプロパティを設定する場所があります。これが環境変数を設定する場所になります。
![スクリーンショット 2024-04-09 17.32.53.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3766230/b42b6be0-afef-7aa8-f77d-a514bd119715.png)

プロパティに環境変数名（今回はsheetIDとします）、値にスプレッドシートのIDを入れます。

:::note warn
値にはダブルクオーテーション(")で挟まないようにしましょう。自分はそれで動かなくて困りました
:::

設定したら、スクリプトプロパティを入れて設定完了です。

# スクリプトプロパティへの参照方法

スクリプトプロパティへは、以下のコードで参照します。

```
const sheetID = PropertiesService.getScriptProperties().getProperty('プロパティ');
```

これで参照することが出来ます。

# さいごに
初の個人開発としてdiscord botを作っているのですが、トークンを知られないように環境変数を設定することの重要性を認識したところだったので、環境変数設定できないのかなぁとかなり疑問に思っていたので解決してよかったです。

qiitaで記事を書いたことがなかったので試しに書いてみましたが、これを備忘録代わりにするのもありだなぁと思いました。まだ初学者中の初学者ですが、たくさん書けるようにたくさん開発しようと思います。
【勉強用まとめ】C++のsetについて

## 本記事の目的
[AtCoder Beginner Contest 347](https://atcoder.jp/contests/abc347/tasks/abc347_b)に取り組んでいた際に行き詰ってしまい、解説を読んだところ、私の知らないsetなるものを使って解くことが推奨されていたので、調べてみました。
以下はその学習のまとめです。

## setとは
setは重複を許さず（一意性）、昇順にデータを格納するデータ構造です。

```c++
#include <iostream>
#include <set>

int main() {
    // 空のsetを作成
    std::set<int> mySet;

    // 要素を追加
    mySet.insert(30);
    mySet.insert(10);
    mySet.insert(50);
    mySet.insert(20);
    mySet.insert(40);
    mySet.insert(10);  // 重複するため無視される

    // 要素をループして出力
    std::cout << "Setの要素:";
    for (auto it = mySet.begin(); it != mySet.end(); ++it) {
        std::cout << " " << *it;
    }
    std::cout << std::endl;

    return 0;
}
```

*実行結果*
```
Setの要素: 10 20 30 40 50
```

## setの使い方

**setの宣言**
```c++
#include <set>
```
このようにしてヘッダーファイルを読み込んで
```c++
std::set<型名> mySet;
```
のようにして宣言することができます。<>内の型名は格納するデータの型名を入力します。

**setの初期化**
setは、std::initializer_listを使った方法や、{}を使った方法で初期化が可能です。
```c++
std::set<int> empty;  // 空のstd::set
std::set<int> mySet{ 5, 1, 2, 4, 1 };  // {}を使った方法で初期化
```

**要素の追加、削除、変更、検索**
```c++
mySet.insert(追加する要素);  // 要素の追加
mySet.erase(削除する要素);  // 要素の削除

// 要素の変更（setでは要素の値を直接変更することはできないので、削除して再挿入する）
int old_value = 40;
int new_value = 45;
mySet.erase(old_value);
mySet.insert(new_value);

// 要素の検索（指定した要素が存在するか確認する）
int target = 30;
auto it = mySet.find(target);  // targetがmySetに存在しない場合、itにはmySet.end()が返される
```
PoweShellでファイル振り分け

ファイルの移動を半自動化したかったんです(´・ω・`)
入力の値によって異なるフォルダへファイルを振り分けます。

## `ファイル振分.ps1`
```powershell
# 宛先フォルダ
$dstRoot = "C:\hoge\"

# 振分先
$dstPath1 = ""
$dstPath2 = ""
Write-Output " --------------------------------------------------"
Write-Output " 振分タイプ"
Write-Output " 　1: あっち"
Write-Output " 　2: こっち"
Write-Output " 　3: そっち"
Write-Output " 　4: どっち"
Write-Output " --------------------------------------------------"
$input = Read-Host "振分タイプを入力してください: "

# タイプに応じて振分先を変える
If ($input -eq 1) {
  # 1: あっち
  $dstPath1 = $dstRoot + "あっち\one"
  $dstPath2 = $dstRoot + "あっち\two"
} ElseIf ($input -eq 2) {
  # 2: こっち
  $dstPath1 = $dstRoot + "こっち\one"
  $dstPath2 = $dstRoot + "こっち\two"
} ElseIf ($input -eq 3) {
  # 3: そっち
  $dstPath1 = $dstRoot + "そっち\one"
  $dstPath2 = $dstRoot + "そっち\two"
} ElseIf ($input -eq 4) {
  # 4: どっち
  $dstPath1 = $dstRoot + "どっち\one"
  $dstPath2 = $dstRoot + "どっち\two"
} Else {
  # 1,2,3,4以外なら何もしない
  exit
}
# ファイルを移動
Get-ChildItem -Recurse -File -Include *.txt | ForEach-Object { Move-Item $_ $dstPath1 -force }
Get-ChildItem -Recurse -File -Include *.csv | ForEach-Object { Move-Item $_ $dstPath2 -force }
```

上記だけだと動かなかったので、別途.batを作成して実行ポリシーを渡す。

参考にさせて頂いたのは↓
[PowerShell のスクリプトが実行できない場合の対処方法 #Windows - Qiita](https://qiita.com/Targityen/items/3d2e0b5b0b7b04963750)

## `ファイル振分.bat`
```bat
PowerShell -ExecutionPolicy RemoteSigned .\ファイル振分.ps1
```

ファイル振分.batを実行すればプロンプトが上がり、
入力値に応じた振分先にファイルを移動してくれるようになりました。

めでたしめでたし。
文系大学生からプログラマになる

こんにちは、クインサシャ健太です。
このアカウントでは、プログラミング初心者である私の日々の気づきを皆さんに共有していきます。


## 文系はエンジニアに向いていない


いきなりですが、このような言葉を聞いたことはありませんか？
私自身がいわれたことはないですが、世間一般ではこのように考えられているように感じます。

本には、論理的に物事を考える能力がプログラミングにおいて重要であると書かれています
論理的な思考力の高さを、一番適切に表す科目は数学でしょう。
そして文系を選択する理由として数学が苦手であることが多いです。僕もそうです。

では「文系はエンジニアに向いていない」という言葉は正しいのでしょうか。

以下の理由から、僕は必ずしも正しくないと思います。

数学は抽象的な概念を使って問題を解くので、現実に対して行動を起こしている感覚が薄い。小学校4年生から算数が抽象的になり、壁に直面するのが有名。

対してプログラミングは問題を効率的に解決する方法を考えること。実際に自分のプログラムが実行されるので、より学習のモチベーションが保ちやすい。




結論は「文系でもエンジニアになれる」です！
みんな一緒に頑張りましょう！
【GitHub】プルリクにコメント返信した"つもり"になってた話


今の会社に入社してだいたい2カ月くらい経ちました！
面倒見の良い先輩たちのおかげ＆日々学びがあってとても楽しく過ごしています～！

そんな中、案件参画前の課題で起きた出来事を取り上げたいと思います。


# レビューを無視するやばい新人に…
諸先輩方からレビューをいただいて、すべて返信していたのですが、なんとなくやりとりがうまくいっていない…自分の説明スキルが足りていないのだろうか…と悩んだ矢先

slackでやり取りしている際に
私　「その件はプルリクエストのコメントで返信しました！」
先輩「返信きてないですよ…？」
私　「！！！！！」

そう、返信した"つもり"になっていたのです。

# 原因
結論から言うと全部pendingになってました↓
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3716338/4d3f4ce0-a8e3-8624-0ba1-7f8b40b93b55.png)

基本的に[Conversation]タブから返信していれば、pending状態にはならないようなのですが、

どうやら、一度でも[FileChanged]タブから[Start a review]ボタンでコメント返信したあとに
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3716338/52c2fb96-844c-8a08-a22a-7eb8552e11e0.png)

[Conversation]タブ上から返信すると、すべてpendingになってしまうようです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3716338/d1c06d1f-225e-d2e7-605a-c05656610ac7.png)


# 解決策
[FileChanged]>[Review changes]>[Submit review]を押下すると
それまでpendingだったコメントがすべて送信されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3716338/262b14e9-e224-5b37-d3c8-72f1f3077e64.png)


# 疑問
## GitLabだと？
実はGitHubはあまり使っておらず、前職ではずっとGitLabを使っていました。
今まで利用していたGitLab上では、コメントがpendingになる状態を見たことがありませんでした。

試しにトライアル版を入れて確認したところ、なんとGitHubと同じ挙動でした。
私が今まで使っていたのはGitLabでも、GitHubでもなかったということ…！？

## 今までずっとオンプレの古いバージョンを使ってたせい？
ありがたいことに未だに、前の職場の人と交流があるので、聞いてみました。
すると「そんなのみたことない！」とのことでした。

完全に推測ですが、前職ではオンプレ環境かつ、だいぶ古いバージョンを使っていたため、その機能がなかったのでは？と一旦納得することにしました。

# 反省
実はこの件、何の因果か永遠にアンジャッシュ状態となってしまい、約3~4週間ほど気が付くことできず…

ここまで気が付けなかった要因としては、以下３つかなと考察しています。
* 入社後で意識がフワフワしすぎて、視野が狭くなっていた
* 今まで使っていたGitLabと大方同じだろうと高をくくりすぎていた
* Slack上でも返信していたので、プルリクでコメント返さないキャラだと思われていた（アンジャッシュ状態）

何はともあれ、案件参画前に気が付くことができてよかったです！

# 参考
* https://qiita.com/Ryo-0131/items/29080f242256ab3f1375
* https://qiita.com/C_HERO/items/c5cfbdbb269efb72fb8f
ChromeでPage Sidebarを使いサイドパネルに常にGoogle TasksのToDoリストを表示させる

私はタスク管理が苦手だ。

何か作業をしていて、コレが終わったら次はアレをしなければ、と思う。
私は愚かではないので、その程度の事、忘れるわけがない、と確信がある。
確信がある以上、それをメモしたり、リストにいちいち書くなど、面倒でやれるはずがない。

だが、メールが来て、割り込みが入る。
メールで入った割り込みを対処している間に、Slackが来て、割り込みが入る。
メールで入った割り込みを対処している間に入ったSlackの割り込みを対処していると、人が来て、割り込みが入る。
人を追い返し、メールで入った割り込みに戻り、対処する。
対処が終わり、えーと何をしていたっけ？そうだ、アレをしないといけなかったんだよな。
アレをしているとふと気づく。違う、アレじゃない、コレをしていたんだった。
コレを…どこまでやっていたんだったか…と記憶を遡る。遡っていると、メールが来て、割り込みが入る。
メールで入った割り込みを対処していると、Slackが来る。
「先ほどの問い合わせの回答をお願いします」
いい加減にしろ！

---

私は愚かではないが、私を取り巻く環境はそれを上回るいやらしさで、私に気にしていたタスクを忘れさせようとする。
いいだろう。ToDoリストを使ってやろうじゃないか。

そしてGoogle Tasksにタスクを登録する事にした。
するべき作業をGoogle Tasksに登録し、作業にとりかかる。
メールで割り込みが入る。舌打ちをし、悪態を独りごちて、それをGoogle Tasksに登録し、対処を始める。
Slackが来る。怒号混じりのため息をつき、それをGoogle Tasksに登録し、対処をし、チェックボタンにカーソルを合わせ、力強くクリックする。打ち消し線が入り、忌々しいそいつが消え去る！なんと清々しい！！最高の気分じゃないか！

---

MTGの時間だ。画面共有のため、一旦ブラウザを閉じる。アドリブをまくし立て、上席を煙に巻いてやりすごし、自席に戻る。
ブラウザを開く。MTG中にもいちいち私を苛立たせるメールがいくつも届いており、それに対応していく。Slackが来る。人が来る。もうたくさんだ！！

そういえばToDoリストがあったのではないか！！すっかり存在を忘れていた！一旦ブラウザを閉じた時に閉じてしまったのだ！目に付かないToDoリストなど、存在していないのと何も違わないのだ！！

Googleカレンダーをスタートページに登録しても、タブを次から次へ開いていくと、埋没してしまう。
このままでは「Googleカレンダーのタブを探す」というタスクをGoogle Tasksに登録しようとしてGoogleカレンダーのタブを探す…という無限ループに突入してしまう！
私の人生は、こんなところでおしまいなのか！？

---

Vivaldi ブラウザには「サイドパネル」の機能があり、そこにGoogle Tasksの埋め込みURL(※後述)を設定する事で、ブラウザの右端に常にToDoリストを表示させ、ようやくToDoリストが機能するようになった。
ただ、Vivaldiはフォントが小さかったり、Ubuntu MATEだとタブを別ウィンドウに分離させようとタブをドラッグしてデスクトップ上にドロップした時に、ウィンドウは開くのだがエラーダイアログが表示され、デスクトップにゴミファイルができてしまう。地味に不快。

何とかChromeでそのサイドパネルが実現できないか。Chromeにもリーディングリストやブックマークを表示させられるサイドパネルは存在する。隠しオプションを有効にするとそこに「WebView」が追加され、それを使えば実現できそう…という情報も検索すると出てくるが、今のChromeではどう探してもそれが無い。どこかのタイミングで、削られてしまったのだろうか。
これでおしまいなのか！？

---

Page Sidebar | Open any page in side panel
https://chromewebstore.google.com/detail/page-sidebar-open-any-pag/gkkebamcfeaggmcfciekfakbmlgckdnh?hl=ja

ありがたい Chrome Extension を作ってくださっている人がいた。

このExtensionをインストールし、その設定で
```
https://tasks.google.com/embed/?origin=https://calendar.google.com&authuser=《Googleアカウント名》
```
というGoogle Tasksの埋め込み用URLをデフォルトで開くようにすれば、Extensionのアイコンワンクリックで、表示しているChromeのウィンドウの右端にGoogle Tasksが表示される。

これでようやく、タスクリストとともに、前に進むことができる。
java　メソッド　例え

## メソッドとは
クラス内に定義された関数で特定のタスクを実行するためのコードブロック。
複数の文をまとめて、名前をつける。mainメゾットを分割し呼び出すので、スッキリ見やすいコードが書けるのでエラーなどおきてもわかりやすく、修正範囲も狭くて済む、繰り返し使用でき手間が省ける

なんとなく、わかるようでわからない、、、:joy::joy:（笑）

## 例えてみた:raised_hands:
プログラミングが料理とするなら:ramen:、、、
メソッドがレシピ
配列が調味料や食材
要素が調味料名、食材名:fish_cake:
かな・・・・:laughing:合ってるのか？



## メリット
①プログラムの見通しがよくなり、全体を把握しやすくなる
②機能単位に記述するため、修正範囲を限定できる
③同じ処理を１つのメゾットにまとまることで、作業効率が上がる
高可用性のアーキテクチャとは？(AWS)

## 初めに
可用性の高いアーキテクチャとは何かをまとめてみました。
皆様のご意見頂けたら幸いです。

## 可用性とは？
<font color="green">**システムが正常に継続して動作し続ける能力**</font>の事を言います。

障害が起きてしまった場合、システムダウンしてしまったら困りますよね:fearful:
そちらを防ぐ為には、可用性の高いシステムを構築しないといけません！

一般的な対策としては...
①サーバーの冗長化
②別サーバーへのフェイルオーバー
が挙げられます。

## AWS上での対策としては
###### ①リリースを冗長化する
![スクリーンショット 2024-04-09 17.13.02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3744656/36f0de73-0771-6fc9-41ad-06c03e3ce2b4.png)
→単一障害点(SPOF)を作らない。(障害が発生するとシステム全体が使用不能になる)


###### ②地理的に離れた場所で冗長化する
![スクリーンショット 2024-04-09 17.13.21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3744656/0e7ae72d-49cb-680d-838f-ce9ccf58c9c2.png)
→例)2つのAZにそれぞれEC2インスタンスとRDSのデータベースインスタンスを構成

###### ③システムを疎結合で構成する
![スクリーンショット 2024-04-09 17.13.37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3744656/d2d89507-0897-7d19-5e3c-993428bd5217.png)
→システムやコンポーネントを独立させる。
　システムの一部が故障したり動作不良を起こした場合でも、その部分だけ切り離して復旧作業を行える

 の3点が挙げられます。

 ## 最後に
必ず可用性の高いアーキテクチャを意識しないといけませんね。
システムダウンが発生しても、いかに早くリカバリーが出来るかがとても大切です。
利用者が困らないシステムを作るべきだと、改めて肝に命じたいと思いました！
Macにiosシュミレーターを入れる方法 2024年最新版

# 概要

こんにちは、ゆめみに新卒フロントエンドエンジニアとして４月から働き出しました[kawabata](https://twitter.com/haru1125632)です。

業務で、iosシュミレーターを使って動作確認を行う必要が出てきたので、今回はシュミレーターを入れる方法を紹介できればと思います。困ったときの参考にしていただければ幸いです。

**2024年度４月9日現在のUIです。UIが変わる可能性あります。**

xcode: Version 15.3
mac: Apple M2 Pro 14.4.1

# 方法

### 1. MacにXcodeをインストールする

シュミレーターを入れるには、Xcodeをインストールする必要があります。
下記のリンクからappStoreを開いて、Xcodeのインストールを行なってください。

https://apps.apple.com/jp/app/xcode/id497799835?mt=12


### 2. 任意のiosのバージョンをインストールする

1.XcodeのインストールをしたらXcodeを開きます
2.メニューバーからXcode -> Settingsを選択します

![スクリーンショット 2024-04-09 15.25.09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1980538/25a02dec-06bc-180c-9909-d4de3e04fdb0.png)

3.開いたウィンドウのPlatformsを選択し、最新のiosを探してGetボタンを押してインストールします

（画像だとインストール済みのため、Getの表示は消えてしまっています）

![スクリーンショット 2024-04-09 15.27.34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1980538/1a5729d7-dfeb-3c0c-9a2b-5612bdf6eae7.png)

**インストールにはそこそこ容量を使うので、適切な容量を確保した上で実行しましょう**


#### Tips: 古いiosのバージョンをインストールする方法

新しいバージョンだと対応していない端末があります。また、古いバージョンで動作確認したい場合もあると思います。
そのような場合は以下のような手順を使ってください。


1. Platformsを選択し、プラスボタンを押しiOSを選択します

 ![スクリーンショット 2024-04-09 15.33.41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1980538/a7b31574-a5e6-12f6-d82e-b1c1cef78bd5.png)

2.iosのバージョンを選択して、download&installを選択します


![スクリーンショット 2024-04-09 15.34.00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1980538/51d0b85a-eaf2-54cc-a993-817408ab9a5c.png)


### 3. Simulatorを起動する

1.Xcodeを起動した状態で、Xcode->OpenDeveloperTool->Simulatorを選択する
![スクリーンショット 2024-04-09 15.40.04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1980538/7426e37b-25f1-a042-0363-a7b05e7a846f.png)


2.サイドバーに表示されたシュミレータアイコンから起動したいデバイスを選択する
![スクリーンショット 2024-04-09 15.46.19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1980538/453a8c83-8c4f-ef5c-4078-c513963e58aa.png)


🎉お疲れ様でした

![スクリーンショット 2024-04-09 15.47.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1980538/6683e643-23a1-f06f-7ab4-53c9a75085c0.png)



#### Tips: デバイスを追加する

１.Xcodeを立ち上げた状態でWindow->Devices and Simulatorsを選択します
![スクリーンショット 2024-04-09 15.49.54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1980538/92664ee7-9d32-3369-b7d2-2569b58f774f.png)

2.Simulatorsにタブを切り替えて、右下にあるプラスボタンを押します 
![スクリーンショット 2024-04-09 15.52.04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1980538/3c7b46d6-928a-a33c-3698-32503a59f26f.png)


3.Device Typeおよび、OS Versionを選択して、Createを押してデバイスを追加します
![スクリーンショット 2024-04-09 15.54.00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1980538/c7b684cb-d685-5d36-8e55-94f5dc39bbe5.png)

**OSのバージョンによっては対応外のデバイスなどがあるので、古いiosのバージョンをインストールするなどをすれば解決するかもしれません**

# まとめ

今回は、Macにiosシュミレーター入れる方法を紹介しました。Webのフロントエンドもスマホから触られるケースを想定する機会はあると思うのでまだ入っていない方は是非導入してみてください。
マウスカーソルのスピードをさらにあげる(Mac)

### 新しく買ったトラックボールマウスのカーソルが遅すぎたので...
##### (普通は設定からあげればいいけど、最速にしても遅かった)

1\. ターミナルから、以下を実行(7はスピードの値)
```
defaults write -g com.apple.mouse.scaling 7
```
2\. 再起動

### 現在のスピードをみるには
```
defaults read -g com.apple.mouse.scaling
```


### 補足
トラックパッドの場合は、mouseをtrackpadにして実行する。

以上
OpenAI Dalle-3 APIを使った画像生成Pythonサンプル

# 背景
- Dalle-3をPython APIで呼び出す
- 出力方式がurlとb64_jsonがあるので両方やり方メモ

https://platform.openai.com/docs/api-reference/images

# response_format = url

- httpで画像にアクセスできるurlがかえります
- ただし、1時間しか有効ではないので注意

```py
from openai import OpenAI

client = OpenAI()
res = client.images.generate(
    model="dall-e-3",
    prompt="a cat in the park",
    size="1024x1024",
    quality="hd",
    response_format="url",
    style="vivid"
)
return res.data[0].url
```

# response_format = b64_json

- 指定したpathにpng形式で保存します
- `base64.b64decode` でbytesのデータが取得できるのでそれを書き込みます

```py
from openai import OpenAI

client = OpenAI()
res = client.images.generate(
    model="dall-e-3",
    prompt="a cat in the park",
    size="1024x1024",
    quality="hd",
    response_format="b64_json",
    style="vivid"
)
image_bytes = base64.b64decode(res.data[0].b64_json)
with open(filepath, 'wb') as file:
    file.write(image_bytes)
```
[Google Calendar API(V3)] Javaでカレンダーのイベントを別のカレンダーにコピーする

Gmail API v1（Java）を使用して、
Googleカレンダーのイベントを別のカレンダーにコピーする方法
についてご紹介します。

:::note info
APIを利用する環境の準備から始める場合や、コードを実行する際は、
[⧉[Google Calendar API(V3)] JavaでCalendar APIを使う](https://qiita.com/doran/items/c735c7b05c0a2ed4bfdb)
を参照ください。
:::

|No||目次|
|---|---|---|
|1||[イベントをコピー](#1-イベントをコピー)|
||1|[スコープ](#11-スコープ)|
||2|[実行](#12-実行)|
||3|[レスポンスの内容](#13-レスポンスの内容)|

## 1. イベントをコピー
指定したカレンダーのイベントを別のカレンダーにコピーします。

コピーしたいイベントのID(iCalUID)と、コピー先のカレンダーIDを指定します。
イベントの開始時間、終了時間の指定も必須です。

### 1.1. スコープ
このAPIを実行するには、以下のいずれかのスコープを指定してください。
```
CalendarScopes.CALENDAR
CalendarScopes.CALENDAR_EVENTS
```
[⧉[Google Calendar API(V3)] JavaでCalendar APIを使う(2.2 Driveインスタンスを取得)](https://qiita.com/doran/items/c735c7b05c0a2ed4bfdb#22-calendarインスタンスを取得)
でスコープを指定してください。

### 1.2. 実行

```java
public static void main(String[] args) throws Exception{
    Calendar.Events events = calendar.events();
    
    Event content = new Event();
    content.setICalUID("iCalUID");
    content.setStart(new EventDateTime().setDateTime(new DateTime("2018-06-30T08:30:00.000+09:00")));
    content.setEnd(new EventDateTime().setDateTime(new DateTime("2018-06-30T10:00:00.000+09:00")));
    Calendar.Events.CalendarImport calendarImport = events.calendarImport("コピー先のカレンダーID",content);
    
    Event res = calendarImport.execute();
    System.out.println(res);
}
```
#### 1.2.1. HTTPリクエスト
POST:　https:\//www.googleapis.com/calendar/v3/calendars/{カレンダーID}/events/import
が実行されます。

#### 1.2.2. クエリパラメータ
Calendar.Events.CalendarImportのsetメソッドにより、クエリパラメータを追加できます。

|メソッド|引数|説明|
|---|---|---|
|setConferenceDataVersion|Integer|会議データのバージョン番号|
|setSupportsAttachments|Boolean|イベントの添付ファイルをサポートしているか|

#### 1.2.3. リクエストボディ
Eventのsetメソッドにより、リクエストボディを追加できます。
setICalUID、setStart、setEndの指定は必須です。
※iCalUID：複数のカレンダー間にまたがって一意なイベントID

メソッドの詳細は、
[[Google Calendar API(V3)] Javaでカレンダーのイベントを作成・更新・削除する(1.2.3. リクエストボディ)](https://qiita.com/doran/items/32287fc011243dbbd122#123-リクエストボディ)
を参照ください。

### 1.3. レスポンスの内容

#### Event

[[Google Calendar API(V3)] Javaでカレンダーのイベントを取得する(1.3. レスポンスの内容)](https://qiita.com/doran/items/714407979db97afea29c#event)
と同じです。

<br>
<br>
おしまい。。
Sudachi辞書:新語拡充計画

## 前回のお話

[Sudachi辞書 : 新語収集](https://qiita.com/kawahara_n/items/b5af6348e483e8f9676f)

## これからの新語収集
[Sudachi辞書](https://github.com/WorksApplications/SudachiDict)は約3カ月ごとにメンテナンスを行っており、前回はそのうちの新語収集についてご紹介しました。今回はその続き「新語拡充計画」です。

これまでは、新語の拡充は気づいた範囲で、どちらかというと既登録語の整備(full辞書からcore辞書への登録先変更や分割情報、品詞の修正など)に時間を取られがちでした。なにしろ膨大な規模の辞書なので、整備ひとつとっても時間がかかるためです。ただ、これでは新しい語がなかなか入ってきません。そこで今後は、新語の拡充をもっと計画的に進めていこうと考えています。

## 基本方針

1. 広く浅く
より多くのユーザーにとって使い勝手の良いものとなるよう、専門的な語よりも、日頃よく見聞きしたり使われるような語を優先的に追加していきます。

1. 数よりも質
情報の精度を保ちつつ、効率よく拡充を続けていくためには、ある程度数は絞らざるを得ません。本当に新しい語か、必要とされる語かを吟味して、正しく情報を付与することに重点を置きます。

1. 適切な語を適切なタイミングで
旬な語をできるだけ旬なうちに反映できるよう、分野ごとに拡充する時期や回数を調整します。例えば、テレビ番組名は各クールに合わせて3か月ごとに、会社名は上場の多い12月に合わせて1月に、という具合です。
	

## 拡充計画

具体的には、以下のようなカテゴリについて、定期的に拡充していく予定です。また、カテゴリごとに拡充の時期は異なります。ただし、これはあくまでも基本的な方針で、状況によっては柔軟にその内容を見直していきます。

#### 枠を設けているカテゴリ

枠を設けているカテゴリについては、該当するものをすべて登録します。

|カテゴリ|採用範囲|例|回数|
|:---|:---|:---|:---|
|会社名|上場企業すべて、非上場企業のうち顕著なもの|LINEヤフー、アサヒ飲料|年2回|
|銀行名|銀行、信用金庫、信用組合等|UI銀行、SBI新生銀行|年2回|
|各国首脳|各国元首、国家主席、首相|クリストファー・ラクソン、ガブリエル・アタル|年2回|
|日本の大臣名|大臣、内閣官房長官|上川陽子、自見はなこ|年2回|
|政党名|日本の政党すべて|教育無償化を実現する会|年2回|
|鉄道路線、駅名|新規開通する路線、駅名|東急新横浜線、ゆいの杜中央駅|年2回|
|住所地名|郵便データに記載の住所(番地や丁目は除く)|浜松市中央区元城町|年2回|
|大学名|全大学名|東京科学大学|年2回|

#### 枠を設けていないカテゴリ

枠を設けていないカテゴリについては、使用頻度や人気度などを参考に、顕著なものを登録します。

|カテゴリ|採用範囲|例|回数|
|:---|:---|:---|:---|
|ビジネス、IT用語|ビジネス用語、アプリ名、サービス名、IT技術等|LLM、ハルシネーション、Copilot|年2回|
|スポーツ選手名|サッカー、野球、卓球、バスケットボール、バーレーボール、フィギュアスケート、ゴルフ、大相撲等|佐々木麟太郎、河村勇輝|年2回|
|芸能人名|俳優、声優、歌手、タレント、お笑い芸人等|河合優実、iScream|年4回|
|番組名|ドラマ、バラエティ、アニメ等|光る君へ、マッシュル|年4回|
|作品名、作家名|書籍、ゲーム、漫画、映画等|カラオケ行こ!、東京都同情塔|年2回|
|商品名|商品や関連するキャラクターなど|マッサージガン、サメにゃん|年2回|
|ランドマーク|国内の商業施設、娯楽施設等|イマーシブ・フォート東京、Kアリーナ横浜|年2回|

#### そのほか

これらのカテゴリにはまらない雑多な語彙についても、継続的に収集して辞書に登録していきます。

|カテゴリ|採用範囲|例|
|:---|:---|:---|
|その他|一般語、略語、既登録語の表記展開等|転塾、政倫審、紅こうじ|

※事例は既に登録済みのものも含む。

## おしまいに
語彙の拡充は、ある程度機械的に行えても、最終的には人間の目で見て確認する必要があると考えています。そのため、時間はかかりますが、きちんと時代に沿った辞書になるよう、継続して取り組んでいきます。
ultramon で アプリを開くモニターを固定

windowsマークを右クリック
-> ファイル名を指定して実行

```
shell:startup
```

と入力。

ここでパソコンを起動したときに自動で実行するショートカットを置く


この際、アプリを開くモニターの位置を固定したい。
ultramonでアプリのウィンドウを固定するにはショートカットのプロパティ

![1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/31338/67452dfe-1315-ec29-debf-1a4a8f3b5fdc.png)

ultramon をクリックし ultramon-windowをクリック

![2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/31338/9cf94748-7c6d-c0fb-d70b-06a94b92be13.png)


use custom settings で 開くモニターを固定することができる