OmniAICreator/Qiita-1.07M huggingface dataset:
CSSでcalc()を使おう．

## calc()ってなに？

calc()は、CSSで計算を行うための関数です。この関数を使用することで、要素のサイズや位置を柔軟に調整することができます。calc()は四則演算やパーセンテージなどを組み合わせて使うことができ、動的なレイアウトやデザインを実現するのに便利です。

## どんな時によく使われる？

calc()は、特に要素のサイズや位置を動的に調整する必要がある場合によく使われます。例えば、レスポンシブデザインでは、デバイスの幅や高さに応じて要素のサイズを調整する必要があります。このような場面で、calc()を使用することで柔軟性の高いレイアウトを実現することができます。

```calc.css
body{
    height: calc(100vh - 16px);
}
```
``上記のコードはbodyタグの高さをcalcを使って「ディスプレイの高さ100%から16px分引いたもの」となります``


## 使う際の注意点

　calc()を使う際に注意すべき点がいくつかあります。まず、ブラウザの互換性を考慮する必要があります。一部の古いブラウザではcalc()がサポートされていない場合がありますので、その点を考慮してください。
 
※今現在推奨のブラウザを使用する分には問題ない．

　さらに、計算式の中にスペースを含める際には注意が必要です。適切な位置でスペースを入れる必要があります。Javaなどに慣れていた自分はココで一度詰まった．
 ### 正しい例
 ```calc.css
body{
    height: calc(100% - 16px);
}
```
 ### 悪い例
 ```calc.css
body{
    height: calc(100%-16px);
}
```
``
四則演算記号の左右に空白がないとダメだよ！！！！
``

これらの注意点を踏まえつつ、calc()を使うことで柔軟で動的なレイアウトを実現することができます。
Pythonの検索処理 search match

# はじめに
Pythonの検索処理、```re.search```と```re.match```についてまとめる。
```re.search```はヒットした最初の文字列を抽出し、```re.match```は先頭からヒットした文字列を抽出する違いがある。それぞれヒットした場合、```re.Match```オブジェクトを返す。

