OmniAICreator/Qiita-1.07M huggingface dataset:
ServiceNow の Navigation メニューを Excel やスプレッドシートのフィルタを使って調査できるようにしたい

# きっかけ
例えば Knowledge の Administration のモジュールには何がある、といった調査を、Excel などでフィルタしながら調査できるようにしたい、と思ったのがきっかけです。ServiceNow の Navigation メニューを下にスクロールしながらメモするとかではなく。

# 前提
* Navigation メニューの表示に使用されている sys_app_module テーブルに Link Type = separator のレコードがあると、以降の Order 値のレコードがグルーピングされて表示されています。これをうまく活用したいです。
* ServiceNow の開発者でなくてもできるように、Script は使わず、エクスポート後にデータ加工する前提で方法を検討しました。自宅の私用の PC には Excel は入っていないので、Google Drive のスプレッドシートを使用しました。
* Link Type = separator のレコードの Display menu が空欄の場合は、レコードのグルーピングではなく、区切り線表示をしているようですが、その対応は割愛します。

# ServiceNow からエクスポート
フィールドは、Application menu, order, Link type, Display menu の 4 個を選びます。Application menu が not empty のレコード および Active = true のレコードを選択します。
図のように Application menu および order をソートするかわりに、エクスポート後にソートしても良いです。![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/27855/0cfdfe58-429f-25d3-07ff-946a8360ac10.png)

エクスポート後、Application menu が empty になっているレコードが見つかることがあります。sys_id に該当するアプリケーションが存在しないためです。それらのレコードも除去します。

# 仕様みたいなもの
* Application menu 単位で、separator が出現するまでの間のメニューは第 1 階層にする。
* separator が出現したら、separator の名前を第 1 階層とし、次の separator を見つけるまで同じ名前にする。以降のメニューは第 2 階層にする。
* 次の Application menu に進んだら、再びメニューを第 1 階層にする。以降その繰り返し。

# スプレッドシートの設定
## 追加する列
エクスポートしたフィールドに加えて下記の 4 列を追加します。最終的に level1 および level2 が得たい結果です。
grouping, level1, level2

## 各列の式
grouping は下記のようにします。
* Link type = Separator なら Display menu の値をセット。
* Separator 以外の場合、上の行の値を継続。ただし Application menu が変わっている場合は空欄にします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/27855/3fc2c0ed-2946-2219-00bd-58398e2ffe38.png)

level1 は、grouping が空欄なら Display menu の値、grouping の値があるなら、その値にします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/27855/d0166247-4900-760a-47ee-c351e6f26fd0.png)

level2 は、grouping が空欄なら、空欄。grouping の値がある場合、Separator ならハイフン記号にして、Separator ではない場合は Display menu の値にします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/27855/39b91852-8152-d19a-c6f6-333cd1ed52bc.png)

## 整形
* 新しいシートを用意しておき、すべての列をコピーして、「特殊貼り付け」＞「値のみを張り付け」を選んで新しいシートに張り付けします。 そのうち、Application menu, level1 および level2 の列だけを残します。
* level2 の値がハイフン記号だけの行を削除します。

# 結果
Application menu が Knowledge で、level1 が Administration のメニューには何があるか、スプレッドシートで調査できるようになりました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/27855/437a75fc-4311-51d5-a114-6017988897dd.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/27855/5889458b-ba9a-b253-82b3-26c17a950c06.png)
「slapd-config」(新)と「slapd.conf」(旧)のグローバルセクションに使用する主なディレクティブ

●「slapd.conf」（旧）のグローバルセクションに使用する主なディレクティブと、「slapd-config」（新）のディレクティブ
・argsfile ファイル名　slapdデーモン起動時のコマンド引数を格納するファイルを指定
・pidfile ファイル名　slapdのプロセスIDを格納するファイルを指定
・include ファイル名　読み込む設定ファイルを指定
・logfile ファイル名　デバッグログの出力先ファイルを指定
・idletimeout 秒数　アイドル状態のクライアント接続を強制的に切断するまでの秒数を指定
・timelimit 秒数　slapdが検索要求の応答に使う最大秒数を指定。

他にも、SASL認証やSSL/TLS関連の設定はグローバルセクションに記述する。

●「slapd.conf」（旧）のデータベースセクションで使用する主なディレクティブと、「slapd-config」（新）のディレクティブ
・database 種類　バックエンドデータベースの種類を指定
・suffix DN ディレクトリのトップとなるDNを指定
・rootdn DN データベース管理者のDNを指定
・rootpw パスワード　データベース管理者のパスワードを指定
・index 属性名　種類　属性に作成するインデックスの種類を指定
・directory ディレクトリ　データベースファイルを格納するディレクトリを指定

他にも、アクセス制御やレプリケーションを設定する場合もデータベースセクションに記述。
Ruby on RailsでDBを途中からmysqlに変更したいときに変更する場所

# はじめに
当記事はRuby on Railsでアプリケーションを作成している途中でDBを変更したいと思ったときに変更する場所を記します。
今回はSQLiteからmysqlへ変更します。

また、最初からmysqlで始める場合は以下のコマンドで`new`することでmysqlで開始することができます。

```terminal:terminal
rails new アプリケーション名 -d mysql
```

# 環境

```terminal:terminal
$ ruby -v
ruby 2.7.3
$ rails -v
Rails 7.0.4
mysql -version
mysql  Ver 8.0.31
$ bundle -v
Bundler version 2.1.4
```

# 前提条件

* DBの設定が完了していること。（mysqlだと最低限、rootユーザーでアクセス可能である。）


# DB変更

1. Gemfileに以下を追記する。

    ```:/Gemfile
    gem "mysql2"
    ```
1. terminalから`Gemfile`を元に`gem`を更新する。

    ```terminal:terminal
    bundle install
    ```
1. `database.yml`を更新する。

    ```yml:database.yml
    default: &default
      adapter: mysql2
      encoding: utf8
      pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>

    development:
      <<: *default
      database: [DB名]
      username: [ユーザー名]
      password: [パスワード]

    test:
      #略
    
    production:
      #略
    ```

    DB名や、ユーザー名、パスワード等その他環境情報は環境に応じて変更してください。

1. データベースを作成していない場合はcreateコマンドを叩く。

    ```terminal:terminal
    rails db:create
    ```
PythonからChrome DevTools Protocolを使ってChromeを操作する

