OmniAICreator/Qiita-1.07M huggingface dataset:
Introduction to SystemVerilog - 8

## 演算子と式

### 二項演算子

これまで何度か説明しないで演算子をコードの中で扱っていました。（算術）論理演算の排他的論理和（”^"）と論理積（”&"）です。これらの論理演算は各ビット位置について並行して論理演算を行います。そしてビット位置を扱うことから幅（スライス）を併用することがよくあります。主な二項論理演算子は次の通りです。

| 演算          | 種類      | 演算子   | 例             | 例の結果  |
|-|-|-|-|-|
| 論理和        | 論理演算  | \|       | 4'h5 \| 4'h6   | 4'h7 |
| 論理積        | 論理演算  | \&       | 4'h5 \& 4'h6   | 4'h4 |
| 排他的論理和   | 論理演算  | ＾       | 4'h5 ^ 4'h6    | 4'h3 |
| 加算          | 数値演算  | ＋       | 4'h5 + 4'h6    | 4'hb |
| 積算          | 数値演算  | *        | 4'h5 * 4'h6    | 8'h1e |
| 割算          | 数値演算  | /        | 4'h5 / 4'h6    | 4'h0 |
| 乗除          | 数値演算  | %        | 4'h5 % 4'h6    | 4'h5 |
| 乗数          | 数値演算  | **       | 4'h5 ** 4'h2   | 8'h19 |
| 左論理シフト   | 算術演算  | <<       | 4'h5 << 4'h1   | 4'ha |
| 右論理シフト   | 算術演算  | >>       | 4'h5 >> 4'h1   | 4'h2 |
| 左算術シフト   | 算術演算  | <<<      | 4'h5 <<< 4'h1  | 4'ha |
| 右算術シフト   | 算術演算  | >>>      | (-4'h5) >> 4'h1| -4'h2 (= 4'hd) |

幅（ベクトル長）が一致していない場合、割り当てと代入それぞれでどうなるか考えて試してみてください。また、引数に割り当て先や代入先のある二項演算の場合、その同じ引数を省略して例えば```inc += '1```とインクリメントを記述できます。

### 単項演算子

一つの引数のみ取る演算子の代表例は論理否定（"~"）です。他の論理演算同様各ビット位置に対して論理否定演算を行います。例えば```~4'h5 = 4'ha```です。数値演算では符号付き表記があります。例えば```-4'h5 = 4'hb```です。

他にリダクション演算子が論理演算に対してサポートされています。リダクションは指定されたビット位置（或いはすべて）に対して各ビットを引数として演算を行います。リダクション演算は主に次の３つを用います。

| 演算          | 種類      | 演算子   | 例       | 例の結果  |
|-|-|-|-|-|
| 論理和        | 論理演算  | \|       | \|4'h5   | 1'h1 |
| 論理積        | 論理演算  | \&       | \&4'h5   | 1'h0 |
| 排他的論理和   | 論理演算  | ＾       | ^4'h5    | 1'h0 |

### 比較演算子

他の言語同様に比較演算子もサポートされており、主に次のようなものがあります。

| 演算          | 種類      | 演算子   | 例       | 例の結果  |
|-|-|-|-|-|
| 大なり        | 算術演算  | >       | 4'h5 > 4'h6   | 1'h0 |
| 小なり        | 算術演算  | <       | 4'h5 < 4'h6   | 1'h1 |
| 等しい        | 算術演算  | ==      | 4'h5 == 4'h6  | 1'h0 |
| 等しくない     | 算術演算  | !=      | 4'h5 != 4'h6  | 1'h1 |
| 等しい        | 2値演算  | ===     | 4'h5 === 4'b011z  | 1'h0 |
| 等しくない     | 2値演算  | !==     | 4'h5 !== 4'b011z  | 1'h1 |
| 等しい        | 2値演算  | ==?     | 4'h5 ==? 4'b010z  | 1'h1 |
| 等しくない     | 2値演算  | !=?     | 4'h5 !=? 4'b010z  | 1'h0 |

他の言語同様に大なりと小なりに等しい条件を含めた```>=```と```<=```をサポートしています。
2値演算は4状態を持つ型、例えばlogic型で不定とハイインピーダンスも比較します。最後の二つは**右の二項目の引数**にワイルドカードとして不定とハイインピーダンスを含めることができます。

### ブール代数演算子

先に説明した論理演算は各ビット（ベクトルの各要素）に対して論理演算を行うものでした。他にブール代数に従った論理演算もサポートしており、このシリーズではブール演算演算子として名称を区別しています。他の言語と同様に真と偽を表現するもので演算の結果としてそれぞれ1と0とした結果を持ちます。また引数は0値の時を偽、それ以外を真として扱います。

| 演算          | 種類      | 演算子   | 例       | 例の結果  |
|-|-|-|-|-|
| 論理和        | 論理演算  | \|\|     | 4'h5 \|\| 4'h6   | 1'h1 |
| 論理積        | 論理演算  | \&\&     | 4'h5 \&\& 4'h6   | 1'h1 |
| 論理否定       | 論理演算 | \!        | !4'h5            | 1'h0 |


### 式

日常使われている算術数値演算の四則演算では演算子の間に優先順位が暗黙にあります。皆さんが知っているように積算と除算は加算と減算より優先順位が高いです。例えば```5+6*7```は```6*7```を先に演算した後にその結果と加算を行います。この優先順位は暗黙に決まっており、カッコ"("と")"を用いて演算の順番、つまり優先順位をコード上指定していないことに起因しています。SystemVerilogでは演算子に関して暗黙の優先順位を定義しています。この優先順位はこの言語特有のものであり、例えば算術積算より**単項**の加算の方が優先順位が高く定義されています。
WORDの図形をPNG形式で保存する

WORDの図形をPNG形式保存できないかなと調べてみました。
似たようなことを実施していらっしゃる方がおりました。

https://rikei-fufu.com/2020/03/31/post-2991-vba-word/

今回の環境は WORD2019 のためか、InlineShapes ではなく Shapes に画像ファイルが入っていました。
なので以下の1部を修正するだけで動作しました。

```
'図をコピーしてペイントで保存
Dim shp As Variant
For Each shp In wdDoc.Shapes
```
WORDから図形を取り出すのは簡単ですが保存するのってとても面倒なのですね。
図形を入れるのは簡単なのに・・・。
イーサリアム 2.0：ビーコンチェーンのブロック構造

イーサリアム 2.0 にはコンセンサスレイヤーとしてビーコンチェーンがあります。このチェーンのブロック構造を調べてみました

## ブロックデータ

キー | データ型 | 内容
-- | -- | --
slot | uint64 | Slot の番号
proposer_index | uint64 | バリデータに振られているインデックス
parent_root | Bytes32 | 親ブロックのルートハッシュ
state_root | Bytes32 | ステートデータのハッシュ
body | BeaconBlockBody | ボディーオブジェクト
body.randao_reveal | BLSSignature | RANDAO のランダム値更新データ
body.eth1_data | Eth1Data|  eth1 ブロックに対する投票データ（ eth1 ブロックのハッシュ、バリデーターの預金ツリーのルートハッシュ・既にに行われた預金の数を含んでいる）
body.graffiti | Bytes32| 任意のデータ
body.proposer_slashings | List | スラッシュするブロック提案者リスト
body.attester_slashings | List | スラッシュする検証者リスト
body.attestations | List[Attestation] | 現在ブロックに対する投票リスト
body.deposits | List[Deposit] | バリデーターになるための新しい入金リスト
body.voluntary_exits | List[SignedVoluntaryExit] | 退出したいバリデーターリスト

### randao_reveal
RANDAO 用のデータです。詳細はまた別途まとめます。

### state_root
イーサリアムの state と block の関係と似ています。
block にあるのは変更リストであり、それを一個前の block の state に適用することで、新しい state が計算できます。

詳細は下記に参照してください。

引用元：https://github.com/ethereum/consensus-specs/blob/dev/specs/phase0/beacon-chain.md#beaconstate

```python
class BeaconState(Container):
    # Versioning
    genesis_time: uint64
    genesis_validators_root: Root
    slot: Slot
    fork: Fork
    # History
    latest_block_header: BeaconBlockHeader
    block_roots: Vector[Root, SLOTS_PER_HISTORICAL_ROOT]
    state_roots: Vector[Root, SLOTS_PER_HISTORICAL_ROOT]
    historical_roots: List[Root, HISTORICAL_ROOTS_LIMIT]
    # Eth1
    eth1_data: Eth1Data
    eth1_data_votes: List[Eth1Data, EPOCHS_PER_ETH1_VOTING_PERIOD * SLOTS_PER_EPOCH]
    eth1_deposit_index: uint64
    # Registry
    validators: List[Validator, VALIDATOR_REGISTRY_LIMIT]
    balances: List[Gwei, VALIDATOR_REGISTRY_LIMIT]
    # Randomness
    randao_mixes: Vector[Bytes32, EPOCHS_PER_HISTORICAL_VECTOR]
    # Slashings
    slashings: Vector[Gwei, EPOCHS_PER_SLASHINGS_VECTOR]  # Per-epoch sums of slashed effective balances
    # Attestations
    previous_epoch_attestations: List[PendingAttestation, MAX_ATTESTATIONS * SLOTS_PER_EPOCH]
    current_epoch_attestations: List[PendingAttestation, MAX_ATTESTATIONS * SLOTS_PER_EPOCH]
    # Finality
    justification_bits: Bitvector[JUSTIFICATION_BITS_LENGTH]  # Bit set for every recent justified epoch
    previous_justified_checkpoint: Checkpoint  # Previous epoch snapshot
    current_justified_checkpoint: Checkpoint
    finalized_checkpoint: Checkpoint
```