# 目次
+ [re.search：全体ヒット](#research)
+ [re.match：先頭ヒット](#rematch) 
+ [re.Matchオブジェクト](#rematchオブジェクト)

## re.search
ヒットした最初の文字列を抽出する。
構文|意味
---|---
m = re.search(p,s)|m:検索結果re.Matchオブジェクト<br>p:パターン文字列<br>r:検索文字列


```python:search_sample.py
example='ABCDEF_abcdZ0123456789_Z0123456789_xyz_Z0123456789'

m = re.search(r'a.*Z',example)
#aから始まり、Zで終わる文字列の検索
print(m)
# <re.Match object; span=(7, 40), match='abcdZ0123456789_Z0123456789_xyz_Z'>

m = re.search(r'a.*?Z',example)
#aから始まり、最短のZで終わる文字列の検索
print(m)
# <re.Match object; span=(7, 12), match='abcdZ'>
```
同じパターンが含まれる場合、最短でヒットさせたい場合は```?```を使う。

[戻る](#目次)


## re.match
先頭からヒットした文字列を抽出する。
構文|意味
---|---
m = re.match(p,s)|m:検索結果re.Matchオブジェクト<br>p:パターン文字列<br>r:検索文字列


```python:match_sample.py
example='ABCDEF_abcdZ0123456789_Z0123456789_xyz_Z0123456789'

m = re.match(r'a.*Z',example)
#aから始まり、Zで終わる文字列の検索
print(m)
# None　先頭からヒットしないのでNone

example='abcdZ0123456789_Z0123456789_xyz_Z0123456789'

m = re.match(r'a.*Z',example)
#aから始まり、Zで終わる文字列の検索
print(m)
# <re.Match object; span=(0, 33), match='abcdZ0123456789_Z0123456789_xyz_Z'>
```
[戻る](#目次)

## re.Matchオブジェクト
検索結果はre.Matchオブジェクトに格納される。オブジェクトのパラメータは下記の通り。
```python:rematch_sample.py
example='abcdefg_01234567890@xxx.yyy.com'

m = re.search(r'(a.*)(@)(.*)',example)

print(m)
# <re.Match object; span=(0, 31), match='abcdefg_01234567890@xxx.yyy.com'>

print(f'{m.start()=}')  # m.start()=0
print(f'{m.end()=}')    # m.end()=31
print(f'{m.span()=}')   # m.span()=(0, 31)
print(f'{m.groups()=}') # m.groups()=('abcdefg_01234567890', '@', 'xxx.yyy.com')
print(f'{m.group(0)=}') # m.group(0)='abcdefg_01234567890@xxx.yyy.com'
print(f'{m.group(1)=}') # m.group(1)='abcdefg_01234567890'
print(f'{m.group(2)=}') # m.group(2)='@'
print(f'{m.group(3)=}') # m.group(3)='xxx.yyy.com'

for i in m.groups():
	print(i)
# abcdefg_01234567890
# @
# xxx.yyy.com
```

re.Matchの詳細は下記参照。

https://docs.python.org/ja/3/library/re.html#re.Match


[戻る](#目次)
Github複数アカウントでssh接続設定を切り替える

いつも設定やり方を忘れてしまうため自分用に手順書作成しました。
[こちら](https://qiita.com/yampy/items/24638156abd383e08758)の記事を参考にしています。
Business, Privateで使い分ける際に使用してます。

# 1. ssh key作成
- ローカル環境で作成する
- オプション整理
    - -t: 作成する鍵の暗号化形式。`rsa`(default), `dsa`, `ecdsa`, `ed25519`から指定
    - -C: コメントを指定。「ユーザ名@ホスト名（default）」以外にするとき使用
    - -f: ファイル名(厳密には保存先)
```bash
cd ~/.ssh
ssh-keygen -t rsa -C {Github mail address} -f {key-name}
# 実行後以下が聞かれる。基本的にはEnter押すだけでOK
# Enter passphrase (empty for no passphrase):
# Enter same passphrase again:
```
以下のような画面が表示されれば問題OK
![Screenshot 2024-04-06 at 16.57.48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2699922/8816eb1b-be38-addb-5cbc-ff2e5c03c301.png)

# 2. ~/.ssh/configの設定
- `~/.ssh/config`の設定を書き換える
- 切り替えが必要なアカウントをHostに登録
- `IdentityFile`にそれぞれのアカウントで使用する秘密鍵のパスを指定(.pubがついてない方です)
```~./ssh/config
Host github.com.main
  HostName github.com
  User git
  Port 22
  IdentityFile ~/.ssh/{main's key-name}
  TCPKeepAlive yes
  IdentitiesOnly yes

Host github.com.{sub account}
  HostName github.com
  User git
  Port 22
  IdentityFile ~/.ssh/{sub account key-name created above}
  TCPKeepAlive yes
  IdentitiesOnly yes
```
# 3. Githubに公開鍵(.pubがついてる方)を登録する
- [こちら](https://qiita.com/shizuma/items/2b2f873a0034839e47ce)の記事を参照のこと
- クリップボードへのコピーは以下を利用(Mac用)
- 下記はMac用。windowsの場合は`clip < ~/.ssh/{key-name created above}.pub`

```bash
pbcopy < ~/.ssh/{key-name created above}.pub
```

# 4. ssh接続確認
- `~/.ssh/config`で登録したHostにてssh接続確認
```bash
ssh -T git@github.com.{sub account set above}
# 以下が表示されれば成功
# Hi {sub account set above}! You've successfully authenticated, but GitHub does not provide shell access.
```
# 5. リポジトリをClone
- リポジトリをcloneする
- ssh設定ファイルに登録したHostを指定

通常ssh接続でgit cloneする際は以下のようにします。
```bash
git clone git@github.com:github username/repository-name.git
```
これを先ほど設定したHostを使用して書き換え実行します。
```bash
git clone git@github.com.{sub account set above}:github username/repository-name.git
```
設定を確認し以下の表示が出ればOKです。
```bash
cd {your repository path}
git remote -v
# origin  git@github.com.{sub account set above}:github username/repository-name.git (fetch)
# origin  git@github.com.{sub account set above}:github username/repository-name.git (push)
```
remoteレポジトリのアドレスを追加する場合は以下のようにします。
上記設定確認ですでに存在する場合は不要です。
```bash
git remote add origin git@github.com.{sub account set above}:github username/repository-name.git
```
# 6. `gitconfig`の設定
- リポジトリごとユーザー名を切り替えるため`--local`のユーザー名を設定
- `{your repository path}/.git/config`を直接設定してもOK
```bash
cd {your repository path}
git config --local user.name {git user name}
git config --local user.email {git email}
```
それぞれ以下にて設定が確認できます。
```bash
cd {your repository path}
git config --local user.name
git config --local user.email
```
# 参考 - Special Thanks
- [[備忘] 複数Githubアカウントでssh接続設定(config)を使い分ける手順](https://qiita.com/yampy/items/24638156abd383e08758)
- [GitHubでssh接続する手順~公開鍵・秘密鍵の生成から~](https://qiita.com/shizuma/items/2b2f873a0034839e47ce)
BIのパフォーマンスを向上させよう

BIエンジニアをやっていたら必ず発生する問題といえば・・・
__「BIが遅い！！！」__

そうパフォーマンス問題です。

エンジニアでもパフォーマンス改善というのはかなり難しいですが、自分の経験を活かせそうなので記事にまとめてみます。

### おことわり
* 筆者の専門がMotionBoard・Dr.Sumのため、一部 MotionBoard・Dr.Sumに限定した記述 が含まれます。
* わかりやすいようイメージで記述する部分がありますが、すべてに対して正確な裏付けを取っているわけではありません。
正確な仕様を把握したい場合は、お使いのサービスの公式サポートにお問い合わせください。



# １．パフォーマンス低下の主な原因
パフォーマンス問題が発生しました。あなたはどれくらい原因箇所が浮かびますか？
思いついた原因の数とBIシステムの理解度はわりと比例すると思います。

考え方は色々あると思いますが、僕なりに分類分けしてみたのが以下です。
![01_パフォーマンス悪化原因箇所.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3343290/4eb2d85c-d385-dd0e-7dbf-f8e47e258bc3.png)

「遅いからBIツールを変えてみた」とか「サーバースペックを上げてみた」という対応をよく聞きますが、あくまでこれらは解決策の１つであるということがわかると思います。

# ２．パフォーマンス改善効果の確認
この記事では「どうパフォーマンスを改善するか」ということを書いていくのですが、その前に重要なことがあります。
それが

### 「パフォーマンス改善することでどの程度効果を得られるか？」

ということです。
厳密に効果測定する方法は、実際に改善するまでわからないのですが、１つの判断基準をご紹介しようと思います。
それが

### BIツールからデータベースのテーブルを参照する

という方法です。

## テーブル参照により速度の限界値を知る
パフォーマンス改善ではサーバースペックを上げるのは最後の手段であることがほとんどなので、「BIツールとデータベースの修正でどこまで速度を上げられるのか？」ということを早めに把握する必要があります。

そして、BIツールとデータベース修正で実現できる最速値が
「BIツールからデータベースのテーブルを参照する」
という方法になります。

![02_テーブル参照による限界速度.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3343290/cbc167c6-a940-81aa-7700-b6faf4828905.png)

Dr.Sumであればビューからテーブルへのデータエクスポート機能があります。
他のデータベースであればBIが参照しているビューのデータを全てSELECT INTOでテーブルに投入すればよいでしょう。
データ投入の時間はかかりますが、難しい作業ではありません。

## テーブル参照した結果からわかること
テーブル参照した場合とビューを参照した場合の違いは何でしょうか。
それは「結合」と「データベース関数」の処理がテーブルを参照した場合には無くなるということです。

つまりテーブルを参照した場合にデータを表示するまでの時間は
### BIでデータ表示するまでの時間　=　データベースの集計処理時間　＋　BIツールの処理時間
となります。


もしこの速度でも満足できないのであればデータベース側でチューニングできる要素がほぼありません。
そのような場合には
* サーバースペックを上げる
* BIの画面要件を落とす
* BIの長所である集計の柔軟性を失ってでもあらかじめ集計後テーブルを作成する

という解決策を検討する必要が出てきます。

チューニングし終わった後に結局上のような結末になるのは残念すぎるので、チューニング作業前には確認しておくと良いでしょう。

## ３．次回予告
ここまではパフォーマンスに関する基本と、実際に改善する前にやることについての話でした。
次回以降で具体的な原因箇所の調査方法や改善方法を書いていこうと思います。
laravelでの静的ページカンタン生成


```php5:route/web.php
//必ず最後にかくこと
Route::get('{code}', 'PageController@page');
```

```php5:contoller
<?php

namespace App\Http\Controllers;

use View;

class PageController extends Controller
{

 /**
   *静的ページ系
   *
   * @return \Illuminate\Http\Response
   */
    public function page($code)
    {
        if(View::exists('page.'.$code) ){Q
            return view('page.'.$code);  
        }
        abort(404);
        
    }
}
```


こうすることで以降`resources/views/page`に該当のview(ex:`/company`みたいなurlにしたいならcompany.blade.php)を入れるだけで
ページの追加が可能となる
web.phpの追加すら不要
Linux版VoiceVoxをネット越しで使う

# 前提
ネットワーク越しでVoiceVoxを使う方法としてsshでlocalhost上のVoiceVoxポートをポートフォアーディングします。
なのでVoiceVoxが動作しているLinuxPCでopenssh-serverが動作している必要があります。

# 準備
１．VoiceVoxがインストールされているLinux PCでVoiceVoxを起動しておきます。
２．ssh username@targetpc.local -L 50021:localhost:50021
　　でVoiceVoxが動作しているPCにsshで接続します。

# VoiceVoxクライアントを起動する。
VoiceVoxクライアントとしては次のようなコードを使います。
```python:vvnar
#!/usr/bin/python3
# このプログラムはVOICEVOXを利用したLinux版ナレータープログラムです。
# 使用するためにはVOICEVOXを起動しておく必要があります。

import PySimpleGUI as psg
import requests as req
import json
import pyaudio as pa

#　ここにナレーションを入れます。('よみ','表示')の順で入れます。
mess = [
(
'説明読み',
'説明表示'
),
(
'今回は以上です',
'今回は以上です'
),
(
'',
''
)
]
dispnum=0

# init window
wlay = [[psg.Multiline(default_text=mess[0][1],size=(60,4),border_width=2,font=("",17),key='MText',disabled=True)],
        [psg.Button('Next',key='Next'),psg.Button('Top',key='Top'),psg.Button('終了',key='END')]]
win = psg.Window('VOICEVOX ナレータ(波音リツ)',wlay,keep_on_top=True)

# sperk function
def speak(mess,no):
    qu_requrl='http://localhost:50021/audio_query'
    ad_requrl='http://localhost:50021/synthesis'
    reqprm = (('text',mess), ('speaker',no), )
    rsvdat = req.post(qu_requrl, params=reqprm)
    wavdat = req.post(ad_requrl,
        headers={"Content-Type": "application/json"},
        params = reqprm,
        data = json.dumps(rsvdat.json())
    )
    wav = wavdat.content
    dev = pa.PyAudio()
    dev_stream = dev.open(format=pa.paInt16,
        channels=1,rate=24000,output=True)
    dev_stream.write(wav)
    dev_stream.close()
    dev.terminate()

while True:
    ev,val = win.read()
    if ev in ('END',None):
        break
    if ev == 'Next':
        dispnum+=1
        if dispnum >= len(mess):
            dispnum=len(mess)-1
    if ev == 'Top':
        dispnum=0
    win['MText'].Update(mess[dispnum][1])
    evT,valT = win.read(timeout=10,timeout_key='T10')
    try:
        # キャラを変えるためには第２引数の数値を変更します。
        # 3 はずんだもん
        speak(mess[dispnum][0],9)
    except Exception as e:
        print(e)

win.close()

```
なお、このコードは自由に改修してお使い下さい。
ファイルに取ったらそのファイルに実行権をつけてくださいね。

クライアントプログラムは、準備の２で接続した端末はログイン状態を維持したままで別の端末でこのプログラムを実行します。
するとポートフォアディングされているのでローカルでVoiceVoxが動作しているかのように動作します。
意外とVoiceVoxはCPUを使用するので非力なマシンではしんどいところがあるのでこの方法を使うことで非力なマシンでもテキストの読み上げができます。
Ansible Trial

# はじめに
Ansibleで、PCをセットアップしています。その備忘録として記録します。

# 事前準備

ssh-copy-idを設定して、パスワードレスでログイン

# コマンドライン

```
ansible-playbook --user ubuntu -i ubuntu ubuntu-setup.yml
```

# yamlファイル詳細
ヘッダを先頭に、必要なタスクを1つのYamlファイルにまとめればOK。

## ヘッダ
先頭の"---"が重要。

```
---
- name: setup ubuntu
  hosts: all
  become: 'True'
  tasks:
```

## apt update/upgrade

```
    - name: apt update and upgrade
      apt:
        upgrade: yes
        update_cache: yes
        cache_valid_time: 86400
```

## グループ作成

```
    - name: create group "myid"
      ansible.builtin.group:
        name: myid
        state: present
        gid: 1001
```

## ユーザ登録・ホームディレクトリ作成

```
    - name: Create user "myid"
      ansible.builtin.user:
        name: myid
        password: "{{ 'myid' | password_hash('sha512', 'myid') }}"
        uid: 1001
        group: myid
        groups:
          - sudo
          - users
          - adm
          - cdrom
          - dip
          - plugdev
          - lxd
        state: "present"
        shell: "/bin/bash"
        skeleton: "/etc/skel"
        system: false
        create_home: true
        home: "/home/myid"
```

## SSH情報のコピー
ansibleを実行している環境から.ssh情報を、新しい環境へコピーする

```
    - name: Create /home/myid/.ssh
      ansible.builtin.file:
        path: /home/myid/.ssh
        state: directory
        owner: myid
        group: myid
        mode: "0700"
    - name: Copy .ssh/id* to hosts
      ansible.builtin.copy:
        src: "{{ item }}"
        dest: "/home/myid/.ssh/"
        owner: myid
        group: myid
        mode: 0600
      with_fileglob:
        - "/home/myid/.ssh/id*"
```

## Sudoersの設定変更
パスワードレスでsudoできるように設定

```
    - name: Check sudoers is already modified
      lineinfile:
        state: absent
        path: /etc/sudoers
        regexp: "ALL=NOPASSWD: ALL"
      check_mode: true
      changed_when: false
      register: check
    - name: Update sudoers
      lineinfile:
        dest: /etc/sudoers
        state: present
        insertafter: "See sudoers"
        line: "%sudo   ALL=NOPASSWD: ALL"
        validate: '/usr/sbin/visudo -cf %s'
      when: check.found == 0
```

今日はここまで。 つづくよてい
[neovim] vim-plugのPlugInstallでエラーメッセージ「E492:エディタのコマンドではありません」 が表示される問題

# 結論

解決しました。neovimの話です。
PlugInsallコマンド実行時に生成されるpluggedディレクトリを下記のように明示的に指定することで、エラーコードE492が表示されることなく無事プラグインをインストールできました。
```
call plug#begin('~/.config/nvim/plugged')
```

ちなみにエラーメッセージの詳しい内容はこちら。
```
E492: エディタのコマンドではありません: PlugInstall
```
# 背景
neovimのプラグイン管理ツールとして有名なvim-plugをインストールしました。
その後、適当なプラグインを見つけてインストールを試みたものの、PlugInsallの実行がなかなかうまくいかず困った、という話でした。
openSUSEの起動が遅い

# 概要
以前適当にセットアップした弊デスクPCのopenSUSE Tumbleweedの起動が遅くて地味に不便だったのでなおしました

## 原因
```console
# systemd-analyze critical-chain
```
上記のコマンドを入力すると、systemdの起動パフォーマンスについて問題があるところがハイライト表示されて出てきます。
- 初期化に最も時間がかかったクリティカルなユニットが特定できる（らしい）

すると、スクショ忘れましたがswap関係が赤く染まっていたので、おそらくswap関連に問題があることがわかりました

## 解決
swap関連で何かが起こっていることがわかったので、ググると次のページがヒットしました
[System Recovery Disk (SRD) を使用した Linux サーバーのリカバリ完了後にシステムの起動時間が長くなる](https://www.veritas.com/support/ja_JP/article.100051309)

- このページによると、単独パーティションとしてswapパーティションが存在する場合、この問題が発生することがあるとのことでした。
- わたしの環境も同じで、SSD上に単独パーティションとしてswapパーティションがあるのでこの問題が発生しているようでした。

```console
rlysleepynick@rlySUSEpc ~> lsblk
NAME        MAJ:MIN RM   SIZE RO TYPE MOUNTPOINTS
sda           8:0    0 111.8G  0 disk 
├─sda1        8:1    0    50M  0 part 
├─sda2        8:2    0 111.2G  0 part 
└─sda3        8:3    0   551M  0 part 
sdb           8:16   0 931.5G  0 disk 
└─sdb1        8:17   0 931.5G  0 part 
sdc           8:32   0 465.8G  0 disk 
└─sdc1        8:33   0 465.8G  0 part 
sdd           8:48   1  14.8G  0 disk 
├─sdd1        8:49   1  14.8G  0 part 
└─sdd2        8:50   1     1M  0 part 
sr0          11:0    1  1024M  0 rom  
nvme0n1     259:0    0 232.9G  0 disk 
├─nvme0n1p1 259:1    0   256M  0 part /boot/efi
├─nvme0n1p2 259:2    0    16G  0 part [SWAP] ←これ
├─nvme0n1p3 259:3    0    80G  0 part /home
└─nvme0n1p4 259:4    0 136.6G  0 part /var
                                      /usr/local
                                      /srv
                                      /root
                                      /opt
                                      /boot/grub2/x86_64-efi
                                      /boot/grub2/i386-pc
                                      /.snapshots
                                      /
```

### GRUB 設定ファイルの修正
先ほどのサイトを参考にして、```/etc/default/grub```を編集し、以下のように変更しました。

```config
(変更前) GRUB_CMDLINE_LINUX_DEFAULT="splash=silent resume=/dev/disk/by-uuid/6bde5af3-0aca-4258-94e6-a75a7f6a35d3 quiet security=apparmor mitigations=auto"
```

```config
(変更後) GRUB_CMDLINE_LINUX_DEFAULT="splash=silent resume=UUID=6bde5af3-0aca-4258-94e6-a75a7f6a35d3 quiet security=apparmor mitigations=auto"               
```

ちょうど、直接UUIDを渡すような挙動に変わったような感じです。
UUIDは ```lsblk -f```で出てきます。

変更したら、```grub2-mkconfig -o /boot/grub2/grub.cfg```をして再起動 & 完了です。
SQL関数power():PostgreSQL16の新機能で遊んでみよう#1


### SQL関数power()について
数値のべき乗を出す関数。

**power(a,b)**…aのb乗

### PostgreSQL15(16以前)とPostgreSQL16では何が違うのか

・べき乗の計算の精度が向上しました。

**PostgreSQL15**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3533750/0c1ab500-d63b-3e4a-c189-a7d565533e8a.png)

**PostgreSQL16**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3533750/f116ec74-88af-dd2a-d35b-6ad5450b9ed0.png)

より正確な計算ができるようになりました！
Minecraft Kotlinプラグイン開発 番外編 プラグインフォルダへ直接ビルドする方法

## 初めに
今回は番外編第2回で、プラグインをサーバーの再起動なしで更新する方法を紹介します。

プラグイン開発でビルドの度に起動、停止とファイルの移動を繰り返してると
時間がかかってしまうのでこれから紹介する方法を使うとかなり時短になると思います。

**前** → [中級編 Part.4 コマンドの実行](https://qiita.com/tooooowa/items/7eeee6c2c1b8f5d29b8c)
**次** →

**目次** →  [目次と今後の展望](https://qiita.com/tooooowa/items/7809ec65dee757570250)

## アーティファクトの追加
IntelliJ IDEA を起動し、上のメニューから三本線をクリックします。
すると下の画像のようにファイルや編集などが画面上部に出てきます。

![アーティファクトのビルド.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3682428/4fbb6fca-1b44-7a5f-3ee4-68df4e9295fb.png)

その後画像のガイドのように
`ファイル(F)` → `プロジェクト構造` の順番にクリックしてください。

---

その後開いたGUIで `アーティファクト` をクリックしてください。

![出てきたGUI.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3682428/f189de32-6383-a43d-fcf4-a8b01512f8bd.png)

---

画像のように `+` → `JAR` → `依存関係を持つモジュールから...` をクリックします。

![カチカチカチ.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3682428/732a916b-43b3-2749-5c3c-279594690e85.png)

---

その後色々設定する画面が出ますが、
ここは特に変更無しで `OK` を押してください。

![OK.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3682428/9c0e1057-08a8-c52f-2141-5974221a676b.png)

---

次に plugin.yml を読み込むファイルに追加します。
`＋` → `ファイル` の順にクリックします。

![追加.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3682428/f7cc241a-7127-2f4b-742a-c01f09196826.png)

---

その後、パスの選択画面が開くのでプラグインの `plugin.yml` を指定します。
`plugin.yml` ファイルは
`プラグインのフォルダ` → `src` → `main` → `resources` の中にあります。

指定したら `OK` を押してください。

![plugin.ymlパスの追加.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3682428/9b8dba7b-0cc4-89d4-52b5-b9135eb1255e.png)

---

パスの指定が終わると元の画面に戻るので
最後に、出力ディレクトリにサーバーの `plugins` フォルダへのパスを指定してください。

パスを入力したら `OK` を押して設定完了です。

![最後に.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3682428/713103aa-8dc8-4fa0-286e-5dd7a70fdc5b.png)

## 試しにビルド
今設定した方法で試しにビルドをしてみます。
最初に押した三本線をクリックして
`ビルド(B)` → `アーティファクトのビルド(B)` の順番でクリックします。

(画像では一度クリックしたので再ビルドになってしまっています。)
![アーティファクトのビルドの選択.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3682428/5afd1b7c-ac3f-9b9e-ad53-0d9e7de6017b.png)

---

すると以下の画像のように出てくるので `ビルド` を選択します。
`ビルド` を押すと自動でビルドが開始され、
ビルドしたものがサーバーのプラグインフォルダに導入されます。

![ビルド.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3682428/abc5c620-e721-d470-715c-956b1c5f43d3.png)

## 終わりに
これでプラグインフォルダへ直接ビルドする方法の解説は終了です。

これをサーバー起動中に実行するとプラグインが新しいものと入れ替わるので、
`/reload` コマンドや[Plugmanプラグインを利用したリロード](https://mcspigot.com/post-228/)で
プラグインを再読み込みすると再起動無しで更新ができます。

今回の方法ではバージョンが書かれていなかったり、
一部読み込みのバグが起こる可能性あるので、
不具合が起こった際はいつものビルド方法を使用してください。

次回は権限について紹介していきます。
お疲れ様でした。

**前** → [中級編 Part.4 コマンドの実行](https://qiita.com/tooooowa/items/7eeee6c2c1b8f5d29b8c)
**次** → 未定

**目次** →  [目次と今後の展望](https://qiita.com/tooooowa/items/7809ec65dee757570250)

## 参考
[https://qiita.com/RikuS3n/items/2363dbee2d3a8b8b2791](https://qiita.com/RikuS3n/items/2363dbee2d3a8b8b2791)
[https://mcspigot.com/post-228/](https://mcspigot.com/post-228/)
rescueとrescue_fromの使い方

# はじめに




先日、業務でrescueを使用したエラー処理を実装したので、備忘録として記事にしたいと思います。

この記事では、rescue と rescue_from の基本的な使い方をまとめてみました。

私自身、まだまだ未熟な経験の浅いエンジニアですので、誤った解釈をしている可能性もあります。もしそういった場合がありましたら、ぜひコメントでご指摘いただければ幸いです。

# rescue

`rescue` は、プログラム内で発生する特定のエラーを効果的に捕捉し、対処するための機能です。
これにより、エラー発生時の適切な対応やプログラムの安定稼働が可能になります。

### 基本構文

`rescue` を使うことで、特定のエラーが発生した時に特定のコードを実行するよう設定できます。
基本的な形式は以下のようになります。

```ruby
begin

# 例外が発生する可能性のあるコード

rescue [例外クラス]

# 例外が発生した時に実行するコード

end
```

### 使用例

例えば、ユーザーがデータベースに存在しない ID でアクセスしたときにエラーを捕捉する場合、以下のように記述できます。

```ruby
begin
  @user = User.find(params[:id])
rescue ActiveRecord::RecordNotFound
  redirect_to root_path, alert: "ユーザーが見つかりません"
end
```

1. `User.find` メソッドで `ActiveRecord::RecordNotFound` 例外が発生
2. ユーザーをルートパスにリダイレクト
3. `「ユーザーが見つかりません」`と警告メッセージを表示

のような流れになります。

# rescue_from

一方、`rescue_from` は Rails のコントローラーレベルで例外を捕捉するためのメソッドです。
これにより、複数のアクションにまたがる例外のハンドリングを一箇所で管理することができます。

### 基本構文

`rescue_from` は、特定の例外に対して共通のレスポンスを定義する場合に便利です。
構文は以下のようになります。

```ruby
class ApplicationController < ActionController::Base
  rescue_from [例外クラス], with: :[例外を処理するメソッド名]
end
```

### 使用例

例えば、すべてのコントローラーで `ActiveRecord::RecordNotFound` 例外を捕捉して共通の処理を行う場合、以下のように記述できます：

```ruby
class ApplicationController < ActionController::Base
  rescue_from ActiveRecord::RecordNotFound, with: :record_not_found

  private

  def record_not_found
  redirect_to root_path, alert: "指定されたレコードが見つかりません"
  end
end
```

このコードでは、アプリケーション内のどのコントローラーでも下記のような流れで処理が行われます。

1. ActiveRecord::RecordNotFound 例外が発生
2. record_not_found メソッドが呼ばれる
3. ルートパスにリダイレクト
4. `指定されたレコードが見つかりません`という警告メッセージを表示

# 参考

https://railsguides.jp/action_controller_overview.html#rescue
wsl2　いれるの簡単だった件　windows11 + vsc  2024 3/17

# はじめに
・新生活でノートパソコンを買い、もう一回 wslいれるのめんどくさいなって思ってたら　一瞬で入ったのでメモしときます
・2024 / 3/ 17 に入れました　

# wslとは
Windows Subsystem for Linux の略です
windows 上で linuxを動かす仕組みのことです！
今回は ubuntuという linux のディストリビューション使います

## なぜみんな linux を使うのか
環境構築がしやすいからです！
・デメリットは ハードルが少し高いことです
・メリットは コマンドさえしっていれば一瞬で環境が作れることです

・linux 単体であればハードルの高さはありますが、今回は windows 上で動かすのでそこまでハードルも高くないと思います

# 実際に入れてみる

・バグった人　・ほかの linux のディストリビューションが使いたい人 ・詳細が気になった人は公式ドキュメントを見てください ↓
[wsl公式ドキュメント](https://learn.microsoft.com/ja-jp/windows/wsl/install "WSL を使用して Windows に Linux をインストールする方法")

## power shell を管理者として実行
### wsl --install 
なんとこのコマンドだけで wsl が実行されて Ubuntu(linux ディストリビューション) をインストールする一歩手前までこれるみたいです
僕の場合は Ubuntuが実際にダウンロードされました

![WindowsPowerShell.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3669184/e0017e78-5e57-346e-ca70-3b9cb48d7116.png)

### PCを再起動する
再起動した段階でもう wsl のインストールは終わっています

## Ubuntu を起動する
### ubuntu を起動して user name , passwordを決める
user name と password を設定したら　welcome to ubuntu 22.04.3 LTS　現在のバージョンがでてきました

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3669184/1d493d0e-030d-12a8-dc0c-2e1c48cfc886.png)

### 念のためにUbuntu を更新しておく
#### ubuntuのバージョンの確認

[ubuntuの最新バージョンの確認](https://jp.ubuntu.com/download "Ubuntu の最新バージョンの確認")

･ sudo apt update でアップデートがあるか見るという方法もあります

僕の場合は最新バージョンじゃなかったので念のため更新します

    sudo apt update  
    sudo apt upgrade
この 2つのコマンドを使います　
ざっくりと説明すると　sudo apt update はパッケージリストを更新します sudo apt upgrade で実際に upgradeします

    lsb _release -d
このコマンドで 名前 + バージョンをしることができます

22.04.3 LTS から 22.04.4 LTSにアップデートされました！

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3669184/5da3309f-93f0-4979-3ac1-a31974149556.png)

## VSC (visual studio code) をインストールする

[vsc 公式ダウンロードページ](https://code.visualstudio.com/Download "vsc　公式ダウンロードページ")

今回は windows 版をインストールしていきます！
### vsc 拡張機能
インストールができたらこの四角が四つあるところを押して wsl と調べてください
このかわいいペンギンが見えたらインストールしてください！

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3669184/b0a3a469-1132-2f6a-3136-f1e170215cd2.png)

### ゴール　terminal で開いてみる

無事使えるようになりました！

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3669184/a60d3b5d-1e4a-7afb-320a-3a64779a7bcb.png)

# おわりに
・vsc の terminal で git を使いたかったのでいれてみました
・git を便利に使いたいだけなら git bash でもいいんじゃないかとも思ったんですが wsl のほうが環境構築しやすかったり周りのエンジニアも使っていたのでインストールしてみました

・linux の知識は全然ないので間違えてるところがあるかもしれません、もしあったら教えてもらえると嬉しいです！

・以上です、お読みいただきありがとうございました！
VRChatにワールドアップロードしようとすると AssignSceneNetworkId's reported a failure と出る

# 解決方法

１. VRChat SDK→Utilities→Network ID Import and Export Utilityを開く

![スクリーンショット 2024-04-06 164803.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3764621/8b6b14b2-bd00-065e-96b5-a1f5dd9fbe8f.png)

２. Regenerate Scene IDsを押し、IDを作り直す

![スクリーンショット 2024-04-06 164931.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3764621/1049d97c-df41-2421-227f-64a94918a84d.png)

３. 以上
【Rails】form_withモデルニカONE {PIECE of cake}アイランド編【初心者です】

# form_withの今の認識
※間違っている可能性があります

viewからcontrollerに送るヘルパーメソッド、
モデルを入れると、viewがnewならcreateへ、
viewがeditならupdateへ良き塩梅で行ってくれる。
良き塩梅に行ってくれるため、
新規作成の時と編集画面の時で_formのようにviewをフォーム配下でまとめられたりする。
良き塩梅で行ってくれるとなんでまとめられるのかって？
newの時urlでcreateに繋げちゃった世界線で考えてみて下さい、
editの時におんなじ感じで書くし、まとめよって思いますよね？
createいってまうて！おいだるいて！ってなるでしょ？
痒い所に手が届く、そんなヘルパーメソッドだと思ってます。

# form_with使い方
```ruby
<%= form_with @ニカ do |d| %>
<%= d.hidden_field :ヒトヒトの実 %>
<%= d.submit 'ゴムゴムの実' %>
<% end %>
```

これがform_withの使い方です。
今回の場合form_withを用いて、
dに隠されたヒトヒトの実をゴムゴムの実で伝えて、モデルニカで送ってます。
もっともふざけたform_withですね。

ついでに

本当に知らない人向けに、ちゃんとしたのも置いておきます。
```ruby
<%= form_with @モデル do |f| %>
#ここにf.でモデルに送るものを選択したり入力させる場所を入れる
<% end %>
```
こんな感じになってます。
つまり上のふざけたform_withでは
hidden_field :表示はされないがモデルに送りたい時使うメソッド
submit　送信ボタン
この二つをcontrollerに送っているということです。
つまり隠されたヒトヒトの実をゴムゴムの実で伝えて、モデルニカでcontrollerに送っている。
そういうことです。
ちなみにこのf.の一族は他にも、
こんなのがあるよって友達のChatGPTが言ってました。

text_field: テキスト入力フィールドを生成します。
password_field: パスワード入力フィールドを生成します。
email_field: メールアドレス入力フィールドを生成します。
phone_field: 電話番号入力フィールドを生成します。
number_field: 数値入力フィールドを生成します。
date_field: 日付入力フィールドを生成します。
time_field: 時刻入力フィールドを生成します。
datetime_field: 日付と時刻入力フィールドを生成します。
text_area: テキストエリアを生成します。
select: セレクトボックスを生成します。
collection_select: コレクションからセレクトボックスを生成します。
check_box: チェックボックスを生成します。
radio_button: ラジオボタンを生成します。
file_field: ファイルアップロードフィールドを生成します。
hidden_field: 非表示のフィールドを生成します。
submit: 送信ボタンを生成します。

良き塩梅のものを使っていきたいですね。
# 使っていて最近思ったことと、それの腹落ち
form_tagとform_forがなくなってform_withに統一されたと歴史の教科書で読みました。
form_with url:'飛びたいurl'みたいにurlで直接も飛べる、
それを聞いた時には便利だなって思いました。
でも使っているとモデルに絶対送るのにわざわざなんでurlで送るんや？
newからupdateに送ったりする時があるんか？
そう疑問に思いました。
そして良き友のChatGPTに聞いてみました。
そしたらこういう時はモデルに送らないでしょ？って言われて腹落ちしました。

検索フォーム: ユーザーがデータを検索するためのフォームは、通常モデルに紐付いていません。検索結果を表示するためのフォームを作成する場合、form_withを使用しますが、モデルは必要ありません。

お問い合わせフォーム: ユーザーがウェブサイトの管理者にメッセージを送信するためのフォームも、通常モデルに紐付いていません。このようなフォームは、メール送信などのアクションを実行するために使用されます。

カスタムアクションへのフォーム: モデルに紐付いていない特定のアクションに対してフォームを作成する場合、form_withを使用します。たとえば、ユーザーがサイトに新しいページを提案するためのフォームを作成する場合などがあります。
iTerm2 でスクロールしたときの履歴を消さないようにする方法

![](https://raw.githubusercontent.com/noraworld/developers-blog-media-ja/master/iterm2-scrollback-history/231628444-af06c8e1-8780-48b4-844a-7c1358424fa6.png)

iTerm2 で上にスクロールすると今までの表示履歴を確認することができますが、スクロールの行数が多すぎると過去の履歴は削除されてしまいます。スクロールできる全履歴を、iTerm2 を終了するまで保持するには以下の手順に従い設定を変更します。

1. `Command` + `,` を押下し iTerm2 の環境設定ウィンドウを開きます
2. `Advanced` タブをクリックします
3. 検索フィールドに `scrollback history` と入力します
4. `Prevent CSI 3 J from clearing scrollback history?` という項目を `Unspecified` から `Yes` に変更します
UUIDとPostgreSQLについて調べたメモ

## はじめに

PostgreSQLで設計をする際、プライマリーキーにUUIDを使うことについて調べたときのメモです。

何を使用すればいいかは、デーブルのサイズやデータ量、いろいろな条件によって場合によります。厳密に正しい選択をしたい場合に関しては「推測するな、計測しろ」が正しいです。

あくまでメモのリンク集なので、結論や計測結果などはこの記事には記載されておりません。

## 公式ドキュメント

公式ドキュメントを読んでみたが、UUIDのパフォーマンスについての記載はなし。

- UUID Typeについて
https://www.postgresql.org/docs/15/datatype-uuid.html

- UUIDの生成関数
https://www.postgresql.org/docs/15/functions-uuid.html

- UUIDの追加のモジュールについて
https://postgresql.org/docs/15/uuid-ossp.html

## UUIDのデメリット

- uuid を主キーとして使用すると、パフォーマンスに重大なデメリットが生じますか?
https://www.reddit.com/r/PostgreSQL/comments/mi78aq/any_significant_performance_disadvantage_to_using/?rdt=46851

- MySQLでプライマリキーをUUIDにする前に知っておいて欲しいこと
https://techblog.raccoon.ne.jp/archives/1627262796.html

- MySQLとPostgreSQLと主キー
https://speakerdeck.com/hmatsu47/mysqltopostgresqltozhu-ki

- Postgres と MySQL における id, created_at, updated_at に関するベストプラクティス
https://zenn.dev/mpyw/articles/rdb-ids-and-timestamps-best-practices

**MySQLではUUIDに明確なデメリットがある。**

- Postgres で主キーとして UUID を使用することの長所と短所
https://blog.bhanunadar.com/pros-and-cons-of-using-uuid-as-primary-key-in-postgres/

- 30%高速化、UUIDの欠点、WALの増大、プロセスとの比較
https://www.scalingpostgres.com/episodes/271-30-percent-faster-uuid-downsides-growing-wal-processes-vs-threads/



## CUID

- Prismaの公式ドキュメント CUID
https://www.prisma.io/docs/orm/reference/prisma-schema-reference#cuid

- CUID公式GitHub
https://github.com/paralleldrive/cuid?tab=readme-ov-file

CUIDは非推奨、CUID2を使ってくださいと公式には書かれている。PrismaではCUIDだが、このセキュリティ的な問題点は、UUIDにも同様に存在するため、今回は無視する。

- UUID/GUID、CUID、NanoID: 違いは何ですか?
https://dev.to/harshhhdev/uuidguid-cuid-nanoid-whats-the-difference-5dj1

この記事ではPrismaを使用する場合はCUIDが最良の選択と説明している。

- PostgreSQL と外部キーを使用した CUID と UUID
https://github.com/prisma/prisma/discussions/21489

PrismaでCUIDを使う場合に@db.VarChar(30)をつけるという話。

## シーケンシャルID

- PostgreSQLの自動生成主キーの UUID,シーケンシャルID
https://www.cybertec-postgresql.com/en/uuid-serial-or-identity-columns-for-postgresql-auto-generated-primary-keys/
Snowflakeのオブジェクト名の大文字・小文字の区別に注意

# はじめに
Snowflakeのオブジェクト名の小文字・大文字の区別をあまり理解できていない時にいろいろとハマったので、ハマりやすいポイントについてまとめ。

# 前提
* オブジェクト名を引用符で囲わなければ、小文字で記載しても自動的に大文字として認識されて保存される。（大文字小文字が区別されない）
* オブジェクト名を引用符で囲うと大文字小文字が区別され、かつ数字や特殊文字のみのオブジェクト名が利用可能となる。


https://docs.snowflake.com/ja/sql-reference/identifiers-syntax

# 失敗例：デフォルトパラメータが適用されない
ユーザ「user_aaa」のデフォルトロールとしてロール「role_aaa」を設定したい。
```ruby:ロール作成
use role USERADMIN;
select current_role();

create role role_aaa;
show roles like 'role_aaa';
```
###### 実行結果
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3764466/c1fb99e5-e9c9-4185-5713-a9fc32a3d2c3.png)

```ruby:ユーザ作成
create user user_aaa password = 'Password1234' default_role = 'role_aaa' ;
grant role role_aaa to user user_aaa;
show users like 'user_aaa';
```
###### 実行結果
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3764466/afe14f29-e18a-8737-3700-71fd860d3b76.png)

###### ログイン結果
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3764466/26d9ed1f-27e1-ee43-4f0a-df1e5f6f74f5.png)

あれ？ログイン時のロールが「PUBLIC」になっている。。
再度ユーザの情報を確認。
```ruby:ユーザ情報確認
show users like 'user_aaa';
```
###### 実行結果
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3764466/a015ee2d-740d-6d8c-fcd0-26a7ec07758d.png)

パラメータ「defalut_role」は「role_aaa」が設定されているけど、小文字になっているために別のオブジェクトとして認識されてしまいうまく適用されていない。

```ruby:パラメータ修正
alter user user_aaa set default_role = role_aaa ;
show users like 'user_aaa';
```
###### 実行結果
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3764466/39d34a00-c450-d384-dd36-a226cd89ce04.png)
###### ログイン結果
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3764466/c695f299-e3f5-4781-7189-14f253846d21.png)

ロール名を囲っていたシングルクウォーテーションを外すことで大文字のオブジェクト名として認識され、正常に適用。

:::note warn
注意
「defalut_role」に限らず基本的にdefalutパラメータは、存在しないオブジェクトや権限のないオブジェクトを指定してもエラーとならず、適用されないだけという挙動
:::
:::note warn
注意
基本的にdefalutパラメータは追跡性がないため、指定されているオブジェクト名がRENAMEされても自動で変更されず、手動での変更が必要
:::



# 結論
* オブジェクト名は特別な理由(※)がなければ、引用符で囲わない方がバグを誘発しにくい
(※)ユーザ名を数字や記号のみとしなければいけない、テーブル名で日本語を利用する等

:::note
TIPS
ユーザ名については、小文字大文字どちらで定義しても、ログイン時はどちらでもログイン可能
（例）「"test_user"」で作成した場合も「TEST_user」、「TEST_USER」等でログイン可
:::
nodenvでnodeのバージョンを管理する方法

今回はnode.jsのバージョンをnodenvで管理することで、node.jsのバージョンを簡単に切り替えることができるため紹介します。

:::note info
【前提知識】
- vim操作ができる
- .zshrcファイルが既に作られている
:::

# brewコマンドが使えるか確認する
以下のコマンドを実行しbrewコマンドが使用できるか確認を行う。
```terminal
brew -v
```

ここで、`command not found: brew`と表示された場合は以下のコマンドを実行してください。

【公式サイト】
https://brew.sh/
```terminal
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
```

以下のコマンドを実行しバージョンが表示されるか確認する
```terminal
brew -v
```

:::note warn
MacOSを使用しておりAppleシリコン（M1など）の場合は以下を実行しパスを通してください
:::

vimで.zshrcファイルを開く
```terminal
vim ~/.zshrc
```
.zshrcファイルにパスを追加
```terminal
export PATH="/opt/homebrew/bin:$PATH"
```
保存完了後パスを通す
```terminal
source ~/.zshrc
```
以下のコマンドを実行しバージョンが表示されるか確認する
```terminal
brew -v
```

:::note warn
バージョンが表示されない場合はターミナルを一度再起動してみてください
:::

# nodenvをインストールする
homebrew経由でnodenvをインストールし、使用できるようにセットアップします。
以下のコマンドでnodenvをインストールします。

```terminal
brew install nodenv
```

次に.zshrcファイルにパスを通します。
vimで.zshrcファイルを開き、以下のコマンドを実行します。
```terminal
vim ~/.zshrc
```

以下を.zshrcファイルに記述し保存します。
```terminal
eval "$(nodenv init -)"
```
保存完了後、以下のコマンドを実行します。
```terminal
source ~/.zshrc
```
nodenvの設定が完了しているか確認するために以下のコマンドを実行します。
```terminal
curl -fsSL https://github.com/nodenv/nodenv-installer/raw/master/bin/nodenv-doctor | bash
```

```terminal
// 以下のように表示さた場合OKです
Checking for `nodenv' in PATH: /opt/homebrew/bin/nodenv
Checking for nodenv shims in PATH: OK
Checking `nodenv install' support: /opt/homebrew/bin/nodenv-install (node-build 4.9.142)
Counting installed Node versions: none
  There aren't any Node versions installed under `/Users/PCのユーザ名/.nodenv/versions'.
  You can install Node versions like so: nodenv install rc
Auditing installed plugins: OK
```

# インストールしたいNode.jsのバージョンをインストールする
以下のコマンドを実行しインストールしたいNode.jsのバージョンを確認します。
```terminal
nodenv install -l
```

今回は19.9.0と20.0.0のNode.jsをインストールします。
```terminal
nodenv install 19.9.0
```

```terminal
nodenv install 20.0.0
```

nodenvに認識させます。
```terminal
nodenv rehash
```

# Node.jsのバージョンを切り替える
まずは現在インストールされているNode.jsのバージョンを確認します。
```terminal
nodenv versions
```
バージョンを確認すると19.9.0と20.0.0がインストールされているはずです。

PCのシステム全体、すなわちグローバルでNode.jsのバージョンを変更する場合は以下のコマンドを実行してください。
```terminal
nodenv global 20.0.0
```

PCのシステム全体ではなく、プロジェクトごとなど、ローカル（カレントディレクトリ配下）で利用するNode.jsを設定する場合は以下のコマンドを実行してください
```terminal
nodenv local 20.0.0
```

nodenvを使用することで、簡単にNode.jsのバージョンを切り替えることが可能になりました！🍺
お疲れ様でした！
【Tips】kaggle notebookで出力した画像やグラフをコピーする方法

# はじめに
通常、右クリックをすると、「画像をコピー」を選択できますが、kaggle notebookでは選択できません。

↓kaggle notebookで画像を「右クリック」した図
![スクリーンショット 2024-04-06 15.58.16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/846404/0637e240-8fa1-88bf-81df-a65b532418da.png)


# 解決策
「shift + 右クリック」でいつものメニューを表示できます

↓kaggle notebookで画像を「shift + 右クリック」した図
![スクリーンショット 2024-04-06 15.59.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/846404/d50f46db-5dbc-4126-d60b-160ad81f5087.png)

これで画像をコピーできます!!
【Ruby】ハッシュを使って条件分岐をスッキリさせよう

## これは何？

目の前にいる海外からやってきた人にあいさつしたいとき、ありますよね？
どうせあいさつするならその方の国の言語であいさつしたいものです。

相手の国に合わせたあいさつをするときに便利なのが、条件分岐です。
この条件分岐をスッキリ書く方法を学んだので、アウトプットします。

## やってみよう

レベル別に段階を踏んでやっていきます。

### if文

```ruby
if country == 'Japan'
  hello = 'こんにちは'
elsif country == 'USA'
  hello = 'Hello'
elsif country == 'France'
  hello = 'Bonjour'
elsif country == 'Spain'
  hello = 'Hola'
elsif country == 'China'
  hello = '你好'
else
  hello = 'Hello'  # デフォルトの挨拶
end
```

もっとも地道に書く方法として、if文があります。
でも、いちいち`elsif country ==`、`hello =`と書くのはあまりスマートには見えないですね。

### case文

```ruby
case country
when 'Japan'
  hello = 'こんにちは'
when 'USA'
  hello = 'Hello'
when 'France'
  hello = 'Bonjour'
when 'Spain'
  hello = 'Hola'
when 'China'
  hello = '你好'
else
  hello = 'Hello'  # デフォルトの挨拶
end
```

if文から卒業し、case文で条件分岐をしています。
ただしこれもいちいち`hello =`と代入するのはちょっとカッコ悪いですよね。

### ハッシュを使用

今回のような、**条件と代入する変数のそれぞれが常に同一である場合**は、以下のようにハッシュを使用することが可能です。

```ruby
hello = {
  Japan: 'こんにちは',
  USA: 'Hello',
  France: 'Bonjour',
  Spain: 'Hola',
  China: '你好'
}[country.to_sym]
```

`to_sym`しない場合は以下のように書きます。

```ruby
hello = {
  'Japan' => 'こんにちは',
  'USA' => 'Hello',
  'France' => 'Bonjour',
  'Spain' => 'Hola',
  'China' => '你好'
}[country]
```

countryと一致するキーが見つからない場合のデフォルト値を設定する場合は以下のようにします。

```ruby
hello = {
  Japan: 'こんにちは',
  USA: 'Hello',
  France: 'Bonjour',
  Spain: 'Hola',
  China: '你好'
}.fetch(country.to_sym, 'Hello')
```

## まとめ: あいさつは手短に

条件分岐のシンプルな書き方を知っておけば役に立つはず。
古いラズパイ４BのマイクロSDを、新しいラズパイ４Bで使う

古いラズパイ４BのマイクロSDを、新しいラズパイ４Bで使う

				2024/4/6 takkejan

２０１９年頃に購入したラズベリーパイ４Bを長年使っていたが、最近、
usb3.0まわりで障害が発生するようになり、この障害対応を行う過程で、
新規でラズパイ４Bを購入して古いラズパイ４BのマイクロSDを挿したところ、
起動しなかった。

障害対応はさておき、古いラズパイ４BのマイクロSDで新しいラズパイ４Bを
動かしたい、と考える人はいるだろうと思えたので、今回実施したドタバタを
記載しておきます。

家サーバーのラズパイ４Bがハード的に壊れたときに、ラズパイ４Bを
交換しようと新規で購入したら、SDをド新規で作成しないといけないとなると、
長年いろいろ修正してきたマイクロSDへの修正を一から全てやり直すことに
なるので、それは避けたい、と思う人は多分必ずいるだろうと考えた次第です。
もしかしたらそういう人が同じドタバタをするときに、多少は参考になるかも
知れません。

＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊
対応経緯：

ラズパイ４Bを家サーバーとして使用していたが、raidやsambaやopenVPNと
いったインフラを積んだ重要な常駐サーバーなので、ハードウエア障害に
備えて、バックアップ用のラズパイ４Bを購入しておくこととした。

常時動いてないと非常に困るサーバーなので、OSのバージョンアップなどは
リスキーなので、基本的にはやりたくない。

ところが新規のラズパイ４Bに古いラズパイ４BのマイクロSDを挿して起動
しても、立ち上がらなかった。このままだとバックアップ号機の意味がない。

いろいろ試していると、どうやらボードのファームウエアが新しくなって
いるらしく、起動時に以下のメッセージが出て起動しないことが判明。

　recover4.els: is not compatible　

新しいマイクロSDに、ド新規でラズパイOSをインストして挿せば起動する。

以下の対処で、とりあえず起動するようにはなった。

・事前に、現行サーバーのマイクロSDを、レスキューCDを起動させた
　PCにマウントし、ルートである区画/dev/mmcblkp7（以下p7と記載)の
　データをtarでバックアップ。
・新しいマイクロSDに、新規で最新のラズパイOSをインストール。
　SDのパーティションは以下のように変更になっていた。
　　/dev/mmcblkp1　＜ー　/boot
　　/dev/mmcblkp2　＜ー　/  (ルート)
・PCでレスキューCDを起動して、上記マイクロSDをマウントし、mkfs.ext4で
　/dev/mmcblkp2をフォーマット。
・tarで、現行p7のバックアップをp2へ落とす。
　（古いルートを活かすようにする）
・レスキューCDのPCで、p2を/mnt/p2にマウントし、/mnt/p2/etc/fstabをviで、
　以下修正。
　　/dev/mmcblkp6を、/dev/mmcblkp1へ修正。
　　/dev/mmcblkp7を、/dev/mmcblkp2へ修正。
・修正したマイクロSDを新しく購入したラズパイ４Bに挿して起動させると、
　とりあえず起動した。

・ところが、起動したラズパイで、/dev/md0が作成されないことが判明。
　syslogを確認したところ、以下のメッセージが出ていた。

Apr  6 12:15:50 ps002 systemd-modules-load[225]: could not open moddep file '/lib/modules/6.6.20+rpt-rpi-v8/modules.dep.bin'

　ルートを全部消して、元のルートをリストアしたので、新しい
　/lib/modules/6.6.20+rpt-rpi-v8/　が消されてしまい、OSが正常に
　起動されていないらしいことが判明。。
　これを追加してやる必要がある。

　別のマイクロSDに、またド新規でラズパイ４BのOSをインストして、
　そのラズパイの/lib/modules/の下のデータを、tarで吸い上げ。
　上記で吸い上げたモジュールを、新ラズパイ４Bの/lib/modulesの下で
　tar展開したうえで、再起動したところ、障害は発生しないで正常に
　起動していることが確認できた。

　ちなみに古いラズパイで発生していたusb3.0がらみの障害も、
　発生しなくなった。

１点覚書：

新しいOSの場合、ルートが入っているp2は、metadata_csumという、
ext4のオプション付きでフォーマットされているとのことで、
手持ちのシステムレスキューCDではバージョンが古くてマウントできなかった。
metadata_csumというのは、マイクロSDが破損しにくいように
考えられたフォーマットらしいが、システムレスキューCDが
使えないのは困るので、このオプションを付けない普通の
ext4フォーマットでフォーマットを行った。

参考：
古いラズパイ４BのOS:
Linux 4.19.75-v7l+　　　(2019年１２月）

新しいラズパイ４BのOS:
Linux 6.6.20+rpt-rpi-v8　（2024年４月）

以上
「現代数理統計学の基礎」演習問題解法メモ　第8章問2～7

問5　スラツキーの定理　現代数理統計学の基礎P98　命題5.18　の記述だけで皆様はわかっているのだろうか?私にはさっぱり???です。
次回で8章が終わり、とりあえず完了となります。
![第8問2 P1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3576811/459bd733-6771-f691-7ef1-7ef54e54b7f0.jpeg)
![第8問2 P2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3576811/9eb3bb45-689a-4e8d-38cf-14b7d931272a.jpeg)
![第8問3.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3576811/1a86c3ad-fbac-e10b-c16e-c6daa9514d9c.jpeg)
![第8問4 P1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3576811/a963074c-2287-896f-45fe-e65b68fddcd7.jpeg)
![第8問4 P2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3576811/7c410f3f-d560-9bd5-04c7-4134a8535a3d.jpeg)
![第8問5.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3576811/ee7770bc-d348-0489-f7d5-5dc2351e3b4b.jpeg)
![第8問6.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3576811/043dddbb-2e4f-b0cb-570b-259301007300.jpeg)
![第8問7 P1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3576811/d99c4a91-9176-fb4c-905e-878521ef1a9c.jpeg)
![第8問7 P2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3576811/e893f773-abd2-c24e-c3e5-5a7fb564838f.jpeg)
結論から報告すればよいわけでもないを考察してみた

## はじめに

こんなやり取りがあったとします。

部下「右手に棒状の物を２本持ちました。その後、右手を前に出しぶよっとした茶色い物体をつまみ、しげしげと見つめました。」
上司「結論から話して？」
部下「すげー美味しかったです！」
上司「」

若干謎な例文ですが、日常で割と発生しているやり取りかなと思います。
これについて少し回りくどく考察してみたいと思います。

## 「すげー美味しかったです！」は結論？

部下としては結論を語っている様に見えますが、なんとなく釈然としません。

とりあえず、この部下が取ろうとしているコミュニケーションの種類を考察してみましょう。

- 報告・共有（重要度：★☆☆）
自分のタスクの進捗などを共有する。
これを適切に行わないと、遅延の発覚が遅れるといったことが起きます。
- 確認（重要度：★★☆）
自分のタスクについて、このまま進めてよいか分からない時に確認する。
これを適切に行わないと、作業誤りによる手戻りの原因となります。
- 質問（重要度：★★☆）
自分のタスクについて、疑問が発生した時にどのように進めていいか質問する。
これを適切に行わないと、作業誤りによる手戻りの原因となります。
- 相談（重要度：★★★）
自分のタスクについて、このまま進めても遂行できない場合に相談する。
これを適切に行わないと、リリース日程を守れないなど調整やリカバリーが困難な状況に陥る原因となります。

これらのコミュニケーションは、内容や頻度が適切ではないと **「それって今必要？」**、 **「なんでもっと早く言わないの？」** と心をえぐるリアクションが返ってくることがあったりします。
また、 **「適切さ」** はプロジェクトにおいてはある程度傾向がありますが、細かくは相手によって異なるという高難易度ゲーです。プロジェクトや相手をよく見てリトライを繰り返し攻略法を見つけましょう。

さて、「すげー美味しかったです！」は **「それってあなたの感想ですよね」** という気もしますが、この中だと **「共有」** に分類されるコミュニケーションでしょうか？
今のところ「なんだかよく分からない手順でぶよっとした茶色い物体を見つめたら、すごく美味しかった！」しか理解できていない困った状況となりました。

## ぶよっとした茶色い物体の正体は？

上司「ところで、ぶよっとした茶色い物体って何？」
部下「唐揚げです！」

どうやら、この部下は「唐揚げについて作業をしていて、それが美味しかった！」ことを伝えたかったようです。

上司が「唐揚げを食べる」タスクを指示していれば、その前提は当然共有されていると思い、部下は「右手に棒状の物を～」から会話を初めていたようです。

ところが、上司はいくつものプロジェクトを掛け持ちしており、本プロジェクトの細かいタスクを覚えておらず、なんの話をされたのかを全く理解できない状況に陥っていたしまったみたいです。

## ところで表現が難しい

ここまで来ると、「右手に持った棒状の物」が箸ということが推察されるかと思いますし、「箸で唐揚げをつまんで、しげしげと見つめた。」ことも推察できるかと思います。レモンをかけたかも気になるかもしれませんね。

一方で、再現が難しい障害であれば、原文「右手に棒状の物を２本持ちました。その後、右手を前に出しぶよっとした茶色い物体をつまみ、しげしげと見つめました。」を箇条書きにした方が望ましいかもしれません。

1. 右手に棒状の物を２本持つ
1. 右手を前に出す
1. ぶよっとした茶色い物体をつまむ
1. しげしげと見つめる

ただ、今回は「共有」したいだけですし、「箸」は日本人としては共通理解がある物体であることも考えると、元々の報告はやはり難しいと言っていいでしょう。

## じゃあどうすればよかったの？

冒頭にコミュニケーションの種類を明記して、報告の概要（サマリー）を3行程度でさっくり書くようにすると汎用性が高いと考えますがいかがでしょうか？

「美味しい唐揚げの食べ方研究プロジェクトの進捗について共有します。箸でつまんでそのまま食べずにしげしげと見つめてから食べると美味しいということが分かりました。引き続き美味しい食べ方について調査を継続します。」

## おわりに

「概要を書けばよいのでは」と簡単に書きましたが、概要はプロジェクトの全容のうち、自分のタスクがどのような意味を持つかを把握していないと書けなかったりします。

訓練としては、プロジェクトを俯瞰して見たり、インプットを分解・理解・整理することを習慣づけることが考えられます。
時間はかかりますが、よりよい報告を行ったり今後キャリアを積む上での基礎としても役に立つと思います。

## おまけ１（新卒エンジニア向け手紙）

https://qiita.com/kaku3/items/2c8d4d783be7ce4fc9ea

https://qiita.com/kaku3/items/0bf1703cb8d6f84afbc5

## おまけ２（新卒エンジニア向け記事）

https://qiita.com/kaku3/items/fb949aa1a53f1f71c796

https://qiita.com/kaku3/items/aa2f81cf1e3974b8ad3a

https://qiita.com/kaku3/items/937354cc180c8bee823b

https://qiita.com/kaku3/items/b1c94328f273c750286b

## おまけ３（パイセン向け記事）

https://qiita.com/kaku3/items/cafccb1ee631d9f61190

https://qiita.com/kaku3/items/422b5427024d29da6a6e

## おまけ４（...は難しいシリーズ）

https://qiita.com/kaku3/items/34b40446337a59213a75

https://qiita.com/kaku3/items/f8411523cce000de750e

https://qiita.com/kaku3/items/5b11d2e1aace73c36340

## おまけ５（営業A短編シリーズ）

https://qiita.com/kaku3/items/03aae7b9e3c70c55f513

https://qiita.com/kaku3/items/3378ea55b1240d7360a1

## おまけ６（エンジニアのためのお仕事問題集）

2030年にIT人材が最大79万人不足するとのことで、学習用の資料をgitで**無料**公開してます(不定期更新)。
よろしければどうぞ。

[エンジニアのためのお仕事問題集](https://github.com/kaku3/workbooks)
Lexicalエディタって何ぞや

# はじめに

早稲田大学4年のkouta222です！
Lexicalエディタをインターンで使う機会があるので、学習も兼ねて記事を書きます。

# Lexicalエディタとは

Lexicalエディタは、Mataが開発したテキストエディタを作成するためのフレームワークです。一般的な`<textarea>`よりも高度な機能を備えた、プレーンテキストエディタ、ブログやソーシャルメディア、メッセージングアプリなどで使用されるリッチテキストエディタ、CMSで使用されるWYSIWYGエディタ、リアルタイムコラボレーション機能を持つエディタなどを実装するのに適しています。

他のリッチテキストエディターライブラリと異なり、Lexicalはテキストエディタの核となる機能を提供するフレームワークです。ツールバーやスタイリングなどの機能は、プラグインとして別途実装する必要があります。これにより、最小限の設定で使用できますが、開発者が柔軟にカスタマイズできるようになっています。

## Lexicalの特徴

**Lexicalのライフサイクルには大きく分けて3つの概念が登場します。**

- **EditorState**: エディターの状態を保持する不変のモデル
- **Editor**: LexicalのコアAPIで本体を指す
- **DOM(contentEditable)**: ユーザーが入力するテキストを反映するDOMエレメント

ユーザーがDOMを操作するとEditorStateが更新され、Editorがその変更をDOMに反映させる、といった単方向のデータフローになっています。


### **EditorStateの構造**

EditorStateには以下の2つのデータが含まれています:

1. **Node**
    - 編集中のデータをツリー状に管理
    - ユーザーがHeadingブロックを追加すると`HeadingNode`が、その中にテキストを表す`TextNode`が追加される
2. **Selection**
    - エディター上の選択状態を表現
    - テキストの選択範囲や、キャレットの位置を管理

### **Commands**

ユーザーによるすべての操作は **Commandのディスパッチ** に変換されます。特定のCommandに対して予め実行する処理をEditorに登録しておき、EditorがCommandを受け取ったらその処理(多くはEditorStateの更新)を行います。

Editorにあらかじめ用意したCommandを登録し、dispatchで呼び出すことができます。以下のようなAPIが用意されています。

- `createCommand()`: 新しいCommandの作成
- `LexicalEditor.registerCommand()`: 対象のEditorにCommandを登録
- `LexicalEditor.dispatchCommand()`: 対象のCommandをEditor内で実行



### レキシカルエディタの処理の流れ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3291381/48e02c8b-277d-1d1e-d376-5a86a62be113.png)

https://lexical.dev/docs/int





**Lexicalの使い方**

Lexicalを使ったリッチテキストエディターを実装する例を示します。

```jsx
jsxCopy code// LexicalComposer
import { LexicalComposer } from '@lexical/react/LexicalComposer';
import { RichTextPlugin } from '@lexical/react/RichTextPlugin';
import { OnChangePlugin } from '@lexical/react/OnChangePlugin';
import { ContentEditable } from '@lexical/react/LexicalContentEditable';
import { HistoryPlugin } from '@lexical/react/HistoryPlugin';

const initialConfig = {
  namespace: 'my-rich-text-editor',
  onError: (error) => console.error(error),
};

function App() {
  return (
    <LexicalComposer initialConfig={initialConfig}>
      <RichTextPlugin
        contentEditable={<ContentEditable />}
        placeholder={<div>Enter some rich text...</div>}
      />
      <OnChangePlugin onChange={handleChange} />
      <HistoryPlugin />
      {/* Add custom plugins and toolbar here */}
    </LexicalComposer>
  );
}

function handleChange(editorState) {
  console.log('Editor state changed:', editorState);
}

```

1. **LexicalComposer**: エディターの初期設定を行うProviderコンポーネント
2. **RichTextPlugin**: リッチテキスト機能を提供するプラグイン
3. **OnChangePlugin**: エディターの変更を検知するコールバック関数を設定するプラグイン
4. **HistoryPlugin**: 編集履歴の管理を行うプラグイン

LexicalComposerでは、名前空間の設定やエラー処理の関数を指定しています。RichTextPluginでは`contentEditable`コンポーネントとプレースホルダーを設定し、OnChangePluginでは変更検知のコールバック関数を指定しています。
国税の電子納付のやり方

# 会社やっていると、消費税を納めることに
免税期間が終わり、消費税を納め始めると中間納税なども発生してきます。その時に、銀行へ行かなくとも納税が出来るe-taxという便利なやり方があるので、全体の概要をまとめます。外部サイトを引用しながら、自分が理解出来た方法を将来の自分のために記録するモノです。

## e-taxは登録したか？！
税理士さんや会計士さんなどに会計をお手伝いいただくとe-taxの登録がされると思います。なので、登録されていないという事は無いと思いますが、これが無いと進みません。登録されているか確認して、「利用者識別番号」、「パスワード」、「納税用確認番号」の3点を確実にGETして下さい。

## 税務署から納付の通知書が届いたら（消費税の中間納税、年1回の場合
早めに相談して、納税額を確定しましょう。中間納税は仮決算して、正しい値に修正する事もできます。今年は昨年に比べて売上が悪いという事であれば、仮決算して納税額を修正するのも有りです。

### そのまま納税する場合
昨年の1年間の消費税の半分を納税する数字になっていると思います。ここから良く分からなくて色々調べたのですが、電子納付のやり方は2種類ある様です

「登録方式」
「入力方式」

この2つです。何が違うかというと、登録方式は全ての税目に対応しているそうです。入力方式は6税だけに対応とのことです。

#### 入力方式対応税目
入力方式は、
* 申告所得税
* 法人税
* 地方法人税
* 消費税及地方消費税
* 申告所得税及復興特別所得税
* 復興特別法人税

の6税目の納付が行えます。

登録方式は全部に対応している方式とのこと。入力方式はよく使うグループのサブセット用と覚えましょう。

使い方も異なります。

:::note info
入力方式
自分で納税用のコードを組み上げて支払いします。
:::

:::note info
登録方式
1度納税用の情報をe-taxに保存して、申請をして、納付用の情報が発行されて納税できるようになります。
:::

という違いだけで、あえて入力方式が使える6税も登録方式で納税することも出来ます。

ここまでまとめておけば、どっちを使っても問題なさそうな税の場合は、入力方式でe-taxにログインすること無く納税した方が楽なことに気がつくと思います。

2つにはやり方以外に、違いが無い、結果は同じという事です。

ここまでが理解出来たら、あとは納める税の種類に合わせて入力方式を使うか、登録方式を使うかだけです。

そしてここから先は、詳しいやり方が書いてあるサイトがあるのでやり方を確認して、払い込みしてください。


https://www.pay-easy.jp/corporation/

上記のサイトに、両方式の詳しいやり方が書いてあります。e-taxで行う登録方式は、何度かやると雰囲気がわかってくるのですが、初めは良く分からないですよね。WEBから大概のことは出来るので、macの皆さんもビビらずドウゾ。

:::note info
上記のサイトは登録方式の説明が簡単過ぎるので、他に詳しいページ見つけたら更新したいと思います。既にご存じの方はコメントで教えてください。
:::


## さいごに
地方税のel-taxも似たような仕組みになっています。入り口が違うだけなのですが、こちらは登録方式だけしかないサービスだと思って使い始めると判りやすいかと思います。el-taxは専用のWinアプリをまだ使っています。（2024.04.06現在）まあそのうちWEBで全部完結させてほしい所ですね。

今まで、支払の3枚綴りの紙を税理士さんにもらって銀行の窓口へ行って、現金用意して、紙書いて渡して、待つ。みたいな事やっていたのですが、これでだいぶ楽になりました。現金扱わなくて良いのは本当に楽ですね。切手なんかもはやくQRを印刷するみたいなことになると良いなと思っています。
cscの作法 その481

# 概要
cscの作法、調べてみた。
練習問題やってみた。

# 練習問題
comboboxで、Datasourceを使わないで組み立てよ。

# 写真

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/8f632899-b92e-ed5a-de5d-5ccb35f5dfb3.png)


# サンプルコード

```
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace App
{
	public partial class Form1: Form {
		ComboBox comboBox1;
		Label lb1;
		Label lb2;
		public Form1() {
			Text = "ComboBox";
			comboBox1 = new ComboBox();
			comboBox1.Width = 100;
			comboBox1.Height = 25;
			comboBox1.Left = 50;
			comboBox1.Top = 50;
			this.Controls.Add(comboBox1);
			comboBox1.Items.Add("");
			comboBox1.Items.Add("りんご");
			comboBox1.Items.Add("みかん");
			comboBox1.Items.Add("ぶどう");
			comboBox1.Items.Add("なし");
			comboBox1.Items.Add("もも");
			comboBox1.SelectedIndex = 0;
			comboBox1.SelectedValueChanged += comboBox1_SelectedIndexChanged;
			lb1 = new Label();
			lb1.Text = "disp";
			lb1.Left = 50;
			lb1.Top = 150;
			this.Controls.Add(lb1);
			lb2 = new Label();
			lb2.Text = "value";
			lb2.Left = 150;
			lb2.Top = 150;
			this.Controls.Add(lb2);
		}
		private void comboBox1_SelectedIndexChanged(object sender, EventArgs e) {
			lb2.Text = comboBox1.SelectedItem.ToString();
		}
		[STAThread]
		public static void Main() {
			Application.Run(new Form1());
		}
	}
}





```

以上。
[Windowsコマンド]ファイルリスト出力コマンド

## [Windowsコマンド]ファイルリスト出力コマンド
ファイルリストを出力したいディレクトリで以下コマンドを実行する

```
forfiles /s /c "cmd /c echo @path @fdate @ftime" > ../filelist.out
```

:::note info
出力したい情報に応じて以下を設定
:::

/C "コマンド"	各ファイルに対して実行するコマンドを指定する
　@file：ファイル名（例：test.txt）
　@fname：拡張子なしのファイル名（例：test）
　@ext：ファイルの拡張子のみ（例：txt、exeなど）
　@path：ファイルのフルパス（例：C:\temp\test.txt）
　@relpath：ファイルの相対パス（例：.\test.txt）
　@isdir：ファイルの種類　（ディレクトリの場合は"TRUE"、ファイルの場合は"FALSE"）
　@fsize：ファイルサイズ（バイト単位）
　@fdate：ファイルの最終更新日
　@ftime：ファイルの最終更新時刻