スクレイピングやブラウザの自動操作をするときに、[Selenium](https://www.selenium.dev/ja/)を使う人が多いと思います。しかしSeleniumを使うにはブラウザのバージョンとdriverのバージョンを合わせる必要があり、少し面倒臭いです。

この記事では、[Chrome DevTools Protocol](https://chromedevtools.github.io/devtools-protocol/) (CDP)を使ってdriverを経由せずPythonからChromeを操作する方法を紹介します。

## ライブラリのインストール
今回は[PyChromeDevTools](https://github.com/marty90/PyChromeDevTools)というものを紹介します。他にも[pychrome](https://github.com/fate0/pychrome)というものもあります。

インストールはpipでできます。
```bash
pip install PyChromeDevTools
```
## サンプルコード
まずChromeをdebugging-port経由で起動しておく必要があります。Macの場合は以下のように起動できます。
```bash
/Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome --remote-debugging-port=9222 --user-data-dir=./user
```
次のコードはhttps://qiita.com/ を開くコードです。
```python
import PyChromeDevTools

chrome = PyChromeDevTools.ChromeInterface()
chrome.Network.enable()
chrome.Page.enable()

chrome.Page.navigate(url='https://qiita.com/')
chrome.wait_event("Page.loadEventFired", timeout=60)
```
ここではCDPの[Page.navigate](https://chromedevtools.github.io/devtools-protocol/tot/Page/#method-navigate)メソッドを使っています。

JavaScriptのコードを実行するときは[Runtime.evaluate](https://chromedevtools.github.io/devtools-protocol/tot/Runtime/#method-evaluate)メソッドを使います。次のコードはhttps://qiita.com/ の1番上の記事をクリックするコードです。
```python
chrome.Runtime.evaluate(expression="document.querySelector('.style-11rvgoz').click()")
```
私は、Developer Toolでcssセレクタを確認→Console画面でJavaScriptのコードを実行して確認→コピペしてPythonから実行という流れでスクレイピングをよく行なっています。

Chrome DevTools Protocolを使ってChromeを自動操作してHTMLを取得し、[Beautiful Soup](https://www.crummy.com/software/BeautifulSoup/bs4/doc/)でパースという流れで複雑なスクレピングも行うことができます。
VScodeでソースコードの途中から一括で置換したい

## はじめに
VScodeでプログラムを修正する作業などがありますが、　　
ソースコードすべてが同じわけではないけど、一部の箇所だけ、まとめて置換したいという時に
便利な方法です。

## ルールに置換をかける
値で置換をかけるのがいつもの置換、ルールに置換をかけるのが正規表現による置換。

test1 = data(AAAAA).A
test1 = data(BBBBB).B
test1 = data(CCCCC).C

ここでは上記のような「data(XXXX)」部分を一括で置換したいとします。
置換機能で[.*][マークの正規表現を使用する]を押します。

変更したい箇所の共通部分を入力して.*を入れます。
.*には共通部分以降が選択されます。
`\(バックスラッシュ）`でどこまで置換したいか選択できます。

今回の場合
`data.*\)`と置換項目欄に入れて変更したい置換内容（今回だと`demo`）を入力すると
`data(XXXXX)`部分が`demo`に置換できます。

今回使用している正規表現の意味
- `「.」（ピリオド）` 　は「改行以外の一文字」という正規表現で「あ」でも「a」でもなんでもいいのですが「.」ピリオド一つで１文字を表しています。
- `「*」（コメ）`は「その直前の文字が０回以上繰り返す」という正規表現で「テス*ト」と入れると「テト、テスト、テススススト」などが検索で引っかかります。
- `「\」（バックスラッシュ）`は直後の1文字をエスケープします。`「(」（丸かっこ）`など、正規表現が特別な認識をしてしまう文字に対してつけます。
![demo](https://gyazo.com/b63d3585353bbdd45c81b6d7bffecb42.gif)

## いろんな正規表現置換
### ゼロ埋め
「YYYY-M-D」を「YYYY-MM-DD」にゼロ埋めにする方法について説明します。
結構ややこしいです。

サンプルで以下のデータがあるとして進めて行きます。
  ```text: sample
  2022-10-23
  2023-2-3
  ```
このデータの場合
０埋めを行うとすると`-([0-9]+)`で月と日を選択出来ます。
今回は日付が`-(ハイフン)`が区切りなので先頭をハイフンを付けてますが、使うケースで選んでください。

`-0$1`で一度、月と日のどっちも０を追加して埋めます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2702878/6ff26f84-25fe-f014-0ab5-dcd3de1fdfa0.png)

`-0*([0-9]{2,})`で数字二桁以上で選択して`-$1`で二桁に整形し直します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2702878/f0cb1d26-c059-ee39-2b70-007295eee992.png)

### JSONフォーマットのキーのダブルクォーテーション除去
{"data": "abcd"}」のようなJSONフォーマットのキーのダブルクォーテーションの除去方法
以下のデータあるとします

  ```json: sample
  [{"mail": "test1@example.com"},
  {"mail": "test2@example.com"},
  {"mail": "test3@example.com"},
  {"mail": "test4@example.com"},
  {"mail": "test5@example.com"}]
  ```
`"(.*)":`でキー部分を指定できます。
`$1:`で`()`で指定した所を変更できます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2702878/4f4f1510-701b-e46a-c282-7e5628d7abf0.png)
Video.js完全マニュアル part11 〜言語設定〜

# はじめに
Video.js完全マニュアルとしてVideo.jsの解説をしていくシリーズのpart2です。
Video.jsの公式のガイドである[Video.js Guides](https://videojs.com/guides)を翻訳ツールを使いながら解説していきます。

前回はPlayerのサイズを変更する方法を紹介しました。今回はPlayerで使われるテキストの言語周りの設定を変更する方法を紹介します。

前回
[Video.js完全マニュアル part10 〜Playerのサイズ設定〜
](https://qiita.com/manzoku_bukuro/items/10137f64810f0dc40543)

part1から読む人は[こちら](https://qiita.com/manzoku_bukuro/items/10137f64810f0dc40543)

# この記事の対象者
- Video.jsを利用する人
- 動画プレイヤーのUI操作をしたい人
- 動画再生関連のサービスを作りたい人

# この記事の解説する章
[Languages](https://videojs.com/guides/languages/)

# 言語設定
Video.jsで生成したPlayerでは、コントローラーをホバーさせた時に機能名が表示されます。以下の画像をご覧ください。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2849606/0fb365f6-82df-7338-d032-fab0f6336714.png" width=80%/>

再生ボタンをホバーさせると、「Play」というテキストが表示されるのが分かります。
こちらのテキストは、デフォルトだと英語ですが、オプション指定等で言語変更したり、文言を変更することが可能です。

## 文言一覧
再生ボタンをホバーしたときは「Play」、音量ボタンをホバーしたら「Mute」と表示されます。
Video.jsで扱っている文言一覧は、以下のVideo.js公式のリポジトリで確認できます。

[英語の文言一覧](https://github.com/videojs/video.js/blob/main/lang/en.json)
[日本語の文言一覧](https://github.com/videojs/video.js/blob/main/lang/ja.json)

## 対応言語一覧
Video.jsで切り替えることが出来る言語は、以下のVideo.js公式のリポジトリで確認できます。

[対応言語一覧](https://github.com/videojs/video.js/tree/main/lang)

## 言語変更
### 対応言語読み込み
例えば日本語に言語変更したい場合、以下のようにVideo.jsが用意するスクリプトを読み込む必要があります。

以下は日本語の文言を読み込む場合です。
```html
<script src="https://vjs.zencdn.net/7.20.3/lang/ja.js"></script>
```

#### フォーマット
```html
<script src="https://vjs.zencdn.net/Video.jsのバージョン/lang/言語.js"></script>
```
上記のフォーマットでスクリプトを読み込むことで、指定言語に対応する文言を読み込むことが出来ました。

### 言語変更
以下のようにオプション、もしくは関数で変更することが出来ます。

#### オプション
```js
const video1 = videojs('video1', {
    'language': 'ja',
});
```
#### 関数
```js
const video1 = videojs('video1'});
video1.language('ja');
```

## ローカルでの文言変更
上記の方法ではVideo.jsのスクリプトを利用して英語以外の文言を読み込む方法を紹介しました。ですがスクリプトを読み込まずに、オプションや関数を利用して文言を変更する方法もあります。

### Video.js全体の変更
`videojs.addLanguage()`関数を利用すれば、作成されるPlayer全てに指定の文言が適用されます。

```js
videojs.addLanguage('ja', {
    {
        'Play': '再生！！！',
        'Mute': '停止！！！',
    }
})
const video1 = videojs('video1', {
    'language': 'ja',
});
```
また、上記の指定の場合現在の言語設定が日本以外の場合は設定した文言は適用されないので、オプション指定で日本語表示にしています。

#### 注意
`videojs.addLanguage()`関数を利用しても、既に生成されているPlayerには適用されませんのでご注意ください。

```js
// 先にvideo1を生成
const video1 = videojs('video1', {
    'language': 'ja',
});

// video1には適用されない
videojs.addLanguage('ja', {
    {
        'Play': '再生！！！',
        'Mute': '停止！！！',
    }
})
```
### Player毎の文言変更
`videojs.addLanguage()`関数はPlayer全体の設定変更方法ですが、Player毎に設定変更をする方法もあります。

`languages`オプションを指定することで、Player毎の文言変更が可能です。

```js
const video1 = videojs('video1', {
    'languages': {
        'ja': {
            'Play': '再生！！！',
            'Mute': '停止！！！',
        },
        'en': {
            'Play': 'Play！！！',
            'Mute': 'Mute！！！',
        },
    },
});
```

---
[Twitter](https://twitter.com/manzoku_bukuro)もやってます
【matplotlib】サブプロットの余分なプロットを削除する3つの方法

# 概要
matplotlibでグラフを作るとき、[subplots()](https://matplotlib.org/stable/api/_as_gen/matplotlib.pyplot.subplots.html)は便利なのですが、下図のように**余分なプロットがあり削除したい**場合があると思います。筆者もその場面に遭遇し、そのときに色々と調べたので、解決方法を3つ紹介します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1599258/75da85f7-2017-0532-f189-47a0e888f175.png)

# 実装
Google Colabで作成した本記事のコードは、[こちら](https://colab.research.google.com/drive/1THcoiY1LQWMAYI7amKR7uP4U5jh9R9cd?usp=share_link)にあります。

# 方法
2×2plotで右下のプロットを消す場合のコードで簡単に紹介します。おすすめ度は3段階で表示しています。
結論としては、[delaxes(ax)](https://matplotlib.org/stable/api/_as_gen/matplotlib.pyplot.delaxes.html)が一番良くおすすめ度は3です。というのも、それ専用のモジュールだからです。
[ax.set_visible(False)](https://matplotlib.org/stable/api/_as_gen/matplotlib.artist.Artist.set_visible.html)は、他にも使い道があるのでおすすめ度は2です。
[ax.set_axis_off()](https://matplotlib.org/stable/api/_as_gen/matplotlib.axes.Axes.set_axis_off.html)は、軸のみを削除しています。なので、このコードの前後でプロットしていた場合、プロット情報は表示される(プロットされていなくてもプロットの領域は確保される)ので、期待する挙動にならない可能性があるため、おすすめ度は1です。
## ``delaxes(ax)``(おすすめ度★★★)
```python:
import matplotlib.pyplot as plt

fig, axs = plt.subplots(2, 2)
fig.delaxes(axs[1, 1])
```
## ``ax.set_visible(False)``(おすすめ度★★)
```python:
import matplotlib.pyplot as plt

fig, axs = plt.subplots(2, 2)
axs[1, 1].set_visible(False)
```
## ``ax.set_axis_off()``(おすすめ度★)
※プロットの領域は確保されるので、上の2つの手法と厳密には異なります。
```python:
import matplotlib.pyplot as plt

fig, axs = plt.subplots(2, 2)
axs[1, 1].set_axis_off()
```




# まとめ
matplotlibのサブプロットを消す方法は色々とあるようですが、好み、おすすめ度、状況などによって適当に選んで快適に使いこなしましょう。

# 参考資料
https://matplotlib.org/stable/api/_as_gen/matplotlib.pyplot.delaxes.html

https://matplotlib.org/stable/api/_as_gen/matplotlib.artist.Artist.set_visible.html

https://matplotlib.org/stable/api/_as_gen/matplotlib.axes.Axes.set_axis_off.html
git 操作でよく使うコマンド一覧（備忘録）

## 始めに
git 操作でよく使うコマンドを備忘録としてまとめました。
随時更新していきます。


## 環境
| 開発環境    |バージョン |
|-----------|------------|
| __git__ | 2.36.1 |

## コマンド一覧
__状況確認__
| コマンド    | 効果 | 英語翻訳 |
|-----------|------------|------------|
| __git status__ | カレントブランチの状況を確認できる | 状態や状況 |
| __git branch__ | ローカルに存在するブランチ名をすべて表示 | 枝 |
| __git branch -vv__ | ローカルに存在するブランチ名をすべて表示 ＋ 最終コミットID、コミット名 | 枝 |

__ブランチ関連__
| コマンド    | 効果 | 英語翻訳 |
|-----------|------------|------------|
| __git branch -D ブランチ名__ | 指定したブランチを強制削除 | 枝 |
| __git checkout 切り替えたいブランチ名__ | カレントブランチを切り替える | 出ていく、去る |
| __git checkout -b "ブランチ名"__ | 新規でブランチを作成する（カレントブランチから派生される） | 出ていく、去る |
| __git checkout "ブランチ名" "派生元リモートブランチ名"__ | 新規でブランチを作成する（指定したリモートブランチから派生される） | 出ていく、去る |
 
__コミット履歴関連__
| コマンド    | 効果 | 英語翻訳 |
|-----------|------------|------------|
| __git add .__ | 変更があるすべてのファイルをコミット対象にする | 付け加える、追加する |
| __git commit -m "コミット名"__ | コメントをつけてコミットする | 委託する（引き渡す、ゆだねる）  |
| __git push origin リモートブランチ名__ | 指定したリモートブランチにカレントブランチのコミット履歴をpushする | 押す、押しやる |
| __git fetch origin リモートブランチ名__ | リモートリポジトリのコミット履歴をローカルに反映する（マージはしないよ） | 取ってくる |
| __git pull origin リモートブランチ名__ | 指定したリモートブランチをカレントブランチにpull（fetch ＋ merge）する | 引く、引っぱり出す |
| __git log__ | カレントブランチのコミット履歴を確認できる | 記録、工程日誌 |
| __git reset HEAD__ | 直近のコミットと同じ状態にする（間違えて"git add" した時に使うことが多い） | 置き直す、組み直す |
| __git reset 戻りたいコミットID__ | 戻りたいコミットIDまで戻ることができる | 置き直す、組み直す |
| __git merge --abort__ | マージを中断することができる（例：pullでコンフリクトが起きた時） | 中断する、やめる |

__stash関連__
| コマンド    | 効果 | 英語翻訳 |
|-----------|------------|------------|
| __git stash save "stash名"__ | 名前を付けて変更ファイルを退避する | こっそりしまう、隠す、蓄える |
| __git stash list__ | 退避した変更ファイルのリスト一覧を表示 | こっそりしまう、隠す、蓄える |
| __git stash apply stash@{番号}__ | 退避した変更ファイルを戻す（退避リストから削除されない） | apply：当てる、用いる、(…に)適用する |
| __git stash pop stash@{番号}__ | 退避した変更ファイルを戻す（退避リストから削除される） | pop：ポンと鳴る、ひょいと入る、急に動く、飛び出る、ポンと開く |

※"."をつけるところ、つけないところに注意する。
※ダブルクオーテーションをつけるところ、つけないところに注意する。

## 終わりに
ご覧いただきありがとうございました。

おすすめのコマンドありましたら、知らせいただけますととありがたいです💦
Linux LVM 操作コマンド メモ

# はじめに

- LVM を理解してるけどコマンドわすれがち、メモ

# 物理ボリューム

## 登録

- pvcreate

```terminal
# pvcreate /dev/sdb
# pvcreate /dev/sdc
```

## 削除

- pvremove

```terminal
# pvremove /dev/sdb /dev/sdc /dev/sdd
```

## 確認

- pvs
- pvdisplay

# ボリュームグループ

## 作成

- vgcreate

```terminal
# vgcreate vg_data01 /dev/sdb/ dev/sdc
```

## 削除

- vgremove

```terminal
# vgremove vg_data01
```

## 確認

- vgs
- vgdisplay

# 論理ボリューム

## 作成

- lvcreate

```terminal
# lvcreate -L 10G -n lv_data01 vg_data01
```

## 削除

- lvremove

```terminal
# lvremove /dev/vg_data01/lv_data01
```

## 確認

- lvs
- lvdisplay

# ファイルシステム

## 作成

- mkfs.xfs

```terminal
# mkfs.xfs /dev/vg_data01/lv_data01
```

## マウント

- mount

```terminal
# mkdir /data
# mount /dev/vg_data01/lv_data01 /data
```

## アンマウント

- umount

```terminal
# umount /data
```

# その他

## UUID確認

- blkid

```terminal
# blkid /dev/vg_data01/lv_data01
```

## ボリュームグループの拡張

- vgextend
- 物理ボリュームの登録とボリュームグループの拡張

```terminal
# pvcreate /dev/sdd
# vgextend vg_data01 /dev/sdd
```

## 論理ボリュームの拡張

- lvextend
- 論理ボリュームの拡張とファイルシステムの拡張

```terminal
# lvextend -L+2G /dev/vg_data01/lv_data01
# xfs_growfs /data
```

## スナップショットの作成

- /data のスナップショットを /snapshot として作成
- /dev/vg_data01/lv_data01 のスナップショットを /dev/vg_data01/lv_snap01 として作成
- xfs_admin でスナップショットのUUIDを変更

```terminal
# umount /data
# lvcreate -s -n lv_snap01 /dev/vg_data01/lv_data01
# xfs_admin -U generate /dev/vg_data01/lv_snap01
# mount /dev/vg_data01/lv_data01 /data
# mkdir /snapshot
# mount /dev/vg_data01/lv_snap01 /snapshot
```

# 参考資料

- [［改訂新版］プロのためのLinuxシステム構築・運用技術](https://www.amazon.co.jp/dp/B01LZURAPK)
【Shell】シェルの設定をする方法

## `set`コマンドについて
`set`を使用することでシェルの設定の確認や変更ができます。
```sample.sh
#! /bin/bash
set -eu

```
```sample.sh
#! /bin/bash -eu

```

オプションを設定したい場合には`-`を記述し、 解除したい場合には`+`を記述します。
```sample.sh
#! /bin/bash

# 設定
set -eu

# 解除
set +eu
```

## 主なオプション
<table>
	<tbody>
    <tr>
      <td>オプション</td>
      <td>説明</td>
	  </tr>
	<tbody>
  <tr>
			<td><span>-a, -o allexport  </span></td>
			<td><span>新規に作成した変数や関数，値を変更した変数や関数を，以後，自動的にエクスポートする</span></td>
	</tr>
		<tr>
			<td><span>-b, -o notify </span></td>
			<td><span>終了したバックグラウンド・ジョブのステータスを即座に出力する</span></td>
		</tr>
		<tr>
			<td><span>-e, -o errexit </span></td>
			<td><span>コマンドが0以外のステータスで終了した場合，一部の場合を除いて即座に終了する</span></td>
		</tr>
		<tr>
			<td><span>-f，-o noglob </span></td>
			<td><span>パス名のワイルドカードによる展開（*や?）を無効にする</span></td>
		</tr>
		<tr>
			<td><span>-h, -o hashall </span></td>
			<td><span>コマンドの位置を記憶し，検索時間を短縮する</span></td>
		</tr>
		<tr>
			<td><span>-k, -o keyword </span></td>
			<td><span>キーワードとなる引数をコマンドに対する環境として渡す</span></td>
		</tr>
		<tr>
			<td><span>-m, -o monitor </span></td>
			<td><span>ジョブ制御を有効にする</span></td>
		</tr>
		<tr>
			<td><span>-n，-o noexec </span></td>
			<td><span>コマンドを実行せず，構文エラーだけを確認する</span></td>
		</tr>
		<tr>
			<td><span>-o emacs </span></td>
			<td><span>emacs形式のコマンド行編集インタフェースを有効にする</span></td>
		</tr>
		<tr>
			<td><span>-o history </span></td>
			<td><span>コマンドの実行履歴を有効にする</span></td>
		</tr>
		<tr>
			<td><span>-o ignoreof </span></td>
			<td><span>CTRLキーを押しながらDキーを押しても，シェルを終了しないように設定する。exitコマンドは利用できる</span></td>
		</tr>
		<tr>
			<td><span>-o posix </span></td>
			<td><span>bashの動作をPOSIX 1003.2に準拠させる</span></td>
		</tr>
		<tr>
			<td><span>-o vi </span></td>
			<td><span>vi形式のコマンド行編集インタフェースを有効にする</span></td>
		</tr>
		<tr>
			<td><span>-p, -o phiysical </span></td>
			<td><span>特権モードを有効にし，ENV変数とBASH_ENV変数を処理しなくなる</span></td>
		</tr>
		<tr>
			<td><span>-t, -o onecmd </span></td>
			<td><span>コマンドを1つ読み込み，実行後，終了する</span></td>
		</tr>
		<tr>
			<td><span>-u, -o nounset </span></td>
			<td><span>未定義の変数を参照するとエラー・メッセージを表示する</span></td>
		</tr>
		<tr>
			<td><span>-v, -o verbose </span></td>
			<td><span>コマンドを実行する前に入力行を表示する</span></td>
		</tr>
		<tr>
			<td><span>-x, -o xtrace </span></td>
			<td><span>コマンドと引数の展開処理を表示する</span></td>
		</tr>
		<tr>
			<td><span>-B, -o braceexpand </span></td>
			<td><span>シェルのブレース展開を有効にする。ブレース展開では，「L{i,n,u}x}」という文字列を「Lix Lnx Lux」と展開する。ブレース展開は他の6つの展開にさきがけて実行される</span></td>
		</tr>
		<tr>
			<td><span>-C, -o noclobber </span></td>
			<td><span>既存のファイルに対する出力リダイレクトを禁じる。ただし，「&gt;|」を用いればリダイレクトできる</span></td>
		</tr>
		<tr>
			<td><span>-H, -o histexpand </span></td>
			<td><span>!形式のヒストリ置換を有効にする</span></td>
		</tr>
		<tr>
			<td><span>-P, -o physical </span></td>
			<td><span>ファイルのシンボリック・リンクをたどらない</span></td>
		</tr>
  </tbody>
</table>
【tips】int (*a(void))(int); これ分かりますか？

答えは、関数アドレスを返す関数です。
使い方はこんな感じです。

```c:
#include <stdio.h>

int sub(int p) { return 123 + p; }		//ここの値が下記のprintfで表示される
int (*a(void))(int) { return sub; }		//sub関数のアドレスを返す
int main(void)
{
	printf("%d\n", a()(0));
    return 0;
}
```
socket.ioを利用したアプリのデプロイをしたい(迷走編)

前回、Socket.ioについて学んだ。
サーバーとクライアントをソケット通信で接続し、送受信するやり方を非常に簡単にだが学んだ。

ただ、そもそもクライアントとサーバーが何を指していてどうすれば実際にデプロイ出来るのか分からなかった。

そのため、Netlifyをつかってクライアントとサーバーに分けてデプロイしてみるとしたのようにCROSポリシーエラーが生じて通信できない。

![Untitled (7).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2971002/3dd5a5dd-c523-bf2c-fe0a-91006da50ee5.png)

socket.ioのトラブルシューティングからCROSポリシーエラーの対処を眺めてみたがイマイチイメージしにくい。
やはり、サーバーとクライアントの関係や違いを知らなすぎることが原因だと考える。

したがって、サーバーとクライアントの関係をまとめ、socket.ioの学習で作成してみたチャットアプリをデプロイするところまでこの記事ではやることにする。

古い記事であるが、こちらを読んだ。

https://entershare.jp/2430/

記事によると、サーバーはパソコンと同じでクライアントはリクエストを送り、それに対応するレスポンスを返すのがサーバーということになる。

socket.ioが送受信を可能にするのはブラウザをクライアントとして、Webサーバーがサーバーと言うかたちでクライアントとサーバーを接続している。

つまり、socket.ioのデプロイを試すにあたってブラウザを表示するサーバーと、socket.ioサーバーを切り分ける必要は必ずしもないということである。


ということで同じプロジェクト内にプロジェクトを同居させるとそもそもアプリケーションすら起動しない。

https://shimmering-bublanina-70b7dd.netlify.app/

それは、アプリケーションの仕様などをそもそも書いていないからなのだと思うが書き方がわからない。

あとで流行りのChatCPT聞いてみようかなと思っていますが、今はキャパがいっぱいのようです。

今、考えられるこれからの方針は、
別のサーバーでデプロイしてCROSポリシーエラーを解消する。これが最短な気がしてきた。

または、Netlifyでチャットアプリが起動するような仕様に変更する方法を調べるという方法である。

ちょっと下のほうができなければまずい気がしてきたので下を中心に調べて作成しようと思う。


毎日、少しでも進めていこうと決意したのに試験が近いので中途半端になってしまった。
とりあえずもう寝る。

参考記事

https://zenn.dev/kikutaro/articles/12c1b9848bd6e0




面白い記事を見つけたので近々これを基にチャット機能の進化を目指す。

https://blog.katsubemakito.net/nodejs/socketio/realtime-chat1
【お手軽】回線スピードテスト

テレワークが増えてきてビデオ会議をする頻度が増えてきました。映像が止まるたびに「自分の回線が原因じゃないか？」と不安になる人も多いでしょう。

そういうときは https://fast.com/ が便利です。すぐに自分の回線速度がわかります。

では、VPSやクラウドのコンピュートリソースなどの CLI 環境ではどうするか。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/38967/fb04e7fb-48ae-d87f-b664-359b304cdf19.png)

## VPS などの CLI 環境でのスピードテスト

[speedtest-cli](https://www.speedtest.net/ja/apps/cli) を使います。　`speedtest-cli` は Debian であれば [Package 登録されている](https://packages.debian.org/bookworm/speedtest-cli)ので　apt　で簡単にインストールできます。

その特徴を生かして Docker で手軽にインストールして使います。

```bash
docker run -it --rm debian:11-slim bash -c 'apt-get update -y && apt-get install -y speedtest-cli && speedtest-cli'
```

ほかにも fastcli　などのツールがあるようです。[参考](https://zenn.dev/ryuu/articles/how-use-fastcli)

### 結果

```
Retrieving speedtest.net configuration...
Testing from XXXXXXXXXXXXXX (xx.xx.xx.xxx)...
Retrieving speedtest.net server list...
Selecting best server based on ping...
Hosted by Verizon (Tokyo) [4.91 km]: 30.83 ms
Testing download speed................................................................................
Download: 113.95 Mbit/s
Testing upload speed......................................................................................................
Upload: 126.14 Mbit/s
```
草莽Erlang ── 27. lists:reverse

口で言うより行うことがErlang習得への近道と信じています。

https://qiita.com/mnishiguchi/items/9237780e849d80a85e11

## lists:reverse/1

```erlang
reverse(リスト) -> 新しいリスト
```

リストの要素を逆順に並べた新しいリストを返します。

https://www.erlang.org/doc/man/lists.html#reverse-1

練習してみます。

```erlang
> lists:reverse([1, 2, 3]).
[3,2,1]
```

## lists:reverse/2

```erlang
reverse(リスト1, リスト2) -> 新しいリスト
```

リスト1の要素を逆順に並べたものにリスト2が連結された新しいリストを返します。リスト2は逆順にはなりません。

https://www.erlang.org/doc/man/lists.html#reverse-2

練習してみます。

```erlang
> lists:reverse([1, 2, 3, 4], [a, b, c]).
[4,3,2,1,a,b,c]
```

[listsモジュール](https://www.erlang.org/doc/man/lists.html)には他にもリスト処理のための関数がたくさんあります。

## Elixirにも挑戦したい

闘魂ElixirシリーズとElixir Schoolがオススメです。

https://qiita.com/torifukukaiou/items/3b65e5c04fa8c55f526e

https://elixirschool.com/ja

https://qiita.com/piacerex/items/09876caa1e17169ec5e1
【Unity】方向ベクトルが四角推の範囲内か判定する拡張メソッド

# 概要
方向ベクトルが四角推の範囲内か判定する拡張メソッドを作りました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/307985/51e255f5-7a46-5a23-4c24-cef0d74f33d1.png)
画像で説明すると、ベクトルが球の中心から選択されている面の方向にあるかを判定できます。回転にも対応しています。
ついでに円錐版も作りました。
不具合等ありましたらご連絡ください。

# コード

お手持ちのVectorExクラスに追加してご利用ください。

``` C#
public static bool IsWithinDirectionTo(this Vector3 vector, Vector3 direction, float degree)
    => Vector3.Dot(vector, direction) >= Mathf.Cos(degree * Mathf.Deg2Rad);

public static bool IsWithinDirectionTo(this Vector3 vector, Vector3 direction, float yDegree, float xDegree = 180f, float rotationDegree = 0f)
{
    var v = Quaternion.AngleAxis(-rotationDegree, direction) * vector;
    var angles = Quaternion.FromToRotation(v, direction).eulerAngles;
    angles.x = (angles.x + 180f) % 360f - 180f;
    angles.y = (angles.y + 180f) % 360f - 180f;
    return Mathf.Abs(angles.x) <= xDegree && Mathf.Abs(angles.y) <= yDegree;
}
```
wslでDockerサービスの自動起動設定

# 概要
wslではデフォルトで毎回Dockerサービスを手動起動しないといけない。
その対応について。

# 方法その１ systemdを動くようにする
一番素直な方法な気がする。

## wsl.confに設定を追加する
```/etc/wsl.conf
[boot]
systemd=true
```

## wsl再起動
コマンドプロンプトもしくはPSで以下を実行してwslを終了する。
```
> wsl --shutdown
```

# 方法その２ .bashrc等で起動する

## sudoでパスワード無しでサービス起動できるようにする
sudoers.d下に設定ファイルを作る。

```
$ echo "$USER ALL=(ALL:ALL) NOPASSWD: /usr/sbin/service docker start" |sudo tee /etc/sudoers.d/docker
```

## .bash_profileに記載
```
# read default file
. .profile

# start docker service
if test $(service docker status | awk '{print $4}') = 'not'; then 
  sudo /usr/sbin/service docker start
fi
```

# おまけ
sudo無しでdockerコマンドが動くようにする。
```
$ sudo gpasswd -a $USER docker
```

# 参考
https://teachme.jp/90980/manuals/19146802

https://qiita.com/ko-zi/items/949d358163bbbad5a91e

https://qiita.com/DQNEO/items/da5df074c48b012152ee
Mendixを始めてみました（２）

[前記事](https://qiita.com/lacky-lacky/items/9b0fdf9b010ef16a5558#%E3%81%BE%E3%81%A8%E3%82%81)
# 初めに
前記事で、Mendixの勉強を始めてみました。
環境づくりまでを前回の記事で記載しました。
今回はもう少し色々なものを試してみようと思います。

# 新規アプリを作る
Mendixでは、色々な土台を用意してくれているみたいです。
既に作成済みのアプリに対して色々と機能追加して
新規アプリとして作成することができることが分かりました。

検索バーで「task」と検索して出てきたものを選択してください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1991436/0cf5aa49-9095-34e5-527d-ec11f38e36df.png)

今回は、こちらの名前でアプリを作ってみます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1991436/f42a2ef6-b0d9-65cf-6a0c-eaf4ace9aabc.png)

Mendix Studioで編集してみます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1991436/1dc79736-5679-5041-9c0c-b1a01f09743f.png)
Mendix Studioは、Proと違って、ブラウザで編集できるみたいですね。
さて、今回は、先ほど述べたように土台ありのアプリから始めてみました。
それが、ここに現れたことが分かります。
実際にどんな機能があるのか見てみます。
右上にプレビューボタンらしきものがありますので、それをクリック。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1991436/f195ccd0-00e1-b892-447a-97c7121ed2b7.png)

土台ページを見ることができました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1991436/0b77f71c-e0c8-b34b-086a-4e9f59ff5ccc.png)

TODO横にある「+」ボタンを押してみると、入力欄が出てきました。
色々と入力してみます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1991436/78e0ee0f-02c2-9d79-dcac-98ac4e7c57c7.png)

先ほど入力したものが一覧に出てきました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1991436/0b41b35a-daba-9474-e572-79ec4a65714e.png)

# ここまで分かったこと
Mendixには、ゼロから作ることもできますが、
目的に合った土台を選択すれば、こんな感じですぐにページを
作ることができることが分かりました。
ここまで10分もかかっていないと思います。

# まとめ
今回は、土台ありのページを新規で作成してみました。
次回はもっと機能的な部分に触れてみたいと思います。
vue-cli + electron-builder環境構築とIPC

環境
Mac Ventura13.1
node v16.14.2
@vue/cli 5.0.8

### 環境構築
`vue create アプリ名`
routerはオフにしましょう、入れてると後でこんなエラーが出ます
```
It is detected that you are using Vue Router. It must function in hash mode to work in Electron. Learn more at https://goo.gl/GM1xZG 
```
ここではTypeScriptのVue3に。

`cd アプリ名`
`yarn serve`
ブラウザで起動することを確認。

`vue add electron-builder`
これを入れるとelectronアプリとして起動できるようになる
今回は13系を選択。

### エラー対応
`yarn electron:serve`
ここでエラー。

ts-loaderがないらしい。
`yarn add ts-loader@8.2.0`

これで起動はするがvueエラー。
62行目のtryCatchのerrorに型が当たっていないのでとりあえずanyにしておく。
~~background.ts内の"VUEJS3_DEVTOOLS"が存在しない。VisualStudioCodeさんによると"VUEJS_DEVTOOLS"ならあるので書き換える。~~　環境作り直したらこれは起きなくなった。

これでelectron:serveは通るようになった。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/522264/2002ea4a-22e3-c046-82a6-fdfe57774218.png)

`yarn electron:build`
こちらは通らない。エラーを見ると/usr/bin/pythonがないよと。brewで入れたpython3なら入ってるがpython2じゃないとダメらしい

`brew install pyenv`
`echo 'eval "$(pyenv init --path)"' >> ~/.zshrc`
`source ~/.zshrc`
`pyenv install --list`
`pyenv install 2.7.17`
`pyenv global 2.7.17`

これでpython2が入るので環境変数から指定してあげる

`which python`
`PYTHON_PATH=/Users/{{username}}/.pyenv/shims/python yarn run electron:build`
これで通ったのでdist_electronを見るとdmgが入ってるので開くとお馴染みの画面が出る
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/522264/d34553ae-2870-4532-e4a0-b2dd8af7271a.png)
また./dist_electron/macに.appがそのまま入ってる

windows用に.exeを吐くには
`yarn run electron:build --win --x64`
とする
こっちはpython必要ないっぽい

### プロセス間通信

```js:vue.config.js
module.exports = {
  pluginOptions: {
    electronBuilder: {
      nodeIntegration: true
    }
  }
}
```
nodeIntegrationはfalseの方が望ましいがvue側でelectronをimportするとこんなエラーが出てしまう
```
Module not found: Error: Can't resolve 'fs' in '/Users/username/dirname/node_modules/electron'
```

##### メイン→レンダラ
```ts:background.ts
//async function createWindow() {
//  const win = new BrowserWindow({
// 中略
win.webContents.send("channel", "メッセージ");
```
```ts:HelloWorld.vue
import { ipcRenderer } from "electron";
ipcRenderer.on("channel", (event: any, message: string) => {
  alert(JSON.stringify(event));
  alert(message);
});
```

##### レンダラ→メイン
```ts:HelloWorld.vue
import { ipcRenderer } from "electron";
ipcRenderer.send("channelName", "にゃーん");
```
```ts:background.ts
app.on("ready", async () => {
  ipcMain.on('channelName', (event: any, message: string) => {
    console.log(event);
    console.log(message)
  })
})
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/522264/ff8e8466-ad21-4da0-a77d-724168d5bb81.png)

ここまでできればvueのイベントをメインプロセスに送っていろいろできる
numpy を使わないで配列の中身を右にローテーションする方法

モジュールを使えない環境でリストの中身をn回ローテーションする機能実装するために、めちゃ頭悩ませたので備忘録として残す。


```
def rotateByTimes(list,n):
    for a in range(n):
        first = list[-1]
        remains = list[:-1]
        list[0] = first
        for b in range(len(list)-1):
            list[b+1] = remains[b]
    return list

list = [1,2,3,4,5]
print(rotateByTimes(list,n))
```
Gatsbyでsvgをimport出来ない場合の備忘録

こんにちは。
今回はGatsbyを使用する中でsvgファイルをimportしたいけど、エラーが出て出来ない場合の備忘録として記します。

私の環境
```
├── @emotion/react@11.10.5
├── @emotion/styled@11.10.5
├── @mdx-js/react@2.2.1
├── @types/node@18.11.18
├── @types/react-dom@18.0.10
├── @types/react@18.0.26
├── gatsby-plugin-emotion@8.4.0
├── gatsby-plugin-image@3.4.0
├── gatsby-plugin-mdx@5.4.0
├── gatsby-source-filesystem@5.4.0
├── gatsby@5.4.0
├── react-dom@18.2.0
├── react@18.2.0
└── typescript@4.9.4
```
# :frowning2: エラーとなる状況

```tsx
import logo from "../assets/logo.svg"
```
↑こんな感じでimportしてもパスがエラーになってしまう。


# :bulb: 解決法

### ステップ1
適当な`.d.ts`ファイルを作ります。今回は`svg.d.ts`とします。このファイルに以下のような記述をします。

```ts
declare module "*.svg"
```

### ステップ2
次に`tsconfig.json`の`compilerOptions`に以下のような記述をします。

```json
"baseUrl": ".",
    "paths": {
      "*": ["src/assets/*"]
    }, 
```

# :v: これでエラーなくsvgの表示ができた

`gatsby-plugin-react-svg`というプラグインもあるのですが、私の環境下では`vulnerabilities`が複数出てしまい厄介だったのでなんとかプラグイン無しで出来ないか模索した結果こうなりました。

https://www.gatsbyjs.com/plugins/gatsby-plugin-react-svg/

React、Typescript、Gatsbyどれを取っても初心者中の初心者ですので、他にもっと良い方法があったらコメントでご指摘頂けますと幸いです！



### 参考文献

https://lepus.netlify.app/type-error-svg

https://zenn.dev/nakashi94/articles/c3603f095a973a
figmaでプロダクトの画面イメージを作成する

## はじめに
プロダクト開発の要件定義に際して、画面イメージをfigmaで作成しました。そのとき調べたことなどを備忘録的にこちらに残しておきます。

## figmaとは
Figmaとは、ブラウザ上で簡単にデザインができるツールです。インターフェースのデザインを、場所を選ばずにブラウザさえ起動できれば使えるため、利便性が高くチーム体制での作業にも向いています。何よりフリープランがあり無料で利用できるので、誰にでも手軽に導入できることから、デザイナーではない人でもちょっとした用途に役立つでしょう。

ちなみに私は要件定義のフェーズでチームメンバーと画面イメージを共有するときに使いました。チームメンバーそれぞれが編集でき、非常に便利でした。

引用元リンク
https://ferret-plus.com/13195
## 使い方
簡単にfigmaの使い方について紹介していきます。

### ダウンロード
まずは下記URLからダウンロードし、アカウントを取得しましょう。
https://www.figma.com/ja/downloads/

### 作成手順
まずはフレームを作成します。左上のメニュー（レイヤーパネル）からフレームを選択し、右側のメニュー（デザインパネル）からフレームを選ぶことができます。
![図1figma.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1527144/61a53332-fe17-3548-c60e-1719a847c9c7.png)

図形や文字も左上のメニューから追加することができます。
![図1fig1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1527144/6f184cab-a352-a316-38c7-0d331be773cf.png)

実際にフレームを作成し、図形と文字を入れてみました。作成した図形や文字は左のレイヤーパネルの中に格納されていきます。コピー＆ペーストも可能であり、感覚的にはPowerPointと似た感じだと思います。
![図1fig3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1527144/0b4ad6af-5f71-6cac-b99e-f1f7581091d3.png)

figmaにはデザインファイル内で、何度も利用するオブジェクトやレイヤーをグループ化して扱うことができるコンポーネント機能があります。同一デザインファイル上でよく使うものをコンポーネント化しておくと、管理がしやすくなり、効率的に開発が進みます。
コンポーネント化するときは、オブジェクトやレイヤーを全選択し「右クリック→コンポーネントの作成」でできます。また下記ショートカットでもコンポーネント可能です。

Mac    : ⌥ Option – ⌘ Command – K
Windows: Ctrl + Alt + K
![図1fig4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1527144/538cb2bc-24dc-6ceb-2a5a-1c7fdaeb1aac.png)

## まとめ
- Figmaとは、ブラウザ上で簡単にデザインができるツールであり、サクッと画面イメージを作成することができる。
- チームメンバーそれぞれが編集できるので便利。
- 共有するチームメンバーが編集しやすくなるよう、コンポーネント化して整理しておくことが重要。
- これは初歩の初歩で、他にも便利な機能がたくさんあるので、引き続き他の機能も整理したいと思います。
Laravelで日付操作をする場合は、Carbonではなく「CarbonImmutable」を使用する

## Carbon処理の意外な落とし穴
普段何気なくCarbonを使用していないでしょうか？私もハマったのですが、Carbon処理には以下のような落とし穴が存在します
```PHP
<?php
use Carbon\Carbon;

$now = Carbon::now();
$tomorrow = $now->addDay();

if ($now->format('Y/m/d H:i:s') !== $tomorrow->format('Y/m/d H:i:s')}) {
    echo "期待する結果です！";
} else {
    echo "意図しない結果です"
}
```
このコードは、`$now`と`$tommorow`は別々の日付を代入しているので、`期待する結果です！`という値が表示されるはずです

実行結果：
```
意図しない結果です
```
なんということでしょう・・・。`$now`と`$tommorrow`が等しいと評価されています。これは、**「Carbonのメソッドを呼び出したインスタンス自身が書き換えられる**」ことが原因です

つまり、下記コード（一部抜粋）の`$now->addDay()`でインスタンスが`now`ではなく`tomorrow`に書き換えられえています
```PHP
$now = Carbon::now();
$tomorrow = $now->addDay(); // インスタンス自身が書き換えられる
```
この仕様により、バグを引き起こす原因になり得ます・・・。`Carbon::copy()`で状態の変化を防ぐことも可能ですが、毎回この処理を書くのは大変ですし、変更漏れも起こり得ます

そこで登場するのが、`CarbonImmutable`です

※ mutableは「変更可能な」、immutableは「変更不可能な、不変の」という意味を持つ形容詞である

## CarbonImmutableを使用する
こちらはCarbonのイミュータブル（不変）版です。組み込みのDateTimeImmutableクラスを継承しています
こちらは新しいインスタンスが返されるため、copy()する必要がありません。さらにインスタンスが作られた一番最初の状態を持つので、「思わぬ副作用」が発生しないのです


先ほどのサンプルコードをCarbonImmutableで書き換えてみましょう

```PHP
<?php
use Carbon\CarbonImmutable;

$now = CarbonImmutable::now();
$tomorrow = $now->addDay(); // Immutableなので新しいインスタンスが返却される

if ($now->format('Y/m/d H:i:s') !== $tomorrow->format('Y/m/d H:i:s')}) {
    echo "期待する結果です！";
} else {
    echo "意図しない結果です"
}
```

実行結果：
```
期待する結果です！
```
これで期待する結果になりましたね。何か特別な理由がない限りはLaravelでは思わぬ副作用を防ぐためにも、CarbonImmutableを使った方が無難かなあと思います

## 補足：イミュータブル（immutable）とは
イミュータブル（immutable）なオブジェクトとは、作成後にその状態を変えることのできないオブジェクトのことである。対義語はミュータブル(mutable)なオブジェクトで、作成後も状態を変えることができる。

## おわりに
というわけで、この記事ではLaravelで日付操作をする場合は、Carbonではなく「CarbonImmutable」の使用について紹介してきました

CarbonImmutableは組み込みのDateTimeImmutableクラスを継承しているので、気になる方は下記リンクからご覧ください（見なくてもいいかもですが）
https://www.php.net/manual/ja/class.datetimeimmutable.php
Google Drive 上に Anything V3 - Better VAE を保存して Stable Diffusion web UI で使う

# はじめに

Anything V3 - Better VAE と Stable Diffusion web UI を Google Drive 上に保存して、すべてすることを目標にする。

 メリット

- Google Drive から生成した画像を実行中に確認できる。
- まとめてダウンロードが簡単。

デメリット

- Google Drive の容量を多少圧迫する。（5 GB / 15 GB ほど）

# 0. Google アカウントの作成

既存のアカウントを使用してもいいが、容量を食うので新たにアカウントを作成することをすすめる。

# 1. Google Drive への保存 （一度だけ）

手順に必要なものに番号を振ったものを全て以下に示す。

![① ~ ④ の解説](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2986389/60108747-e445-1ee9-f73d-5d535641352a.jpeg "① ~ ④ の解説")

![⑤ ~ ⑨ の解説](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2986389/b7fdf84e-699e-3c19-2008-39f0ca313462.jpeg "⑤ ~ ⑨ の解説")

Google Drive 左上の [新規] ① → その他 ② → アプリを追加 ③ → Colaboratory を追加する。

Google Drive 左上の [新規] ① → その他 ② → Google Colaboratory ④を選択し、下のコードを張り付ける。

```txt: setup.ipnyb
# UI のダウンロード
%cd /content/drive/MyDrive
!git clone https://github.com/AUTOMATIC1111/stable-diffusion-webui

# モデルのダウンロード
%cd ./stable-diffusion-webui/models/Stable-diffusion
!wget https://huggingface.co/Linaqruf/anything-v3-better-vae/resolve/main/any-v3-fp32-better-vae.safetensors
```

画面左のファイル ⑤ → ドライブをマウント ⑥ を選択する。

セルの左の再生ボタンを押してしばらく待つ。

# 2. UI の起動（毎回）

1\. をやったのち 10 分ほど待ってから実行する。そうでないとデータが Drive に移動しきっていないことがあるため。

Google Drive 左上の [新規] ① → その他 ② → Google Colaboratory ④ を選択し、下のコードを張り付ける。

```txt: main.ipynb
# UI の起動
%cd /content/drive/MyDrive/stable-diffusion-webui
!COMMANDLINE_ARGS="--share --gradio-debug" REQS_FILE="requirements.txt" python launch.py
```

画面右上のランタイム ⑦ → ランタイムのタイプを変更 ⑧ → ハードウェアアクセラレータをGPU ⑨ に変更する。

画面左のファイル ⑤ → ドライブをマウント ⑥ を選択する。

セルの左の再生ボタンを押してしばらく待つ。

すると下のようなテキストが出てくる。最後の行の Running on public URL の右側の URL をクリックする。

```txt
/content/drive/MyDrive/stable-diffusion-webui
Python 3.8.16 (default, Dec  7 2022, 01:12:13) 
[GCC 7.5.0]
Commit hash: ff6a5bcec1ce25aa8f08b157ea957d764be23d8d
Installing gfpgan
Installing clip
Installing open_clip
Installing requirements for CodeFormer
Installing requirements for Web UI
Launching Web UI with arguments: --share --gradio-debug
No module 'xformers'. Proceeding without it.
LatentDiffusion: Running in eps-prediction mode
DiffusionWrapper has 859.52 M params.
Downloading: 100% 939k/939k [00:00<00:00, 1.88MB/s]
Downloading: 100% 512k/512k [00:00<00:00, 1.23MB/s]
Downloading: 100% 389/389 [00:00<00:00, 394kB/s]
Downloading: 100% 905/905 [00:00<00:00, 922kB/s]
Downloading: 100% 4.41k/4.41k [00:00<00:00, 4.14MB/s]
Loading weights [3088848987] from /content/drive/MyDrive/stable-diffusion-webui/models/Stable-diffusion/any-v3-fp32-better-vae.safetensors
Applying cross attention optimization (Doggettx).
Textual inversion embeddings loaded(0): 
Model loaded in 115.5s (5.4s create model, 109.3s load weights).
Running on local URL:  http://127.0.0.1:7860
Running on public URL: https://d108e42e-5997-431e.gradio.live
```

ドライブ内の stable-diffusion-webui/outputs 内のフォルダに画像が保存されている。スター付きにすると便利である。

---

参考リンク

https://github.com/AUTOMATIC1111/stable-diffusion-webui

https://huggingface.co/Linaqruf/anything-v3-better-vae
VSCodeでよく使うショートカットキー（備忘録用）

## 始めに
VSCodeでよく使う便利なショートカットキーを備忘録としてまとめました。
少しずつ加えて更新していきます。

## 環境
| 開発環境    |バージョン |
|-----------|------------|
| __windows__ | 11 |
| __Visual Studio Code__| 1.74.3 |


## ショートカットキー一覧

__文字関連__
| ショートカットキー| 効果 |
|-----------|------------|
| 「 ctl 」 ＋ 「 l 」 | 一行選択 | 
| 「 ctl 」 ＋ 「 a 」 | 全行選択 |
| 「 ctl 」 ＋ 「 shift 」 ＋ 「 l 」 | 同じ文字をすべて選択 |
| 「 tab 」            | インデント追加 |
| 「 tab 」 ＋ 「 shift 」 | インデント削除 |


※「 l 」= 小文字のエル


__切り替え関連__
| ショートカットキー| 効果 |
|-----------|------------|
| 「 ctl 」 ＋ 「 p 」 | ファイル検索 | 


## 終わりに
ご覧いただきありがとうございました。
便利でよく使うショートカットを発見したら、随時更新していきます。

おすすめのショートカットキーありましたら、どしどしご連絡お願いいたします。
GCPの可用性は月単位なのか年単位なのか

GCPの可用性は月単位なのか年単位なのか気になったので調べてみました。可用性99.99%だとして、月単位なら1ヶ月以内の停止時間が5分以内に収まるが、年単位なら十分超えることも想定されているのかなと思い。

# 結論
基本月単位でした。
[こちらのページ](https://cloud.google.com/terms/sla)に各プロダクトのSLAのリンクが載っています。

例えば[Cloud Spannerならこちら](https://cloud.google.com/spanner/sla)。
Monthly Uptime PercentageがMulti-Regional Instanceなら99.999%以上、Regional Instanceなら99.99%以上と記載されています。
Googleプロジェクト管理：プロジェクト計画の構成要素

# はじめに

わたしが [Google プロジェクト管理:プロフェッショナル認定証で得られた素晴らしい体験][google]を、要点をまとめ小さく分割して、わかりやすく簡潔に紹介していきます。

興味があれば、ぜひ ***"Google プロジェクト管理:プロフェッショナル認定証"*** を受講してみてください。

[google]: https://qiita.com/mapami/items/317ae776a2268fd54c8f

https://jp.coursera.org/professional-certificates/google-project-management

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2358573/7c79c997-e4e4-7d71-3686-e01b7badaa3c.png" width="800">

# プロジェクト計画の一般的な構成要素

プロジェクト計画は、規模の大小に関わらず、どのようなプロジェクトにも有効なものです。

プロジェクト計画の中身は企業によって異なるかもしれませんが、ほとんどの計画には5つの基本要素が含まれています。

- タスク
- マイルストーン
- メンバー
- ドキュメント
- 時間（見積もり時間）

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2358573/eeede677-4aed-9548-ec14-2a4ccd66a035.png" width="700">

### タスク＆マイルストーン

[前回説明したタスクとマイルストーン][ref1]が含まれます。
- タスクは、決められた期間内に達成しなければならない活動である。役割やスキルに応じて、それぞれのメンバーに割り振られます。
- マイルストーンは、スケジュールの中で進捗状況を示す重要なポイントです。通常、プロジェクトの成果物やフェーズの完了を意味する。

[ref1]: https://qiita.com/mapami/items/5b21a1f6151bbfae28fb

### メンバー

あなたのチームで働く人々とその役割も含まれます。各チームメンバーが自分の役割と完了すべきタスクを理解することが重要です。全員が自分の仕事を明確にすることで、あなたはプロジェクトの管理に集中することができ、チームメンバーには個人的な責任感が生まれます。

### ドキュメント

関連文書とリンクさせるのに適した場所です。

- RACIチャートは、チーム内の個人の役割と責任を定義するのに役立ちます。
- また、プロジェクトを明確に定義し、目標を達成するために必要な詳細を記した憲章にもリンクさせることができます。
- 関連文書には、予算やリスク管理計画などの文書も含まれます。

### 時間（見積もり時間）

プロジェクトに費やされる予定時間を記載します。これはスケジュールの基礎となるもので、プロジェクト計画の要となるものです。

- 見積もり時間には、タスクを開始し完了すべき日付と、さまざまなマイルストーンを達成するための日付が含まれます。
- また、プロジェクトの開始日と終了日も含まれます。これは、どのリソースがいつ必要になるかを決定する上で重要です。

# プロジェクト計画のピースを組み立てる

これまで、タスク、マイルストーン、メンバー、文書、時間など、プロジェクトプランの一般的な要素について説明してきました。ここでは、これらの要素と他の重要な要素がどのように交差し、プロジェクトの包括的な計画を作り上げていくかを見ていきましょう。

プロジェクト計画の中心は、プロジェクトスケジュールであり、プロジェクト完了までにかかる時間を見積もり、目標に対するプロジェクトの進捗をチームで確認するためのものです。プロジェクト計画には、スケジュールのほかに、次のような要素も含める必要があります。

- スコープとゴール
- WBS
- 予算
- 管理計画

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2358573/8559b29d-5382-78d5-392a-305f685286f5.png" width="400">

### スコープとゴール

プロジェクトのスコープとゴールは、プロジェクト憲章に最初に取り込まれます。プロジェクト憲章は、プロジェクトプランの中でリンクさせることができます。プロジェクトの範囲と目標に関する詳細に簡単にアクセスできるようにしておくと、チームが達成しようとしている目標を思い出すことができ、その目標を達成するために最初に合意した以上のことが要求された場合にも役立ちます。

### WBS

WBSとは、プロジェクトのマイルストーンやタスクを、完了すべき順番に階層的に並べたものです。 WBSは、作業をより管理しやすいピースに分解するため、プロジェクト計画の鍵になります。プロジェクト計画では、タスクを一箇所にまとめて、明確な説明、所有者、期日を表示する必要があります。これにより、あなたとあなたのチームは、誰がどのタスクに責任を持ち、それぞれのタスクがいつ完了することになるのかを理解することができます。また、これらのタスクに関連するマイルストーンとステータスを詳細に記載することで、あなたとチームメンバーがプロジェクトの進捗を視覚化できるようになります。

WBSの他に、役割と責任を明確にするために、RACIチャートのような文書もプロジェクト計画に追加すると効果的です。このような文書を一箇所に集めておくことは、透明性を高め、効果的なコミュニケーションのためのベストプラクティスです。

### 予算

プロジェクトのライフサイクルを通じて、予算は管理、モニターされる必要があります。プロジェクト予算は、プロジェクトの重要な要素に大きく依存するため、プロジェクト計画と連動させることが多い。これらの構成要素をリンクさせることで、よりスムーズな管理と可視化が可能になります。

プロジェクトの規模や組織によっては、あなたがプロジェクト予算管理の主要な責任者であるとは限りません。例えば、プロジェクトが大規模な組織で、資金が他の部署で管理されている場合、あなたは予算要素のすべてについて、それほど自律性や洞察力がない可能性があります。その結果、あなたは予算を厳密に監視することができなくなるかもしれません。他の部署の誰かが予算を管理している場合、その人と定期的にチェックインを行い、自分がどのようにトラッキングしているかを確認するようにしてください。

### 管理計画

変更管理計画、リスク管理計画、コミュニケーション計画などの管理計画は、プロジェクトを組織的かつ計画的に進めるために不可欠なものであり、プロジェクト計画の中で関連付ける必要があります。
ArtifactHubからhelmのリポジトリをlocalに落としたい


# helmのchartファイルをローカルに落としたいです。

https://artifacthub.io/packages/helm/external-secrets-operator/external-secrets


## 解決策

リポジトリをrepoに落とす。
```shell
helm repo add external-secrets https://charts.external-secrets.io
```


以下コマンドで圧縮ファイルを取得できる。
```shell
# helm pull external-secrets/<Chart.yamlのname>
helm pull external-secrets/external-secrets 
```
TypeScriptでTypeを指定するについて

<h2>Type Declaration</h2>
JavaScriptの場合

```javascript
const container = document.getElementById('root');
```

TypeScriptの場合、【cont variable:TYPE = data】
```typescript
const container: HTMLElement | null = document.getElementById('root');
```

VisualStudio Codeツールでは、以下のように変数にmouse hoverすると何Typeを指定すればいいか教えてくれます。VSCode自体がTypeScriptで作られたようで、TypeScriptの機能を沢山サポートするようです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3097775/c260c166-e82d-b22a-fbc3-53697892963d.png)

<h2>Object Type Declaration</h2>
JavaScriptの場合

```javascript
const store = {
  currentPage: 1,
  feeds: [],
};
```
TypeScriptの場合、Typeを記述する方法が二つあります。

```typescript
// ①Interface
interface Store {
  currentPage: number;
  feeds: NewsFeed[]; // NewsFeed[]がType。NewsFeed配列しか扱いしないと制約をかけます。
}

// ②Type Alias
type Store = {
  currentPage: number;
  feeds: NewsFeed[]; // NewsFeed[]がType。NewsFeed配列しか扱いしないと制約をかけます。
}
```

```typescript
const store: Store = {
  currentPage: 1, //'1'にすると、エラーが発生。上でcurrentPageのTypeをnumberとしたため。
  feeds: [],
};
```

<h2>Type Interface</h2>
Typeを推論するとの意味。
以下のfor文を書くと、let iにtypeを指定していないのに、<br>typeを書きなさいとメッセージが出ません。
<br>
それは、TypeScriptがコード上の状況を見て自らどのTypeを扱っているか認知するからです。<br>
「i = 0」としているので、TypeScriptはnumberでしょ・・と推論するわけです。

```typescript
function makeFeeds(feeds: NewsFeed[]):  NewsFeed[] {
  for (let i = 0; i < feeds.length; i++) {
    feeds[i].read = false;
  }
  return feeds;
}
```

<h2>Type Guard</h2>
containerはHTMLElement Typeとnullデータが入れます。<br>
Typeが二つであり、その一つがnullであれば、Type Guardをしてあげる必要があります<br>
<b>つまり、データが当然あるでしょと思い、変数にアクセスしようとした時に、Typeを制御する仕組みになります。</b>
そのため、下の【No Type Guard】ロジックのままだとエラーが発生するはずです。

```typescript
// No Type Guard
const container: HTMLElement | null = document.getElementById('root');
// containerがnullかもしれないのに？
container.innerHTML = "Is there a container? Yes" 


// Do Type Guard
function updateView(html: string): void {
  if (container) {
    container.innerHTML = html;
  } else {
    console.error('do not exist container')
  }  
}
```
Unityで心理実験ーUnityのインストール

---
前回：[その０](https://qiita.com/I-Kent/items/c5710b7395efee8e9326)
 ## Unityのインストール

今回はとりあえず、Unityのインストールまで！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2699725/c682eb77-aece-cca6-bdab-fd7a56064663.png)
https://unity3d.com/jp/get-unity/download

Unityのホームページへ行き、UnityHubをダウンロードのボタンを押せばDLできます
DLしたUnityHubSetup.exeってやつを実行してインストール
インストールが終わったらUnityHubを開いてみてください
ファイヤーウォールの警告はアクセスを許可で
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2699725/beeecdf4-e386-9f74-b8cd-770adad53bdb.png)

現在インストールしたものはUnity HubであってUnity本体はまだインストールしていません
そこでインストールのタブの右上の[エディターをインストール]のボタンをクリックして
推奨バージョン、LTSと書かれたバージョンをインストールしてください。
とりあえずそのバージョンを入れとくのが定番っていう感じです。
モジュールは必要であれば言語パックの日本語のチェックを入れておくだけで大丈夫です。
（バージョン・モジュールについて詳しく知りたい人は↓）
https://dkrevel.com/makegame-beginner/unity-hub/

 ## Unityをいじってみる
インストールが終わったら早速Unityを触ってみましょう
プロジェクトのタブから右上の「新しいプロジェクト」をクリックして、3Dを選択、
プロジェクトを作成でプロジェクトを作ります。
ファイヤーウォールの警告が出たら「アクセスを許可」
しばらく待つと
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2699725/49d19b41-df2f-8350-72c3-b43b36a461be.png)
こんな感じの画面が開くと思います
これが基本的な開発の画面になります
詳しくどんなことができるのかなどは追って理解していくと思う
（私自身もそんな知ってるわけではない）のでここでは説明を省きます。

まぁとりあえずいろいろ作ってみましょう！

----
取り合えず今回はここまで！
作成まで入ると長くなりそうなので短いけど次に続きます…
次回からは早速簡単な実験を作ってみます
よろしければ見ていただけると嬉しいです

twitterアカウント : [I.Kent](https://twitter.com/dodocker1?t=8G_9dRCIIKqIow2_UmeZMw&s=09)
←前回：[その０](https://qiita.com/I-Kent/items/c5710b7395efee8e9326)
context.select,read,watchの違い

[providerを使用](https://pub.dev/packages/provider)

watch ⇒ notifylistenerが呼ばれるたびに再描画が行われる。

read ⇒ 再描画が行われない。

select ⇒ 状態の値が変化してかつnotifylistenerが呼ばれると再描画が行われる。

続く...
アセンブリ言語 とは

## 勉強前イメージ

カーネルとか関係あるっけ？
細かいところの話とかOSとかそんな話だった気がする・・・
アセンブラとはちがう？

## 調査

### アセンブリ言語 とは

プログラミング言語の種類の一つで
CPUが直接実行できるマシン語に対応する命令語で記載された言語になります。
要するに人間が使うプログラミング言語で機械に近い低水準言語になります。

アセンブリ言語はそのまま実行できないので機械語に変換することを `アセンブル` と言います。
また、変換するためのソフトウェアのことを `アセンブラ` といいます。
まとめるとアセンブリ言語はアセンブラでアセンブルして実行されます。

コンピュータは機械語の命令をオペコードというビット列で表されます。
オペコードは人間には読解が困難です。
なので人間でも読めるニーモニックという命令語を定義し、オペコードと対応したものをアセンブリ言語と言われます。

## 勉強後イメージ

アセンブラとかアセンブリとかよくわかってなかったけど
機械語に近いものがアセンブリ言語なのね。

## 参考

- [アセンブリ言語【assembly language】](https://e-words.jp/w/%E3%82%A2%E3%82%BB%E3%83%B3%E3%83%96%E3%83%AA%E8%A8%80%E8%AA%9E.html)
俺のvimの今の話

## 浦島太郎

……もうすっかりQiitaで記事を書くことがなくなってしまったんですけど、まぁ別に別なblog使ってるとかではなく、**自分が使いたくてvimの話を始めたケースがほぼすべてなくなってしまっている**というのが理由だったりします。その間にも[このあたり](https://qiita.com/astrorobot110/items/4cce7b4871eb3b8fd341)とか[このあたり](https://qiita.com/astrorobot110/items/d76e7358cc35929e90ba)とかはいいね改めLGTM改めいいね貰っていたんです。ホンマこんなスクリプトキディの話に乗ってくださってありがとうございます。

気が付けばvimもメジャーバージョンアップして、vimscriptも爆速になったらしいんですけど、まぁそんなのさておきでついこないだまで数年継ぎ足しては使っていた自分のvimrcを先日ついにワイプして設定しなおしたんです。

さて玉手箱の中身は……

[git:astrorobot110/vimrc](https://github.com/astrorobot110/vimrc)

## 使わないものは必要ない

とにかく必要じゃなかったものはそぎ落としてしまいました。

今までQiitaに垂れ流してきた自作のプラグインはほぼすべて外しています。自分流のハックとして残ったものは`<Leader>:`でbangし忘れたコマンドをbangしなおすハックくらいですが、これに関しては思いついてやっている人も居そうなやつです。

```pligin/remap.vim
" bang実行
nnoremap <expr> <Leader>: substitute( @:, '^\(\S\+\)', ':\1!', 'e')
```

割とお気に入りの方法です。

このほかに……まーバッドノウハウなんですけど、めったに使わないkaoriya版vimの`hz_ja.vim`をgithubから読み込んだりしています。

```plugin/snippet.vim
" 必要な時だけ半角全角変換を読み込むやつ
cabbrev hz= source https://raw.githubusercontent.com/koron/vim-kaoriya/master/kaoriya/vim/plugins/kaoriya/plugin/hz_ja.vim
cabbrev HZ= sp +/Japanese\ Description: https://raw.githubusercontent.com/koron/vim-kaoriya/master/kaoriya/vim/plugins/kaoriya/plugin/hz_ja.vim
```

もっとスマートな方法が、それこそvim-plug使ってそれだけって出来る方法があれば誰か教えてもらえると……。このロードに使う方法がスニペット経由なんですけど、確かこのあたりも村岡師のスパルタンな思想だった気がします。

あと残した有能っぽい方法は、昔秀丸ユーザーだった頃から手放せない「カレント行を計算して計算結果をputするマクロ」です。

```/autoload/calcIt.vim
function! calcIt#main(...) abort
    let formula = len(join(a:000)) > 0 ? join(a:000) : matchstr(getline('.'), '^=\?\zs.*')
    let answer = len(join(a:000)) > 0 ? [ formula ] : []

    try
        call add(answer, '='..string(eval(formula)))

        if mode() ==? 'i'
            return "\n"..answer[-1]
        else
            call append(line('.'), answer)
        endif
    catch /E\(15\|121\)/
        echo '=42.0'
        return ''
    endtry
endfunction
```

あとは、現在のメモツールが[Obsidian](https://obsidian.md/) + onedrive & [OneSync](https://metactrl.com/)という組み合わせになっています。
Obsidianの場合、ノートがディレクトリ/ファイル名管理なのでデイリーノートはvimでアクセスしてしまっても、あとは勝手に読むし、何ならoneDriveで勝手にandroid側でも同期しています。パッと読むときはObsidianがいいけど、書くときはvimがいい、という需要をいい感じに満たしてくれるので満足度は高いです。

## スパルタンvimのその先はあるのか？

……それがあるのかどうかと言われると、「自分にはあったけど、それは研鑽することではなかった」というところに落ち着きました。具体的に何を言っているのかというと、**頑張らないことでリラックスして使おう**ということになりました。

頑張らないので`hjkl`おしっぱで移動もヨシです。
頑張らないのでマウス移動もオーケーです。
頑張らないので挿入モードで矢印使……うのはナシですけどさすがに。

とにかくリラックスして使っていればオーケーなんです。

そう言う意味で、逆に望む操作をまとめてしたいからスクリプトを書くことも減らしたいんです。特にリマップですね。それでも人並みにはしていると思うんですけど、本当にこの操作とこの結果が指で結びつくかをちょっと試して、馴染んでなかったら使わないことにしたいんです。**その代わり、vimの機能でクールにやれるならそれ覚えます**。
何より僕、エンジニアではない故に無理に時間効率を上げる必要がないので、リラックスと言って非効率にvimと戯れてもいいし、逆にキーマップ覚えて操作詰めるための時間がもったいない、という事もないので。

そんなこんなで、ちょっとは気にしていただいてるので久しぶりにエントリを残した次第です。

Happy vimming.