### eth1_data
内容はバリデーターになる際の預金のルートハッシュと総数と、ブロックハッシュになります。
ブロックハッシュが１個しかないので、シャーディングの際にどうなるかは気になりますね。

```python
class Eth1Data(Container):
    deposit_root: Root
    deposit_count: uint64
    block_hash: Hash32
```

### proposer_slashings と proposer_slashings
バリデーターはブロック提案者と検証者として担当する処理があり、その処理が正しく実行できなかったり、または悪意の行為をした場合、罰則によって預かった預金を減らされてしまうことがあります。これが「スラッシュ」と呼ばれています。
この２つの項目はこれらの情報を記録するための項目です。

[イーサリアム 2.0のスラッシュとは？](https://coinchoice.net/what-is-ethereum20-slash/) で紹介した Epoch#208 の slot#6669 で proposer_slashings のデータがあります。
興味ある方はどうぞ。

https://beaconcha.in/slot/6669#overview

## まとめ
ビーコンチェーンはコンセンサスレイヤーとして、メインはバリデーター関連の情報を記録しているようなイメージですね。
圧倒的な成長を促すフィードバック文化とは

## フィードバックがなぜ重要か
主に現場があるような仕事においては、立ち話のようなその場限りのものになってしまうことが圧倒的に多いと思います。
もちろん規模感の違いもあると思うが、１時間程度の時間を別途設けることでその場限りで終わるものでなく、次に活かせるようなきっかけになります。
そんなフィードバックですが、やらされている感や注意のような捉え方になってしまうことが多いと思います。
そこでフィードバックにおける大事な点はこの３つになると思います。

### 意味のあるフィードバックにする３箇条
:::note info
主導はあくまでフィードバックをする側
:::
:::note info
内容は３つに絞る
:::
:::note info
２４時間以内にアクションサマリーの提出
:::


## 主導はあくまでフィードバックを受ける側
フィードバックにおいて１番の問題点は一方通行になってしまいがちなことです。
それはどちら側からもしかりで、双方言いたいことの言い合いになるのは絶対に避けるべきです。
とはいえ、フィードバックする側はあくまで上司なので少しでも軽減するためには、部下が実施のタイミングから内容なで決める方が良いと考えています。


## 内容は３つに絞る
会議の時間が短時間である以上内容をあらかじめ決めておくのは必須です。
私が今の会社でフィードバックを開催する際は
「できなかったこと」「できたこと」「対策」
を各３つまでと決めています。

順番も大事で必ず、「できなかったこと」を先に言うようにします。
後味が良い方が嬉しいじゃないですか笑

この内容を話してフィードバックもらうのが１人当たりだいたい２５分くらいが全体の時間を見ても、ちょうど良い時間になると思います。


## ２４時間以内にアクションサマリーの提出
正直ここがフィードバックを意味あるものにする最重要項目だと思っています。
ここでいうアクションサマリーは、備忘録のような議事録とは全く目的が異なります。

記録目的の冗長な議事録はひたすら正確を期して何日も費やして書き、 他の人に見せて間違いがないかOKをもらってから出します。当然のことですがそんなことでは何日も時間がかかります。


下手をすると会議が終わってから1週間や10日経ってからそれが人々の手に届く。 これでは
書かれている行動期限がとっくに切れていたりするものです。情報は鮮度が重要です。

意志決定の場で話し合われた末の結論、そして結論から導かれる次に取るべきアクション、
これをどれだけ速くチームに伝達できるか、その勝負だと思います。

アクション・サマリーの目的は「人を動かすこと」です。
DoctrineとEloquent比較大全17: 更新チェック

day17(?)の今日はエンティティ・モデルのデータに更新があるか（UPDATE文を発行する必要があるか）チェックする方法を見ていきます。

## Doctrine

```php
<?php

declare(strict_types=1);

use App\Entity\Book;
use Doctrine\ORM\EntityManagerInterface;

require __DIR__.'/../vendor/autoload.php';

/** @var EntityManagerInterface $entityManager */
$entityManager = require __DIR__.'/bootstrap.php';

$book1 = $entityManager->getRepository(Book::class)->find(1);
$book1->setTitle('Symfony6 The Fast Track');

$entityManager->getUnitOfWork()->computeChangeSets();
if ($entityManager->getUnitOfWork()->isEntityScheduled($book1)) {
    echo 'dirty!'.PHP_EOL;
} else {
    echo 'not dirty!'.PHP_EOL;
}
```
<https://github.com/77web/doctrine-vs-eloquent/blob/26769edf7f4874a14870758fd3272a7c844cae69/Doctrine/Usecase/check_if_dirty.php>

- EntityManagerのUnitOfWorkを使い、チェンジセットを計算させて、更新（UPDATE）が必要な状態かどうかを確認します。

## Eloquent

```php
<?php

declare(strict_types=1);

use App\Models\Book;

require __DIR__.'/../vendor/autoload.php';
require __DIR__.'/bootstrap.php';

/** @var Book $book1 */
$book1 = Book::find(1);
$book1->title = 'Symfony6 The Fast Track';

if ($book1->isDirty()) {
    echo 'dirty!'.PHP_EOL;
} else {
    echo 'not dirty!'.PHP_EOL;
}
```
<https://github.com/77web/doctrine-vs-eloquent/blob/26769edf7f4874a14870758fd3272a7c844cae69/Eloquent/Usecase/check_if_dirty.php>

- モデルの `isDirty()` メソッドを呼ぶだけでできます
docker-composeでコンテナ同士で通信できない

# 現象
ローカル環境でdocker-composeで下のようにコンテナを立ち上げたが、`app`から`mysql`に接続できない。

```js: アプリコード
const mysql = require('mysql2/promise');
const db = {
  host: 'localhost',
  user: DB_USERNAME,
  password: DB_PASSWORD,
  database: DB_DATABASE
};
const connection = await mysql.createConnection(db) //接続エラー
```
```Dockerfile: docker-compse.yaml
version: '3'
services:
  app:
    build:
      context: ./docker/app
    volumes:
      - .:/usr/src/app
    ports:
      - 3000:3000
    depends_on:
      - mysql
  mysql:
    build:
      context: ./docker/mysql
    volumes:
      - db-store:/var/lib/mysql
    environment:
      - MYSQL_DATABASE=${DB_DATABASE}
      - MYSQL_USER=${DB_USERNAME}
      - MYSQL_PASSWORD=${DB_PASSWORD}
      - MYSQL_ROOT_PASSWORD=${DB_PASSWORD}
      - TZ=${APP_TZ:-Asia/Tokyo}
    ports:
      - 3306:3306

volumes:
  db-store:
```

# 解決策

- コンテナ名で名前解決する
- コンテナ同士を同じネットワークに置く

```diff_javascript: アプリコード
const mysql = require('mysql2/promise');
const db = {
- host: 'localhost',
+ host: 'myDB',
  user: DB_USERNAME,
  password: DB_PASSWORD,
  database: DB_DATABASE
};
const connection = await mysql.createConnection(db)
```
```diff_docker: docker-compose.yaml
 version: '3'
 services:
   app:
     build:
       context: ./docker/app
     volumes:
       - .:/usr/src/app
     ports:
       - 3000:3000
+    networks:
+      - network1
     depends_on:
       - mysql
   mysql:
+    container_name: myDB
     build:
       context: ./docker/mysql
     volumes:
       - db-store:/var/lib/mysql
     environment:
       - MYSQL_DATABASE=${DB_DATABASE}
       - MYSQL_USER=${DB_USERNAME}
       - MYSQL_PASSWORD=${DB_PASSWORD}
       - MYSQL_ROOT_PASSWORD=${DB_PASSWORD}
       - TZ=${APP_TZ:-Asia/Tokyo}
     ports:
       - 3306:3306
+    networks:
+      - network1
      
 volumes:
   db-store:

+ networks:
+   network1:
```

# 参考
https://stackoverflow.com/questions/53250559/connecting-nodejs-docker-container-to-a-mysql-docker-container-docker-compose

https://amateur-engineer-blog.com/docker-compose-network/

https://sagantaf.hatenablog.com/entry/2019/12/18/234553#%E3%83%87%E3%83%95%E3%82%A9%E3%83%AB%E3%83%88%E8%A8%AD%E5%AE%9A
paizaのスキルチェック最初何からやればいいかわからない。

# この記事の目的
前提として、**超初心者のための記事です。**
最初、paizaの問題の解き方がわからなく、何をしていいかわからなかった経験があるので掴みだけでもまとめていく。
*特定の問題についての解き方ではない。
# 筆者の情報
・**変数って何？レベル**でDランクの問題を解こうとした。解き方がわからず一度挫折した。
・プログラミング初心者
・現在、PHP, JavaではBランクを解ける。
# 本文
今回は、PHPを使います。
```
    $input_line = fgets(STDIN);
    echo "XXXXXX";
```
どの問題を選んでもこの形からスタートします。

...う〜ん、どこから手をつければいいんだろー。

自分は最初、こんな感じになっていました。笑

### まず、初めにやって欲しいこと！！
`fgets()` `STDIN` `echo`
この３つについて調べてみる！

検索例：`PHP fgets()`
こんな感じで😆

調べ終わったら、変数`$input_line`を実際に出力してみて何が入っているのか確認してみましょう！

そのあとは、
`使用している言語＋スペース＋やりたい事`
で検索、実際に使用してみるを繰り返して問題の**期待する出力**になるようにロジックを考えていきます。

### エラーの解決方法
最初は、
`使用している言語＋スペース＋エラー文`
これでOK!
最初から難しく考える必要はありません。調べていくとだんだん分かってきます！
絶対、**使用している言語**は検索ワードに入れましょう！！
# まとめ
自分も初心者ですが、コツコツ学習していけばBランクは解けるようになりました！
今から頑張ろうとしてる誰かのためになればいいと思います。
皆さんも頑張って学習していきましょう！！！
【Git】どこでignoreされているか確認する方法

## 確認方法

ignoreされているファイルがどこでignoreされているのか確認するには次のコマンドを実行します。  

```terminal
git check-ignore -v ファイルパス
```

```terminal
$ tree
.
├── .git
│   ├── info
│   │   └── exclude
│ 
├── .gitignore
├── example.txt
├── sample.txt
└── test.txt

$ cat .gitignore
/sample.txt

$ cat .git/info/exclude
/example.txt

$ cat ~/.config/git/ignore
/test.txt

$ git check-ignore -v *
.git/info/exclude:1:/example.txt        example.txt
.gitignore:1:/sample.txt        sample.txt
/Users/Username/.config/git/ignore:1:/test.txt     test.txt

```

以上のようにignoreの設定がされているファイルと行数が表示されます。
案件スタートから更新を貰うまでに心掛けたこと４選

# はじめに
今回は案件を受けて仕事が始まってから次の更新までに個人的に心掛けていたことをまとめてみました。
社会人として無礼のないような行動は当然ですが、それ以外に当たり前かもしれないけど無下にしないように意識していたことです。


# 1.わからないことへの質問
チームで先に同じプロジェクトを触っている人がいるなら、なるべく同じ状態で触れるように**セッティングの仕方やコード内容のその人なりの理解**など、を聞いておけると、そのあとの躓きポイントを先に消化できるかもしれません
また、一つの事で一人で悩んでしまうとなかなか進捗が出せないまま時間だけが過ぎてしまうことになるので小さなことでも積極的に質問できるといいかもしれません。


# 2.コード全体を理解
なるべく早いうちにコードを理解しておくと、タスクを振られた際にすぐに着手することができます
細かいところまですべてを理解する必要はないと思いますが、全体の流れやコーディングの癖、チームでの決まり事等を確認するためにもコード全体に目を通しておくと良いかもしれません。

# 3.進捗＆現状報告
向こう側から特に進捗や仕事内容など、聞かれることがなくても
こちら側から少なくとも**週に１回以上**　タスクに対しての進捗度や躓いている点があるなら　その問題に対しての現状報告をします。
リモートでの案件が増え、直接こちら側の仕事への姿勢が見せられない以上
向こう側も進捗の報告がなく、音沙汰ない状態が続くと不安になると思います。
そんな思いを感じさせる前にこちらからアクションを起こしましょう。


# 4.積極的なコミュニケーション
自由参加のミーティングや勉強会などがあった場合、なるべく参加しコミュニケーションをとれる機会をなるべく増やしていきます。
チームの方との関係を深めていく近道になりますね。


以上になります。
今後もなにか心掛けていることを思い出だしたら追加してみようかなと思います。
JavaScriptでスクリーンロック（操作不可に）させる

# 使用用途
何かしらの処理をしている間、画面操作をしてほしくない場合に使う。
処理開始時にスクリーンロックさせて、終了時に解除するという使い方。

# スクリーンロックさせる
画面いっぱいのdiv要素を作ってクリック＆タッチできなくする。
```javascript
function screen_lock(){
  let lock_screen = document.createElement('div');
  lock_screen.id = "screenLock";

  lock_screen.style.height = '100%';
  lock_screen.style.left = '0px';
  lock_screen.style.position = 'fixed';
  lock_screen.style.top = '0px';
  lock_screen.style.width = '100%';
  lock_screen.style.zIndex = '9999';
  lock_screen.style.opacity = '0';

  let objBody = document.getElementsByTagName("body").item(0);
  objBody.appendChild(lock_screen);
}
```

# スクリーンロックを解除する
画面いっぱいのdiv要素を消せば解除される。
```javascript
function screen_unlock(){
  let screenLock = document.getElementById("screenLock");
  screenLock.parentNode.removeChild(screenLock);
}
```
テスト実行結果数：2種類の積み上げグラフ

本エントリーは [VeriServe Advent Calendar 2022](https://qiita.com/advent-calendar/2022/veriserve) の18日目の記事となります。所属企業の企画ということで、[昨年の記事](https://qiita.com/vKinjiAkemine/items/51c01b6fe8daa2aac0ef) に続き、本業のメインではテスト管理ツール [QualityForward](https://www.veriserve.co.jp/qualityforward/) を扱っているので、それに関連してテスト管理の小ネタをお届けします。

## テスト管理ツールの利点

ソフトウェアテストの現場では、まだまだテスト管理の手段としてExcelやGoogleスプレッドシートのような、スプレッドシートツールでテストケースやその実行結果を管理しているところが多いかと思います。これらのツールは非常に有用ではあるのですが、プロジェクトの大規模化や、リリースサイクルの高速化によるテスト頻度の増加に伴い、以下の問題が大きくなってきます。

- テスト結果の集計や、集計マクロのメンテナンス作業に時間がかかる
- テストケースの変更差分の確認・レビューに時間がかかる
- 修正・実行したいテストケース探しに時間がかかる

世の中にある様々なテスト管理専用ツールはこうした問題にそれぞれのアプローチで対応しています。特に上記のひとつめの問題に対しては、各ツール様々なビルトインレポートを提供しており、誰かが1件でもテスト実行をしたらその結果が即時レポートに反映されます。

## テスト実行結果数のレポート

さて、本日は小ネタ記事ということで、さらにぐっと話題をしぼって、表題のとおり **テスト実行結果数** のレポートの仕方について考察をします。テスト実行の進捗管理としては、まずは予定実行数に対して実際に実行した件数をみるのがテッパンでしょう。ただ、実行件数が増えていっても、たとえばほとんどテストがfailしていたらプロジェクトとしては決して順調な状況とはいいがたいです。したがって、パッと見でテストの概況を知るには、実行した件数の結果の内訳も含めて可視化することが重要です。多くのテスト管理ツールでは、日次のテスト実行結果数を、その結果の内訳で色別で積み上げて可視化するグラフを標準で提供しています。

## テスト結果の扱い方と積み上げグラフの見え方

さて、テストケースそのものと、その実行結果のデータの扱い方はツールによって考え方が異なります。前述のグラフは、このデータの扱い方によって見え方が大きく変わってきます。

#### パターン1 : 上書きタイプ

テストにおいて一発で全件がpassするに越したことはないですが、残念ながら現実にはそうなることは稀で、たいていfailするケースや、そもそも実行できなくて進捗しないケース（block）が出て、それらはプロダクト修正後に再テストすることとなります。再テストしたときの結果の扱い方のひとつは、すでにfailした結果に2回目以降の結果を上書きしているスタイルです。その場合、テスト実行結果数の推移はたとえば以下のようなイメージになります。

![chart2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1297056/77d4b51b-df7e-2eb9-6e29-3a181a4f0d7b.png)

1回目の実行までは右肩上がりに増えていき、それ以降は上書きによって結果が書き換わるだけのため累計数に変化はありません。

#### パターン2 : 別実施タイプ

もうひとつのアプローチは、テストケースとテスト実行を1:nの関係でモデリングし、2周目以降のfailやblockのケースの再実行は、1周目とは別の件数として扱うパターンです。この場合、実行数は最後まで右肩あがりで増えていきます。

![chart1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1297056/447844eb-31ed-8c06-6025-aae918c4518c.png)

## 考察

上記に2パターンのグラフはそれぞれ以下のようなメリット・デメリットがあります。

||メリット|デメリット|
|---|---|---|
|パターン1 : 上書きタイプ|特にテスト終盤にて、「すべてpassしている状況」がパっと見すぐわかる|2周目以降、リグレッションテストなども実施しているときに、pass数とfail数が同じときに相殺され進捗状況が可視化できない|
|パターン2 : 別実施タイプ|どのフェーズでも日次の進捗概況を確実に把握できる|特にテスト終盤にて、「残っているfail数」を把握しづらい|

グラフとしてはどちらがいいということはなく、それぞれデメリットを補完するために別のチャートと組み合わせて概況を見たり、もしくはこれら2パターンを両方出せるようにするのもいいかもしれません。（後者のグラフのデータがあれば、前者のグラフを出すのは可能）一方で、前述のとおり、データの持ち方としては別実施パターンで保持しておいたほうが小回りがきくため、データ管理の仕方はこちらのほうが確実によいでしょう。

## おわりに

以上、テスト実施結果数の推移レポートに仕方に関する小ネタでございました。スプレッドシートツールでテスト管理されている方は独自レポートの検討のインプットに、またテスト管理専用ツールを検討されている方は、ツール選びの際のテスト結果の管理の仕方やレポート機能を比較する観点としていただければ幸いです。
インターフェースと抽象クラス

# 初めに
インターフェースと抽象クラスってできることほぼ同じで使い分けとかいまいちわかってないなということで理解を深めて正しく使い分けれるようにしたいと思いこの記事を書こうと思いました。

調べる前のイメージはインターフェースは依存性逆転のために使われるのはよく見るけど、抽象クラスってそもそもあんま使われてるイメージがないという感じです。

# インターフェースと抽象クラスの比較
　|抽象クラス|インターフェース
-|-|-
アクセス修飾子|public,protected|publicのみ
定数の定義 | インスタンス変数、ローカル変数、クラス変数など定義できる |　クラス変数しか定義できない
多重継承 | 不可 | 可能
メソッドの定義 | 具体的な処理もかける | メソッドの型しか定義できない

上から順番にコードを書いて試してみます。

### 抽象クラスのアクセス修飾子
```php
abstract class Hoge {
    abstract public function fuga1();
    abstract protected function fuga2();
    abstract private function fuga3();
}
```
実行結果
```
Abstract function Hoge::fuga1() cannot be declared private
```

### インターフェースのアクセス修飾子
```php
interface Hoge {
    public function fuga1();
    protected function fuga2();
    private function fuga3();
}
```
実行結果
```
Access type for interface method Hoge::fuga2() must be public
```

### 抽象クラスの変数の定義
```php
abstract class Hoge {
    // インスタンス変数
    public string $fuga1 = "";
    // クラス変数
    const fuga = '';
}
```
### インターフェースの変数の定義
```php
interface Hoge {
    const fuga = '';
    public string $fuga1 = "";
}
```
実行結果
```
  Interfaces may not include properties
```

### 抽象クラスの多重継承
```php
class Hoge extends Hoge1, Hoge2 {
    public function fuga1() {
        
    }
    
    public function fuga2() {
        
    }
}

abstract class Hoge1 {
    public function fuga1();
}

abstract class Hoge2 {
    public function fuga2();
}
```
実行結果

```
syntax error, unexpected token ",", expecting "{"
```
他の言語はわからないですが、PHPでは多重継承できないみたいなエラーじゃなくてそもそも構文エラーになるんですね。

### インターフェースの多重継承
```php
class Hoge implements HogeInterface1, HogeInterface2 {
    public function fuga1() {
        
    }
    
    public function fuga2() {
        
    }
}

interface HogeInterface1 {
    public function fuga1();
}

interface HogeInterface2 {
    public function fuga2();
}
```
問題なく実行できました。

### 抽象クラスの具体的な処理
```php
abstract class Hoge1 {
    public function fuga1() {
        echo "fuga1";
    }
}
```
問題なく実行できました。

### インターフェースの具体的な実装
```php
interface HogeInterface1 {
    public function fuga1() {
        echo "fuga1";
    }
}
```

実行結果

```
Interface function HogeInterface1::fuga1() cannot contain body
```


# 概念的な話
元々抽象クラスとインターフェースはどういう役割を持つために作られたのかを調べてみました。

抽象クラスは`もの`を定義するために作られたそうです。
ものはものでももっと抽象的な例えば

- 犬、猫、人間をもっと抽象的にすると動物
- 車、バイクをもっと抽象的にすると乗り物

といったように大分類的な表現のものを定義して、そこから子クラスに継承するといった役割。

次にインターフェースは`振る舞い`を定義するために作られたそうです。
ふるまいとは「〜できる」といったような例えば
- 歩くことができる
- 食べることができる

などがあてははまるかと思います。

:::note
抽象クラスと具象クラスはis-aの関係で例えば
犬は動物である。
車は乗り物である。
という関係性である必要があるそうです。
:::

# 使い分けは？
極端に言えば、共通的に扱いたいグループが、もの(Object)で分類することができる場合、抽象クラスにし、それ以外の場合は、インターフェースにするとそれぞれのできた経緯に沿った実装ができるのかなと思います。

# さいごに
インターフェースと抽象クラスについて書きましたが、正直抽象クラス使わずに基底クラス的なの作ってる実装がほとんどな印象なのであまり意識する必要はないのかもしれないですが[なぜ抽象クラスを実装するのか](https://qiita.com/aiko_han/items/e8ddce85188970fd77da)という記事があったので参考までに貼っておきます。


# 参考
https://qiita.com/yoshinori_hisakawa/items/cc094bef1caa011cb739

https://4engineer.net/oo/abstract-vs-interface/
【完走賞ゲット-18】p5.js で sin() を使った波の描画数を指定したり変化させたり

## はじめに
こちらは、[完走賞ゲットのため小ネタを毎日投稿しようとチャレンジする Advent Calendar 2022](https://qiita.com/advent-calendar/2022/youtoy) の 18日目の記事です。

## 今回の記事を書くことになったきっかけ
今回の記事を書くことになったきっかけは、以下のツイートとそれに対するコメントです。

https://twitter.com/senbaku/status/1603665015474507776

https://twitter.com/youtoy/status/1603875378132848640

この話は、自分も将来、何か使う時が来るかもしれないと思って、「i*5*TAU/w なのでは？」と書かれていたものを試してみたくなりました。
そして、さらに少し手を加えたバージョンの何かも作ってみようと思いました。

## 最終的に作ったもの
最終的に作ったものは、以下になります。

https://twitter.com/youtoy/status/1603882881973366784

波の数を指定するものを試した後、主に以下の追加実装を行いました。

- 点の大きさと色を変更
  - 色は、[今年のアドベントカレンダーで記事を書いていた](https://qiita.com/youtoy/items/8dcfd5d69721bf73d5d6)「Chroma.js Color Palette Helper」を使って作った、カラーパレットを利用
- 波の数を動的に変化させるようにした

## 作ったプログラム
上で出てきていた p5.js で作ったアニメーションのプログラムは、以下の通りです。

```javascript
const colorList = [
  "#00429d",
  "#2e59a8",
  "#4771b2",
  "#5d8abd",
  "#73a2c6",
  "#8abccf",
  "#a5d5d8",
  "#c5eddf",
  "#ffffe0",
];

function setup() {
  createCanvas(450, 350);
  strokeWeight(5);
}

function draw() {
  background(220);

  const num = (frameCount / 30) % 10;
  for (let i = 0; i < width; i++) {
    const colorNum = i % colorList.length;
    stroke(colorList[colorNum]);    
    point(i, 0.5 * height + height * 0.3 * sin((i * num * TAU) / width));
  }
}
```

### プログラムの補足
上記のプログラムについて、一部補足します。

#### カラーパレット
冒頭の `colorList` で指定しているパレットは、以下の記事にも登場していた「[Chroma.js Color Palette Helper](https://qiita.com/youtoy/items/8dcfd5d69721bf73d5d6)」を使っています。

●【完走賞ゲット-5】「Chroma.js Color Palette Helper」というサイトを試してみる（設定変更とカラーパレットの出力） - Qiita
　https://qiita.com/youtoy/items/8dcfd5d69721bf73d5d6

こんな感じで出てきていたものを使いました。
![カラーパレット](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50868/ae6790ce-479b-222d-8e8a-3122cbbcdc63.png)

#### frameCount をもとにした繰り返し
アニメーションは、一定時間で同じものが繰り返されます。
その繰り返しが発生する部分は frameCount を使った処理によるものです。

`const num = (frameCount / 30) % 10;` という部分で、0 から 9 まで増加して、また 0 に戻る数を生成しています。30 で除算している部分がありますが、このアニメーションはデフォルトの 60fps で描画させており、frameCount の増加が早いため、その変化を遅くすることを意図したものです。

#### 色の設定
最初に用意していたカラーパレットの色を指定するのは、 `const colorNum = i % colorList.length;` の部分です。
ここで `i` は、 `for (let i = 0; i < width; i++)` という for文の中で、「0 から width-1」の範囲で 1ずつ増加していきます（波を描画する点の x座標として使っています）。

その変数i を、カラーパレットの数を使った剰余演算で、カラーパレットの色を指定する番号にしています。カラーパレットの最初の色を選び、リストの最後まで順番に選んでいき、そしてまた最初に戻って...、という選び方をする形です。

#### 点の描画
点の描画は `point(i, 0.5 * height + height * 0.3 * sin((i * num * TAU) / width));` という処理にしました。
点の x座標は、上でも少し書きましたが i をそのまま使えるようにしています。

そして、y座標のほうは以下のような意図の処理にしています。

- `0.5 * height` という部分で、縦方向の真ん中を基準に上下に波を描画させる
- sin() に `height * 0.3` を乗算して、振幅をキャンバスの高さの 30% にする（上下方向それぞれに 30%ずつとなるため、波の全体の高さはキャンバスの高さの 60% になる）
- `(i * num * TAU) / width)` の部分は、冒頭の Twitter でのやりとりに出てきた、波の数を指定するためのもの

このようにして、波の数を指定した描画が行えました。

## こういった話も
今回の話の元になったツイートに対して、別のコメントもされていました。
正規化はあまり使いこなせてないので、こちらも気になった話でした。

https://twitter.com/senbaku/status/1604008620760629248

## 【追記】 こんなものも作ってみた

https://twitter.com/youtoy/status/1604471795641647106
Hydraでランダムな実験IDを扱う

こんにちは。今日は研究で使っているHydraでディレクトリの作成の際に、ランダムに生成した実験IDを使うための方法です。

Hydraでは自動で実験の結果をいい感じにディレクトリを切ってくれて出力してくれるのですが、デフォルトの設定では`日付/時間`と行った形でディレクトリが切られます。

ただ、実験を多く重ねていくと、あれこの結果っていつの実験だっけ？となることが多々あり、実験の際の設定を探そうにも膨大な数のディレクトリを一つ一つ開けて探すことになるので、実験の管理としてはあまり良くありません。

そこで、今回はPythonの`uuid`ライブラリを使用して、ランダムな実験IDを発行し、それをHydraで使う方法についてご説明します。

# Hydraの出力ディレクトリをカスタマイズする

まず最初にHydraの出力ディレクトリのカスタマイズ方法について確認していきます。

これは公式ドキュメントにも記載されていますが、スクリプトで使用する`.yml`ファイルに以下を追記することで出力ディレクトリをカスタマイズすることができます。

```yml

hydra:
  run:
    dir: ${now:%Y%m%d}T${now:%H%M%S}-${experiment_id}
  sweep:
    dir: ${now:%Y%m%d}T${now:%H%M%S}-${experiment_id}
    subdir: ${hydra.job.num}

experiment_id: "30d3974d"
```
このように、`hydra.run.dir`を指定してあげることで、出力フォルダ名をカスタマイズすることができます。

しかしこの方法では、わざわざ毎回手作業でexperiment_idを発行して、貼り付ける必要があり、面倒ですし、ミスも増えます。

そこでこの部分を自動化したいのですが、調べてもなかなか類似のことを行おうとしている記事が存在せずに困っていました。
`hydra.job_id`も使おうと思ったのですが、普通にhydraを実行するとこの値はNoneになってしまうので使えませんでした。

# 実験IDとして`uuid`を使う

そこで今回はPythonで`uuid`を発行し、ディレクトリに使うことを考えます。
やり方は２つあり、

1. `ComposeAPI`を使う
2. `hydra-plugins`を作る

のどちらでも目標を達成することができます。
ただ、`ComposeAPI`は古いAPIで使用すると本来のHydraでできることができなくなり、かえって手間が増えることがあります。

なので今回は2の方法で実装していきたいと思います。

といってもやり方は単純で以下の方法で終わりです。

ソースコードが書かれているルートディレクトリに(今回の場合は便宜的に`src`とします)、`hydra-plugins`フォルダを作成して、以下のpythonファイルを作ります。

```python
# src/hydra-plugins/random_id_provide.py
import uuid
from omegaconf import OmegaConf

class IDGenerator:
    def __init__(self, digit: int = 8) -> None:
        self.digit = digit # 長すぎるので切り捨てる桁数を指定。

    def generate(self) -> str:
        return str(uuid.uuid4())[: self.digit]
id_generator = IDGenerator()

OmegaConf.register_new_resolver("experiment_id", id_generator.generate)
```

`hydra`で使われている`OmegaConf`の`register_new_resolver`に呼び出したい関数を渡すだけです。このように`hydra-plugins`の中に適当なファイルを作成しておくだけで、後はhydraがよしなに読み取ってくれてconfig内で使用することが可能です。

以下のようなディレクトリを考えてみましょう。

```yml
hydra:
  run:
    dir: ${now:%Y%m%d}T${now:%H%M%S}-${experiment_id}
  sweep:
    dir: ${now:%Y%m%d}T${now:%H%M%S}-${experiment_id}
    subdir: ${hydra.job.num}

experiment_id: "${experiment_id:}"
```

このようにするだけで以下のようにuuidに従って出力用ディレクトリが作成されます！

![スクリーンショット 2022-12-18 20.23.59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/307982/1145206f-6f7a-4799-fe39-d06c296daf0a.png)

以上です！
【TypeScript】Unknown型を絞り込みたい！


こんにちは．TypeScript を使ったアプリ開発をしていて，unknown型を絞り込んで型に応じた処理をしたいという場面に遭遇しました．様々勉強になることがあったのでまとめたいと思います！

# unknown型を絞り込みたい
型の絞り込みの方法については，[こちらの記事](https://typescriptbook.jp/reference/statements/unknown#unknown%E3%81%A8%E5%9E%8B%E3%81%AE%E7%B5%9E%E3%82%8A%E8%BE%BC%E3%81%BF) がとても勉強になります．
## プリミティブ型かどうかで絞り込みをしたい
例えば，unknown 型がstring 型かどうか絞込をしたい場合は以下のように行います．
```javascript
const NarrowType = (unknownTypeValue: unknown) => {
    if (typeof unknownTypeValue === "string") {
        // string 型に応じた処理
    }
}
```
## オブジェクト型かどうかで絞り込みをしたい
「あれ，でもオブジェクト型かどうかの絞り込みはどうやるの？typeof で，`object` かどうかは分かるけど，その内側のプロパティまでちゃんと含まれているかチェックしたいんだけど．．．」となりました．
そのような場合は，以下のように行うのが良いみたいです．
```typescript
type User = {
    email: string;
    name: string;
};

const NarrowType = (unknownTypeValue: unknown) => {
    const user = unknownTypeValue as Record<keyof User, unknown>;
    if (typeof user.email === "string" && typeof user.name === "string") {
        // User 型に応じた処理
    }
}
```

ここでポイントは，以下の部分です．
```javascript
const user = unknownTypeValue as Record<keyof User, unknown>;
```

`Record<keys, type>` は，プロパティーのキーが `Keys` で構成されていて，各プロパティの型が`type`であるオブジェクトの型を表します．そのため，`Record<keyof User, unknown>` は，以下の型を表します．
```javascript
{
    email: unknown;
    name: unknown;
};
```
そして，`as` の型アサーションを使って，unknown型の`unknownTypeValue`をこの型にします．
ところで，unknown型の`unknownTypeValue` に email とか name とか含まれなかったら型アサーションでエラーにならないの？と思うかもしれませんが，型アサーションの対象がunknown型であればエラーは出ないらしいです．


# 絞り込む処理を共通化したい
「ここまででunknown型を絞り込む処理は書けたけど，何回も絞り込む必要が出てきたから共通化したい」と思いました．そこで便利なのが __型ガード関数__ らしいです．

以下のように絞り込む処理を定義して後はそれを呼び出すだけです．
```javascript
type User = {
    email: string;
    name: string;
};

// 型ガード関数
const isUserType = (unknownTypeValue: unknown) : unknownTypeValue is User => {
    const user = unknownTypeValue as Record<keyof User, unknown>;
    if (typeof user.email === "string" && typeof user.name === "string") return true;
    else return false; 
}

const NarrowType = (unknownTypeValue: unknown) => {
    if (isUserType(unknownTypeValue)) {
        // ★ 
        // User に応じた処理
    }
}
```

ここで重要なのが，`unknownTypeValue is User` という部分です．これがないと，Userの絞り込みが機能せず，// ★ の部分で，`unknownTypeValue is of type 'unknown'` などのエラーが出てしまいます．

# おわりに
unknown 型を絞り込みたい！ということだけでも，Record や型アサーション，型ガード関数など様々な概念が出てきてとても勉強になりました！同じような場面に直面している方がいましたら，参考にしていただけると嬉しいです！

# 参考文献
https://typescriptbook.jp/reference/statements/unknown#unknown%E3%81%A8%E5%9E%8B%E3%81%AE%E7%B5%9E%E3%82%8A%E8%BE%BC%E3%81%BF
github actionsを使ってNext.jsをfirebase hostingにdeployする

# 概要

[Next.js + firebaseでSSR、SSG、ISRがサポートされたので試してみる](https://qiita.com/gosshys/items/db5eab449eeb4b30b97a) の記事で、firebase hostingがNext.jsのデプロイをサポートしたので試してみましたが、github actions経由でデプロイするときにハマったのでメモを残します

# experiments:enable webframeworks は環境変数を設定する

[Next.js を統合する  |  Firebase Hosting](https://firebase.google.com/docs/hosting/nextjs)の手順を見ると、firebase-toolsで以下の設定が必要になるが、github actionsからのdeploy時の指定方法が示されていない

```
firebase experiments:enable webframeworks
```

github actionsのコンソールにこんな感じのエラーがでます

```
Error: Cannot deploy a web framework to hosting because the experiment webframeworks is not enabled. To enable webframeworks run firebase experiments:enable webframeworks
```

## 対応方法

環境変数に`FIREBASE_CLI_EXPERIMENTS: webframeworks`を設定します


```firebase-hosting-merge.yml
name: Deploy to Firebase Hosting on merge
'on':
  push:
    branches:
      - main
jobs:
  build_and_deploy:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2
      - run: yarn
      - run: yarn build
      - uses: FirebaseExtended/action-hosting-deploy@v0
        with:
          repoToken: '${{ secrets.GITHUB_TOKEN }}'
          firebaseServiceAccount: '${{ secrets.FIREBASE_SERVICE_ACCOUNT_XXXXX }}'
          channelId: live
          projectId: xxxxx
        env:
          FIREBASE_CLI_EXPERIMENTS: webframeworks
```

## 参考

[How can run firebase experiments:enable webframeworks with GitHub actions? | stackoverflow　](https://stackoverflow.com/questions/74426925/how-can-run-firebase-experimentsenable-webframeworks-with-github-actions)

# AUTH_PERMISSION_DENIED などの 403エラーが発生する

直観でわかりづらいのがこのエラーで、どうやらgithub actionsのサービスアカウントにいろいろと権限が足りないようです

```
You can add the permissions by granting the role 'roles/artifactregistry.reader'.
```

## 対応方法

GCPのIAMで`github-action-9999999999@xxxxx.iam.gserviceaccount.com`の`Role`に`Editor`の権限を追加します

[Google Cloud Console](https://console.cloud.google.com/iam-admin/iam)

![スクリーンショット 2022-12-18 19.49.00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/38174/df92f293-7ca7-918d-b342-e4a3b2c27c44.png)

果たしてこの対応が本当に正しいかは謎

## 不明の原因でデプロイが失敗する

GCPのコンソールからデプロイに失敗したcloud functionsを削除する

以下のコマンドで消せそうだったけど、消せなかったので半ばあきらめてましたが、GCPのコンソールからは消せました

```
firebase functions:delete [function名]
```
Google Compute EngineのWordpressをHTTPS化する

# CertbotでSSL証明書を作る

```bash:
sudo apt install certbot python3-certbot-apache
```

必要なプログラムをaptでインストール。

```bash:
sudo certbot --apache
```

certbotを起動。質問に答えるだけでSSL証明書を作ってくれる。

> Enter email address (used for urgent renewal and security notices) (Enter 'c' to
cancel):

メールアドレスとドメインを聞かれるので入力する。

> Please read the Terms of Service at
> https://letsencrypt.org/documents/LE-SA-v1.3-September-21-2022.pdf. You must
> agree in order to register with the ACME server at
> https://acme-v02.api.letsencrypt.org/directory

規約に同意する。

> Would you be willing to share your email address with the Electronic Frontier
> Foundation, a founding partner of the Let's Encrypt project and the non-profit
> organization that develops Certbot? We'd like to send you email about our work
> encrypting the web, EFF news, campaigns, and ways to support digital freedom.

「お知らせメールを送ってもいいですか？」→どっちでもいいです。

> No names were found in your configuration files. Please enter in your domain
> name(s) (comma and/or space separated)  (Enter 'c' to cancel):

ドメインを入力する。

> We were unable to find a vhost with a ServerName or Address of 403world.net.
> Which virtual host would you like to choose?
> \- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
> 1: 000-default.conf               |                       |       | Enabled
> 2: wordpress-https.conf           |                       | HTTPS | Enabled
> \- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
> Select the appropriate number [1-2] then [enter] (press 'c' to cancel): 

どのconfファイルに仮想ホストの設定を書き込むか。とりあえず「2」を選んだ。

> Please choose whether or not to redirect HTTP traffic to HTTPS, removing HTTP access.
> \- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
> 1: No redirect - Make no further changes to the webserver configuration.
> 2: Redirect - Make all requests redirect to secure HTTPS access. Choose this for
new sites, or if you're confident your site works on HTTPS. > You can undo this
change by editing your web server's configuration.
> \- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
> Select the appropriate number [1-2] then [enter] (press 'c' to cancel): 
 
HTTPアクセスをHTTPSに自動リダイレクトするか。「2」を選択。

これで完了。

# Wordpressの設定変更

phpmyadminで、`wp_options`の`siteurl`と`home`を手で書き換える。（もっといい方法ないものかなあ）

# adminのパスワードを忘れた

デプロイメントマネージャ見て。
SQLITE→POSTGRES　同じクエリが動かなくて3日ほど悩んだ

少しだけ教訓めいたことを書く

# 状況
* SQLTIEで、何でもクエリが書けて動くので喜んでいた
* POSTGRESに、クエリを移植しようとした
* ことごとくクエリが動かなかった

# POSTGRES

例えば、以下のSQLだが、SQLITEだととにかく動いた。
しかし、POSTGRESだと怒られる。　
→　要するにGROUP　BYをするときは、集合関数を使ったもの以外はダメだと。この場合はIDがそもそも、集合に値しない
→　メッチャ基本やねえ。。。

```
select id, sum(data) from table group by data
```

次のサブクエリはSELITEだと問題なく動いた。
しかし、POSTGRESだと確実に怒られる。
→　selectにはちゃんとエイリアスをつけなさいと・・・

# 詳細
```
select * from 
(select * from table)
```
```
select a.* from 
(select * from table) as a
```

# その他

先ほどのGroup byにも関係するが、改めてGROUP化させたテーブルに、元のテーブルをjoinしたり
GROUP化したものをHaving句で処理したり、いろんなテクニックを学んだ。
Postgresは、ポイントさえ掴めば、ちゃんという事を聞いてくれるデータベースだった。
【自分流】UiPathライセンス更新作業の楽しみ方について

# はじめに
仕事でUiPathのライセンス更新を行いました。
当初は特に何も感じずに黙々と作業していたのですが、
作業が少しだけ楽しくなる「どうせなら…」を記録として残したいと思います。
作業内容自体は11日目の記事に纏めていますので、是非併せてご覧ください。

https://qiita.com/tansuke2021/items/8fed921c5508bb4e6cc7

この記事はこの記事はRPA（ロボティック・プロセス・オートメーション） Advent Calendar 2022 19日目の記事です。

# 結論
下記2点が本記事の結論です。
- 「あえて、手打ちで」実践してみる
- 考え方ひとつで作業は楽しくできる

楽しみ方の具体的な方法については以下で説明していきます。

# 楽しみ方

- コマンド（ライセンスツール）から更新する
- あえて手打ちで更新する

## え、なんで？（当然の疑問）
理由としては以下3点です。
- コマンドが覚えられる
- CUI自体に慣れればほかへの抵抗も少なくなる
- CUIはGUIでの操作と比べて変更が少ない
以下で一つずつ説明していきます。

## 理由1.コマンドが覚えられる
コマンド（ライセンスツール）を使って更新するわけですから、完璧に覚えるのは難しくとも、ある程度は覚える必要が出てきます。
これは手打ちで数打って体に覚えさせることが最適解なのではないかなと考えます。

## 理由2.CUI自体に慣れればほかへの抵抗が少なくなる
業務上では、UiPathのアクティビティだけで実装できないことが出てきた場合、
UiPathと組み合わせて実装することは珍しくありません。
同じようにCUIで動作させるPowerShellやMS-DOS（コマンドプロンプト）など、様々なCUIで動作させるツールもあります。
ライセンスツールでのライセンス確認、更新作業はそれらに触れる前段階として非常にとっつきやすいのではないかなと思います。
UiPath×PowerShellの記事も過去に書いていますので、併せてご覧いただければ幸いです。

https://qiita.com/tansuke2021/items/d91749743f94cbbcfbc2

## 理由3.CUIはGUIでの操作と比べて変更に強い
CUIはGUIでの操作と比べて変更に対して強いと思います。
例えば、マニュアルを作成した時、GUIで操作していた場合のマニュアルはUIが変更されればそれに合わせて都度変更する必要が出てきます。
これに対してCUIであれば、該当の行を修正するだけでことが足ります。

# おわりに
精神論かつポエムな内容の記事ですが、（大体）年一とかで実施する作業です。
もちろん、様々な制約があり、この楽しみ方が誰にでもできるものではないかとは思いますが、
エンジニアとして
「どうせ…」と考える考え方より
「どうせなら…」と考えて、より作業を楽しんだほうがより自身の中に学びが増えると信じています。

この考え方は、定期的な作業の楽しみ方としても当てはまるのではないかと思います。
今回扱ったUiPathのライセンス更新に限らず、定期的な作業がイマイチ退屈で楽しめない…と考えている方にも届けば幸いです。
【Swift】containsメソッドとは

# 文字列が特定の文字を含むかどうか
containsメソッドとは、**文字列が特定の文字を含むかどうかを判定する**メソッドです。
例えば`name.contains()`のように、containsメソッドを呼び出して、containsメソッドの引数に判定したい文字列を指定します。
```swift
name.contains("アーニャ")
```
containsメソッドは、引数に指定した文字列が存在すれば「true」を返し、存在しなければ「false」を返します。

# 例
```swift
var name = "アーニャ"

print(name.contains("アーニャ")) // true
print(name.contains("ボンドマン")) // false

if name.contains("アーニャ") {
  print("ピーナッツ！！") // ピーナッツ！！
}
```
このように、`if contains`で、含まれていた場合に何かの処理をすることが多い。

# 配列に指定の要素が含まれているか
配列に指定の要素が含まれているかを確認するときも「contains(_:)」を使用します。
含まれていたら「true」、含まれていなかったら「false」を返します。

# 例
```swift
var characters: [String] = ["ロイド", "ヨル", "アーニャ", "ボンド", "ダミアン"]

print(characters.contains("アーニャ")) // true
print(characters.contains("デズモンド")) // false

if characters.contains("アーニャ") {
  print("ピーナッツ！！") // ピーナッツ！！
}
```
Railsの「開発」環境へのデプロイ

### 想定した環境

タイトルの「開発」環境と言っている部分の想定は、

- 何らかのCI/CD環境を用いRailsアプリをクラウドなりオンプレの実環境へデプロイをする
- 一般的な「開発/dev/development」→「ステージング/stg/staging」→「運用/prd/prod/production」といった環境の流れを想定
- この「開発」用途の環境であり、デプロイするたびにデータベース丸ごと壊し初期化して良い、というかしたい
- `RAILS_ENV`の`development`/`production`とは別の話、「開発」環境だけど`RAILS_ENV=production`である
- そして初期化されたクリーンな状態で動作テストをしていく
- 「運用」用途でデータベースの内容を維持していくものは対象にしてはいない

### データベースを破壊すのに困ること

まず初期化だがrailsのコマンドで行おうとすると`rails db:reset`になると思う。そして、これを阻む諸々がある。

#### データベース破壊保護

そもそも`RAILS_ENV=production`の場合、Rails5以降では、データベース破壊系コマンドに対する保護が入っているので、`DISABLE_DATABASE_ENVIRONMENT_CHECK=1`を設定する必要がある。

https://qiita.com/Esfahan/items/75ade0233fe02ab04381

#### Spring preloader

また、Rails4.1以降プリローダーとして[Spring](https://github.com/rails/spring)が入り、これが`rails`コマンドの実行を阻むので、`DISABLE_SPRING=1`を指定する必要がある。

https://qiita.com/YumaInaura/items/622c699975702bd0ea39

#### PostgreSQL 13

ここは、PostgreSQL限定の話になるが、該当データベースに対してコネクションが貼られた状態の場合、単純には`DROP DATABASE`できない仕様に変わっており(12→13)、特にCI/CDの様な形でアプリケーションプロセスが動いている状態ではdropできなくなっている。ここでPostgreSQL側は`WITH (FORCE)`という強制実行のオプションを付与しdropできる様になっているが、rails側が生成するクエリーにはそのオプションが付与されないので`db:reset`の実行では基本的に初期化できない(アプリケーションのデプロイによる再起動やタイムアウトでコネクションが切れていた場合に稀に成功するので悩む)。

https://zenn.dev/monicle/articles/58ea12e76bf889

上記の記事の様にモンキーパッチを当てて対処するのもあるかもしれませんが、メンテナンスの事を考えてCI/CD側のステップで行うというのが良いと思う。

### 結果

実際のCI/CD実装によるかと思うのですが、次のようなCLIコマンド/環境変数を実行する感じになる(あくまでもシェルスクリプト的なイメージ例)

```sh
# PostgreSQLの場合データベース初期化
PGPASSWORD={何らかの機密情報ストアー系から取得し環境変数で指定} \
psql -h ${POSTGRES_HOST} -U ${POSTGRES_USER} template1 \
  -c 'DROP DATABASE IF EXISTS \"${POSTGRES_DB}\" WITH (FORCE)'

# Rails側での初期化処理
RAILS_ENV=production \
RAILS_MASTER_KEY={何らかの機密情報ストアー系から取得し環境変数で指定} \
DISABLE_DATABASE_ENVIRONMENT_CHECK=1 \
DISABLE_SPRING=1 \
bundle exec rails db:reset
```

もしかしたら、使っているライブラリーや環境によっては他の環境変数などの設定が必要かも。
全社的なタスクをSlackで通知してくれるやつをサクッと作った

# 概要
たまに全社的なタスクをしなければならないことがあります。（例.年末調整資料の提出）
全体チャンネル等でアナウンスはされるものの、忘れてしまうことがあります。また、チームリーダなどは回答状況を把握しておきたいということもあるかと思います。
この問題を解決するためにスプレットシート、Google App Script（以降、GAS）、Slack組み合わせて、未完了のタスクを定時で通知し、回答状況の管理をするアプリケーションをサクッと作ったので紹介します。

以下のスプレットシートをコピーすることで、スクリプトごとコピーされます。ぜひ利用してみてください。
https://docs.google.com/spreadsheets/d/170QtHwhLA0KHwzAxn9Q0_26IVBe386qiMjBWNzp8fY4/edit?usp=sharing

# 作ったもの

Slackに以下画像に示す内容が日次で通知されます。GASの定期実行によって、自分のチームのチャンネルに毎朝通知されるようにしています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/133979/de0f6e44-f1d7-d650-29ce-95f50d23850c.png)

タスクはスプレットシートで管理します。
タスクは行に追加していきます。D列以降に対象者のSlack名を入力します。チェックマークの入っていない未完了のタスクが通知されます。
リンクにはSlackのリンク等を任意で設定します。
"Slack送信"というボタンを押すと、定期実行のトリガーを待たず手動でSlack通知が出来ます。記入直後に使うイメージです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/133979/7eac5258-5f64-e803-722a-059a639409f9.png)


# 実装
sendTodoという関数がメインの関数です。
タスクごとに未完了の対象者を抽出し、送信内容を組み立てているだけです。

```js

function sendTodo() {
	const SLACK_URL = 'https://hooks.slack.com/services/~'; // 通知したいチャンネルのSlack Webhook URL
    const SPREAD_SHEET_URL = 'https://docs.google.com/spreadsheets/~' // spreadsheetのURL

	const spreadsheet = SpreadsheetApp.getActiveSpreadsheet();
	const input_sheet = spreadsheet.getSheets()[0];
	const HEADER_LENGTH = 3
	const member_count = input_sheet.getRange(1, 1, 1, 99).getValues()[0].filter(value => value !== '').length - HEADER_LENGTH
	const todos = input_sheet.getRange(1, 1, 999, 3 + member_count).getValues().filter(value => value[0] !== '');
	const member_list = todos[0].slice(3, 3 + member_count)
	var message = ''
	var send_flag = false
	for(let todo of todos.slice(1)) {
		if(!todo.slice(3).every(value => value)) {
			send_flag = true
			var year = todo[1].getFullYear();
			var month = ("00" + (todo[1].getMonth() + 1)).slice(-2);
			var date = ("00" + todo[1].getDate()).slice(-2);
      if(todo[2] !== ''){
        message = message + '*<' + todo[2] + '|' + todo[0] + '>*' + ' 期限:' + year + '/' + month + '/' + date + '\n'
      }else{
        message = message + '*' + todo[0] + '*' + ' 期限:' + year + '/' + month + '/' + date + '\n'
      }
			const not_do_member = todo.slice(3).map((value, index) => {
				if(!value) {
					return member_list[index]
				}
			}).filter(value => value !== undefined)
			for(let member of not_do_member) {
				message = message + "<@" + member + ">" + ' '
			}
			message = message + '\n\n'
		}
	}
	if(send_flag && !isTodayHoliday()) {
		var data = {
			'text': "以下のタスクが終わってないよ！終わったら<"+ SPREAD_SHEET_URL +"|スプシ>にチェックを入れてね！\n" + message + "\n" + ""
		};
		var options = {
			'method': 'post',
			'contentType': 'application/json',
			'payload': JSON.stringify(data)
		};
		UrlFetchApp.fetch(SLACK_URL, options);
	}
}

// 土日かどうかのチェック
function isTodayHoliday() {
	let today = new Date();
	let weekInt = today.getDay()
	if(weekInt <= 0 || 6 <= weekInt) {
		return true;
	}

	return false;
}

```


# まとめ
スプレットシート、GAS、Slackの組み合わせで全社的なタスクを通知してくれるアプリケーションを作成しました。GASはちょっとした自動化がサクッとできるのでとても重宝しています。
今後の展望として、Slackのスタンプリアクションでタスクやチェックマークを書き込めるようにしたら更に便利になるかと思っています。
AndroidStudio使われていないコードを探す方法

複数人で開発をしていたり、プロジェクトを引き継ぎ開発したりしていて、不要なコードを見かけたりすることがあると思います。
その不要なコード一覧を表示させる方法があるのでやってみようと思います。
（警告系のコードも表示されます。）


# 方法
AndroidSutudioを開き、上部のCodeをクリックします。
![スクリーンショット 2022-12-18 19.12.35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/274615/8d3e1fdc-0131-1492-86c2-853c6b44832d.png)

そして、Inspect Codeをクリックします!


![スクリーンショット 2022-12-18 19.13.31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/274615/04cadbfa-9590-a079-8afc-686c0470ca0d.png)


Custom scopeで検索したい範囲を決めて、OKを押します。
※検索範囲が広いと時間がかかる可能性があるため。なるべく小さい範囲でやることをお勧めします。

![スクリーンショット 2022-12-18 19.15.56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/274615/4af15f54-6b9c-fce0-feda-ab32eb497394.png)

そうすると一覧が出てきます！

年末でお掃除すると思いますが、コードのお掃除も検討してみるのはいかがでしょうか？
以上です。
OutSystemsのAggregateでSQLのInを使いたい場合のTips

# 自己紹介
こんにちは。tetraです。上場企業でSESをしています。
業務ではOutSystemsを使用することが多いです。

# この記事でわかること
1. OutSystemsでAggregateの中で疑似的なINを使用する方法

# この記事でわからないこと
1. OutSystemsの使い方など、基本的な部分
1. SQLの基本的な部分

# 解決方法
OutSystemsにはIndex関数というBuiltIn関数があり、これをフィルターに適用します。
以下に例を示します。
![無題.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/621694/d5ddd659-630a-3ec4-bb15-b77311901889.png)
例えば、嵐（5人組男性アイドルグループ）の中で櫻井、松本、大野の3名を抽出したいと考えた時にAggregateではInを使用できないため、別の方法が必要になります。
SQLを使用できる場合はそれを使用すれば問題ないですが、コーディングルールの影響などで、Aggregateを使用しなければいけない場合は画像のように対応します。

1. 画像では最初のAssignに松本、桜井、大野の3名を変数に代入（この辺りは自由に変更してください。）
1. ListAppendでText Structure List型の変数に代入します。
1. String_Joinで#区切りの文字列にします。（検索時の文字列に影響のないseparatorを選択してください。）
1. Aggregateのフィルター内でIndex("#"+String_Join+"#", GetUsers.FirstName)<>-1を使用します。


>あるテキスト文字列が別のテキスト文字列の中に含まれているかどうかを確認するには、テキストビルトイン関数Indexを使用します。
>Index関数は、別のtext文字列に含まれるkeyword文字列のゼロから始まる位置を表す整数を返し、keywordが見つからない場合は-1を返します [1](https://success.outsystems.com/ja-jp/Documentation/How-to_Guides/Logic/How_to_find_out_if_a_string_is_contained_in_another_string)


#いかがでしょうか？
いかがでしょうか。経験が浅いため至らぬところがまだまだあります。
もし間違い等に気がつきましたら、コメント又は[tetra](https://twitter.com/_T_E_T_R_A_)までお知らせください。

# 参考文献

https://success.outsystems.com/ja-jp/Documentation/How-to_Guides/Logic/How_to_find_out_if_a_string_is_contained_in_another_string


https://www.outsystems.com/forums/discussion/53735/how-do-i-perform-in-operator-in-aggregate/
(リンクだけです)「群数列」(group sequence?)について調べてみた。

「群数列」の、でどころ？はどこですか？
群数列は、日本だけですか？

# 学習指導要領
### ?「群数列」は、指導要領に見当たりませんでした。
（ｲ）「数学 B」（2 単位）
＜数学編 理数編＜高等学校学習指導要領（平成 30 年告示）解説　平成 30 年 7 月

https://www.mext.go.jp/content/1407073_05_1_2.pdf#page=24

# 大学入試数学問題集成で(M.E.T.A.様のサイト内検索)
googleの内部検索について、ダブルクォーテーションのありなしで、(もちろん？)結果が違います。

"群数列"

https://cse.google.com/cse?cx=a8908fbc24340ebc5&q=%E7%BE%A4%E6%95%B0%E5%88%97&oq=%E7%BE%A4%E6%95%B0%E5%88%97&gs_l=partner-web.12..0i512l10.3260.3260.0.5087.1.1.0.0.0.0.112.112.0j1.1.0.csems%2Cnrl%3D10...0....1.34.partner-web..0.1.112.r5NHo-Sw9DE

群数列

https://cse.google.com/cse?cx=a8908fbc24340ebc5&q=%E7%BE%A4%E6%95%B0%E5%88%97&oq=%E7%BE%A4%E6%95%B0%E5%88%97&gs_l=partner-web.12..0i512l10.3260.3260.0.5087.1.1.0.0.0.0.112.112.0j1.1.0.csems%2Cnrl%3D10...0....1.34.partner-web..0.1.112.r5NHo-Sw9DE

# googleで

https://www.google.com/search?q=%E7%BE%A4%E6%95%B0%E5%88%97&rlz=1C1CHBD_jaJP908JP908&sxsrf=ALiCzsbas31MF35pP_dMGrmgArCZQyIysA%3A1671357855660&ei=n-WeY_H4J4-2oATt5J-ADQ&ved=0ahUKEwixxJ2a9YL8AhUPG4gKHW3yB9AQ4dUDCBA&oq=%E7%BE%A4%E6%95%B0%E5%88%97&gs_lcp=Cgxnd3Mtd2l6LXNlcnAQDDIECCMQJzIECCMQJzIECCMQJzIJCAAQBBCABBAlMgkIABAEEIAEECUyCQgAEAQQgAQQJTIJCAAQBBCABBAlMgkIABAEEIAEECUyCQgAEAQQgAQQJTIJCAAQBBCABBAlOgoIABBHENYEELADOgkIABAIEB4Q8QQ6BQgAEIAESgQIQRgASgQIRhgAUIYGWMwNYNYeaAFwAXgAgAHgAYgBugWSAQU0LjEuMZgBAKABAcgBCsABAQ&sclient=gws-wiz-serp

# group sequence　だと検索の仕方が悪いですか？

https://www.google.com/search?q=%22group+sequence%22&rlz=1C1CHBD_jaJP908JP908&sxsrf=ALiCzsaoTUTxnk9cVNjEEmhMVmQE5kHuqg%3A1671357451851&ei=C-SeY-_GM5r5hwO0mKmYDQ&ved=0ahUKEwiv-NbZ84L8AhWa_GEKHTRMCtMQ4dUDCBA&oq=%22group+sequence%22&gs_lcp=Cgxnd3Mtd2l6LXNlcnAQDEoECEEYAEoECEYYAFAAWABgAGgAcAF4AIABAIgBAJIBAJgBAA&sclient=gws-wiz-serp
Leafony を、そのままブレッドボードで使えるようにしてみた

> なんかアドベントカレンダー空いてるので小ネタで埋めます。

Webエンジニアです！
Leafonyネタの3回目です。

- [Leafony Basic Kit 2 のSTM32 でLチカに挑戦！](https://qiita.com/tadfmac/items/ae03a581386510becc40)
- [LTE-M Leaf を使ってモノを制御するプロトタイピングをやってみる](https://qiita.com/tadfmac/items/8e679967eb732d96aa35)

## AX02 29PINだけではプロトタイピングが進まん...

前回2回、Leafonyを使った記事を書いたのですが、結構無理のあるものでした。
何が無理があるって、それは。

- Leafony Basic Kit 2 を買っただけではブレッドボードと併用するのがかなり無理

なので、無理やり AX02 29PIN を使ってプロトタイピングしたわけですが、AX02 29 PINからブレッドボードに繋ごうとすると、それはそれで大変そう。

というわけで、LEDを繋ぐことくらいしかできてませんでした。

## ブレッドボードが使いたいんじゃ！

やはりブレッドボードがつかいたい！ということで、Leafonyを簡単にブレッドボードにつなげるリーフを作ることにしました。

できたのがこれです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/31758/d00b6796-ef0b-2c9e-eaa5-4ed61aa8d04b.png)
![IMG_2442.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/31758/57cb4541-4f00-788d-ffe9-a2e233eebddf.jpeg)


下記githubでAutodesk Eagle用のデータを公開しました。（KiCadじゃなくてスマン）

gerberも一緒に置いてありますので、作りたい方はご自由に基板屋さんに投げていただいて構いません。が、一応設計/製造のミスがないか、ざっくり調べたところ問題なさそうなので公開しましたが、細かいチェックはできていないので、何か問題があるかもしれません。ご利用にあたっては、自己責任でよろしくお願いします。

https://github.com/tadfmac/lf-breadboard

今日は以上です！

## 謝辞

デザインに際しては、下記公開ファイルに含まれているライブラリを改変して利用させていただきました。
https://github.com/Leafony/HW-Design-Files/blob/master/AX02_29pin/AX02_29pin_PCBLayout_EAGLE.zip
デュアルブート環境を実用して感じた利点と欠点

# 記事の概要
ここ3ヶ月ほどLinuxとWindowsを一台のマシンに同時にインストールして、起動時にLinuxかWindowsを指定して起動するデュアルブート環境を常用しています。そこで、デュアルブート環境で感じた利点と欠点について記事にしました。

※ 具体的な作業手順については本記事では扱っていません。

# 環境の説明
私が使用しているパソコンのスペックは以下の通りです。
```yaml
# 中枢装置装置
CPU: core i7 6700(3.4GHz, 4core/8thread)
RAM: 16GB(DDR4)
GPU: GTX 1060(6GB)

# 記憶装置
Windows(Windows 10):
    SSD: 240GB(SATA)
    HDD: 4TB(SATA)

Linux(Ubuntu Studio 22.04):
    HDD: 1TB(SATA)
```
パソコンの性能に詳しくない方向けに一言で説明すると、最新のパソコンでいうとほぼエントリーモデルぐらいの性能です。
そのため、最近パソコンを使用している方なら比較的容易に、性能的に同等以上の環境が作れると思います。

# デュアルブートの目的
次になぜWindowsとLinuxをデュアルブートすることにしたのかを説明します。

一言で言うとプログラミングの開発環境としてLinuxが欲しかったからです。
元々、Windows上でVirtualBoxやDockerなどでLinuxを動かしていたのですが、脳の演算リソースが余分に持っていかれる問題がありました。
- 仮想マシンだと、実質リモートマシンの操作になるので開発環境にしては操作が煩雑
- また、Linux on WindowsだとCUIコマンドなど異なる操作体系が混在するため、常に今どちらの環境にいるか考える必要がある
- 同じコマンドのSSHでもファイルの権限回りなどシステムが違い問題が発生する

<br />
しかしLinuxに完全移行するには、Windows限定のソフトを捨てられない問題もありました。

 - 購入したソフトウェア
 - 使い慣れたソフトウェア
 - ゲームなど

これらは今後も使用するため、WindowsとLinuxの共存するという方針でデュアルブートを実施することにしました。

# デュアルブートの利点
- マシンスペックをフルで利用できる
これの利点は、単純に開発環境の性能が上るだけではありません。
DropboxやDiscordなど開発に便利だけど、物理マシンに入っているから仮想マシンに入れないソフトも心おきなくインストール・使用できるという点もあります。

- OSが単一障害点ではなくなる
マシンの動作が安定しないとき、ソフトかハードの問題を切り分けるのにデュアルブート環境は有用です。また、どちらかが不安定になってもWeb上でできる作業はどちらでもできるため、簡単な事務処理程度なら不安定な環境を復旧させずとも実施できます。

# デュアルブートの欠点
- OSの切り替えには再起動が必須
たとえば、Linuxで作業中にWidowsでしかできない作業をする必要があると、一度再起動をする必要があります。通話中なら通話を切る必要がある、切り替え時に集中が途切れるなど切り替えは煩わしいです。

   ==> 対策方法(仮)
VirtualBoxのディスクパススルー機能を利用してもう一つの環境を仮想マシンとして起動するという対策があります。ただし、仮想マシンとして安定して起動しない、物理WindowsをWindows on Linuxとして仮想マシンにすることはライセンス的に問題がある(*)など万全な対策ではないです。

(*) 私が使用しているWindowsがDSP版のためハードウェアの変更に制限があります。物理マシンと仮想マシンでWindowsから見えるハードウェアが変わるため問題になりそう判断です。そのため、Windows on Linuxのとして仮想マシンは起動させていません。

# 総評
OSの切り替えコストを許容できれば、WindowsとLinuxそれぞれ専用の環境を一台のパソコンで実現できるのでデュアルブートおすすめです。