OmniAICreator/Qiita-1.07M huggingface dataset:
rex0220 算式自動採番プラグイン 既存アプリへの導入手順

[算式自動採番プラグイン](https://qiita.com/rex0220/items/2e40a57d2d08023affde)を既存アプリへの導入する場合の手順です。

# 概要

既存レコードに番号を付与済みのアプリに、算式自動採番プラグインを導入する場合の手順です。
既存レコードと番号が重複しないように、採番キー、連番項目の値をセットする必要があります。
今回は、採番キー、連番項目の値を計算式プラグインでセットします。
※CSV 読み込み等で。採番キー、連番項目の値をセットしてもOKです。

- 採番キー（文字列1行）、連番項目(数値)を追加
- 算式自動採番プラグインを設定
- 計算式プラグインで、採番キー、連番項目の値をセット
- 採番キー、連番項目の値を確認
- 対象アプリの計算式プラグインを無効または削除する

# 採番キー（文字列1行）、連番項目(数値)を追加

![2024-04-16_19h11_46.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100572/be3cf2eb-74dd-89b5-1929-78f95b464581.png)

# 算式自動採番プラグイン設定

区分毎に連番を付与するルールとします。
※ A-00001, B-00001...

![2024-04-16_19h47_23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100572/d03945c1-60e6-b5fa-6be6-54526664e423.png)

```.js
// 採番の計算式
区分&"-@@@@@"
```

# 計算式プラグインで、採番キー、連番項目の値をセット

- 既存レコードの採番キー、連番項目の値をセットする計算式を設定
    - 区分が採番後に変更されていない前提
    - 区分が採番後に変更される場合は、「番号」から採番キーを計算してください
- 「既存レコードを変更」をクリックして、既存レコードを変更

![2024-04-16_19h27_57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100572/4baaf900-79dc-8503-b0d8-c555dd86694f.png)

```.js
// 採番キー SINGLE_LINE_TEXT
区分&"-@@@@@"

// 連番 NUMBER
SLICE(番号,-5)
```

# 採番キー、連番項目の値を確認

一覧画面で、採番キー、連番項目の値を確認します。

![2024-04-16_19h33_10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100572/afad4aa7-e79d-4880-41dc-e041de088684.png)

# 対象アプリの計算式プラグインを無効または削除

計算式プラグインを無効にした例

![2024-04-16_19h34_10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100572/9883e220-1b7c-8e79-383d-7126cb4dff06.png)
【備忘録】jQueryでURLに特定の文字を足す

# したい事

### URLに特定の文字を足す

page-link01.htmlの末尾に、「#content」を追加したい


▼対象のソース（例）


```
<ul class="page-link">
<li><a href="page-link01.html">リンク01</a></li>
<li><a href="page-link02.html">リンク02</a></li>
<li><a href="page-link03.html">リンク03</a></li>
</ul>
```

# 方法
### jQueryを使用

①対象を絞込む(.page-link要素内のa)

②eachに関数を渡す

③関数内のjQuery(this)で、対象オブジェクトを取得し、変数objに代入

④変数objに代入した対象オブジェクトのリンクURLを取得し、変数linkに代入

⑤attrでリンクURLを「変数linkで取得したリンクURLに#contentをプラスした文字列」に置き換える

```
<script>
jQuery(function(){
    jQuery(".page-link a").each(function() {
        var obj = jQuery(this);
        var link = obj.attr("href");
        obj.attr("href",link+"#content")
    });
});
</script>
```


# 実行例
```
<ul class="page-link">
<li><a href="page-link01.html#content">リンク01</a></li>
<li><a href="page-link02.html#content">リンク02</a></li>
<li><a href="page-link03.html#content">リンク03</a></li>
</ul>
```



# 分からなかった事
ネットの記事を参考にしましたが下記が特に分からなかったので、別途調べて記事を書きます。

1. eachに関数を渡すとは？ 
2. jQuery(this)とは？
3. attr()とは？
ChatGPTでExcel VBAのコード生成

個人メモ

複数のブックのSheet3のデータを1つのブックにまとめるVBAコードをChatGPTで作成。

このコードは、フォルダ内のすべてのExcelファイルを処理し、それぞれのSheet3からデータを取得して、1つの新しいブックに統合する。

手順１
同じフォルダに全てのデータをまとめる。

手順２
以下のコードをコピペ。
適宜修正。

```:Excel VBA
Sub CombineSheet3Data()
    Dim myPath As String
    Dim myFile As String
    Dim currentWb As Workbook
    Dim newWb As Workbook
    Dim lastRow As Long
    Dim i As Long
    
    '新しいブックを作成します
    Set newWb = Workbooks.Add
    
    'マクロが保存されているフォルダのパスを取得します
    myPath = ThisWorkbook.Path
    
    'マクロが保存されているフォルダ内のExcelファイルを処理します
    myFile = Dir(myPath & "¥*.xls*")
    Do While myFile <> ""
        'ファイルがExcelファイルであることを確認します
        If myFile <> ThisWorkbook.Name Then
            'Excelファイルを開きます
            Set currentWb = Workbooks.Open(myPath & "¥" & myFile)
            
            'Sheet3のデータを取得します
            With currentWb.Sheets("Sheet3")
                lastRow = .Cells(.Rows.Count, 1).End(xlUp).Row
                If lastRow > 0 Then
                    .Range("A1").CurrentRegion.Copy Destination:=newWb.Sheets(1).Cells(i + 1, 1)
                    i = i + lastRow
                End If
            End With
            
            'Excelファイルを閉じます（保存しない）
            currentWb.Close False
        End If
        
        '次のExcelファイルを処理します
        myFile = Dir
    Loop
    
    '新しいブックをアクティブにします
    newWb.Activate
    
    '統合した行数を表示します
    MsgBox "統合された行数: " & i, vbInformation
End Sub

```

おまけ
連番のみが降ってある場合に、空白を消去するコード
```:Excel VBA
Sub 空白消去()
    
    For i = 50 To 1 Step -1
        If Cells(i, 2).Value = "" Then
             Rows(i).Delete
        End If
    Next i

End Sub
```
【Azure AI Search】旧：Azure Cognitive SearchのBlob Storageの削除検出方法（indexへの反映）

# はじめに
Azure AI Searchを用いた社内資料検索アプリを実装しているのですが、Blob Storageから資料を削除してindexerを実行したらindexからBlob Storageから削除したドキュメントが同期されて同じく削除されるようになる方法の紹介です。

# 解決方法
１．まず、BlobStorageの左ペインのデータ保護から、Blobの論理的削除を有効にしてください。

![スクリーンショット 2024-04-16 185322.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3754813/870810e3-bf1b-434a-67fb-2a797cad978c.png)

![スクリーンショット 2024-04-16 185547.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3754813/a4f12b50-6158-d3a8-fcee-e7cd8b877e22.png)

２．Azure　AI Searchのサービスに行って、データソースからネイティブBLOBの論理的削除ボタンにチェックを入れます。

![スクリーンショット 2024-04-16 185940.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3754813/7d05c254-12cf-fd4f-3853-04316e30fafe.png)

![スクリーンショット 2024-04-16 185754.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3754813/20433ce7-48fd-cadd-51af-5aca2f148f95.png)

３．現状2個ドキュメントが入っているので、indexには2個資料が入っています。

![スクリーンショット 2024-04-16 192840.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3754813/a86bd155-bb6e-2319-2b43-145b4db7a7c2.png)

![スクリーンショット 2024-04-16 192906.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3754813/dc1e7dd1-c5ec-bb57-3ad9-5425a7bc1c1d.png)

４．BlobStorageからdownload.pdfを削除します。

![スクリーンショット 2024-04-16 193001.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3754813/f7ffef1f-955e-4aeb-3710-e38a92de93f1.png)


５．indexerを実行すると、1件の更新を検出できていることがわかります。

![スクリーンショット 2024-04-16 191124.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3754813/003ce222-2775-1b8f-d180-d1413fa2d2ee.png)

![スクリーンショット 2024-04-16 193049.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3754813/d87de863-70f7-086d-aa00-7cb23a1ca43a.png)

６．indexも先ほど2個ドキュメントが入っていた状況から1つ減って1個になっていることが確認できます。
＊同期に少々タイムラグがあります。

![スクリーンショット 2024-04-16 194246.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3754813/466c100b-5133-424a-ae83-39469131a721.png)


# まとめ

これでBlobstorageから削除したドキュメントを検出してindexに反映させることができます。
反対に、Blobにアップロードしたドキュメントをindexに反映させることも可能です。
indexへの反映は2～3分ほどかかるのでご注意ください。
Bootstrap.css と バニラJSで お手軽ローディングスピナー実装

```html
<!-- Bootstrap CSSの読み込み -->
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-9ndCyUaIbzAi2FUVXJi0CjmCapSmO7SnpJef0486qhLnuZ2cdeRhO02iuK6FUUVM" crossorigin="anonymous">

<!-- 〜略〜 -->

<!-- スピナー本体＋CSS -->
<style>
  #loading {
        background: rgba(0, 0, 0, .75);
        z-index: 10000;
    }
</style>

<div id="loading" class="position-absolute top-0 start-0 w-100 h-100 d-none">
  <div class="text-center position-absolute top-50 start-50 w-100 translate-middle">
      <div class="spinner-border text-light" style="width: 10vw; height: 10vw;" role="status">
          <span class="sr-only"></span>
      </div>
  </div>
</div>

<!-- JS -->
<script>
  // ロード開始時にローディングを表示
  show_loading();

  // 全てのリソースが読み込まれた後でローディングを非表示にする
  window.addEventListener('load', function() {
      console.log('All resources finished loading!');
      hide_loading();
  });

  // ローディング表示
  function show_loading() {
      console.log('Showing loading spinner');
      document.getElementById('loading').classList.remove('d-none');
      document.documentElement.style.overflow = 'hidden';
  }

  // ローディング非表示
  function hide_loading() {
      console.log('Hiding loading spinner');
      document.getElementById('loading').classList.add('d-none');
      document.documentElement.style.overflow = '';
  }
</script>

```

アコーディオンとかはBootstrapのJSで動くのになぜスピナーは自分でJSを書かないかんのか謎ですが、とにかくこれで動きます。
Cloud Identity APIでGoogle Workspaceのグループ(Google Groups)を操作する

# 概要

ビジネスアカウント(じゃないとダメっぽい)のGoogle Workspaceのグループ(Google Groups)をメーリングリストとして使用する際のメンバー操作をするためにCloud Identity APIをPythonで使ったのでまとめます。サーバー側操作なのでサービスアカウントを使いました。

よく使われる手段はAdmin Directory APIだと思いますが、使用するサービスアカウントに対してドメイン全体の委任が必要になるため、それを避けるためにいろいろと調べた結果Cloud Identity APIで行うことができました。普段GCPを使わないので、用語などがおかしい部分があるかもしれませんが、ご容赦下さい。

# 準備

それほど複雑な手順はないと思います。サービスアカウントの作成まではできているものとします。使用するサービスアカウントはディフォルトの設定で作成したものです。

- サービスアカウントのプロジェクトに対して`Cloud Identity API`を有効にする
- 対象となるグループをGoogle WorkspaceのWebコンソールで作成する
- 対象となるグループに使用するサービスアカウントを追加する
- API操作可能

## アカウントおよびグループの準備

サービスアカウントをディフォルト設定で作成します。また、プロジェクトが使用するAPIとしてCloud Identity APIを有効にしておきます。また、サービスアカウントのJSONファイルをダウンロードしておきます。APIでのグループの操作ドキュメントにはグループ管理特権を追加する(roleAssignments)などが書かれていますが、このやり方だと不要でした。

対象となるGoogle GroupsをGoogle WorkspaceのWebコンソールで作成します。必要な状況に応じて権限の設定などを行って下さい。続いて、用意しておいたサービスアカウントのメールアドレスを「マネージャー」として追加します(メンバーの表示や管理ができるロールを付与しておきます)。

# 実装
## 環境

- Rocky Linux 9.3 + Python 3.11
- google-api-python-client 2.125.0
- oauth2client 4.1.3

## コード

- サービスアカウントのJSONを `service-account.json` とします

### メンバーのリストを得る

```python
#!/usr/bin/env python3
import json
from oauth2client.service_account import ServiceAccountCredentials
from googleapiclient.discovery import build

SCOPES = ["https://www.googleapis.com/auth/cloud-identity.groups"]
CUSTOMER_ID = "C01xxxxxx"
GROUP_ID = "mygroup@example.com"

# 認証情報の読み込みとサービス構成
keyobj = json.load(open("service-account.json"))
creds = ServiceAccountCredentials.from_json_keyfile_dict(keyobj, SCOPES)
service = build("cloudidentity", "v1", credentials=creds)
groups = service.groups()

# グループ名(groups/01xxxxxxxxxxxxx)をグループアドレスから得る
group_name = None
res = groups.list(parent=f"customers/{CUSTOMER_ID}").execute()
for grp in res["groups"]:
    if grp["groupKey"]["id"] == GROUP_ID:
        group_name = grp["name"]
        break
assert group_name

# メンバーのリストを得る
res = groups.memberships().list(parent=group_name).execute()
for user in res["memberships"]:
    print(user)
```

### メンバーをグループに追加する

上のコード中のgroup_nameを使ってます。

```python
NEW_MEMBER_EMAIL = "foo@example.com"
membership = {
    "preferredMemberKey": {"id": NEW_MEMBER_EMAIL},
    "roles": {"name": "MEMBER"},
}
res = groups.memberships().create(parent=group_name, body=membership).execute()
print(res)
```

### メンバーをグループから削除する

```python
# メンバーのIDが必要となるので検索
res = groups.memberships().list(parent=group_name).execute()
for user in res["memberships"]:
    if user["preferredMemberKey"]["id"] == NEW_MEMBER_EMAIL:
        # メンバーのIDが得られた
        res = groups.memberships().delete(name=user["name"]).execute()
        print(res)
        break
```

# まとめ

Google WorkspaceのAPIはクセが強いので私はあまり使わないのですが、今回は動的にメーリングリストを操作したかったのでGoogle Groupsを使うことにしてみました。

どなたかのお役に立てば幸いです。

# 参考

- Groups APIの設定 -- https://cloud.google.com/identity/docs/how-to/setup?hl=ja
- Googleグループのメンバーシップの管理 -- https://cloud.google.com/identity/docs/how-to/memberships-google-groups?hl=ja
PHPでファイルを操作する際にファイルの権限によって書き込み・読み取りができなることがある件

# 環境
- CentOS Linux release 7.9.2009(Core)
- Apache 2.4.6
- PHP 7.1.33
# 起こったこと
PHPでWebスクレイピング的なプログラムをWindowsからCentOSに転送してCentOS側で実行したとき、色々なセーブデータをファイルに保存するはずが保存されてませんでした。
自分はurlencode、urldecode関数が混沌としていたためそこらへんでエラーが起こっていたと思っていました。
# 原因
自分はWindowsでscpでCentOSに転送してからCentOSでまたドキュメントルートに転送するスクリプトを実行していたので無駄だったため、CentOSからWindowsにscpして、というスクリプトでやっていました。
その時のスクリプトはこちら。モザイクは[]で囲っています。
```sh:apply.sh
echo -n "Host Address: "
read hostaddr

hostip="[ユーザー名]@192.168.0.$hostaddr"
hostdir=":C:[Windows側のドキュメントルート]"
host="$hostip$hostdir"
rm -r ~/docroot
scp -r $host ~

sudo cp -r ~/docroot /var/www/html
sudo rm -r /var/www/html
```
お察しの方がいますでしょうか。そう！　sudo権限でドキュメントルートにコピーしていたのです！！
# 対処法
スクリプトにこのような分を追加して解決しました。
```sh:apply.sh
sudo chmod 766 /var/www/html/[セーブデータのファイル名]
```
# まとめ
ファイルの権限管理はしっかりしましょう！
Microsoft Fabricを知るためのリンク集（自分用）

# はじめに
Microsoftから近い技術に触れてると今後避けては通れなさそうな「Microsoft Fabric」について、いろいろできるのはわかるけど具体的にどうやるのか、そもそもどんな思想なのかなどがいまいちわかってないので、確認済み・未確認含めてリンク集にします。
将来的にはそれらをまとめて記事にしたい・・・

# Microsoft公式
## 動画
https://www.youtube.com/watch?v=nWXr5kV2LSs&t=629

https://www.youtube.com/watch?v=W5T_7FC6F88

https://www.youtube.com/watch?v=khqAGkD01T0

## Docs
https://learn.microsoft.com/ja-jp/fabric/get-started/microsoft-fabric-overview

https://learn.microsoft.com/ja-jp/power-bi/guidance/fabric-adoption-roadmap?context=%2Ffabric%2Fcontext%2Fcontext&bc=%2Ffabric%2Fbreadcrumb%2Ftoc.json

# その他
## 記事
https://marshal115.hatenablog.com/entry/2023/05/24/155319

https://qiita.com/yangjiayi/items/605d9679e1e35d391a1a
タブがアクティブかどうかでタイトルを変更する方法

Akiflowのサイトで別タブを閲覧中の時、タイトルが「🥺 Come back」になっており、どのように実装しているのか気になって調べたのでご紹介します。

https://akiflow.com/

Akiflow閲覧中

![スクリーンショット 2024-04-02 17.43.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1125523/7e55f372-4fd1-360a-a437-a0cbdd727e5c.png)

Akiflow閲覧してない

![スクリーンショット 2024-04-02 17.43.56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1125523/46a63682-e9c1-44e7-c221-1f51e17226a3.png)

## コード

`document`の`visibilitychange`イベントで、タブのアクティブが変更されたか監視できます。
また、`document.visibilityState`でタブがアクティブかどうか判別できます。

```javascript
document.addEventListener('visibilitychange', () => {
  if (document.visibilityState === 'visible') {
    document.title = '閲覧中';
    return
  }

  document.title = '🥺 閲覧してない';
});
```

## おまけ

上記方法とは少し違いますが、ウィンドウのフォーカスが変更された時の判別方法もご紹介します。


```javascript
window.addEventListener('focus', () => {
  document.title = 'フォーカス中';
});

window.addEventListener('blur', () => {
  document.title = '🥺 フォーカス外れた';
});
```

## まとめ

タブがアクティブかどうかで、タイトルを変更する方法をご紹介しました。
あまり使用するイベントでは無いですが、ユーザーが閲覧してない時に重い処理を止めたい場合などに有効かなと思いました。

## 参考サイト

https://developer.mozilla.org/ja/docs/Web/API/Document/visibilitychange_event

https://developer.mozilla.org/ja/docs/Web/API/Window/focus

https://developer.mozilla.org/ja/docs/Web/API/Window/blur

## 最後に

### GoQSystemでは一緒に働いてくれる仲間を募集中です！

ご興味がある方は以下リンクよりご確認ください。

https://goqsystem.recruit.site?qiita=
古いkopsクラスタがEC2再生成後に起動しなくなったとき


## 概要

kopsを使って構築したKubernetesクラスタにて、クラスタノードのEC2が再作成されたときはcloud-initを利用して自動的にKubernetesクラスタノードになる構築プロセスが実行されます。
このプロセスの中で`apt-get update`を実行しますが、古いkopsを使い続けているとOS (Ubuntu) のバージョンも古くなり、やがてaptリポジトリがEOLして自動構成が完了しなくなります。
このようなときは、リポジトリのEOL警告を無視して強制的に`apt-get update`するコマンドを手動で実行することで、構築プロセスを続行させることが可能です。
運用回避ではありますが、バージョンアップまでの繋としてご活用ください。

## 手順

1. ELBのインスタンスステータスを確認する
    * 本症状であればOutOfServiceになっています
    * InServiceにも関わらず障害状況であれば、本手順の適用外です
2. クラスタのEC2にsshする鍵を取得する
    ```bash
    $ aws s3 cp s3://hoge.domain.k8s.local/keyfile .
      # 構築時に鍵やステートを保管するS3バケットを指定したはずなので探してください
    $ chmod 400 keyfile
    ```
3. クラスタのEC2にsshログインする
    ```bash
    $ ssh -i keyfile admin@<EC2のIP>
      # EC2のIPはAWSコンソールで確認して下さい
    ```
4. 本手順が適用可能な症状であるかログを確認する
    * 下記のようなパッケージインストールに失敗したメッセージ (error installing package) があれば本手順の適用対象です
        ```bash
        $ sudo tail -f /var/log/daemon.log
        Jan 21 05:51:18 ip-172-20-50-32 nodeup[718]: W0121 05:51:18.977780     718 executor.go:130] error running task "Package/ebtables" (9m59s remaining to succeed): error installing package "ebtables": exit status 100: Reading package lists..
        ```
5. リポジトリのEOL警告を無視して、手動でapt-get updateを実行する
    ```bash
    $ sudo apt-get -o Acquire::Check-Valid-Until=false update
    Hit http://security.debian.org jessie/updates InRelease
    (中略)
    Fetched 13.8 MB in 2s (5,174 kB/s)
    Reading package lists... Done
    ```
6. クラスタの全EC2で同様の操作を繰り返す
7. 自動的に構成プロセスが再実行されるので5～10分程待つ
    * ELBのインスタンスのステータスがInServiceに変われば復旧完了です
言語ごとの 関数を実行する際の 参照渡しの扱いについて 明示的/暗黙的/なし で分類する

言語ごとの 関数を実行する際の 参照渡しの 明示的 / 暗黙的 / なし を纏めてみました。
| 言語 | 実引数の 暗黙的/明示的/なし
| -- | -- |
| Java | なし| 
| Python | なし|
| C++ | 暗黙的 [^5] |
| Rust | 明示的 (& の指定が必要) [^4] |
| C# | 明示的 (ref / out の指定が必要 ※ただし、in の場合は暗黙的なので注意) [^3] |
| PHP | 暗黙的 [^2] |
| C | なし（※ポインタの値渡しな為）|
| Go | なし（※ポインタの値渡しな為）|
| Swift |  明示的 (& の指定が必要) [^1] |

[^1]: https://www.swiftlangjp.com/language-guide/functions.html#in-out-%E3%83%91%E3%83%A9%E3%83%A1%E3%83%BC%E3%82%BFin-out-parameters
[^2]: https://www.php.net/manual/ja/language.references.pass.php
[^3]: https://learn.microsoft.com/ja-jp/dotnet/csharp/language-reference/keywords/method-parameters#reference-parameters
[^4]: https://doc.rust-jp.rs/book-ja/ch04-02-references-and-borrowing.html#%E5%8F%82%E7%85%A7%E3%81%A8%E5%80%9F%E7%94%A8
[^5]: https://www.ibm.com/docs/ja/xl-c-and-cpp-aix/13.1.0?topic=calls-pass-by-reference-only

もし、他の言語についての情報や、参考リンク等ありましたらコメントや編集リクエストを宜しくお願いします。
AGP8系にアップデート時にパッケージにnamespaceがない場合

## 回避策

```android/build.gradle
subprojects {
    project.buildDir = "${rootProject.buildDir}/${project.name}"
    afterEvaluate {
        // check if android block is available
        if (it.hasProperty('android')) {

            if (it.android.namespace == null) {
                def manifest = new XmlSlurper().parse(file(it.android.sourceSets.main.manifest.srcFile))
                def packageName = manifest.@package.text()
                println("Setting ${packageName} as android namespace")
                android.namespace = packageName
            }

            def javaVersion = JavaVersion.VERSION_17
            android {
                def androidApiVersion = 34
                compileSdkVersion androidApiVersion
                defaultConfig {
                    targetSdkVersion 33
                }
                compileOptions {
                    sourceCompatibility javaVersion
                    targetCompatibility javaVersion
                }
                tasks.withType(org.jetbrains.kotlin.gradle.tasks.KotlinCompile).configureEach {
                    kotlinOptions {
                        jvmTarget = javaVersion.toString()
                    }
                }
            }
        }

    }
}

```
## 解説
- パッケージのアップデートが追いついていないのでgradle側からnamespaceをつけてあげる(らしい)


[github(issue)](https://github.com/flutter/flutter/issues/125181#issuecomment-1555034383)
内製開発チームをビルディングしてみた

はじめまして！
ポーラ・オルビスホールディングスのITプロダクト開発チームでスクラムマスターをしている川田と申します。
ITプロダクト開発チームについては、以前に早川が書いた記事をぜひご参照ください。

https://qiita.com/hayakawa_POHD/items/84aecdb2128801f53911

私たちポーラ・オルビスホールディングスで内製開発チームを作るのは初めての試みでした。今回の記事では雰囲気やカルチャーに焦点を当てて、私たちのチームをご紹介します！:smiley:

# チームの価値観
開発チームには様々な経験年数やバックグラウンドを持つ方が集まっていますが、プロダクトの価値を高めるために、また自分たちの開発プロセスを改善するためにはどうすればよいか、立場や役割に関係なく意見を言うことができる環境だと感じています:+1:
私はチームに新しく参加した際に、気になる点があれば積極的に声を上げるように心掛けていました。これはチームやプロダクトを深く理解していないからこその視点もありますが、自ら発言することで他のメンバーが意見を言うハードルを下げる目的もあります。しかし、自分の意見だけを述べるのではなく、チームの今までの歩みや経験、メンバーの考え方を尊重し、プロダクトやプロセスにフォーカスした発言を心がけています。このような取り組みを重ねることで、チームの雰囲気が良い方向に変わってきたと感じます！

また、何か提案があったときはとりあえずスモールな規模から始めて、改善を続けながら進め、それから判断するというスタンスを重視しています。これは私の考えでもありますが、やる前からできない・続かない・無駄だと決めつけるのは、変化のチャンスを逃してしまうもったいない行為だと思っています。
最近、メンバー間の認識合わせやゴールの明確化、タスクの漏れ防止を目指して、チケットに最低限記載してほしい内容をテンプレートに設定しました。私からの突然の提案にも関わらず「効果があるか試してみましょうか」という姿勢で、皆さんに記載を続けてもらっています。
とりあえずやってみよう、効果が無ければやめよう、というマインドで協力してくれるメンバーには本当に感謝しています。このマインドを持てているのはチームとして大きな強みだと思っています！:clap:

ちなみに弊社では課題管理にBacklogを使用しており、Backlogでは[種別毎にテンプレートを設定する](https://support-ja.backlog.com/hc/ja/articles/360035642034-%E8%AA%B2%E9%A1%8C%E3%81%AE%E3%83%86%E3%83%B3%E3%83%97%E3%83%AC%E3%83%BC%E3%83%88)ことが可能です！
設定した種別で課題を新規に作成すると、テンプレートが自動的に内容欄に反映されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3550354/b7a39e11-d269-b771-474c-ce907e836b47.png)

# 働き方とコミュニケーション
私たちのチームでは必須の出社日を設けず、リモートワークを中心とした働き方を実践しています。家庭の事情による都合が調整しやすい・通勤時間が削減できるなどメリットはある一方で、顔が見えづらいリモートの環境下でコミュニケーションを密に行い、業務を円滑に進めるために以下のような取り組みを行っています。

## :two_men_holding_hands:プロジェクト参加の直後は対面でのコミュニケーションを増やす:two_women_holding_hands:
プロジェクトに参加して間もないころは、チームのルールや業務の進め方などちょっとしたことでもわからないことが多いですよね。また、チームの雰囲気やメンバーの人柄がわからない状況で、リモートで質問するのはハードルが高いと思います。よって、プロジェクトに参加した直後はタイミングを合わせて出社し、対面でのコミュニケーションを行えるようにしています。基本的なことですが、最初の関係構築という点では大事ですね！

## :microphone2:通話を繋ぎっぱなしにして、いつでも声をかけられるようにする:microphone2:
ポーラ・オルビスグループではチャットツールとしてMicrosoft Teamsを利用しています。Teamsの通話機能を使い、打ち合わせなどの予定がない時間はチームのチャンネルで通話を繋げたままにして、いつでも話しかけられる環境を整えています。対面だと、他のメンバー同士が話している内容からヒント・気づきを得たり、逆に自ら会話に参加してアドバイスや経験を話したりすることがありますよね。そのようなシナジー効果をリモートでも得ることを目的にした取り組みです。
一方で、自分の作業に集中したいときに隣で会話されると集中できない、という場面もあると思います。対面では解決が難しい問題ですが、リモート通話では必要に応じて一時的に会話を離れ、集中することができます。もちろん離れる頻度が多いと当初の目的が果たせなくなってしまうので本末転倒ですが、作業の内容や状況に応じて使い分けたり、テキストコミュニケーションと併用したりできるのはリモートならではの強みですね。

# 個人やチームの成長に向けた取り組み
これはITプロダクト開発チームだけではなく、所属している部門（グループデジタルソリューションセンター）全体に言えることですが、スキルアップを目的としてセミナー・研修への出席や資格の取得が推奨されています:+1:
例えば直近だと、開発チームに参画したPOメンバーが、Scrum Inc. Japanが提供する認定資格プロダクトオーナー研修を受講しています。私個人としては以前に Scrum Allianceの認定スクラムマスター研修を受講して認定を受けましたが更新をしていなかったので、改めて勉強してScrum.orgのProfessional Scrum Master試験の制覇を目指しています。ちなみにProfessional Scrum Masterは他と異なり試験だけ受験することが可能で、しかも更新の費用が不要という点が特徴です！

https://www.scrum.org/professional-scrum-certifications

また、チームとしての成長に向けて、という観点では現在絶賛企画中です。昨年はチームを新規に組成した段階ということもあり、具体的な計画を立てられませんでしたが、今年は個人の学びをチーム全体で共有できるような企画を考案しています。実際の取り組みやその結果は、Qiitaで発信したいと思います！:muscle:

# 最後に
私たちのチームはご紹介した考え方や取り組みを実践しながら、メンバー全員で議論しながら開発を進めています。メンバーの皆さんはそれぞれタスクを進めていますが、チームとしてゴールを達成するために、お互いにサポートしながら業務を行っています。
もしチームのコミュニケーションに苦労されている方がいましたら、この記事が参考になれば嬉しいです！:smiley:
Elixirで言語処理100本ノックやってみた！vol.5

こんにちは！
3ヶ月で、Elixir言語で開発できるようになるため、奮闘中のこーへーです！

vol.4は20時間かかったので、vol.5も覚悟していたんですが1時間ぐらいで終わってしまいましたね。笑
自分で言うのも微妙なんですが、確実に実力がついてきていますね。

ということで、100本ノックvol.5をやっていきたいと思います。
[100本ノックの記事はこちら](https://nlp100.github.io/ja/ch01.html)

### 05. n-gramPermalink
>与えられたシーケンス（文字列やリストなど）からn-gramを作る関数を作成せよ．この関数を用い，”I am an NLPer”という文から単語bi-gram，文字bi-gramを得よ．

案の定、問題の意味がわからずn-gramを理解するところから始めました。簡単に言うと、「I am an NLPer」を各単語と文字に区切って要素を2つずつ(bi-gram)格納してね。さらに、それを関数化してくれとのことなので、今まではiexでインタラクティブに試していたんですが、今回は.exファイルに関数を作ることにしました。

### モジュール、関数の作成
```
defmodule NGram do
  def bigram_word(input) do
    input
    |> String.split()
    |> Enum.chunk_every(2, 1)
    |> Enum.drop(-1)
  end

  def bigram_string(input) do
    input
    |> String.codepoints()
    |> Enum.filter(fn x -> x != " " end)
    |> Enum.chunk_every(2, 1)
    |> Enum.drop(-1)
  end
end
```

### NGram.bigram_word("I am an NLPer")の実行結果
```
# 単語区切りのbigram
[["I", "am"], ["am", "an"], ["an", "NLPer"]]
```

### NGram.bigram_string("I am an NLPer")の実行結果
```
# 文字区切りのbigram
[
  ["I", "a"],
  ["a", "m"],
  ["m", "a"],
  ["a", "n"],
  ["n", "N"],
  ["N", "L"],
  ["L", "P"],
  ["P", "e"],
  ["e", "r"]
]
```

### まとめ
vol.4までは、iexで問題を解いてきました。そのおかげで、ちゃんと関数を作る力がついているんだとvol.5の問題で実感することができました。
n-gramも思ったより時間はかかりましたが、頭の中で解はあったので、かなり楽に感じました。
LTspiceのAC解析結果をgnuplotで扱えるように整形する（その2）

## はじめに
LTspiceでAC解析を行い、結果をgnuplotでグラフ化するためのデータファイルを編集する続編です。
## LTspiceシミュレーション回路
とりあえず以下の回路で解析します。[以前の記事](https://qiita.com/nyamm1018/items/42de5f4fead6ff9b53d4)より1段増えました。
![AC2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3759077/1f1f7347-0a8f-d751-34af-b06883f77f8c.png)
## 結果の確認とテキストファイル出力
2か所のコンデンサについて両端電圧を見てみます。
下図のようになりました。
![AC2sim.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3759077/9d41f751-08fd-a6cd-34e8-03f0abc2d411.png)
結果をテキストファイルにエクスポートし、以前の記事で解説したとおり`sed`に通した上で[この記事](https://qiita.com/nyamm1018/items/142d1883de6c2994f653)の`gnuplot`スクリプトを実行します。
## グラフの確認
データ取得点が2個あるのでグラフも2本描かれます。
![out2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3759077/5ae26a12-864e-5740-267f-90814084038c.png)
なんか位相が不自然にジャンプしています。LTspiceの結果画面ではちゃんと -360° に達していましたが、テキストを吐き出したとき ±180° 以内にされてしまうようです。
それでは困るのでデータファイルを処理します。こういうときは`awk`の出番です。
```acedit.awk
BEGIN{
  # 位相ジャンプのしきい値設定
  th0=-165;
  th1=165;
}

{
  for(k=2;k<=NF;k++){
    # 位相がプラス180°へ急にジャンプしたら360°引きずり降ろす
    if(old[k]<th0 && $k>th1){
      offset[k]-=360;
    }
    # 位相がマイナス180°へ急にジャンプしたら360°吊り上げる
    if(old[k]>th1 && $k<th0){
      offset[k]+=360;
    }
    old[k]=$k;
  }
  printf("%.14e",$1); # 先頭の周波数列はそのまま表示
  for(k=2;k<=NF;k++){
    printf(" %.14e",$k+offset[k]); # オフセットを足して表示
  }
  printf("\n");
}
```
データがいくつあろうと`NF`一つで対応できるのがawkのいいところです。
ここで`offset[k]`はk列目のオフセット値を覚えておく配列です。
一つ前と現在のデータが 360° ジャンプしていれば LTspice の出力が変、ということで補正項を加減します。
ただちょうどピッタリ 180° （または-180°）にはならないので、判定のしきい値は 15° の余裕を見ています。
あまり大きくしすぎると正常な位相の変動まで誤判定する可能性が出てくるため注意します。
ゲインの列に対しては何もしなくていいのですが、まぁ判定に引っかかることもないので放置しています。
## 整形したデータを再度グラフ化
![out2-2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3759077/d85dfa51-d372-899c-f0d7-71170f9d62f2.png)
位相がちゃんと変動しました。
AmazonAPIをたたいてみる

## ちょっと思いついたアイデアでAmazonAPIをたたいてみるテストをしたい
たたくのに必要なブログが必要だったので・・・作っては見たが・・・

で以下URLがアソシエイトのURLを張るテスト。
https://amzn.to/49G8mDP
Next.jsでSCSSを使う

# 初めに
Next.jsでSCSSを使用する際の自分用忘備録です。追加事項があれば随時増やしていきたいです。

## 注意書き
初学者のため、誤りや拙い点があるかと思います。明らかな間違いがあるときにはコメントをいただけると嬉しいです。

## Sassの導入
```
### yarn の場合
$ yarn add sass --dev

### npm の場合
$ npm install sass --save-dev
```

上記のコマンドをNext.jsプロジェクトで実行すると、Sassのインストールが完了します。

適当なコンポーネントを追加し、scssファイルが使用できていることを確認してください。

![スクリーンショット 2024-04-16 17.24.29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2918094/d675ade9-afb3-023d-b21d-2110dab702f1.png)

```
// src/app/components/layouts/header/Header.tsx
import React from 'react'
import styles from './Header.module.scss';

const Header = () => {
  return (
    <>
    <header className={styles.header}>
      <h1 className={styles.header__title}>Homete!</h1>
    </header>
    </>
  )
}

export default Header
```

```
.header {
    text-align: center;
    padding: 20px;
    background-color: $main-bg;

    .header__title {
        font-size: 28px;
        font-weight: bold;
        color: $white;
    }
}
```

無事ヘッダーにスタイリングが適用できました！
![スクリーンショット 2024-04-16 17.27.31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2918094/d392ac19-22d0-9916-6942-87993665ebf1.png)

## 変数の設定
SCSSで変数を使う際にも設定が必要です。（先ほどのコード例ではすでに変数を使用しています、すみません...）

```
// next.config.mjs
import path from 'path';
import { fileURLToPath } from 'url';

const __dirname = path.dirname(fileURLToPath(import.meta.url));

const nextConfig = {
  sassOptions: {
    // ファイルパスを記載
    prependData: `@import "${path.resolve(__dirname, 'src/styles/_variables.scss')}";`,
  },
};

export default nextConfig;

```

上記のコードを`next.config.mjs`に記載すると、無事変数がグローバルで使えるようになると思います。

ちなみに自分のstylesの位置はここです。

![スクリーンショット 2024-04-16 17.30.28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2918094/66b0c104-fd34-00bb-fb97-5284dc87b486.png)

## 最後に
いままでNext.jsやReactを使用する時にはTaileind CSSを使っていたのですが、Sassの方が馴染みがあって使いやすく感じます。

Sassの自動整形についての環境構築については以下の記事が参考になりました。

https://zenn.dev/necscat/articles/435db2f1dbbb29
ARK: Survival Ascended(ASA)のScorchedEarth（スコーチドアース）へのMAP切り替え方法

# 1.はじめに
この記事はConohaなどで立てた非公式サーバーのARK: Survival Ascended(以下ASA)のマップをScorchedEarth（スコーチドアース）へ切り替える方法になります。

Conohaでのサーバーの立て方は以下の記事を参照ください。

:::note info
[ConohaでのASAサーバーの立て方（リンク）](https://qiita.com/HAKOTEN/items/0e7d7f9487fc82d0ee55)
:::

# 2.サーバーのアップデートを実施
TeraTermでサーバーに接続して以下コマンドを実行していきます。

```:サーバーの停止
sudo systemctl stop ark-island
```
```:サーバーのアップデート
sudo -u steam /usr/games/steamcmd +login anonymous +app_update 2430930 validate +quit
```

サーバーのアップデート完了画面
![スクリーンショット 2024-04-16 160340.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3716588/4bbc59d2-31ab-7c8f-8c74-25b4916ed586.png)


# 3.起動用のサービスを作成
#### ①ScorchedEarthの起動用のサービスを作成します。

```:サービスのディレクトリに移動
cd /etc/systemd/system
```
```:サービスを複製
cp ark-island.service ark-Scorched.service
```
※今回は分かりやすいようにMapの名前で付けていますが、なんでも大丈夫です。



#### ②viコマンド or WinSCPで作成したサービスを編集します。

[修正箇所]
ExecStart=/home/steam/.steam/compatibilitytools.d/GE-Proton8-21/proton run ArkAscendedServer.exe **TheIsland_WP**?listen~~~~
※大文字部分がMapIDになるのでこちらを以下のMapIDに変更します

```:ScorchedEarthのMapID
ScorchedEarth_WP
```
※viコマンドは「i」で編集モード、「Escキー」を押してから「:wq」でファイル保存できます

編集後に保存し、これでScorchedEarth用のサービスができました。

:::note info
Islandで遊びたい場合は、こちらのサービスを停止して元のサービスを起動することで遊ぶことができます
:::


# 4.起動サービスの変更

サービスを作っただけでは、再起動すると元のIslandが立ち上がってしまうので、自動起動の設定を変更します。

```:自動起動サービスの確認
systemctl list-unit-files -t service
```
![スクリーンショット 2024-04-16 165426.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3716588/7c2bc243-389f-1123-54dd-37d852b04299.png)

enabled = 起動
disabled = 起動しない

```:IsLandサービスの自動起動無効化
systemctl disable ark-island.service
```

```:ScorchedEarthサービスの自動起動有効化
systemctl enable ark-Scorched.service
```

最終的に以下のようになっていればOKです
![スクリーンショット 2024-04-16 170227.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3716588/0a2367b6-5f8a-28d5-03b4-c94437137dc1.png)

最後に以下のコマンドでサーバーのサービス起動設定を更新できます。
```:デーモンのリロード
sudo systemctl daemon-reload
```


# 5.動作確認

手動でサーバーを起動して動作確認を行ってください。

```:サーバーを起動する
sudo systemctl start ark-Scorched
```

```:サーバーを再起動する
sudo systemctl restart ark-Scorched
```

```:サーバーを停止する
sudo systemctl stop ark-Scorched
```

# 6.免責事項
:::note alert
本記事からのリンクなどで移動したサイトで提供される情報、サービス等について一切の責任を負いません。

また本記事のコンテンツ・情報について、できる限り正確な情報を提供するように努めておりますが、正確性や安全性を保証するものではありません。情報が古くなっていることもございます。

本記事に掲載された内容によって生じた損害等の一切の責任を負いかねますのでご了承ください。
:::
DjangoテンプレートでJSに値を渡す

個人的なメモ

```python:view.py
def index(request):
  context = {
    'data': 'a',
    'data_array': ['b', 'c', 'd'],
    'data_dict': {'key': 'e'}
  }
  return render(request, 'index.html', context)
```

```django:index.html
<script>
  const data = "{{ data }}";
  const dataAry = {{ data_array|safe }};
  const dataObj = {{ data_dict|safe }};

  console.log('data:', data);
  console.log('dataAry:', dataAry);
  console.log('dataObj:', dataObj);
</script>
```

コンソール
> data: a
> dataAry: (3) ['b', 'c', 'd']
> dataObj: {key: 'e'}
8-WSON変換

CATVのルーターについていたSPI Flashをヒートガンではがしてみました。

このFlashのパッケージは8-WSONで下がベタグランドでそのまま変換基板に貼り付けると、ショートしてしまいます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/104066/245b0bd5-329f-4ab9-cf8d-05c75b3c65ff.png)

前にやったのはボンディングみたいにしたのですが、これだとピンの順番が変わってしまい再利用に難があります。

![写真（2023-09-28 8.02）.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/104066/9831dd3d-731b-0214-cdbd-d798050435db.jpeg)

ちょっと考えて、トランジスターの絶縁に使う雲母板を適当な大きさに切ってSOP変換基板に挟み込みました。

![写真（2024-04-16 16.35） #2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/104066/1c1f6b82-1567-e0e8-b76a-ecd36d4d161d.jpeg)

テスターの導通でショートがないか確認して、Macのflashromで読んでみます。

![写真（2024-04-16 16.35）.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/104066/541c2849-b9d7-1167-fc52-b91126b2a6dd.jpeg)

```
$ ../flashrom -p ch341a_spi
flashrom v1.2 on Darwin 15.6.0 (x86_64)
flashrom is free software, get the source code at https://flashrom.org

Calibrating delay loop... OK.
Found Macronix flash chip "MX25L12805D" (16384 kB, SPI) on ch341a_spi.
Found Macronix flash chip "MX25L12835F/MX25L12845E/MX25L12865E" (16384 kB, SPI) on ch341a_spi.
Multiple flash chip definitions match the detected chip(s): "MX25L12805D", "MX25L12835F/MX25L12845E/MX25L12865E"
Please specify which chip definition to use with the -c <chipname> option.
```

いけたみたいです。
マウスポインタ移動ＶＢＡ

```
Option Explicit

Declare PtrSafe Function SetCursorPos Lib "user32" (ByVal x As LongPtr, ByVal y As LongPtr) As Long


Sub MovePointer()

Dim i As Long, j As Long
Dim x As Double, y As Double
Dim rng As Range

Application.Cursor = xlNorthwestArrow

For i = 3 To 10 Step 2
    For j = 1 To 40 Step 2
        Set rng = Cells(j, i)
        x = ActiveWindow.PointsToScreenPixelsX(rng.Left * 96 / 72) + rng.Width / 2
        y = ActiveWindow.PointsToScreenPixelsY(rng.Top * 96 / 72) + rng.Height / 2

        Debug.Print rng.Address(0, 0) & "：x=" & x & ",y=" & y

        SetCursorPos x, y
        Application.Wait Now() + TimeValue("00:00:01")
        Set rng = Nothing
    Next j
Next i

Application.Cursor = xlDefault

End Sub
```
LIFFスターターアプリを試したときのエラーについて

### はじめに 
LIFF(LINE内ブラウザで動くWebアプリ)のスターターアプリを試した時にエラーが出たので、それについての備忘録です


### 実行環境
- OS: macOS 13.6.6
- Node.js: 18.6.1
- yarn: 1.22.22

### エラー内容
```
Error: error:0308010C:digital envelope routines::unsupported …
```
下記公式を参考に進めていくと`yarn dev`で上記のエラーが発生しました

https://developers.line.biz/ja/docs/liff/trying-liff-app/

### 対応
検索してみたところ、Node.jsがバージョン的に対応していなさそうなことがわかりました
そのため、公式に書いてある動作環境を参考に、バージョン管理ツール「n」を使ってNodeのバージョンを16.13.1へ変更してみることにしました

- Node.js: 18.6.1　→ 16.13.1

変更後に`yarn dev`を試してみると無事に実行することができました

### 参考
https://qiita.com/yosyosyoyoyo/items/5c8029266f3a1726fca7
[初心者必見]ブログのススメ

# アウトプットをするのだ
プログラム初心者たちよ、学んだことを自分だけで完結しないでキチンとアウトプットするのだ。

二番煎、三番煎だろうが関係ない、
同じような記事が何個もあるだろうがそんなの関係ない、
キミなりの文章・画像でまとめたものは世界に1つだけだ。

# なんて壮大な出だしで書いてみたけど。。。
要はね、初心者が躓きそうなこと・躓いたことを「初心者」のキミが書くことが大事なの。

だってベテランはそんなことに悩まない・悩んだとしてもある程度の調べ方を知ってるので、
そんなことをいちいちアウトプットせずに自己完結してしまうんだもの。
※そうしてまた忘れて似たような検索をしてしまうの。。。

# なんで書いたほうがいいのか？
エラーが出て動かない・どう設定していいかわからない・そもそもどう作っていいのかわからない。。。
大体初心者は調べ方がわからないので、エラーメッセージをGoogleで検索しても解決策がでているであろうStackOverFlowとかの英語記事は基本読まない。
そもそもエラーメッセージすら読まないトンデモナイ人も中にはいるかも知れない。
そんな時に役立つのが、キミが書いた日本語でバカ丁寧にまとめたブログなどのアウトプットというわけさ。

キミと同じレベルの人がキミの書いた記事をありがたがって読むなんて、承認欲求満たされるでしょ？

# そもそも。。。
ある程度知識がついてしまうと
__「こんなくだらない事をアウトプットしていいのだろうか？」__ とか
__「こんなレベルのこと書いてバカにされないだろうか？」__ とか
__「コメントとかで厳しい指摘が来て心が折れちゃうんじゃないか？」__ とか
自分に勝手にブレーキを掛けてしまい中々アウトプットする気持ちが湧いてこなくなるため、
技術者バブちゃんの今のうちに、どんな些細なことでもすぐにアウトプットする癖を付けるのがいいかなと。
※コメントで厳しく指摘してくる「俺すげぇ　なイタイ奴」なんか気にしなくていいよ
※優しく指摘してくれる人の言うことをキチンと噛み砕いて理解できればいいんよ

そうして半年後とか1年後に読み返してみて __「うわ～～～内容がショボすぎる!!」__ と赤面すればいいと思うよ(ﾆｯｺﾘ
→赤面するぐらいになれば、それなりに成長した証でもあるので
laravel breezeでマルチログインのタスク管理ツールを作る⓪_laravel Sailでdocker立上げ ※Windows版

# 次の章

[laravel breezeでマルチログインのタスク管理ツールを作る①_下準備（seederでダミーデータ作成まで）](https://qiita.com/forever---searcher/items/34ef1827314c1756f9d0)

# 表題の手順だけ下記に記載
- windows上でlinuxの仮想環境構築
    - wsl2を導入（これは記事すぐ出てくるので、検索ください。注意：wsl「2」じゃなきゃダメ）
    - ubuntuをmicrosoftアプリストアから導入
- composerでやったほうがいいよ。これも検索ください。
- コマンドプロンプトで`wsl`コマンド、wslに入る
- laravelプロジェクト作成～docker立上げまで下記コマンド
    - `composer create-project --prefer-dist laravel/laravel プロジェクト名`
    - `composer require laravel/sail --dev`
    - `composer require laravel/breeze --dev`
    - `./vendor/bin/sail artisan breeze:install`
    - `./vendor/bin/sail up`

あとは`http://localhost/`にアクセスして、右上にloginなどbreezeが正しく動いていることを確認して終了。
SPSS ModelerとCADSで使えるスクリプト

SPSS ModelerとCADSで使えるスクリプトは様々にありますのでまとめました。Qiitaのタグのリンクも付けました。

# SPSS Modeler
|スクリプト種類|言語|目的|備考|
|:----|:----|:----|:----|
|Modelerスクリプト|- [Python 2.x](https://qiita.com/tags/modelerscript) <BR>- 従来型独自言語|Modeler自体の操作に使います。ノードを作成したり、実行したりすることができます。GUIの操作を自動実行することが主な目的です。|PythonはJava実装のJythonであり、Version 2.xです|
|拡張ノード|-[Python](https://qiita.com/tags/%e3%83%8d%e3%82%a4%e3%83%86%e3%82%a3%e3%83%96python%e6%8b%a1%e5%bc%b5%e3%83%8e%e3%83%bc%e3%83%89)<BR>-[R](https://qiita.com/tags/r%e6%8b%a1%e5%bc%b5%e3%83%8e%e3%83%bc%e3%83%89)<BR>-[Python for Spark](https://qiita.com/tags/pyspark%e6%8b%a1%e5%bc%b5%e3%83%8e%e3%83%bc%e3%83%89)|Modelerの中でのデータを加工したり、そのデータからモデルを作ったりすることができます。[カスタムノード](https://qiita.com/tags/%e3%82%ab%e3%82%b9%e3%82%bf%e3%83%a0%e3%83%8e%e3%83%bc%e3%83%89)にしてノードの部品にすることも可能です|ネイティブPythonはModeler 18.5からの機能です|
|[外部ローダースクリプト](https://qiita.com/tags/%e5%a4%96%e9%83%a8%e3%83%ad%e3%83%bc%e3%83%80%e3%83%bc)|Python|Db2などのRDBにロードするときに利用できます。| |

# CADS
|スクリプト種類|言語|目的|備考|
|:----|:----|:----|:----|
|[REST API](https://qiita.com/tags/cads_rest-api)|Python|CADSジョブの実行やリアルタイムスコアリングの実行が可能です| |
|[Essentials for Python](https://qiita.com/tags/pesimpl)|Python|CADS内のオブジェクトなどの操作が可能です。Deployment ManagerのGUI操作の一部を自動実行することが主な目的です|Zeepパッケージが前提です |
コトリンプログラミング言語の背景

![graphic-designer-1288477_1280.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3771407/2a918006-b026-84f7-8c12-515263559ca6.jpeg)

近年、Kotlinは、Androidアプリケーション開発者の間で人気を集めています。このプログラミング言語は、JetBrainsによって開発され、2011年に初めてリリースされました。 Kotlinは、Java Virtual Machine（JVM）上で実行されることが意図されており、Javaとの互換性がありますが、より現代的で簡潔な文法と機能を提供します。

Kotlinの誕生

Kotlinの開発は、JetBrainsのプログラマーがJava開発の課題を克服しようと試みる中で生まれました。彼らは、Javaの一般的な問題、例えばヌルポインターや冗長なコードなどに対処するための新しい言語を開発することを決定しました。これが、Kotlinの最初のアイデアの端緒となりました。

Javaとの互換性

Kotlinは、Javaとのシームレスな互換性を備えています。これは、既存のJavaプロジェクトに簡単に統合できることを意味します。さらに、Kotlinは[Jepang](https://www.cargojepang.com/)のライブラリやフレームワークを直接利用できます。このため、開発者は既存のコードを再利用し、スムーズに移行することができます。

特徴と利点

Kotlinの特徴の1つは、その簡潔さと読みやすさです。これは、開発者がより少ないコードを書いて同じことを達成できることを意味します。また、Kotlinは、Javaにはないいくつかの新しい機能も提供しています。例えば、null安全性、拡張関数、データクラスなどがあります。

Android開発でのKotlinの採用

Googleが2017年にKotlinをAndroid開発の公式言語として採用した後、Kotlinの人気は急速に上昇しました。多くの開発者がKotlinを採用し、新しいAndroidアプリケーションの開発に使用しています。Kotlinの採用により、開発者はより迅速かつ効率的にアプリケーションを開発し、より堅牢で信頼性の高いコードを作成することができます。

まとめ

Kotlinは、Javaとの互換性を備えた現代的で柔軟なプログラミング言語です。Android開発者の間で急速に人気を集めており、多くの場合、Javaよりも優れた選択肢と見なされています。Kotlinの普及により、より使いやすく効率的なアプリケーションの開発が可能になり、開発者コミュニティ全体に利益をもたらしています。

Kotlinの利点と欠点

利点:

Javaとの互換性: KotlinはJavaとのシームレスな互換性を持ち、既存のJavaプロジェクトに簡単に統合できます。これにより、開発者は既存のJavaコードを再利用し、徐々にKotlinに移行することができます。

コードの簡潔さ: Kotlinは簡潔で読みやすい文法を提供し、開発者がより少ないコードを書いて同じことを達成できるようにします。これは開発速度を向上させ、コードの保守性を向上させます。

拡張関数: Kotlinの拡張関数は、既存のクラスに新しい機能を追加することができる強力な機能です。これにより、開発者は既存のライブラリやフレームワークを拡張し、コードの再利用性を向上させることができます。

null安全性: Kotlinはnull安全性を提供し、nullポインターエクセプションを防ぐことができます。これにより、開発者は安全なコードを書きやすくなり、ランタイムエラーのリスクを軽減することができます。

欠点:

学習曲線: Kotlinは新しい言語であり、開発者が新しい文法や機能を学ぶ必要があります。これにより、既存のJava開発者にとっては学習曲線があります。

リソースの制約: Kotlinの採用には追加のリソースが必要です。新しい言語を導入するには時間と労力がかかるため、一部の組織ではリソースの制約が問題になる場合があります。

エコシステムの成熟度: Kotlinのエコシステムは成熟していますが、Javaのそれに比べるとまだ若干不十分な部分があります。一部のサードパーティライブラリやツールはまだKotlinに完全に対応していない場合があります。

Javaとの比較: Kotlinは優れた言語ですが、完全にJavaを置き換えるものではありません。一部の開発者は引き続きJavaを好み、Kotlinに移行することに抵抗を感じるかもしれません。

これらの利点と欠点を考慮した上で、Kotlinは多くの場面で優れた選択肢であり、Java開発者にとっても有益な選択肢であることがわかります。

Kotlinの利点と利益

開発速度の向上: Kotlinの簡潔な文法と強力な機能により、開発者はより少ないコードを書いて同じことを達成できます。これにより、開発速度が向上し、プロジェクトの完成までの時間が短縮されます。

保守性の向上: Kotlinの明確で読みやすい文法は、コードの保守性を向上させます。これにより、開発者はコードベースをより簡単に理解し、変更や修正を行うことができます。

互換性の強化: KotlinはJavaとの高い互換性を持ち、既存のJavaプロジェクトに簡単に統合できます。これにより、開発者は既存のJavaコードを再利用し、徐々にKotlinに移行することができます。

安全性の向上: Kotlinのnull安全性機能は、ランタイムエラーを防ぎ、アプリケーションの安全性を向上させます。これにより、開発者はバグや予期せぬ問題を事前に検出し、修正することができます。

拡張性の強化: Kotlinの拡張関数は、既存のクラスに新しい機能を追加することができます。これにより、開発者は既存のライブラリやフレームワークを拡張し、コードの再利用性を向上させることができます。

開発者の満足度の向上: Kotlinの近代的で柔軟な機能は、開発者の生産性を向上させ、プロジェクトに対する満足度を高めます。これにより、組織は優秀な開発者を引き留め、新しい人材を獲得することができます。

これらの利点により、Kotlinは多くの組織や開発者にとって有益な選択肢となっています。それはより迅速かつ効率的な開発プロセスを可能にし、高品質なアプリケーションの開発を促進します。
見やすいスライド資料作成時のTipsメモ


## 見やすさや印象は書体選びでキマる
会議のような堅い場面、セミナーや新人研修のような少し砕けた雰囲気が許される場面。それぞれのTPOに合わせた資料作りの際に使用する書体についてまとめ。

* 会議の場に適さない　→ ポップ体
* 会議の場に相応しい　→　明朝体
* 温かみのある印象　→ 手書き風のフォント → フォントや書体選びを間違えると伝えたいことが伝わらなくなる
## 書体による読みやすさと与える印象
#### 読みやすさと与える印象によって4つの種類に分類される
* 読みやすい/格式高い　明朝体・セリフ体
* 読みやすい/親しみやすい　ゴシック体・サンセリフ体
* 読みづらい/格式高い　筆書体・行書体・スクリプト体
* 読みづらい/親しみやすい　デザイン書体

## ビジネス資料で使う資料は２種類だけ
日本語：明朝体/ゴシック体　可読性が高い（長文向き）
英語：セリフ体/サンセリフ体　視認性が高い（見出し向き）

丁寧な印象を与えたい
緊張感のある場で使いたい
→明朝体

あまり硬すぎない方がいい
何を使えばいいかわからないが無難なもの
→ゴシック体

## 読みやすさを決める3つの要素
* 可読性　長文も疲れにくく、ストレスなく読める　
* 視認性　太い文字で目立つ
* 判読性　文字・文を読み間違えない　※I（アイ）とl（小文字のエル）のような

## 読んでもらう文字　見てもらう文字
読んでもらう文字＝本文・長文　可読性（明朝体）
見てもらう文字＝タイトルや見出し　視認性（ゴシック体）

## 読んで貰う為の文字
* 線の細い明朝体（小塚明朝）
* 太いと文字が潰れて見える（游明朝体）
* 線の細いゴシック体も長文に向いている（游ゴシック体・ヒラギノ角ゴ）
### ★ポイントは線の細さ

## 見て貰う為の文字
ポスターやタイトルなど読み手意識を引いたり見てもらうことを意識しよう。
太い文字は視認性が高い。
細い文字は余白が空きすぎて見えてしまう。
→タイトルと本文でフォントを使い分けるとより理解しやすいデザインに

## スライド作成はゴシック体が無難
セミナー・プレゼン資料のスライドにおいては基本的にゴシック体（英字ならサンセリフ体でOK）
スライド資料はあくまで内容を端的に伝える為のものであることを忘れずに。
画面に移す場合、細い文字は掠れることもあるので注意。
### 豆知識
同じサイズでもフォントによって大きさが異なる
例：游ゴシック↔︎メイリオ

## 英語・日本語フォントの使い分け
### 日本語の場合
明朝体：
ヒラギノ明朝（Macのみ）・游明朝・小塚明朝
ゴシック体：
ヒラギノ角ゴシック・游ゴシック体・源ノ角ゴシック・メイリオ（Windowsのみ）

### 英語の場合
セリフ体：Times New Roman・Minion Pro
サンセリフ体：　Helvetica・Arial

## 英語フォントの基礎知識
英語のフォントは英語のフォントで！
明朝体も使用できるが、隙間が目立って不恰好に見える。（日本語非対応のPCでは崩れることも！）

数字も英語フォントで入力するとより見やすく洗練されたスライドに。
→こだわりすぎて時間をかけるのはNG。最終チェック時にフォントの変換を並行して行うのがおすすめ。

## 英語/日本語フォントの組み合わせ
MacにしかないフォントやWindowsにしかないフォントに注意。
* 見た目が合っているか
明朝体＋セリフ体
ゴシック体＋サンセリフ体

* 大きさが合っているか
メイリオ＋Arial
英語フォントは日本語より小さく見えるものが多い
英数字だけ文字サイズを大きくするのもおすすめ

* 太さが合っているか
游明朝体＋Times New Roman
どちらかが太いと可読性が損なわれる原因に！

## 約物記号と単位の使い方
約物とは　鉤括弧やコンマ、ピリオド、クエスチョン/エクスクラメーションマークなどのこと。

半角・全角の使い分け方によって見やすさに差が出るので注意
半角の約物は日本語より少し下がって見えてしまう。
<strong>英語には半角の約物を、日本語には全角の約物を。</strong>

## 約物を使う際の注意点
約物は必ずしも必要ではない。

（）を用いなくても良い例：
調査結果（約物が与える影響）
→ 調査結果｜約物が与える影響

行頭の鉤括弧は左端が揃わなくなるので注意。

全角の約物を並べてしまうと文字間に大きなスペースが空く。
→半角で並べることで全角1文字分の大きさに

闇雲に使用するのではなく、本当に必要か、違和感が生まれていないかを考えよう。

## 間違えやすい約物記号の数々
ハイフン　ー 単語の途中で改行・複合単語を作る
enダッシュ　-　期間や範囲
マイナス -　引き算や数式
emダッシュ -　丸括弧の代わり・省略（...）の代わり

・引用符
“”　ダブルクォート
‘’　シングルクォート

::: note

“　（Opening double quote）	「Option」＋「@」
”　（Closing double quote）	「Shift」＋「Option」＋「@」
option + [　で左シングルクォーテーション

option + shift + [　で右シングルクォーテーション
:::


""　ダブルプライム
''　プライム
→緯度軽度や数学記号で使われる

## 単位・数値の表記方法
数値と単位が同じ大きさに設定されていると、数字のインパクトが小さいように見えてしまう
→単位の文字サイズを小さく設定することで数値を認識しやすくする
※グラフや表においても同じ

単位や曜日・年月日の表記は単位を小さくして、伝えたい数字を強調する。


### 以上！
Ubuntu22.04（Linux）に Node.jsをインストール

以前までは以下の記事と同じ方法で行っていました。

[【2023年4月版】Ubuntu に node.js と npm を入れたい（バージョン管理も）](https://qiita.com/nouernet/items/d6ad4d5f4f08857644de)

具体的にはnodeをaptでインストールし、nというnode.js自体のバージョン管理ツールでnode.jsをバージョンアップし、nを削除という方法でした。



ただ、今回公式を見に行ってみると公式が丁寧になっていたので記事にしてみました。

https://nodejs.org/en/download/package-manager


概要としては、nvmというバージョン管理ツールをcurlにて直接インストールし、node.jsを指定のバージョンでインストールする、という手順のようです。

抜粋というか、ほぼコピペですが、コマンドは以下の通りです。

```shell:bash
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.7/install.sh | bash
```

つぎの画像のような答えが返ってきます。
![curl_answer.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285882/16a2f74c-6e32-13cb-40d2-fb76836d7692.png)


ここで、bashrcなどの環境の再読込をしないといけません。
が、簡単には"exit"等でターミナルを終了させ、新たに起動し直せば良いです。

ターミナルの再起動が済んだら、、、


```shell:bash
nvm install 20
```

これでインストールが完了です。

きちんとnodeが入ったか確認。

```shell:bash
node -v
```

npmも入っているか確認。

```shell:bash
npm -v
```

きちんと表示されれば成功です。
’#’ はシェル内で必ずコメント扱いする常識が覆されたニッチなケース 

課題はHP-UX(SJIS環境)で動作しているバッチをRed hat(UTF-8環境)に移行させるプロジェクトを担当している私のもとにシェルファイルが動かないとの苦情が来たので、動作させることであった。
shのソースを見ても不審な点は何もないどころか綺麗に書かれた、プロダクトクオリティのシェルで何一つ問題がなかった。これで動作しないとは何事かと、BIGGU ISSYU-を抱え込んだような気持になり、心に暗雲が立ち込めた。
動作させてみると「マルチバイト文字が正しくありません」というエラーが出て確かに動作しない。LANGはja_JP.utf8に設定してあるが、シェルスクリプトと環境変数指定用外部ファイルはSJISのままだ。しかし"#"+日本語のコメント部分をreadしてoptに入れるわけでもないだろうから問題がないと高をくくっていた。
結論：環境変数指定用外部ファイルをUTF-8に変換することで解決した。細かくは分析していないが恐らく日本語のコメント部分が「たとい行頭が"#"であろうとも障害になることはあり得る」という事だ。良い子のみんなには深堀りして原因を追究して頂きたい。
マイグレーションで失敗しまくる

```ruby 
Migrations are pending. To resolve this issue, run:
bin/rails db:migrate RAILS_ENV=development
You have 2 pending migrations:
20240321272525_create_rooms.rb
```

文字通りターミナルに
```ruby
rails db:migrate RAILS_ENV=development
```
と書いたが動かない
```ruby
rails db:migrate
```
をしてもだめ

いずれも
```ruby
Caused by:
ArgumentError: you can't define an already defined column 'user_id'. (ArgumentError)

              raise ArgumentError, "you can't define an already defined column '#{name}'."
```
とのこと。
もうわからない！！！！！！
kintoneの「アプリの条件通知」より「リマインダーの条件通知」が便利な場合。

あくまで備忘録的に書きます。技術というより、活用のためのTipsとして。

レコードの追加や編集で通知を欲しいときは「アプリの条件通知」を使うのがスタンダードだと思いますが、これで、どうやっても指定のユーザーに通知が送られなかったのと、どんな変更なのかが通知だけではわからないのが不便だったので、「リマインダーの条件通知」を使うことにしました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/573016/e0c47eee-1617-3c0a-8f6c-05eb27e958ab.png)

通常なら、これで串田幸江（わたし）宛に「レコード追加」や「レコード編集」の通知が届きますが、なんかうまくいかなかった。

通知がうまく届かない理由に「その操作を実行したのが自分だと、通知が届かない」などのケースがあって、それに該当するのではないかと思われます。
例えば、プラグインを介してレコード操作があったとき、そのプラグインもkintoneへのログインを必要とするので、ログインユーザーが自分などで設定してしまうと、通知が届かないことになります。
ちなみに、この時使っていたプラグインは「じぶんページ」と「LITONE」です。

このような制約条件があるので、もっと意図した通知が欲しいときは、その内容を指定できる「レコードの条件通知」や「リマインダーの条件通知」を使う方がいいだろうと思います。

レコードが追加された時の通知ですが、リマインダーの条件通知でこんな風に設定しました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/573016/2a9dba69-012a-e027-ce24-7c87ae38fe36.png)

レコードの作成日時から0日と1時間後に通知を送るよう、リマインド設定しました。
これに通知先ユーザーを設定すれば、自分のユーザーで追加したレコードでも、確実に通知が届くようになります。

プラグインを利用したレコードの更新がある場合、通知との組み合わせで考慮しなければいけないケースもあると思うので、その場合の参考になればと思います。
平方分割

https://paiza.jp/works/mondai/query_primer/query_primer__square_division

コメントで教えてもらった方法を元に
下記のようにしました。
ただ、合わなかったけど。

```py

K = int(input())
A = [int(input()) for _ in range(10000)]
ans = []
for i in range(0, 10000, 100):
    ans.append(max(A[i:i+100]))

for _ in range(K):
    minX,maxY = map(int,input().split())
    minX = int(minX ** 0.5)
    maxY = int(maxY ** 0.5)
    print(max(ans[minX:maxY]))

```
結局わからなかったのでタイムオーバーしたのでギブアップ。
どうやら後半考え方が間違っていたようで。。。
いや、どうやって調べようと思ってたが、よく考えたら100（N0.5乗）で割った商がAnsの該当する配列の要素の番目になるのか。

```py
N,K = 10000, int(input())
root = int(N ** 0.5)
A = [int(input()) for _ in range(N)]
range_max = []
for i in range(0, 10000, 100):
    range_max.append(max(A[i:i+100]))
    
for _ in range(K):
    #左端の数値と右端の数値は出力から−１を引く
    left,right = map(lambda x:int(x) -1,input().split())
    #とりあえず配列Aのleft番目の要素を取得する
    ans = A[left]
    now = left
    #そのleft番目からright番目になるまで、１ずつループ
    while now <= right:
        # たとえば100ごとというのはスタートから100までがrightの中に入っていればその中の配列で最大値を出す
        if now % root == 0 and now + root - 1 <= right:
            ans = max(ans, range_max[now // root])
            now += root
        else:
            ans = max(ans, A[now])
            now += 1

    print (ans)


```
【RHEL8.9】 ifcfgを使ったネットワーク設定

場所
```shell:
/etc/sysconfig/network-scripts/

ifcfg-<device名>
```

```
# cat /etc/sysconfig/network-scripts/ifcfg-ens192
TYPE=Ethernet
PROXY_METHOD=none
BROWSER_ONLY=no
BOOTPROTO=static
DEFROUTE=yes
IPV4_FAILURE_FATAL=no
IPV6INIT=no
IPV6_AUTOCONF=no
IPV6_DEFROUTE=no
IPV6_FAILURE_FATAL=no
IPV6_ADDR_GEN_MODE=eui64
IPADDR=192.168.1.101
NETMASK=255.255.255.0
GATEWAY=192.168.1.254
PEERDNS=no
DNS1=8.8.8.8
DNS2=1.1.1.1
NAME=ens192
UUID=
DEVICE=ens192
ONBOOT=yes
```
[GitLab] もうブランチ名で悩まない! ブランチ名に悩む時間を削減できるChrome拡張を作りました


## TL;DR

ブランチ名をAIでワンクリックで生成できるChrome拡張「GitLab Branch Name Generator
」作りました
https://chrome.google.com/webstore/detail/lbfkhiichdmakpghanpjjbicohannpcf?authuser=0&hl=ja

## ブランチ名悩みませんか?
Issue から、MRとブランチ名作るとき、ブランチ名どうしようか悩みませんか?

* これって英語でなんて言うっけ
* この表現って合ってるのかな
* スペルミス無いかな

などなど
私は悩むんですが皆さんどうなんでしょう

## そもそもブランチ名の命名規約はあるのか
調べてみると、ちゃんとした命名規約は無かったが、ケバブケースにしたほうが良さそう。

## AI使えばいいじゃない

IssueのTitleをAIに渡して、良い感じのブランチ名作ってもらえばいいじゃないか
でもChatGPTにいちいちコピペして、ブランチ名に使える文字をケバブケースで作ってとか書くのも面倒

## Chrome拡張にしちゃおう

GitLabからMR/ブランチを作るときはブラウザから操作するので、Chrome拡張にしちゃえば使うのが楽そう  

IssueのTitleと直接紐づかないブランチもあるかもしれないので、手入力で文字列を入れてそこからブランチ名も作れると更に良さそう

## CSUIでGitLabにUIを追加

`MutationObserver` を使ってDOMの監視を行い、対象のDOMが表示されたらCSUIで追加したUIを表示するようにした。

![スクリーンショット 2024-04-13 14.24.16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3741957/6b393611-c0c7-f319-a925-51dc3fb621c5.png)

場合によって`feature/`だったり、`release/`だったり分けたいと思うので、そこを選べるSelectを置いた。
この辺はオプション画面で設定できるようにした。
Issueのタイトルから自動生成するボタンと、入力したテキストから生成するボタンを設置。
ボタンをクリックすると、

![スクリーンショット 2024-04-13 14.24.32.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3741957/3eaf1f9c-a395-b2dc-7730-b4e1d756f1cd.png)

良い感じの候補をつくってくれました。
AIで10個まで提案してもらうようにしました。
AIからのレスポンスは一定の形式で受け取りたいので、OpenAI APIの `response_format: { "type": "json_object" }` を使用してJSON形式で、指定したフォーマットで受け取れるようにしました。
Claude v3とかには無いので、JSON形式で受け取りたいときは OpenAI API重宝してます。

![スクリーンショット 2024-04-13 14.24.39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3741957/57f6903c-7774-91e1-5997-4f699199b45f.png)

リストから選ぶと、ブランチ名の使用可否がチェックされます。
この辺は、inputに値をセットした後に、
```typescript
const inputElement = document.querySelector('#new-branch-name') as HTMLInputElement;
if (inputElement) {
  inputElement.value = branchName;
  const event = new Event('keyup', { bubbles: true });
  inputElement.dispatchEvent(event);
}
```
として `keyup` イベントを発火させています。

## オプション画面

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3741957/e993b04b-2b52-0c0e-32cc-a26351986025.png)

OpenAI API のAPI KeyやModel、プロンプトの設定に加え、`feature/`だったり、`release/`といったブランチ名のプレフィックスを定義できるようにした。
この辺は会社やチームによって文化があると思うので、並び等も設定したいかなと思い、並び替えのUIも考えたが改行区切りで書いてもらえればいいかという考えに至って簡略化。

## つくってみて & 使ってみて

仕事中のふとした悩みから生まれた拡張ですが、多機能ではない拡張ですが、なかなかいいものが作れたと思います。
3~4時間で作れましたが、ChatGPT&Copilotによる恩恵がかなりデカい。すっかり依存してます・・・。

使ってみるとワンクリックで生成できるのがとにかく楽!
ブランチ名を作る数分だけかもしれないけど、個人的には結構楽になった!
使ってみてください