OmniAICreator/Qiita-1.07M huggingface dataset:
[Ansible]暗黙的なlocalhostにご用心

# 結論

- Ansibleは暗黙的に`localhost`のインベントリ情報が作成されている
- `localhost`をインベントリで定義した場合、[暗黙的に宣言されている変数](#暗黙的に宣言されている変数)も追加しておく必要がある
- トラブル回避のために、プロジェクト開始当初から明示的にlocalhostを定義するのがおすすめ

# 事象

AnsibleでvCenterのようなAPIを使った操作をする際、vCenterログイン情報はグループ`vcenter`に記載して実際の作業は`localhost`というパターンがよくあります。
タスクごとに`delegate_to: localhost`を書くことでも対応はできるのですが全タスクに書くのがとても面倒です。

そういったとき、グループ`vcenter`にホスト`localhost`を含めることでPlaybook側は、`hosts: vcenter`のみ記載するだけでよく、`delegate_to: localhost`もなくPlaybookがスッキリします。

具体的には以下のような記載

```yaml:playbook.yml
---
- hosts: vcenter
  gather_facts: false
  tasks:
    - name: vcenter VM作成
      community.vmware.vmware_guest:
        ～～
```

```yaml:hosts.yml
---
all:
  children:
    vcenter:
      hosts:
        localhost:
```

しかし、このまま動かすとSSHでアクセスしようとして以下のようなエラーが出てしまいます。


```
PLAY [vcenter] ******************************************************************************************************************************************************************************************************************************

TASK [vCenter VM作成] ***********************************************************************************************************************************************************************************************************************
fatal: [localhost]: UNREACHABLE! => {"changed": false, "msg": "Failed to connect to the host via ssh: root@localhost: Permission denied (publickey,gssapi-keyex,gssapi-with-mic,password).", "unreachable": true}

PLAY RECAP **********************************************************************************************************************************************************************************************************************************
localhost                  : ok=0    changed=0    unreachable=1    failed=0    skipped=0    rescued=0    ignored=0
```

# 解決方法

Ansibleはlocalhostが定義されていないときに、わざわざlocalで接続しに行くlocalhostを作成しています。
明示的にlocalhostが定義された場合、上記の設定がなくなりAnsibleのデフォルト接続方法であるSSHで接続しに行ってエラーが起きています。

そのため、暗黙的なlocalhostで定義されていた情報を明示的に書いてあげることで解決ができます。

記載場所は色々ありますが、今回は手っ取り早く`host_vars/localhost.yml`を作成してそこに以下の変数を定義します。

## 暗黙的に宣言されている変数

```yaml:host_vars/localhost.yml
---
ansible_connection: local
ansible_python_interpreter: "{{ ansible_playbook_python }}"
```

# 余談

初歩的な内容ではありますが、localhostへのアクセスはよく使われるポイントであり、初心者が詰まりやすいポイントです。

また、環境差異が起きやすいポイントでもあります。
例えば、Ansible実行サーバが自身のSSH公開鍵を`~/.ssh/authorized_keys`に登録しているなどしているとエラーなく通ってしまいます。


テスト環境では、うまく行ったのに本番環境ではうまくいかなかった。などが起こってしまうので、最初から明示的にlocalhostを定義しておいた方がトラブルなくなるのではないかと筆者は考えます。

# 参考リンク

- [暗黙的なlocalhostドキュメント](https://docs.ansible.com/ansible/latest/inventory/implicit_localhost.html)
VBA セル着色　まとめ

VBAで、ちょこちょこセルの着色って使うくせに、調べるとサイトが色々あっていい感じのが見つけられないことがあるので記載。

以下の記事を参考にしました。
[VBA セルに色を設定する (Interior.Color, ColorIndex)](https://www.tipsfound.com/vba/07006)
[【Excel VBA】ColorIndexプロパティの設定値　インデックス番号と色の対応](https://officek.net/excelvba/v-range/vr-format/vrf-colorindexnum/#i)

## パターン1：ColorIndex
1つ目はColorIndexですね。0~56までの数値を選ぶことで色を決定できるので楽です。
以下実際のコードになります。

```
Range("A1").Interior.ColorIndex = 0  ' 塗りつぶしなし
Range("A1").Interior.ColorIndex = 35 ' 黄緑
```
Cellsを使っても同様に記載できます。

```
Cells(3, 1).Interior.ColorIndex = 0  ' 塗りつぶしなし
Cells(4, 1).Interior.ColorIndex = 20 ' 薄青
```

実行すると以下のようになります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3256521/551841fa-1230-193f-0651-921cea333a30.png)

ちなみに全カラーインデックスは以下です。57以上を指定するとエラーになります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3256521/a6b2b415-e788-a903-4e45-a57915a3e017.png)


## パターン2：RGB指定
1つ目のColorIndexも非常に良いのですが、細かい色調整等がしたい場合は、以下のRGBを直接指定する方法が良いかと思われます。

以下、コードです。Range, Cellsの両者で記載しています。
```
Range("A1").Interior.Color = RGB(255, 0, 0)  ' 赤
Cells(2, 1).Interior.Color = RGB(0, 255, 0)  ' 緑
```

実行すると以下のようになります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3256521/be1a2e88-a6e3-09a7-f55b-34fa7ed7164a.png)

ただまあ、実際に色を選ぶのは素人には難しいので、以下のような色とRGBが記載されたサイトを参考にするのが良いかと思います。
[カラーコードの一覧表(色を調べる/色を作る)](https://itsakura.com/html-color-codes)


# まとめ
以上がセル着色のパターンになります。
pythonとかである、カラーテーブルみたいな便利機能があったりしないか探してみましたが、自分では見つけられなかったですね...
動画制作に役立つフリー素材サイト

# フリー動画素材サイト

動画AC

https://video-ac.com/

ＮＨＫクリエイティブ・ライブラリー

https://www.nhk.or.jp/archives/creative/

モーションエレメンツ

https://www.motionelements.com/ja/

動画素材.com

http://xn--hhro09bn9j8uh.com/

COVERR

https://coverr.co/

# フリー動画と画像素材サイト

Pexels

https://www.pexels.com/ja-jp/

pixabay

https://pixabay.com/ja/

# フリー写真素材サイト

写真AC

https://www.photo-ac.com/

ぱくたそ

https://www.pakutaso.com/

O-DAN

https://o-dan.net/ja/

Unsplash

https://unsplash.com/ja

# フリーイラスト素材サイト

イラストAC

https://www.ac-illust.com/

いらすとや

https://www.irasutoya.com/

Loose Drawing

https://loosedrawing.com/

ヒューマンピクトグラム2.0

https://pictogram2.com/

icooon-mono

https://icooon-mono.com/
Deep Unsupervised Learning using Nonequilibrium Thermodynamicsの個人的理解用メモ

# 論文情報
[Deep Unsupervised Learning using Nonequilibrium Thermodynamics,Jascha Sohl-Dicksteinら,2015](https://arxiv.org/abs/1503.03585)

# 論文の立ち位置
diffusionでよく引用されている比較的最初の論文

# 簡単な説明
- マルコフ連鎖を使用してある分布を別の分布に徐々に変換

# 数式での説明（結果のみ）
### Forward Trajectory
- $q(x^{(0)})$：データ分布
- $\pi(y)$：扱いやすい分布（正規分布とか）
- $\beta$：拡散率
```math
\pi(y)= \int dy'T_x(y|y';\beta)\pi(y')
```
y'からyへy徐々に変換していく。これはxでいうと、$x^{(t-1)}$から$x^{(t)}$へ徐々に変更していく

```math
q(x^{(t)}|x^{(t-1)})=T_\pi(x^{(t)}|x^{(t-1)};\beta_t)
```
以下工事中

# その他
内容に問題がある場合も責任は持てません。
コメントをいただければ修正します。
EC2上で公開しているウェブサイトを入れ替える

### 1. AWSのEC2にssh接続する。

https://qiita.com/kaiyo_yume/items/d6542b95a26a79b392e4

### 2. 新しいターミナルを開き、自分のパソコンのフォルダをec2のフォルダにコピーする。
- 自分のパソコンのフォルダは"/Users/name/Documents/html/hdoc"を指定した。
- ec2のフォルダは"/home/ec2-user"を指定した。
- EC2インスタンスのパブリックDNSは、ec2-3-115-72-15.ap-northeast-1.compute.amazonaws.com:/home/ec2-userを指定した。
```sh
scp -i "/Users/name/Downloads/ec2-key.pem" -r 
"/Users/name/Documents/html/hdoc" ec2-user@ec2-3-115-72-15.ap-northeast-1.compute.amazonaws.com:/home/ec2-user
```
- -iオプションででキーペア（"/Users/name/Downloads/ec2-key.pem"） を指定する。
- -rオプションを追加して、ディレクトリ全体をコピーできるようにする。

### 3. EC２のルートディレクトリ（/var/www/html）にあるすべてのファイルとディレクトリを削除。

```bash
sudo rm -rf /var/www/html/*
```
### 4. EC2のホームディレクトリの内容をドキュメントルートにコピー。
/home/ec2-user/hdoc の内容を /var/www/html にコピーした。

```bash
sudo cp -R /home/ec2-user/hdoc/* /var/www/html/
```
### 5. EC2のドキュメントルートの権限の確認

-lオプションは、詳細な情報を表示するためのもので、所有者やグループを含む情報を表示する。

```bash
ls -l /var/www/html

# drwxr-xr-x 5 root root   64  4月 17 07:45 html-folder
# -rw-r--r-- 1 root root 2940  4月 17 07:45 index.html
# -rw-r--r-- 1 root root 6975  4月 17 07:45 output.html
# -rw-r--r-- 1 root root 1333  4月 17 07:45 はじめに.html     
```
各カラムがどの情報を表しているかの説明。

##### 1. ファイルの属性と権限
- 最初の文字は、ファイルタイプ。
'd' はディレクトリ、 '-' は通常のファイルを意味する。
- 所有者、グループ、他のユーザーに対するファイルのアクセス権限（各3文字）。
許可がある場合は 'r'（読み込み）、'w'（書き込み）、'x'（実行）が表示され、ない場合は '-' が表示される。

##### 2. ファイルのハードリンク数

##### 3. ファイルを所有するユーザー
- root：ファイルの所有者

##### 4. ファイルを所有するグループ
- root：ファイルのグループ所有者

##### 5. ファイルサイズ（バイト数) 

##### 6. ファイルの最終更新日時

##### 7. ファイル名


表示された権限情報を見ると、ファイルとディレクトリは root ユーザーが所有している。
ファイルとディレクトリの権限は適切である。

### 6. サーバー側のスクリプトを使用する場合や、動的コンテンツを提供する場合は、ウェブサーバにユーザーとグループを設定する必要がある。
私のウェブサイトは、HTML、JavaScript、CSS だけで構成された静的なウェブサイトなので、ユーザー名とグループ名をウェブサーバーにする必要はない。
私は所有権を変更しなかったが、やり方は載せておく。

ウェブサーバにユーザーとグループを設定する。
Apache ウェブサーバーの場合、一般的なユーザー名とグループ名は www-data である。
```bash
sudo chown -R www-data:www-data /var/www/html/html-folder
sudo chown www-data:www-data /var/www/html/index.html
sudo chown www-data:www-data /var/www/html/output.html
sudo chown www-data:www-data /var/www/html/はじめに.html
```

### 7. ファイルとディレクトリの権限が適切でない場合は書き換える。
今回は書き換える必要がなかったが、やり方は載せておく。

一般的に、ディレクトリは 755（所有者に読み書き実行、グループと他のユーザーに読み取り実行）の権限が適切。
ファイルは 644（所有者に読み書き、グループと他のユーザーに読み取り）の権限が適切。
```bash
# html-folder以下のディレクトリの権限を755に設定
sudo find /var/www/html/html-folder -type d -exec chmod 755 {} \; 
# html-folder以下のファイルの権限を644に設定
sudo find /var/www/html/html-folder -type f -exec chmod 644 {} \;
# ファイルの権限を644に設定
sudo chmod 644 /var/www/html/index.html
```

### 8. EC2のssh接続を終了
```bash
exit
```
変化するelementのサイズを取得するためのResizeObserver

# はじめに

サイズが決まっていない`<div>`要素を検知するための方法を調べていくうちに`ResizeObserver`というAPIを知ったので簡単にまとめます。

https://developer.mozilla.org/ja/docs/Web/API/ResizeObserver

# 便利だと思ったケース

例えば`<Component />`の高さ(height)が可変だった場合に、その値変数で持っておきたい（さらに値の変化をリアルタイムで監視したい）場合に以下のように書けます。

```jsx
const Container = () => {
    const ref = useRef(null)
    const [height, setHeight] = useState()
    React.useEffect(() => {
        const elem = ref.current
        const observer = new ResizeObserver(() => {
             setHeight(elem.offsetHeight)
        })
    
        if (elem) {
             observer.observe(elem)
        }
    
        return () => {
            if (elem) {
                observer.unobserve(elem)
            }
        }
    }, []);
    return (
        <div>
            <Component ref={ref} />
        </div>
    )
}
```

# ざっくり説明

1. [useRef](https://react.dev/reference/react/useRef)で`Component`を参照
2. `ResizeObserver.observe`で`Component`のサイズ変化を検知
3. [useState](https://react.dev/reference/react/useState)で`height`を保持させて、変更があった場合は再レンダリングする（useRefは値の変化があっても再レンダリングされない）

# さいごに

最初に`useState`の引数配列の中に`ref.current.offsetHeight`を入れて実装していたのですが、うまくいかなかったので調べていくうちにこの方法に辿り着きました。
Laravelのphp artisan migrateで「Multiple primary key defined」エラー

# 環境
- Laravel 10.4.1
- データベース MariaDB 5.5.68
- PHP 8.2.4 

# 状況

php artisan migrate で primary key を複数設定してはいけない、と怒られた。
> SQLSTATE[42000]: Syntax error or access violation: 1068 Multiple primary key defined (Connection: mysql, SQL: alter table `test` add primary key (`id`))



実行しようとしたmigrationファイル
```PHP：\database\migrations\2023_**_**_135543_create_todo_table.php
Schema::create('test', function (Blueprint $table) {
    $table->integer('id')->primary()->autoIncrement();
    $table->integer('user_id');
    $table->string('title', 100);
    $table->text('todo');
    $table->dateTime('add_date');
    $table->timestamp('update_date')->useCurrent()->useCurrentOnUpdate();
    $table->charset = 'utf8mb4';
    $table->collation = 'utf8mb4_general_ci';
});
```
調べると、どうもこの行が問題で↓
`$table->integer('id')->primary()->autoIncrement();`
`auto_increment`を有効にすると自動で`primary key`がついてきてしまうので、2重になってしまうらしい。
なんだか強制的にこうされてしまうと、問題が起こることもあるのでは？という気がするのだけれど、、、汗
参考：[primary key のカラムとは別に auto_incremen するカラムがあるテーブルを migrate したい](https://qiita.com/shimon_haga/items/01abed2579e2927affe3)

確認のため、--pretend で実行されるSQLを確認してみる（実行はされない）。
参考：[Laravel Migration コマンドまとめ](ttps://qiita.com/mikakane/items/6ed937b4904be0f0a5cf)
```PHP
php artisan migrate --pretend
```
生成されたSQL
```SQL
⇂ create table `test` (
`id` int not null auto_increment primary key, 
`user_id` int not null, 
`title` varchar(100) not null, 
`todo` text not null, 
`add_date` datetime not null, 
`update_date` timestamp not null default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP) 
default character set utf8mb4 
collate 'utf8mb4_general_ci'
  ⇂ alter table `todo` add primary key (`id`)
```

確かに、primary keyが2回出てくるので、

`$table->integer('id')->primary()->autoIncrement();`
↓
`$table->integer('id')->autoIncrement();`
に修正し、
`php artisan migrate --pretend`
で確認すると、 primary keyが1つになった。
なので、再度 `php artisan migrate`したら、成功。
なんだか`->primary()`と明示的に指定できないのが気持ち悪いけれど、仕方ない。

## 参考：同様のケース
[primary key のカラムとは別に auto_incremen するカラムがあるテーブルを migrate したい](https://qiita.com/shimon_haga/items/01abed2579e2927affe3)
【2023年4月決定版】Stable Diffusion 公式にはないモデルを使ってフォトリアリスティックな美女画像を作る (3)

## 緊急速報：Stable Diffusion Web UI を Google Colab 上で使うとアカウントBAN?!

https://qiita.com/javacommons/items/e310e37ef7e2fe7b5d52

----

[https://majinai.art/ja/](https://majinai.art/ja/) を見てると、リアリスティックな女性を生成しているカスタムモデルは「chillout-mix」([【1】](https://qiita.com/javacommons/items/77f520d531eaed85ed53)、[【2】](https://qiita.com/javacommons/items/316167a7ecb7b5164537)を参照) 以外に「basil-mix」というのが主流のようです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/140610/b3fe4928-6434-2e3d-ac1e-5f3a0db5daca.png)

[https://github.com/camenduru/stable-diffusion-webui-colab](https://github.com/camenduru/stable-diffusion-webui-colab) には「basil-mix」がないので、ネットをさがしたら：

『[【Colab】basil mixを使って、すごく可愛いイラストを生成しよう！](https://original-game.com/how-to-use-basil-mix-on-colab/)』

で起動方法が紹介されていました。

ここ↓から起動できます。開いたら「ファイル」➡「ドライブに保存」をしておいてください。

[https://colab.research.google.com/github/javacommons/stable-diffusion-webui-colab/blob/main/basil_mix.ipynb](https://colab.research.google.com/github/javacommons/stable-diffusion-webui-colab/blob/main/basil_mix.ipynb)

詳しい起動方法・終了方法については、以下の記事をみながらやってください。

https://qiita.com/javacommons/items/77f520d531eaed85ed53

## 最後に

最後に「basil-mix」で生成された(私が生成した)画像をいくつか貼っておきます。詳しいプロンプトは以下の画像をクリックすると、[https://majinai.art/ja/](https://majinai.art/ja/) 内の詳細ページに飛ぶようになっています。([https://majinai.art/ja/](https://majinai.art/ja/) にアップロード・公開しました。プロンプトおよび各種設定パラメータも見れます)

<a href="https://majinai.art/ja/i/SEj_7GV"><img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/140610/adb6d18e-d818-7132-a393-8a346e5493c6.png" /></a>

<a href="https://majinai.art/ja/i/hAzdx0i"><img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/140610/7a789fa0-008d-fde7-8eff-bf6c9870b597.png" /></a>

このおねぇさんは「basil-mix」の女神様です・・・！

それでゃ！
BigQuery テーブルスナップショットへのクエリキャッシュ機能を試す

# BigQuery テーブルスナップショットへのクエリキャッシュ機能を試す

## はじめに
2023/4/10 のリリースノートで、テーブルスナップショットへのクエリにキャッシュ機能が使えるようになったとアナウンスがありました。

> The results for queries against table snapshots can now be returned from cache.

https://cloud.google.com/bigquery/docs/release-notes#April_10_2023

このアナウンスをメンターに共有したときに、

 - スナップショット元のテーブルのキャッシュを、スナップショットへのクエリ実行時に使えるのか
 - スナップショットへのクエリ結果のみキャッシュされるのか

のどちらの意味でも取れそう、という話をしました。
ので、実際にこの機能を使ってみました。

## 検証
### 検証①
まずスナップショットを作ります。
（ちなみに今回検証に使ったテーブルは Google Analytics のエクスポートデータを一部抜粋したものです。）
スナップショットはテーブル詳細タブの「スナップショット」ボタンから作れます。

![スナップショットボタン.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/426544/b7f234c1-d8c9-8091-f3f3-8ca348ae340e.png)


スナップショットの作成画面でスナップショット作成先や有効期限、スナップショット時間を指定できます。
デフォルトのスナップショットテーブル名は「ソーステーブル名+スナップショット取得日時」となるようです。

![スナップショット作成パネル.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/426544/e45f1a57-c793-2454-4a59-d8f5c89859ee.png)

スナップショットを作成したら、ソーステーブルでクエリを実行してキャッシュを作成します。

1回目
![ソーステーブルクエリ実行1回目.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/426544/e54a7f71-a516-152a-80bf-0bf4a68d6bea.png)


2回目でキャッシュが作成できたのを確認します。
![ソーステーブルクエリ実行2回目.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/426544/ee9f8b48-6a36-4deb-e1ab-fbd52dd82d8d.png)


作成したキャッシュと同じ条件でスナップショットテーブルにクエリを実行すると、キャッシュは使っていませんでした。
![スナップショットテーブルクエリ実行1回目.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/426544/c4205841-ad15-cd74-6ea6-1029a99c6f15.png)

↑と同じクエリを再度実行するとキャッシュが使われていました。
![スナップショットテーブルクエリ実行2回目.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/426544/14bb7d95-a773-a7e0-7c9e-232c23845b79.png)


### 検証②
検証①ではスナップショットを作成してからソーステーブルへのクエリのキャッシュを作成しましたが、
キャッシュがある状態でスナップショットを作成すると結果は変わるのか？という疑問が浮かんだのでやってみました。

ソーステーブルは検証①と同じテーブルを使います。
検証①と同じクエリキャッシュが残っている状態でスナップショットを作成し、キャッシュと同じ条件のクエリをスナップショットへ実行しました。
結果、キャッシュは使っていませんでした。
![クエリキャッシュある状態でスナップショット作成してクエリ実行.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/426544/45752a28-95cc-cacb-5d12-18ed572ba189.png)


## まとめ
クエリキャッシュは同じテーブルのみで、スナップショットであってもキャッシュ内容は共有されませんでした。

キャッシュを使うことでクエリ料金の削減やクエリ実行速度が速くなるというメリットがあります。
スナップショットだとデータが変更されることもないと思うので、有効に使っていきたいですね。

以上です。
誰かの参考になれば幸いです。
Git main(master)ブランチなどを別のブランチの内容で上書きマージしたい

# ユースケース

mainブランチへと、releaseブランチの内容をマージしたい。しかし、mainブランチに直前に別チームの変更内容がマージされていた関係で、releaseブランチとの間にコンフリクトが生じてしまっている。別チームの変更内容は今後不要なので捨てる予定である。そのため、コンフリクトの解除の手間なく、releaseブランチの現在の内容でmainブランチを完全に上書きするという形で、releaseをmainブランチにマージしたい、というようなケース。

# 方法

`git merge -s ours main`(sオプションマージ)を使いましょう。


```shell
git checkout release
git merge -s ours main
git checkout main
git merge release
```

# 参考

[Delftstack - Git マスターをブランチで上書きする](https://www.delftstack.com/ja/howto/git/git-overwrite-master-with-branch/)
[訂正あり] 【Bash】xargsの代わりにwhile readで個別ファイルにリダイレクト

# TL;DR
```bash:bash
$ ls *.zip | { while read zip_name; do md5sum $zip_name > $zip_name.md5; done; }
```

# やりたいこと
`hoge.zip`のmd5sumを`hoge.zip.md5`として保存したい。
`fuga.zip`、`piyo.zip`も同様に処理したい。
```bash:bash
$ ls
hoge.zip fuga.zip piyo.zip
```

# 試したけど駄目だった方法
```
$ ls *.zip | xargs -I{} md5sum {} > {}.md5
```
これをすると`{}.md5`が保存されてしまう。
`xargs`はリダイレクト先の文字列を置き換えられないようだ。

# 変数を経由する
標準入力をリダイレクト先にまで反映させたい、というだけなので、素朴に変数を使う。
[bashでパイプ(標準入力)から受け付けた内容を変数に代入する](https://orebibou.com/ja/home/201708/20170806_001/)
この記事で`read`と`cat`を使う方法が載っていた。

```bash:bash
$ #readを使う場合
$ #標準入力が変数zip_nameに書き込まれる。ただし標準入力が複数あった場合、最初の1つのみ
$ ls *.zip | { read zip_name; md5sum $zip_name > $zip_name.md5; }
```
```bash:bash
$ #catを使う場合
$ #標準入力が変数zip_nameに書き込まれる。標準入力が複数あった場合、配列として読み込まれるため失敗する。
$ ls *.zip | { zip_name=$(cat); md5sum $zip_name > $zip_name.md5; }
```

# ~~複数ファイルに対応する~~
いずれの場合も複数ファイルには対応できないので改良が必要になる。
~~「`while read zip_name; do ~ done;`かな……長すぎて嫌だな」としばらく悩んでいたが、何のことはなく`xargs`を一度挟めば良いだけだった。~~
```bash:bash
$ #xargsで1つずつreadに送る
$ ls *.zip | xargs echo | { read zip_name; md5sum $zip_name > $zip_name.md5; }
```

~~さらに`xargs`は[引数を省略するとデフォルトでechoを実行する](https://genzouw.com/entry/2019/06/28/140010/1634/)ので、~~

```bash:bash
$ #xargsで1つずつreadに送る(改)
$ ls *.zip | xargs | { read zip_name; md5sum $zip_name > $zip_name.md5; }
```
~~これで完成。~~

# 23/04/19 指摘を受け記述を削除
コメント欄で[動作しないとの指摘](https://qiita.com/YamEiR/items/ddce6f0f0745bd33f1a5#comment-a77fc905f5ccb2f5be29)を受け確認したところ、確かに動作しなかった。
@ko1nksm さん、ありがとうございます！

```bash:bash
$ ls
dummy2.zip  dummy.zip
$ ls *.zip | xargs | { read zip_name; md5sum $zip_name > $zip_name.md5; }
-bash: $zip_name.md5: ambiguous redirect
```

誤った情報を記載してしまったことを深くお詫び申し上げます。

取り急ぎ上記内容を打ち消し線で示しつつ、最終的な解決方法は週末にデバッグすることとする。

# 先行記事
`xargs リダイレクト`で検索すると複数の記事がヒットする。
[xargs は個別ファイルへ書き出すリダイレクトのパイプが使えない → for を使う](https://takuya-1st.hatenablog.jp/entry/20110705/1309867505)
forを使う方法。
[xargsで個別ファイルにリダイレクト](https://mkacky.wordpress.com/2013/04/17/xargs%E3%81%A7%E5%80%8B%E5%88%A5%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB%E3%81%AB%E3%83%AA%E3%83%80%E3%82%A4%E3%83%AC%E3%82%AF%E3%83%88/)
関数化する方法。
[xargsで個別のファイルにリダイレクトしたい](https://iww.hateblo.jp/entry/20141219/xargs)
shのサブシェルを呼ぶ方法。

本記事のタイトルも先行記事に倣った。
どれを使っても基本的には問題なさそう。

# 参考
[bashでパイプ(標準入力)から受け付けた内容を変数に代入する](https://orebibou.com/ja/home/201708/20170806_001/)
[xargs は個別ファイルへ書き出すリダイレクトのパイプが使えない → for を使う](https://takuya-1st.hatenablog.jp/entry/20110705/1309867505)
[xargsで個別ファイルにリダイレクト](https://mkacky.wordpress.com/2013/04/17/xargs%E3%81%A7%E5%80%8B%E5%88%A5%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB%E3%81%AB%E3%83%AA%E3%83%80%E3%82%A4%E3%83%AC%E3%82%AF%E3%83%88/)
[xargsで個別のファイルにリダイレクトしたい](https://iww.hateblo.jp/entry/20141219/xargs)
[xargsを使う際には`echo`は書かなくてもよいことをmanページから知った](https://genzouw.com/entry/2019/06/28/140010/1634/)
Laravelのバリデーションの日本語化

個人メモ。
Laravelでデフォルトで出るバリデーションを日本語化する方法。
下記の2つの記事で、基本のエラーメッセージはすべて日本語化し、他の独自メッセージのみ追加で対応できた。参考記事の方に感謝。

## 環境
- さくらVPSサーバー CentOS7
- Laravel 10.4.1
- PHP 8.2.4 

## 参考記事
[Laravelで日本語のバリデーションを設定する。](https://qiita.com/dam-san/items/3c0dc498d2fcab0bda0d)
[Laravelでバリデーションを日本語化する方法！](https://codelikes.com/laravel-validation-message-ja/)
Sass無しでCSSネストが可能に

## そのままのCSSでネストが！？
#### 結論：最新版のchrome(Chromeのv112)とEdgeの二つのみで対応しています。

実装状況は[こちら](https://caniuse.com/css-nesting)から確認できます

https://caniuse.com/css-nesting

EdgeはオープンソースであるChromiumと呼ばれるオープンソースのWebブラウザーエンジンをベースに開発されているので、Google Chromeと同じエンジンを使用しています。ですのでEdgeも対応しています。そしてSafariも次回から対応するようです。他のブラウザに関してはまだ実装されないようです。

ですので、`実務等で使用するのはまだやめておいた方が良い`でしょう。


## 実際に書いてブラウザ毎に確認してみた

共通しているコード
```html:index.html
<!DOCTYPE html>
<html lang="ja">
  <head>
    <link rel="stylesheet" href="style.css" />
  </head>
  <body>
    <div class="parent">
      親要素です
      <p class="child">子要素です</p>
    </div>
  </body>
</html>
```


```CSS:style.css
.parent {
  color: gray;
  .child {
    color: red;
  }
}

/*  ↓ 見やすくするためのスタイル */

.parent {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  height: 120px;
  width: 360px;
  border: 1px solid black;
  display: flex;
  align-items: center;
  justify-content: space-around;
  flex-direction: column;
}

p {
  margin: 0;
  padding: 0;
}
```

簡単に言うと、純粋なCSSでもネストに対応していたら子要素の「子要素です」の文字が赤色になるというだけです。
現在のQiitaのコードブロックでもエラーが出ています。

:::note warn
2023/04/17 現在の状況です。
:::

### Visual Studio Code
![スクリーンショット 2023-04-17 16.14.54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3330151/dc569a03-61fa-12cb-4498-6c3aecc855fb.png)


### Chrome(v.112)
![スクリーンショット 2023-04-17 15.57.40.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3330151/05d4665f-ce31-6b95-11db-c9a54b5b7732.png)

### Safari(v.12.1.2)
![スクリーンショット 2023-04-17 15.58.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3330151/e5ba7d14-65d9-cd93-d789-f3fdeed5e013.png)


### Firefox(v.111.0.1)
![スクリーンショット 2023-04-17 16.13.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3330151/b89934ee-5970-f581-05bb-ac1cb2c159b0.png)

**Chrome -> 反映　 Safari -> まだ反映されていない　Firefox -> 反映されない**

## Sassが必要なくなる？
個人的にSassの強みだと思う部分が変数やネスト、関数や演算だと思っていたのですが少しづつ純粋なCSSでかけるようになってきています。
色に対するアプローチはSassの方に軍配があがるのかなという感じですが、私個人としてはあまり色に対して関数を使用して指定することがないので実感したことはないです…
|            | CSS         | Sass         |
|:-----------|------------:|:------------:|
| 変数        | --primary-color: #ffffff;| $primary-color: #ffffff;|
| 演算　　　　　　     | width: calc(100% / 3);     | width: 100% / 3;|

個人的な感想ではありますが、`@use`ディレクティブやモジュール化のサポートなどSassにしかできないことは数多く残っているので、小さなプロジェクトではわかりませんが、大きくなるにつれてSassの優位性、必要性というのも高くなるのかなと思っています。
## まとめ

仮にある程度のブラウザで対応し始めて、CSSでネストして描くのがスタンダードになったとしてもSassはやはり便利です。
Sassの機能的な部分ではなく記法的な側面（楽にコード書きたい）からSassを使用しているという人たちは将来的にSassを使用しなくてもよくなるかもしれません。
ですが、そうではない強みというのもSassにはありますので、じゃあSass学ばなくてもいいじゃんとは考えずにぜひ学んでいくといいと思います。
【Xcode】プロジェクトをGitHub に上げる

# プロジェクトをGitHub に上げる

### １，プロジェクトを作成。

### ２，プロジェクトが開けたら、first commit 前にしたい変更をする。
（プロジェクト作成して最初に記載されている名前や、作成時間の削除など）

### ３，ターミナルで.DS_Storeファイルを削除する。（いらないファイルなので消したい）
「cd ~ 」でプロジェクトに移動し、以下コマンドを実施
```
// 現在いるディレクトリの.DS_Storeを削除する方法
find . -name '.DS_Store' -type f -ls -delete
// 念の為に削除できているか確認
ls -a
```

### ４，Git と連携
プロジェクトの上バーから「Source Control」を開き、「New Git Repository…」を選択する。
「Create」をする。

### ５，GitHub に上げる
NavigationArea（左側のエリア）の上部で左から2番目のロゴを選択する。
「Repositories」を選ぶ。
「Remotes」を右クリックし、「New “プロジェクト名” Remote…」を選択する。
上げるGitHubのアカウント等の間違いがなければそのまま「Create」

# 終わり
HTTPメソッドの取得方法

AzureFunctionsでリクエストのHTTPメソッド判定方法の備忘録です。
下記のコードの通り、req.methodからHTTPメソッドを取得することができます。
```index.js
module.exports = async function (context, req) {
    const http_method = req.method; 
    if (http_method == "GET") {
        # GETの処理
    } else if (http_method == "POST") {
        # POSTの処理
    }
```
なおリスクエスト情報はreqとバインドさせています。
```function.json
{
  "bindings": [
    {
      "authLevel": "function",
      "type": "httpTrigger",
      "direction": "in",
      "name": "req",
      "methods": [
        "get",
        "post"
      ]
    },
    {
      "type": "http",
      "direction": "out",
      "name": "res"
    }
  ]
}

```
Laravelの本番環境への設定切り替えメモ

個人メモです。
とりあえず思いついたもの。不足などあるかもしれません。

# .env のLOG_CHANNEL
.envの設定がデフォルトで
LOG_CHANNEL=stack
なので、1つのファイルに溜まって出る。
LOG_CHANNEL=daily
に変更して日毎にする。

# .env のLOG_LEVEL
ログの出力レベルを
LOG_LEVEL=debug
↓
LOG_LEVEL=info
に変更

# デバッグバーを非表示にする
.envの
APP_DEBUG=false
にする。

# .env のAPP_ENV

.envファイルで、
APP_ENV=local
↓
APP_ENV=production

値は好きに設定できる。
よく使われるのは
>local	　　　開発環境
staging	　　ステージング環境
production	　本番環境

など。
※この値を設定したことで、本番環境に切り替わるわけではない。
※下記のようにして、本番環境かどうか処理を分岐できる。
```PHP
if (config("app.env") === "production") {

}
```
また、
```PHP
$ php artisan env
```
で環境の値を確認できる。


# 環境ごとに .env ファイルを使い分ける
環境ごとに接続するデータベースやAPIを切り分ける場合は、各環境用に複数の.envファイルを用意する。
例）
ファイル名が　.env.local	　　　→開発環境で使うファイル
ファイル名が　.env.production	→本番環境で使うファイル


# 変更後にキャッシュクリア
.envを編集した際は、キャッシュをクリアしないと設定が反映されない場合があるらしいので、
```PHP
php artisan config:cache
```
を実行しておく。


# 参考
[【Laravel】 環境ごとにログの出力レベルを変更する](https://e-seventh.com/laravel-how-to-change-log-level/)
[LaravelのデバッグモードをOFFにする](https://blog.maro.style/post-1361/)
[Laravelの環境（APP_ENV）の判断方法](https://zenn.dev/naoki_oshiumi/articles/85fc131475b8b8)
[【Laravel】App::environmentとは何か？現在のAPP_ENVの値を調べる方法](https://prograshi.com/framework/laravel/app-environment/)
【EC-CUBE】ログアウトするとNotFoundHttpExceptionがでる

## 概要
EC-CUBEで`/logout`のパスにアクセスするとNotFoundHttpExceptionが発生します。

### 原因: 
UserDataControllerに下記のようなRoutingを設定していたためです。
```
    /**
     * @Route("/{route}", name="user_data", requirements={"route": "([0-9a-zA-Z_\-]+\/?)+(?<!\/)"}, methods={"GET"})
     */
    public function index(Request $request, $route)
~~~
```
カスタムページの`user_data/{ページ名}`からuser_dataを消すためにこのようなルーティングを設定しましたが、結果として`/logout`もキャッチしてしまい、エラーが発生するようになってしまいました。

### 解決策:
__priority__ を使用して、ルーティングの優先度を下げることで解決できます。具体的には、ルーティングアノテーションの中に`priority=-1`を追加します。
```
    /**
     * @Route("/{route}", name="user_data", requirements={"route": "([0-9a-zA-Z_\-]+\/?)+(?<!\/)"}, methods={"GET"}, priority=-1)
     */
    public function index(Request $request, $route)
```

### 他の解決策：
他にも`/logout`のアクションを独自で定義して、カスタムページのルーティングよりも優先順位を高くする方法もありますが、ログアウトを再実装する際には、セッションの破棄や認証の解除など、セキュリティ上の重要な処理を実装することになるため、注意が必要です。

## まとめ
Symfonyのルーティングに関する勉強をしていて、__priority__ の存在を知っていたため、このような解決方法を思いつきました。今後も、SymfonyやPHPの勉強を進め、実務で役立てていきたいと思います。
Firebase Extention がインストールできないときに

### はじめに

最近、Stream Firestore to BigQuery を利用しており、Firebase FirestoreのデータをリアルタイムでBigQueryにストリーミングしようと試みた際、特定のエラーに遭遇しました。この記事では、そのエラーの内容、試みた解決策、そして最終的な解決方法について説明します。


### 解決方法

まずは結論から。

Firebase Extention で設定しているサービスアカウントから何故か Editor 権限が削除されていたため、付与しました。

https://github.com/firebase/extensions/issues/824#issuecomment-1067862577


### エラーの内容

Stream Firestore to BigQuery をデプロイしようとした際、次のエラーメッセージが表示されました。

```
RESOURCE_ERROR at /deployments/firebase-ext-firestore-translate-text/resources/serviceAccount-firestore-translate-text: {"ResourceType":"gcp-types/iam-v1:projects.serviceAccounts","ResourceErrorCode":"403","ResourceErrorMessage":{"code":403,"message":"Permission 'iam.serviceAccounts.create' denied on resource (or it may not exist).","status":"PERMISSION_DENIED","details":[{"@type":"type.googleapis.com/google.rpc.ErrorInfo","reason":"IAM_PERMISSION_DENIED","domain":"iam.googleapis.com","metadata":{"permission":"iam.serviceAccounts.create"}}],"statusMessage":"Forbidden","requestPath":"https://iam.googleapis.com/v1/projects//serviceAccounts","httpMethod":"POST"}}
```


#### 試したこと


このエラーを解決するために、以下の手順を試みました。


1. ユーザーに「オーナー」権限を付与
2. 「Cloud Tasks Enqueuer」「Cloud Datastore User」権限を持っているサービスアカウントを作成
3. 他の拡張機能をインストール（同様のエラーが表示され、インストールできない）
4. Stream Firestore to BigQueryをアンインストール（同様のエラーが表示され、アンインストールできない）
:::note warn
これらの方法ではエラーを解決できません。
:::


### 解決までの手順

まずはエラー文で検索すると、下記の Issue を発見しました。

https://github.com/firebase/extensions/issues/824#issuecomment-1067862577

> 【日本語訳】
私の場合、クラウドサービスのアカウントに十分な権限がなくなっていました。どうやら、途中で紛失してしまったようです...。
Google Cloud API Service Agent (<project-id>@cloudservices.gserviceaccount.com) に必要なロールが全て入っていることを確認してください。デフォルトでは「Editor」（roles/editor）になっているはずです。


そして権限を追加します。
具体的な手順は以下の通りです。

:::note info
1. Google Cloud Console にアクセスし、プロジェクトを選択します。
2. 左側のナビゲーションメニューで「IAM と管理」を選択し、「IAM」をクリックします。
3. サービスアカウントの一覧から、エラーで言及されているサービスアカウントを見つけます。
4. サービスアカウントの横にあるペンシルアイコンをクリックして編集画面に移動します。
5. 「役割を追加」ボタンをクリックし、「プロジェクト」カテゴリの中から「エディター」役割を選択し、追加します。
6. 変更を保存します。
:::


これにより、サービスアカウントにエディター権限が付与され、Stream Firestore to BigQuery のデプロイが正常に完了しました。


### まとめ

今回の記事では、Stream Firestore to BigQuery のデプロイ時に遭遇したエラーと、その解決方法について解説しました。原因は、サービスアカウントからエディター権限が削除されていたことでした。

Google Cloud Platform (GCP) の権限管理は複雑であり、エラーが発生することがあります。権限に関するエラーに遭遇した場合は、サービスアカウントの役割と権限を確認し、適切な権限が付与されているかどうかを確認してください。また、公式ドキュメントや関連する GitHub Issue を参照することで、同様の問題に対処した他のユーザーからの解決策が得られることがあります。

今後も、技術的な問題や解決方法について共有していきますので、引き続きご覧いただければ幸いです。
他人数で開発しているrepoのtagsを削除する方法

他人数で開発しているrepoのtagsを削除しても、復活されることに遭遇したことあるでしょうか？

## 理由
①開発メンバーのローカルのtagsが削除されてなく、Source Treeなどを使う際にpushすると、復活されます
②BitriseなどCIツールのキャッシュで残ってしまって、何かしらのタイミングでpushされます

## 対策
①Github上でいらないtagsを消す
②メンバーのローカルのtagsを消してもらう
`git tag -l | xargs git tag -d`
③remoteからもう一回fetch
`git fetch origin`
④ローカルにいらないtagあるのか確認
`git tag -l`
⑤使っているCI/CDツールのキャッシュをクリア

## 参考
https://stackoverflow.com/questions/45681091/how-do-i-stop-users-from-pushing-all-tags-git-push-tags
https://community.atlassian.com/t5/Sourcetree-questions/Can-you-please-make-the-default-status-of-quot-Push-all-tags/qaq-p/971859
Laravelでのパーミッションの設定メモ

個人メモです。

# 環境
- さくらVPSサーバー CentOS7
- Laravel 10.4.1
- Apatch

# 設定方法

- Laravelのルートに移動
```bash
cd /path/to/laravel_application
```

- webserverユーザーにすべてのファイルとフォルダーの所有権を付与する。
※webserverユーザーとは、Webサーバー（Apache、nginxなど）がデフォルトで通常の操作に使用するユーザーのこと。
Ubuntu　ではwww-data　ユーザー
centosでは　apache　ユーザー
debian　www-data　ユーザー
→今回はcentosなのでapache　ユーザーを使用。
```bash
chown -R apache:apache /var/www/laravel_application
```

- すべてのファイルに 644 パーミッションを設定、すべてのディレクトリに 755 パーミッションを設定。
```bash
sudo find /var/www/laravel_application -type f -exec chmod 644 {} \; 
sudo find /var/www/laravel_application -type d -exec chmod 755 {} \; 
```

- storageとbootstrap/cacheのファイルとフォルダーに適切な読み取りと書き込みのアクセス許可を与える。
```bash
sudo chgrp -R apache storage bootstrap/cache
sudo chmod -R ug+rwx storage bootstrap/cache 
```

- ユーザーをapacheグループに追加
```bash
usermod -a -G apache <ユーザー名>
```
※ユーザーをグループに追加するコマンド
usermod -a -G グループ名 ユーザー名
→開発に使用するユーザーをapacheグループに追加して、apacheグループと同様の操作が行えるようにするという意図？

# 参考
[Laravelでファイルパーミッションを正しく設定する方法は?](
https://morioh.com/p/43a2abe38ef2)
[CentOS/Apache/Laravel使用時のpermission設定方法](https://qiita.com/Todate/items/d0d5c38f62621711a79b)
【UiPath】失敗する可能性のある処理をリトライスコープで成功するまで繰り返す

## 概要
毎回成功するわけではない処理は、もし失敗しても成功するまで繰り返すことができればワークフロー自体が失敗する確率を下げることができます。その方法について解説します。

## 失敗する場合がある処理の例
・ネットワーク通信が発生する処理（例：アセットを取得）
・操作対象のプロセスの状態によって稀に失敗する処理（例：Outlook、Excel、Web操作）

## 1つのアクティビティで完結する処理の場合

単にリトライスコープ内にアクティビティを配置します。リトライの回数を増やすことで失敗する確率を下げることができます。
![cap1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/229678/e4c81c25-d15c-ce5d-6a74-81fd9ed9f075.png)


## トランザクション処理（複数のアクティビティ）の場合
・失敗時のリカバリに複数のアクティビティが必要な場合
・複数の処理においてどこで失敗しても最初からやり直す場合

リトライスコープ内にトライキャッチを配置し、Try内に複数の処理を配置します。
![cap2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/229678/f1ef42d8-aa77-cd55-e9f1-0d2ae59bc5fc.png)

また、Catch内でエラー発生時のリカバリ処理を追加し最後に「Rethrow」を配置します。
![cap6.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/229678/bbd58eef-1ad5-0eb2-6491-a2b4d5f7ef75.png)

### ポイント
・Try内は「ワークフローファイルを呼び出し（InvokeWoprkflowFile）」のみを配置することをお勧めします
（複数の処理を入れてしまうとエラーの種類によってCatchされない場合があるため）
・「ワークフローファイルを呼び出し」は「分離」にチェックを入れ処理に十分なだけのタイムアウト時間を設定します
（処理がフリーズしたと判断し処理を継続するため。プロセスが分離されていればプロセスのフリーズ時でも継続可能です。）

## 環境
Studio 2023.4.0
MyBatis　リストを含む情報の取得(結合テーブルのマッピング)

## 経緯
　MyBatisで、複数のテーブルを結合しリストを含むオブジェクトを一括で取得する実装を行なったが、情報が点々としておりをまとまったわかりやすい情報が少なかったので、記録として残しておく
## 概要
id(カテゴリID)を受け取り、
categoriesテーブルとitemsテーブルを結合して、Categoryオブジェクトを作成する。
わかりやすい例として、DBとドメインは以下のように定義する。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3321564/8d7eb055-4e30-a30e-3dd5-2fbe54e20cd7.png" width=500px>

**↑テーブルイメージ**

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3321564/4d59a462-f445-4448-0579-af6e0ee9c58a.png" width=250px>

**↑Categoryオブジェクトイメージ**

## ディレクトリ構成
```terminal:ディレクトリ構成
.
└── src
    └── main
        ├── java
        │   └── com
        │       └── example
        │           ├── domain
        │           │   ├── Category.java
        │           │   └── Item.java
        │           └── mapper
        │               └── CategoriesMapper.java
        └── resources
            ├── application.yml
            └── com
                └── example
                    └── mapper
                        └── CategoriesMapper.xml
```


## 実装
```java:CategoriesMapper.java
@Mapper  
public interface ItemsMapper {
	Item load(int itemId);
}
```
```xml:CategoriesMapper.xml
	<select id="load" resultMap="categoryWithItemList">
		SELECT
		c.id
		,c.name
		,i,id
		,i.name
		FROM categories AS c
		LEFT OUTER JOIN items AS i
		ON
		c.id = i.category_id
		WHERE
		c.id =　#{categoryId}
	</select>
```

```xml:リザルトマップ
	<resultMap type="com.example.domain.Category" id="categoryWithItemList">
		<id property="id" column="id"/>　　
		<result property="name" column="name"/>
		<collection property="itemList" ofType="com.example.domain.Item">
			<id property="id" column="id"/>
			<result property="name" column="name"/>
		</collection>
	</resultMap>
```

```xml:リザルトマップ(省略版)
	<resultMap type="com.example.domain.Category"
		id="categoryWithItemList" autoMapping="true">
		<collection property="itemList" ofType="com.example.domain.Item" autoMapping="true">
		</collection>
	</resultMap>
```
　オブジェクトの変数名に対応するカラム名が同じであればresultMapタグのautoMappingをtrueにすることで<id>や<result>は省略可能。また、変数名がキャメルケース、カラム名がスネークケースであっても以下のように別途設定を行えば自動マッピング可能。
```yml:application.yml
mybatis:
  configuration:
    map-underscore-to-camel-case: true
```
Alibaba CloudのPolarDBの徹底分析(10)_PolarDBのストレージ料金を削減する方法

# PolarDBストレージの仕様
PolarDBストレージの前提：
- クラスター購入時に容量を指定する必要がなく、データの増加に合わせてストレージ容量は自動的に拡張されます。
- 使用量に応じて課金され、本当に使った分だけ課金され、言われるオンデマンド型の課金方式です。
- クラスターのスペックの向上によりストレージの上限も増え、最大100Tまで自動拡張できる。

https://qiita.com/dennis_wang/items/eff3a3993e4b590cfaca#%E3%82%B9%E3%83%88%E3%83%AC%E3%83%BC%E3%82%B8%E5%AE%B9%E9%87%8F

https://www.alibabacloud.com/help/en/polardb-for-mysql/latest/specifications-of-compute-nodes

とはいえ、ストレージ容量の自動拡張はオンデマンド課金方式になるため、GBあたりのコストが高額になり、容量が一定量を超えるとストレージ料金が上昇することになります。
ストレージ料金を削減するためには、以下の２つの方法があります。

# ストレージパッケージ

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/28664/f32793ee-e478-d3ed-d526-f379f34f819f.png)
ストレージプランは、PolarDBのサブスクリプションベースのリソースプランです。ストレージプランを使用して、ストレージ料金および無料クォータを超えるレベル1バックアップの料金を相殺することができます。ストレージプランは、ストレージリソースとレベル1バックアップを節約するのに役立ちます。ストレージプランのボリューム（容量と期間）が大きいほど、より多くのコストを節約することができます。例えば、月額制のストレージプランでは、同等の従量制クラスタと比較して、10%から45%の節約になります。プランの期間が長ければ長いほど、より多くの節約になります。年間ストレージプランを購入する場合は、月額料金からさらに15%割引になります。このトピックでは、ストレージプランの課金ルールとストレージプランの購入方法について説明します。

https://www.alibabacloud.com/help/en/polardb-for-mysql/latest/purchase-a-storage-plan

# ストレージのサブスクリプション

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/28664/e1bb0416-3578-4235-236d-e2b33e7c887a.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/28664/b8176e27-89fd-f442-217a-e3daf5da0047.png)

https://www.alibabacloud.com/help/en/polardb-for-mysql/latest/subscription

# 両者の使い分け
|  | ストレージパッケージ | ストレージのサブスクリプション |
|:-----------|:------------|:------------|
| 利用前提    | 1. 従量課金時にしか使えない<br>2. 利用できるリージョン内のすべてのPolarDBクラスターでシャアできる <br> 3. PolarDBクラスターをリリースしたとしても、ストレージパッケージをリリースしない限りは、ストレージパッケージ分の料金を払い続ける| 1. サブスクリプション時にしか使えない。<br> 2. 購入した該当のPolarDBしか利用できない <br>3. 該当のPolarDBクラスターをリリースしたら、サブスクリプションのストレージやコンピューティングリリースもリリースされて、課金が止まる|
| 利用範囲     |  1. PolarDBクラスターのストレージ　<br> 2. レベル1バックアップ       | 同様      |
| いつから使える？   | 既存の機能だから、既存のクラスターも対象になる        | 2022年新機能であるため、新規のクラスターしか適用されない |
|超えた分の課金方法|確保したパッケージ容量を超えた分はオンデマンド料金になる。|同様|
| 利用シーン     | お得：<br>複数クラスターにシャアできる容量をまとめて事前に確保することなので、基本的に単一のPolarDBしか使えない「ストレージのサブスクリプション」よりは割安傾向          | もっと気軽に利用できる：　<br> 1. 複数クラスターに必要な合計のストレージ容量(キャパシティ計画）を考えず、自分　のクラスターに必要なストレージ容量を確保すればよい <br> 2. 該当のクラスターをリリースすれば、ストレージ料金も掛からないことになる。          |
レゴブロックでエレベーターを作ったV2

# レゴブロックでエレベーターを作ったV2

### 秋葉原ロボット部　熊秀創吉（熊吉らぼ）

- レゴブロックのテクニック等で製作。　
- ４階建てのエレベーターです。
- 昇降用、扉開閉用の2つのモータで動作します。
モーター (SparkFun　ROB-13258)
https://www.sengoku.co.jp/mod/sgk_cart/detail.php?code=EEHD-53A4
- ScratchとNanoBoardAGを使い動作のプログラムで動作。
ちっちゃいものくらぶ：NanoBoardAG
https://tiisai.ddo.jp/?page_id=935

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3010655/0903843b-dbc2-0437-9981-28625b034a12.png)

### 初期型との変更点
- カゴ側の扉が開いた時、当たらないように本体枠の幅を大きくした。
- メンテナンス用に4Fと2Fのフロアが取り外し可能とした。
- モーターはLEGO用ではなく模型用を使用しビニルチューブ接続とした。
- カゴとフロア側の扉や爪の位置等を変えた。
- SWや扉開閉検知、カゴ位置検知の接続は全てNanoBoardの抵抗センサー入力とした。
- 本体枠からカゴまでの配線の吊り下げを輪ゴムの連続結びからロープにした。

## 構成
- 概略図
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3010655/0b57a5e8-d904-fc1e-4069-a8e758d95e5c.png)

## 全体配線図
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3010655/7cc3fac6-af99-b464-a470-30b1377cc9ca.png)

## NanoBoardAGと抵抗インターフェイス
- 抵抗インターフェイスの固定抵抗と多回転半固定抵抗
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3010655/76080125-f208-5d02-7410-93de06bb8ab2.png)

## 各フロアーとカゴ内のSW
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3010655/f35da181-13cb-2022-7f3e-d13fdd5c775c.png)

## NanoBoardAG と 回路図
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3010655/21ae40cf-cc73-9257-5165-df666fa1035b.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3010655/78ac447a-617e-c0ad-bd07-d395f69192af.png)

## 扉駆動機構
- 扉開閉検出回転VRと扉駆動モーター 及びカゴ位置検出用マイクロSW
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3010655/3a9f8e83-a403-2ea6-aedc-2e72e224da8f.png)

- カゴ側の扉の両サイドのツノがフロア側の扉の爪の間に入る。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3010655/85c67f60-f041-2f79-1e3a-47dd30e4e24a.png)

- フロア側とカゴ側の間にある扉閉まり防止SWはカゴ側の「扉開」SWに接続。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3010655/53af4b00-0768-d228-7818-e4d6943aa043.png)

- フロア側の扉
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3010655/e1d007ec-d7cc-5676-daee-ce0a1478bdd9.png)

## 昇降メカ
- 輪ゴムはロープをタイヤで圧着させるためのもの。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3010655/696c0623-4b8d-9113-bb80-676ff8fe80a5.png)

- ハンドルはカゴの床と各フロアの床を合わせた時、カウンタウエイト側にある爪がフロア検出SWに当たるように調整する為のもの。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3010655/53bbaf62-b244-acfa-a72f-791d0f188965.png)

## カウンターウェイト
- ウエイトを単三電池で代用。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3010655/1b707c1b-f401-27f3-b6a7-1afdf61b9926.png)

- カゴ位置検出用マイクロSW用の爪を装備
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3010655/a2d4bd73-efce-a24a-107c-8e6986abfe93.png)

## 本体からカゴまでのケーブル処理
- 上下に滑車使い輪ゴムはケーブルの緊張用に使用。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3010655/e657983f-fcd7-49a1-b2c3-2188f34eba18.png)

## Scratchプログラム
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3010655/e02488d6-224c-bdb3-888c-4b41f194aa5f.png)
Laravelで「View [] not found.」のエラーが発生

# 環境
- さくらVPSサーバー CentOS7
- Laravel 10.4.1
- PHP 8.2.4 

# 事象
ローカル環境（xampp）で開発したLaravelアプリをサーバーにデプロイしようとしたところ、「View ['フォルダ名,ファイル名'] not found.」のエラーが発生。→「View ['Layouts,（ファイル名）'] not found.」
ちなみにパスはあっておりviewファイルも存在している。
ローカルでは同じフォルダ構成、同じソースで問題なく動いている。

# 原因・解決
- linuxサーバーでは、大文字小文字を区別するシステム（ローカルは区別しない）だったことが原因だった。
- ローカル環境では、viewファイルから
@extends('Layouts.ファイル名')
との呼び出しの記載で動いていた。
呼び出される実際のローカルのフォルダは
\Laravelapp\resources\views\layouts
- linuxサーバー上では、フォルダ名が　layouts　だったため、
@extends('Layouts.ファイル名')
での呼び出しでは、大文字小文字を区別して、そのviewは見つからない、とのエラーになっていた。

- 今回の場合、（viewファイルすべての記載を、layoutsに書き換えるのも手間だったので）サーバーのフォルダ名の方を
layouts　→Layouts　と大文字始まりに変更することで解決した。
→mvコマンド　例）mv 変更前 変更後

※このエラーは、同様のものが複数発生した。サーバー側を変えると影響がでてまずい場合、Laravel側の記載を変更することも検討される。


# 参考
[LaravelにてページにアクセスするとView [] not found.のエラーが発生する](https://teratail.com/questions/200925?link=qa_related_pc)
Mac起動時に自動でVPN接続する

VPNに常時接続する必要があり、いちいち手動でポチポチするのがめんどくさいので起動時に自動接続するようにします。
スクリプトエディタを開いて以下をAppleScriptとして保存。

```AppleScript
tell application "System Events"
	tell current location of network preferences
		set myVpnService to the service "VPNの表示名"
		
		if current configuration of myVpnService is not connected then
			connect myVpnService
		end if
	end tell
end tell
```

VPNの表示名は`システム設定 > VPN`の赤枠の部分。

![スクリーンショット 2023-04-17 14.26.25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3075648/d18d67e3-fd97-7187-81d1-728a6ce266e9.png)

`システム設定 > 一般 > ログイン項目`で`ログイン時に開く`に追加して完了:ok_hand:

![スクリーンショット 2023-04-17 14.48.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3075648/c2e45767-a6b3-a1eb-08e6-81576f9bf5cc.png)
MariaDB（サーバー）のバージョンを確認する方法

# 環境
- さくらVPSサーバー CentOS7
- データベース MariaDB 5.5.68




# インストールパッケージからバージョンを確認する方法

- RedHat系の場合
rpm -qa | grep -i mariadb

```bash
# rpm -qa | grep -i mariadb
mariadb-5.5.68-1.el7.x86_64
mariadb-libs-5.5.68-1.el7.x86_64
mariadb-server-5.5.68-1.el7.x86_64
```
→5.5.68とわかる。

※注：`「mysql -V」で確認できるのは"mysqlクライアントの"バージョン`なのでサーバーのバージョンではない。




# MariaDB Serverに接続して確認する方法

## 1. サーバーでMariaDB（mysql）にログイン
mysql -u root -p
 →パスワード入力
バージョンが表示される。
```bash
# mysql -u root -p
Enter password:
Welcome to the MariaDB monitor.  Commands end with ; or \g.
Your MariaDB connection id is 1192
Server version: 5.5.68-MariaDB MariaDB Server

Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
```
→5.5.68とわかる。


## 2. statusコマンドを使う
```bash
MariaDB [(none)]> status;
mysql  Ver 15.1 Distrib 5.5.68-MariaDB, for Linux (x86_64) using readline 5.1

Connection id:          1194
Current database:
Current user:           root@localhost
SSL:                    Not in use
Current pager:          stdout
Using outfile:          ''
Using delimiter:        ;
Server:                 MariaDB
Server version:         5.5.68-MariaDB MariaDB Server
Protocol version:       10
Connection:             Localhost via UNIX socket
Server characterset:    latin1
Db     characterset:    latin1
Client characterset:    latin1
Conn.  characterset:    latin1
UNIX socket:            /var/lib/mysql/mysql.sock
Uptime:                 24 days 38 min 34 sec

Threads: 1  Questions: 13912  Slow queries: 0  Opens: 157  Flush tables: 2  Open tables: 75  Queries per second avg: 0.006
```


## 3. select version()コマンドを使う
```bash
MariaDB [(none)]> select version();
+----------------+
| version()      |
+----------------+
| 5.5.68-MariaDB |
+----------------+
1 row in set (0.01 sec)
```





# 参考
[MariaDB Serverのバージョンを確認する](https://orebibou.com/ja/home/201602/20160216_001/)
[MariaDB（MySQL）のバージョンを確認する【勘違いが多い】](https://self-development.info/mariadb%EF%BC%88mysql%EF%BC%89%E3%81%AE%E3%83%90%E3%83%BC%E3%82%B8%E3%83%A7%E3%83%B3%E3%82%92%E7%A2%BA%E8%AA%8D%E3%81%99%E3%82%8B%E3%80%90%E5%8B%98%E9%81%95%E3%81%84%E3%81%8C%E5%A4%9A%E3%81%84/)
【Django】Formのあれこれ

# 個別にcss属性を設定する方法
formクラスを作成する際に、__init__メソッド内の中で、```self.fields['フィールド名'].widget.attrs['属性名']```で設定する。

例)クラスとプレースホルダーを個別に設定する場合

```forms.py
from django import forms

class SampleForm(forms.Form):
    name = forms.Charfield(label='お名前', max_length=30)
    email = forms.Emailfield(label='メールアドレス')

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)

        self.fields['name'].widget.attrs['class'] = 'form-control col-9'
        self.fields['name'].widget.attrs['placeholder'] = 'お名前を入力してください'
        self.fields['email'].widget.attrs['class'] = 'form-control col-9'
        self.fields['email'].widget.attrs['placeholder'] = 'メールアドレスを入力してください'

```

# フォームエラーを表示する方法
フィールド単位のエラーを表示する場合は```{{ field.errors }}```で、特定のフィールドと紐づかず、cleanメソッドなどで発生するフィールド間で発生するエラーを表示する場合は```{{ form.non_field_errors }}```を用いる

例) 下記の場合で名前に「あほ」が含まれている場合、これは特定フィールド(nameフィールド)に紐づくエラーなため、```{{ field.errors }}```で「名前に暴言を含めないでください。」と表示される。一方で、カテゴリ1(お仕事の依頼)を選択した上でメールアドレスが未入力でフォームが送信された場合、これはフィールド間で発生するエラーな為、```{{ form.non_field_errors }}```で「お仕事の依頼の場合、メールアドレスは必須です。」と表示される。

```forms.py
from django import forms

CATEGORIES = (
    ('1', 'お仕事の依頼'),
    ('2', 'サイト内容に関する問い合わせ'),
)

class ContactForm(forms.Form):
    """問い合わせ用フォーム"""
    name = forms.CharField(label='お名前', max_length=50,required=False, help_text='※任意')
    email = forms.EmailField(label='メールアドレス', required=False, help_text='※任意')
    text = forms.CharField(label='問い合わせ内容', widget=forms.Textarea)
    category = forms.ChoiceField(label='カテゴリ', choices=CATEGORIES)

    def clean_name(self):
        name = self.cleaned_data.get('name')
        if name in ('ばか', 'あほ', 'まぬけ', 'うんこ'):
            self.add_error('name', '名前に暴言を含めないでください。')
        return name

    def clean(self):
        category = self.cleaned_data.get('category')
        email = self.cleaned_data.get('email')
        if category == '1' and not email:
            self.add_error(None, 'お仕事の依頼の場合、メールアドレスは必須です。')
        return self.cleaned_data

```


```inquiry.html
<form action="" method="POST">
    {{ form.non_field_errors }}
    {% for field in form %}
        <div class="field">
            {{ field.label_tag }}
            {{ field }}
            {% if field.help_text %}
                <span class="helptext">{{ field.help_text }}</span>
            {% endif %}
            {{ field.errors }}
        </div>
    {% endfor %}

    <div class="field">
        <button type="submit">送信</button>
    </div>

    {% csrf_token %}
</form>
```
Googleデータアナリティクス：表計算ソフトにおける文字列の扱い

# はじめに

本記事は、Googleデータアナリティクスのプロフェッショナル認定証のプログラムより、参照させて頂いています。興味を持った方は、是非受講してみてください。

https://www.coursera.org/professional-certificates/data-analytics-japanese

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2358573/21a12cb1-a49a-802f-d903-6f68758eca0c.png" width="800">

# 表計算ソフトにおける文字列の扱い

これは自転車走行データを示すデータです。 開始駅と終了駅の列には 自転車に乗った日付と 時間に関する情報が含まれています。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2358573/b30af765-37d0-6dbc-edc5-0a5f69b8567f.png" width="700">

これらの文字列には、日付や時刻など 複数のデータが含まれていますが、 もし開始時間帯の 平均時間を求めるのであれば 日付は必要ありません。 必要であれば、LEN、LEFTと RIGHT、FIND を使って タイムスタンプを別々の列に分割できます。 これらの文字列の日付を分割する、 簡単な式を作ってみましょう。 

### <font color="MediumBlue">LEN</font>
LEN は文字列の長さを示すもので あるのは、ご存じかと思います。 日時の文字列が、今どれくらいの 長さになっているか確認しましょう。 まず最初に、計算式の最初の 部分を入力します。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2358573/7327ba0f-c162-ace7-c87e-89e83f25dd1d.png" width="600">

そして、日時の文字列が 入力されているセルをひとつ選びます。 文字列の長さは 19 文字です。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2358573/f324aff3-7cd8-704a-9c0b-8b937bc78523.png" width="600">

### <font color="MediumBlue">FIND</font>

FIND 関数を使えば、文字列の中の 特定の文字を探し出すことができます。 ここでは大文字と小文字が 区別されることに注意してください。 FIND を使って部分文字列を取り出す場合は 部分文字列が正しく入力されているのを 確認してください。 すべての日時の文字列に 日付とタイムスタンプを区切る スペースが入っていることがわかります。 したがって、FIND を使用して 日付の終点を特定します。 

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2358573/cb91f10c-ff58-9ec4-9c98-f15331682fe8.png" width="600">

スペースはこの文字列で 11 番目の 文字にあたります。
つまり タイムスタンプを示す部分文字列は 12 文字目から始まることになります。 

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2358573/74f8fcec-10ee-df45-9498-f347bfbfbc9c.png" width="600">

### <font color="MediumBlue">LEFT／RIGHT</font>

ここで LEFT 関数と RIGHT 関数を使い 文字列のどの部分を新しい列に 分離するかを選びます。 ここでは、セルの 1 つに RIGHT を使用して 右側を取得することを指示します。LEFT も 同じように動作します。 次に、C 列の残りの部分にこの機能を 適用すれば、タイムスタンプを取得できます。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2358573/6661f126-40a8-89a5-d9da-cb22dc832030.png" width="600">

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2358573/3ca6f822-cea1-844d-4f04-de61026d5784.png" width="600">

次に、C 列の残りの部分にこの機能を 適用すれば、タイムスタンプを取得できます。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2358573/29a2d5ca-bef3-5fc8-76e6-733c689718f8.png" width="600">

データアナリストにとって、 文字列を扱えることは重要なスキルです。 外部のデータソースからデータを 取得する場合、特にそうです。
Laravelでphp artisan migrateでエラー「1071 Specified key was too long; max key length is 767 bytes」

# 環境
- さくらVPSサーバー CentOS7
- データベース MariaDB 5.5.68
- Laravel 10.4.1
- PHP 8.2.4 

# 事象
`php artisan migrate`で
1071 Specified key was too long; max key length is 767 bytes
エラー発生。

Laravelルートの　app/Providers/AppServiceProvider.php
に
\Illuminate\Support\Facades\Schema::defaultStringLength(191);
の１行追加で解決。
```bash
# vi app/Providers/AppServiceProvider.php
```
```PHP
public function boot()
{
    \Illuminate\Support\Facades\Schema::defaultStringLength(191);
}
```
# 参考
- [Laravel5.5でphp artisan migrateした時にエラー「1071 Specified key was too long; max key length is 767 bytes」が発生](https://akamist.com/blog/archives/982)
composer updateでCould not fetch https://api.github.com/repos/ エラー

具体的には以下のようなエラーが出ました。

```
Could not fetch https://api.github.com/repos/****, please review your configured GitHub OAuth token or enter a new one to access private repos
xxx
xxx
Token (hidden): 
```

ここらへん（http://blog.a-way-out.net/blog/2015/06/26/fuelphp-1-7-3-installation-trouble/) を読むと匿名でのGitHub APIのレート制限に引っかかっているようでもあるのですが、

```
curl -i https://api.github.com/users/whatever
```

をやっても全然リミットに達しておらず原因不明。
でもとりあえずTokenを生成して渡してやれば良いと思い https://github.com/settings/tokens からClassicで作ってみるもなぜか通らず。

Beta（fine-grained personal access token）のほうで作ってみたらうまくいきました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/930440/a0c03b0d-7598-8405-8e30-d749eb6e48d0.png)

Token nameを入れて、Public Repositories (read-only) を選択でOK。
もしかしたら何かやり方が悪かっただけでClassicのほうでもうまくいくのかもしれませんが、とりあえずClassicで駄目だったらfine-grained personal access tokenのほうを試してみてください。
VSCode ExtensionのPrettierでjsonファイルを保存する時にauto formatの設定

`prettier.config.js`に下記のコードを追加したらjsonファイルを保存する際にformatされてます
```
overrides: [
    {
      files: '*.json',
      options: {
        parser: 'json'
      }
    }
  ]
```