OmniAICreator/Qiita-1.07M huggingface dataset:
新人エンジニアがmocker.Mock()とMagicMock()の違いについて調べたのでメモ

最近、初めてユニットテストを書いたので、python のテストフレームワークに登場するmocker.Mock()とMagicMock()の違いについて調べてみました。

## ざっくりとした違い

mocker.Mock()とMagicMock()は、それぞれ異なるテストフレームワークに由来します。mocker.Mock()はpytestの一部であり、MagicMock()はunittestの一部です。

## そもそもmockとは？

モック（mock）とは、テストに必要な部品を擬似的に再現するために用いられます。これにより、テスト対象コードで呼び出しているメソッドや外部ライブラリの機能をモック化し、テスト対象コードの外部依存を排除して適切なテストを行うことができます。

また、モック化に使用するテストフレームワークのクラス自体をモックと呼ぶこともあるため、文脈に応じて注意が必要です。

## pytestとunittest

では、mocker.Mock()とMagicMock()について見ていきます。それぞれのオブジェクトが所属するテストフレームワークにも触れていきます。

### pytest- mocker.Mock()

pytestは、サードパーティ製のpythonのテストフレームワークです。後に紹介する、標準ライブラリのunittestよりも使い勝手が良い（らしい）ので、pytestを使ってテストを書くことが多いようです。

mockerとは、pytest-mockライブラリの一部であり、pytestと共に使用されることが多いようです。pytest-mockは、pytestのためのモッキングツールを提供し、その中のmockerで、Mock()が利用されます。

mocker.Mock()は、pytest-mockによって提供されるモックオブジェクトです。


### unittest -MagicMock()

unittestはPythonの標準ライブラリであり、Pythonに組み込まれているテストフレームワークです。使いやすさや機能の点でpytestに劣ることがあるため、主に

MagicMock()はunittest.mockモジュールから提供されるモックオブジェクトです。Mock()クラスの拡張で、特定のマジックメソッド（例えば`__getitem__`, `__setitem__`, `__iter__`など）を標準でモック化する機能を持っています。

## 結論：

mocker.Mock()とMagicMock()は、それぞれ異なるテストフレームワークに由来しており、MagicMock()はmocker.Mock()の機能に加えて、マジックメソッドをモック化する機能が標準で備わっていることがわかりました。
＃15　Webサービスのセキュリティの基礎知識：「認可」

## はじめに
近頃、Webサービスにおける個人情報漏洩のニュースを目にする機会が多くありました。
そこでWebサービスのセキュリティの基本的な概念である「認証」と「認可」について、前後半に分けて備忘録としてまとめていきたいと思います。
今回は、その後半として「認可」の概念と、認可の管理として用いられるアクセス制御方式の種類と特徴について取り上げたいと思います。

## 認可とは
Webサービスにおける認可は以下のように説明されます。

> 認証されたユーザーの権限に基づいて、特定のリソースへのアクセスを許可します。権限は1つ以上の属性によって定義されます。属性とはユーザーのプロパティまたは特性のことです。たとえば、「Marc」はユーザーで、「会議の発言者」は属性です。

 - 引用：https://docs.oracle.com/cd/F23552_01/ws-manager/12.2.1.4/concepts/understanding-web-service-security-concepts.html#GUID-34DB0E84-2506-4D93-9D37-9FDE86E55EF2

つまり、認可とは「認証を通過した人に認めた権限」であり、「アクセス制御によって操作が認められた範囲」と考えることもできます。
認証という前提の元に認可があるということは、Webサービスのセキュリティ概念を考える上での基本になります。

## 認証と認可を区別する理由
「認証と認可の区別がない」ということは「認証を通過したユーザには全ての権限が付与されている」と考えることができます。
閲覧、作成、編集、削除などあらゆる権限が認証後ほぼ無差別に付与されたとなれば、安全なWebサービスを提供することはできません。
認証と認可が区別されていない場合に想定される危険は様々にあります。
例えば、認証を通過したユーザは

 - Webサービスに登録されている他人の住所やキャッシュカード番号など、個人情報を自由に閲覧できる
 - 他のユーザになりすまし、スパムなどの迷惑行為ができる
 - 他のユーザの投稿などを自由に編集・削除できる

など。
実際にここまで区別のないWebサービスがあるとは思えませんが、不正アクセスによる情報漏洩などの要因として、認証と認可の曖昧さがその一端を担っていることは理解しておくべきでしょう。

## アクセス制御方式の種類
「認可」を管理するための要となるのがアクセス制御方式です。
セキュアなWebサービスを提供するためには、サービスに合ったアクセス制御方式を適切に運用していく必要があります。
以下でアクセス制御方式の種類とその特徴を確認していきます。

#### 任意アクセス制御
DAC(Discretionary access control)とも呼ばれ、各ユーザが制御権限を持つ方式。管理者による一元的な管理は行いません。
最も一般的なアクセス制御方式であるとされ、ファイルなど作成者自身が誰に対してアクセスを許可するかを設定するため、管理者の介入が必要なく、管理の手間は少ないです。
組織としてアクセス制御を行う場合、統一されたセキュリティルールに則って個々人で正しく運用する必要が求められます。

#### 強制アクセス制御
MAC(Mandatory access control)とも呼ばれ、システム担当者など決められた人間だけがアクセス制御の権限を持つ方式。
セキュリティ強度の高さから、機密情報を取り扱う際はこのMACの使用が強く推奨されています。

#### ロールベースアクセス制御
RBAC(Role-base access contorol )とも呼ばれ、ユーザ個人ではなく、グループごとにアクセス権限を付与する方式。
役割（ロール）に応じてユーザをグループに加えることでアクセス制御を行います。
メリットとして、ロールに基づいてアクセス権を付与することができるため、保守や監査などが行いやすいことが挙げられます。
個人単位でアクセス権限を制御する必要がないので、権限管理を効率的に行うことができます。

#### 属性ベースアクセス制御
ABAC(Attribute-base access contorol )とも呼ばれ、ユーザやデータの機密性に応じてアクセス権限を付与する方式。
所属組織や職務といったユーザの持つ属性だけなく、時刻や場所などを指定したアクセス制御を行うことも可能です。
メリットとして、きめ細かくアクセスを制御できるため、組織のニーズに合わせた柔軟なアクセス権限の管理を実現できることが挙げられます。

#### アイデンティティーベースアクセス制御
IBAC(Identity-based access control)とも呼ばれ、「認証」と「認可」の二段階に分けてアクセス制御を行う方式。
第一段階としてアクセス要求者の認証を行い、アクセスが許可されているユーザかどうかを判別します。
第二段階では、誰からのどんな要求であればアクセスを許可するのかをまとめた「アクセス制御リスト」に基づいて、認証を通過したユーザのアクセス要求が、リストで許可された種類のものであるかを判別します。

## おわりに

今回は、Webサービスのセキュリティとして基本的な概念である「認可」と、アクセス制御方式の種類についてまとめてみました。
それぞれのアクセス制御方式の具体例などに関しては、今回の記事では収まりきらないと考え、取り上げませんでした。
機会があれば、実装例などと併せてまとめていきたいと思います。

前後半に分けて「認証」と「認可」の概要について取り上げてみました。
これらの記事が、Webサービスにおけるセキュリティへの理解の一助となることができれば幸いです。

以上です。閲覧ありがとうございました。





出典：

 - https://cybersecurity-jp.com/column/51422
 - https://www.okta.com/jp/identity-101/what-is-role-based-access-control-rbac/
 - https://solution.kamome-e.com/blog/archive/blog-security-20211021/
Amplify Gen2: SQLの設定時に苦戦したこと

# はじめに

サーバーレス大好きエンジニアです！
Amplify Gen2ではSQLデータベースを利用することができます。
実際に使ってみて、登録時に失敗したポイントを共有したいと思います。

# 目次
1. Amplify Gen2とは？
2. 登録方法
3. 失敗したこと
4. 成功した場合
5. まとめ

# 1. Amplify Gen2とは？
TypeScriptを使用してフルスタックアプリケーションを構築するための新たなAWS Amplifyが登場しました。
バックエンドリソースの作成がCLIからCDKに変更されたことで、より拡張性が高くなりました。
また、今までのAmplifyでは実現できなかった機能が追加され、その中でSQLデータベースの使用が可能になったことを知り、使ってみることにしました。


# 2. 登録方法
今回はMySQLの接続方法について書いていきます。
たった2つのコマンドで接続することができます。

まず、以下のコマンドでsandboxのシークレットを設定します。
```
npx ampx sandbox secret set SQL_CONNECTION_STRING
```

ここではSQL_CONNECTION_STRINGというシークレットを登録します。以下のようにSQLの情報を入力してください。

```
npx ampx sandbox secret set SQL_CONNECTION_STRING
? Enter secret value: mysql://user:password@hostname:port/db-name
```

次に以下のコマンドを実行するとデータベース接続が完了し、AmplifyでSQLを利用することができます。
```
npx ampx generate schema-from-database --connection-uri-secret SQL_CONNECTION_STRING --out amplify/data/schema.sql.ts
```

# 3. 失敗したこと

## 3.1 接続するリンクの情報がそもそも違う

`mysql://user:password@hostname:port/db-name`の入力を間違えると以下のようなエラーが発生します。

```
Unable to connect to the database
```

## 3.2 データベースの登録をしていない

データベースが見つからないというエラーが起きます。

```
Error: Unknown database
```

この問題は、SQL内でデータベースを作成することで解決できます。
```sql
CREATE DATABASE hoge
```

## 3.3 スキーマの定義がされていない

既存のMySQLからスキーマをインポートするので、テーブル設計を事前にしておく必要があります。

```
Error: Imported SQL schema is empty.
```

また、`PRIMARY KEY`を設定しない場合もエラーが発生します。

```
Error: No valid tables found. Make sure at least one table has a primary key.
```

以下のようにテーブル定義と`PRIMARY KEY`の設定を行います。

```sql
CREATE TABLE Users (
    id INT AUTO_INCREMENT PRIMARY KEY,
    name VARCHAR(255),
    email VARCHAR(255),
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
```

## 3.4 認証設定

RDSの設定を正しく行わない場合、以下のエラーが発生します。
```
AccessDenied: no identity-based policy allows the rds:DescribeDBProxies action
```

# 4. 成功した場合
成功すると、以下のようなログが出力されます。

```
✔ Successfully fetched the database schema.
```

# 5. まとめ

認証とSQLの初期データを適切に登録すれば問題なく接続できます。
参考になれば幸いです。
VBAにおけるIF文の速度のお話

モダンコードが書きたいなぁと思いを馳せつつ、客要望のシステムを粛々と書いています。ロックマンです。

今回はEXCELツール（VBAマクロ）の作成時の気付きについて忘備録として記事を挙げさせていただきます。

# コードの概要
+ 条件２つが両方TRUEの場合処理をする
  + 条件１：数値の等しくない判定
  + 条件２：文字列の比較判定をする
+ 計測に必要な最低限の時間のため、１億回ループする
+ 処理の前後で時間を取得、差分を取り処理時間を出力する

# 試験コード
以下2種類のコードを用意しました。

## コード１
条件１と条件２をANDでつなぎ、条件は常にTRUEとする。
```
Sub hoge()

Dim startTime As Double, endTime As Double
Dim v As Long
Dim ex1 As Long: ex1 = 100000001
Dim ex2 As String: ex2 = "テキスト"

startTime = Timer
For i = 1 To 100000000
    If (ex1 <> i and ex2 = "テキスト") Then
        v = i
    End If
Next i
endTime = Timer

MsgBox endTime - startTime & "秒"
```
## コード2
条件１と条件２をネストする、条件は常にTRUEとする。
```
Sub hoge()

Dim startTime As Double, endTime As Double
Dim v As Long
Dim ex1 As Long: ex1 = 100000001
Dim ex2 As String: ex2 = "テキスト"

startTime = Timer
For i = 1 To 100000000
    If (ex1 <> i) Then
        If (ex2 = "テキスト") Then
            v = i
        End If
    End If
Next i
endTime = Timer

MsgBox endTime - startTime & "秒"
```

# 結果

| 試行 | コード1 | コード2 |
|:-----|------------:|:------------:|
| 1    | 8.05078秒      | 6.03515秒         |
| 2    | 7.85937秒      | 5.93359秒       |
| 3    | 7.87109秒      | 6.02343秒         |


ANDにしたほうが早いのかな？と思ったらネスト（コード２）のほうが早いのは以外だったって話でした。

# ちなみに

ネストしたほうが条件１の結果がFALSEなら条件２を見に行かないから、条件によっては更に早くなるかもしれない・・・？
AtCoderテンプレメモ

inputの入力をうけるやつ、出力するやつ

```py
# インポート(本編はだいたい30行目あたり)
import sys,itertools,math,heapq
from collections import defaultdict,deque
from sortedcontainers import SortedSet, SortedList, SortedDict #Cpythonでは動かない(importにも多少時間がかかる)
sys.setrecursionlimit(10**8)
dict=defaultdict

# 便利関数定義
def input(): return (sys.stdin.readline()).rstrip()
def yes(): print("Yes"); exit()
def no(): print("No"); exit()
def printe(*values: object,sep: str | None = " ",end: str | None = "\n",): print(*values,sep=sep,end=end); exit() #Cpythonでは動かない
def listr(l:list): return "".join(l)
def debug(*values: object,sep: str | None = " ",end: str | None = "\n",): print(*values,sep=sep,end=end,file=sys.stderr) #デバッグ出力用

# 便利定数定義
ALPHABET="ABCDEFGHIJKLMNOPQRSTUVWXYZ"
alphabet="abcdefghijklmnopqrstuvwxyz"
MOD=998244353

# 関数定義スペース

# Lit_to~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# 入力スペース
# s=list(input())
s=input()
n=int(input())
h,w=map(int,input().split())
a=list(map(int,input().split()))
# board=[list(input()) for i in range(h)]#文字列のリスト
# board=[list(map(int,input().split())) for i in range(h)]#数値のリスト
# Lit_to================================================================================================本体ここから↓




```

優先付きキューをインスタンスにして使えるようにしてみた
``import heapq``必須だよ

```py
class priorityQueue():#heapqラッパー
    def __init__(self,l=list()):#インスタンス化
        self.queue=l.copy()
        heapq.heapify(self.queue)
    def __getitem__(self,i):
        return self.queue[i]
    def __len__(self):#かぞえる
        return len(self.queue)
    def __str__(self):#出力用
        return str(self.queue)
    def enq(self,value):#入れる
        return heapq.heappush(self.queue,value)
    def add(self,value):#入れる
        return heapq.heappush(self.queue,value)
    def deq(self):#出す
        return heapq.heappop(self.queue)
```


ぱぱっと二分探索が必要になったとき向け``配列.index()``より高速にインデックス番号を知ることが出来るもの
```py


def index(arr:list,value:int,exactry:bool=True,ceil:bool=False):
    #ソート済配列をもらって二分探索したうえでインデックスを返す関数。二分探索をします。
    #(必須)第1引数にソート済みの配列、第2引数に探したい値を入れる。
    #(任意,デフォルト)exatry=Trueでその値がドンピシャの時にのみインデックスを返す。なかった場合は-1を返す。
    #この時、値が複数個ある場合はceilルール通りにインデックスを返す。(ceil=Trueの時は一番右側を返し、ceil=Falseの時は一番左側を返す)
    #(任意)exatry=Falseでその値がなくてもceilのルール通りにインデックスを返す。
    #(任意,デフォルト)ceil=Falseでその値より小さい一番大きい値のインデックスを返す。
    #(任意)ceil=Trueでその値より大きい一番小さい値のインデックスを返す。
    left, right = 0, len(arr) - 1
    result = -1
    while left <= right:
        center = (left + right) // 2
        if arr[center] == value:
            result = center
            if ceil:
                left = center + 1  # 右側に同じ値がないかを確認
            else:
                right = center - 1  # 左側に同じ値がないかを確認
        elif arr[center] < value:
            left = center + 1
        else:
            right = center - 1
    if result != -1:
        return result
    if exactry:
        return -1
    if ceil:
        return right if 0 <= right else -1
    else:
        return left if left < len(arr) else -1


```
ビット否定を使用した加算・減算【JS】

# はじめに
ビット否定演算子`~`を使用した加算・減算ができるようです。

# ビット否定演算子

MDNでは以下のように定義されています。
（日本語版では`Bigint`についての記載が不足しているため、英語版を引用）

> The bitwise NOT (~) operator returns a number or BigInt whose binary representation has a 1 in each bit position for which the corresponding bit of the operand is 0, and a 0 otherwise.

:::note 
簡単な訳
- ビット否定演算子`~`は、`number` or `Bigint`を返します
- 各bit部分が0のときは1、それ以外では0を返します
:::

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Bitwise_NOT

## 実例

理解には、実例を見るのが速いでしょう。

**「ビット否定」という名称ですが、「ビット反転」と呼ぶべき挙動です。**

> ```
> 9 (base 10) = 00000000000000000000000000001001 (base 2)
>                --------------------------------
> ~9 (base 10) = 11111111111111111111111111110110 (base 2) = -10 (base 10)
> ```

- `base 10`は10進数のこと
- `base 2`は2進数のこと

1. 10進数の`9` = 2進数の`00000000000000000000000000001001`
1. `~9` = `00000000000000000000000000001001`を反転させたもの
1. = `11111111111111111111111111110110` = `-10`

※ここでの負数の扱いは、以下のページで「2の補数表現」と紹介されているものです。

https://www.cc.kyoto-su.ac.jp/~kbys/kiso/number/negative.html

---

以上の例では、`~9`が`-10`になりました。**この例以外でも、`~n`は`-(n+1)`を返します。**

```js
console.log(~-4) //3
console.log(~0) //-1
console.log(~1) //-2
console.log(~-1) //0
```

# ビット否定を使用した加算・減算

本題です。「`~n`は`-(n+1)`を返す」仕様を応用して、加算・減算ができます。

```js
function add(n) {
  return -~n
}

function subtract(n) {
  return ~-n
}

console.log(add(4)) // 5
console.log(subtract(0)) // -1
```

**この手法は、単に技術的なおもしろさだけでなく、以下の利点があります。**

- オペランドが一つであり、コードが短い
- `undefined`を`0`として扱うことができる

## `undefined`を`0`として扱う

これは、`-~`と同じく「コードが短い」というメリットを持つ`++`と比較した時のメリットです。

以下の例では、`arr[1]`が存在しませんが、それを呼び出して処理をしています。
`++`を使用する場合、`add3`のように`n++ | 1`という書き方をすれば解決できますが、`-~`は、この場合分け記述を必要としません。

```js
function add(n) {
  return -~n
}

function add2(n) {
  return n++
}

function add3(n) {
  return n++ | 1
}

let arr = []

console.log(add(arr[1])) // 1
console.log(add2(arr[1])) // NaN
console.log(add3(arr[1])) // 1
```

# おわりに

面白いだけでなく、実用的な面もある興味深い手法でした。
ただ、一般的には可読性が低いと言って良いでしょう。その点は注意が必要です。

この記事は以下のコメントをもとに作成しました。コメントありがとうございました。

https://qiita.com/kohki_takatama/items/381c5d3f538e4ccf7ca1#comment-758bdf1165d5cd77b9e6
[paiza]足し算するだけの簡単なお仕事

# Dランクをわかりにくく解く
https://paiza.jp/works/mondai/d_rank_skillcheck_sample/addition

# 面倒くさいので画面パタメータをListでもらった後のFunctionだけ
ちなみに引数のListを作ってる箇所は[こっちの記事](https://qiita.com/AsilHatake/items/842548e48ae4a0eae119)に書いてあるYO!!

```javascript:add.js
// [問題文（原文）]
// ２つの正の整数 a, b が半角スペース区切りで入力されるので a と b を足した数を出力してください。
// ※「掛け算」の問題では入力が改行区切りで与えられましたが、今回は半角スペース区切りで与えられます。
function add(lines) {
  if (!Array.isArray(lines) || lines.length !== 1) {
    console.log("1行入れろや！");
    return;
  }
  const vals = lines[0].split(" ");
  if (vals.length !== 2) {
    console.log("値をスペース区切りで2つ入れろや！");
    return;
  }
  if (!vals.every(line => {
    const num = Number(line);
    return Number.isInteger(num) && num >= 0 && num <= 100
  })) {
    console.log("0～100の整数入れろや！");
    return;
  }
  // mapでNumberに変換してからreduceを使って、なんかいい感じに難読で書いてみる
  console.log(vals.map(v => Number(v)).reduce((accumulator, currentValue) => accumulator + currentValue, 0));
}

module.exports = {
  add
};
```
普通に vals[0] + vals[1]でいいじゃんとか思ったけど、
それだと芸がなかったので小難しく書いてみた。
[paiza]文字列をつなげるだけの簡単なお仕事

# でぇベテランだけど、Dランク解いてイキりたい

https://paiza.jp/works/mondai/d_rank_skillcheck_archive/email_address

# 面倒くさいので画面パタメータをListでもらった後のFunctionだけ
ちなみに引数のListを作ってる箇所は[こっちの記事](https://qiita.com/AsilHatake/items/842548e48ae4a0eae119)に書いてあるYO!!

```javascript:createMailAddress.js
// [問題文（原文）]
// Eメールアドレスとはローカル部とドメインを「@」を繋いだ文字列で表されます。
// ローカル部を s ,ドメインを t として、それぞれ長さ n の文字列が改行区切りで入力されます。
// 以下の構文に沿った文字列を出力してください。
// 
// s(ローカル部)@t(ドメイン)
// 
// 例えば
// info
// paiza.jp
// のような入力の場合
// info@paiza.jp
// と出力して下さい。
function createMailAddress(lines) {
  if (!Array.isArray(lines) || lines.length !== 2) {
    console.log("2個の文字列を入れろや！");
    return;
  }
  if (!lines.every(line => line.length > 0 && line.length < 65)) {
    console.log("1行につき1～64文字入れろや！");
    return;
  }
  console.log(lines.join("@"));
  // console.log(`${lines[0]}@${lines[1]}`); // こっちでもいいけど短く書きたい
}

module.exports = {
  createMailAddress
};
```

文字列を「+」で繋ぐとかなんか初心者ぽくってやりたくなかったので、
受け取った形がlistだったので、joinを使って繋げてみた。
またコメントアウトにしてるけど、純粋に1行目と2行目が別々の変数とかに入ってる場合とかだったら、文字列設定時に変数が使える「\` ${変数}\`」と言った形で書くのも良くやるよね。
Pythonの`and`, `or`の動作

# 自分が最初におもっていた仕様



### 誤解1  `or`, `and` は基本的に引数は`bool`型で返り値は`bool`型で`bool`型

たとえば, 
`0<x<10 or x%2==0 `
 という式があったら, `x=14`だとしたら
 
 `0<x<10`は`False`になって, ` x%2==0`は`True`となって
 `False or True`が計算されて`True`になるみたいな感じで頭の中で解釈していた。

### 誤解2 引数が`bool`型じゃない場合は, `None`の場合は`False`になって, それ以外の場合は`True`となる

たとえば, 
```Python
if os.getenv('OPENAI_API_KEY') :
```
とかくと, APIキーが設定されていず, `None`となるとき, `False`として解釈される.
`os.getenv('OPENAI_API_KEY')`があるとき`True`と解釈される.
 
# 誤解2の解消

`None`以外でも以下のものは`False`と評価される。

### 「偽」と評価されるもの
以下のオブジェクトは`False`と評価される

1. `None`
2. `False`
3. 数値のゼロ
   - `0`（整数）
   - `0.0`（浮動小数点数）
   - `0j`（複素数）
4. 空のシーケンスおよびコレクション
   - `''`（空文字列）
   - `[]`（空リスト）
   - `()`（空タプル）
   - `set()`（空セット）
   - `frozenset()`（空フローズンセット）
   - `{}`（空辞書）
5. 空の範囲
   - `range(0)`

### 「真」と評価されるもの
上記以外のすべてのオブジェクトは`True`と評価される。

### 実例
以下の例では、さまざまなオブジェクトが「真」と評価されるか「偽」と評価されるかを確認できます：

```python
# 偽と評価されるもの
print(bool(None))  # False
print(bool(False))  # False
print(bool(0))  # False
print(bool(0.0))  # False
print(bool(0j))  # False
print(bool(''))  # False
print(bool([]))  # False
print(bool(()))  # False
print(bool(set()))  # False
print(bool(frozenset()))  # False
print(bool({}))  # False
print(bool(range(0)))  # False

# 真と評価されるもの
print(bool(True))  # True
print(bool(1))  # True
print(bool(-1))  # True
print(bool(3.14))  # True
print(bool(-3.14))  # True
print(bool(1j))  # True
print(bool(-1j))  # True
print(bool('Hello'))  # True
print(bool([1, 2, 3]))  # True
print(bool((1, 2, 3)))  # True
print(bool({1, 2, 3}))  # True
print(bool(frozenset({1, 2, 3})))  # True
print(bool({'key': 'value'}))  # True
print(bool(range(1, 10)))  # True
```

# 誤解1の解消

誤解1している状態だと
```Python
print(None and "default")    # False
print(0 and "fallback")      # False
print([] or "empty list")   # True
print("value" or "default") # True 
print(1 or 0)               # True 
print(True and False)        # False
```
みたいな結果になってしまう。

**`or` 演算子は、左から右に評価し、最初に`True`と評価される値を返し, すべてが`False`の場合は、最後の値を返す**

**`and` 演算子は、左から右に評価し、最初に`False`と評価される値を返し,すべてが`True`の場合は、最後の値を返す**

という仕様だ。

誤解1している状態だと
```Python
print(None and "default")    # None
print(0 and "fallback")      # 0
print([] or "empty list")   # "empty list"
print("value" or "default") # "value" 
print(1 or 0)               # 1 
print(True and False)        # False
```
となる。

この仕様を利用すると以下のような3項演算子をシンプルにかける
```Python
self.api_key = api_key if api_key else os.getenv('OPENAI_API_KEY')
# の代わりに
self.api_key = api_key or os.getenv('OPENAI_API_KEY')
# とかける.
```
よわよわエンジニア、UI・UX修行を始める ~トンマナって、何……？？？？~

## はじめに
本記事では、UI・UXデザイン方面でつよつよになりたい筆者が、UI・UXデザインに取り組んでいくなかで身に染みて感じたことを書いています。

わたし「**トンマナ**って言葉、何かデザインについて調べてるとよく見るけど、何なんだろ？」
わたし「(たぶん常識なんだろうなあ……)」

## トンマナとは

**トーンアンドマナー**、略して「**トンマナ**」です。
デザインの色やスタイル、文言などの一貫性を保つルールのことを指します。
トーン(tone)が「調子」、デザインの色や雰囲気などのことです。
マナー(manner)が「様式」、デザインの表現方法やスタイルのことです。

## トンマナを合わせるメリット

まずは、そのアプリやサービスのイメージをユーザーに強く印象付けられることです。
アプリやサービスのデザインを作るとき、そのアプリやサービスがユーザーに与えたいイメージ・印象が存在すると思います。それはテーマカラーであったり、「モダン」「クラシック」などのテイストであったりするのかもしれません。
身近なサービス(例えば、今まさにあなたが読んでいるQiitaとか)を思い浮かべてみても、色やフォント、サイトの雰囲気などは統一されています。
トンマナがそろっている場合はユーザーがそのアプリやサービスのUI/UXに触れるとき、統一されたデザインであればそのデザインを何度も目にすることになります。人間の特性として何度も見るものは記憶に残りやすいため、ユーザーにアプリやサービスの世界観を強く印象付けることができます。
そして、そもそも統一されたデザインは美しいです。美しいデザインは、それだけでユーザーは対象のUI/UXを良いものと感じる傾向にあります(美的ユーザビリティ効果)。

逆にトンマナがそろっていないてんでばらばらなデザインでは、ユーザーにイメージを印象付けることはできません。そしてそれはユーザーの離反にもつながりかねないのです。
だって印象がないのですから。

また、事前に決めておいたトンマナに合わせてデザインをすることで、デザインのクオリティを担保することもできます。
色はこの色、フォントはこれ、ここの余白は何px、と決まっていれば、そのルールを守ってデザインを作成することでデザインの一貫性が保たれます。
これはデザインに携わるメンバーが複数いる場合にも有効です。メンバー間でトンマナの認識を合わせておくことで一貫されたデザインを効率よく制作することができます。

## さいごに

トンマナを合わせる、個人的には今まさに苦労しているところです。
デザインを依頼されたとき、ただ良い感じのデザインをすればよいのではなく、デザインをする対象や依頼元のイメージをきちんと掴んでそれに合ったデザインをしなければ、製品のイメージに合わなかったり、ひどい場合にはイメージを損ねてしまうことがあります。
しかし、デザインをする対象や依頼元のイメージを掴むには、デザインをする側の対象への調査やベンチマーク、関係者へのヒアリングを通してきちんと理解しなければなりません。
難しいことですが、UI/UXデザインを志すうえでは避けて通れないと常々思います。
新しいアイテムを追加するボタンを作る


標準の機能では下記のようにこのボタンで新規アイテムを追加します。
同じ機能をカスタムボタンで実現したい。まずはどんなURLを書けばいいのだろうか？

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/45645bc4-f5f8-8d9e-feed-db917b40bdc6.png)

３日程調べてやっとみつけましたね。日本語では全くヒットしません。ニーズないんだろうか？

やっぱり英語で調べるしかないと半日やったら、見つかりました。NewForm.aspxを使うのか...

+ [Program Power Apps Form Button to create new SharePoint list item](https://community.powerplatform.com/forums/thread/details/?threadid=7b815457-0d76-4a09-9c94-fe2ac36c2486)

:::note
If you mean to open a New Item page from SharePoint,  you can use Launch() function to open it, set the OnSelect of button as below:

```
Launch("https://<Domain>.sharepoint.com/sites/<SiteName>/Lists/<ListName>/NewForm.aspx")
```
:::

試してみましたが、機能します。


ボタンにはできなかったが、ハイパーリンクにはできた。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/d6db2432-f2fa-b750-165e-3c4dcad7680a.png)
Microsoft Power Fx 


+ [Microsoft Power Fx の概要](https://learn.microsoft.com/ja-jp/power-platform/power-fx/overview)

Power Fx は Microsoft Power Platform 全体で使用されるロー コード言語です。 汎用、厳密な型指定、宣言型、そして関数型のプログラミング言語です。

Power Fx は、人が使いやすいテキストで表現されています。 作成者が Excel のような数式バーまたは Visual Studio Code のテキスト ウィンドウで直接操作できるローコード言語です。 ローコードの「ロー」は、言語の簡潔でシンプルな性質によるものであり、一般的なプログラミング タスクを作成者と開発者の両方にとって容易にします。 これにより、プログラミング経験のない人向けのコードなしから経験豊富な専門家向けの「プロコード」まであらゆる開発が実現し、新たに学ぶことや書き直しの必要がないので、さまざまなチームが協力して時間と費用を節約できます。

# Microsoft Power Platformとは？

Microsoft Power Platformとは、Microsoftが提供するローコード・ノーコード開発プラットフォームです。ローコード・ノーコードとは、プログラミングの知識やスキルがなくても、ドラッグアンドドロップやGUIなどの簡単な操作で、アプリやワークフロー、ダッシュボードなどを作成できる開発手法です。

Power Platformでは、Power BI、Power Apps、Power Pages、Power Automate、Power Virtual Agentsという5つのサービスを組み合わせて、ビジネスに必要なソリューションを自由に構築できます。

また、Power PlatformはMicrosoft 365やAzure、Dynamics 365などのMicrosoftのクラウドサービスとも連携できるので、既存のデータやシステムの活用ができます。


+ [Query String URL Tricks for SharePoint and Microsoft 365](https://learn.microsoft.com/ja-jp/microsoft-365/community/query-string-url-tricks-sharepoint-m365)
仕事はなぜ属人化してしまうのか？

こんにちは
記事をチラ見していただきありがとうございます。5分お時間をください。

職場で感じていることがあります。なぜ仕事は属人化してしまうのか？について私見を述べます。エンジニアの記事かと言われると違う気もするのですが、現役エンジニアである私としては無視できない問題だと感じています。私見とはいえ、賛否の意見をいただければ幸いです。

## 仕事は与えられるもの
ほとんどの人はサラリーマンで、中小企業に勤めています。もちろん大企業も同様ですが、自分で事業を起こしていない人たちのことです。新卒で入社後、手厚い研修を受け、先輩や上司から仕事を与えられながら働き始めます。そして自らが先輩や上司になったとき、自分がされてきたことを繰り返し、"仕事"をちぎっては部下に与えます。まるで親鳥が雛を育てるように。

## 仕事を守りたい
次第に自分の居場所ができたことに安心し、力が抜けていきます。一方で仕事はほとんどの場合ルーチンワークで慣れてくるため、意図せずとも"自動的に"効率化されていきます。このぬるま湯状態にどっぷり浸かると元には戻りたくなくなります。こうなると人に仕事（＝居場所）を取られたくなくなり、守りに入ります。仕事自体の効率は一見良さそうで、周りからも悪い評価はしづらくなります。単純に知らない業務について第三者が評価しづらいことや、人間関係も絡むためです。

## 仕事の目的を失う
本来、"仕事"とはある目的を達成するための手段にすぎません。多くの場合、その目的とは利益を追求することです。ところが、多くのケースで"仕事"をすること自体が目的になり、本来の目的を忘れていることが見受けられます。

## DX化、RPAは敵
昨今、処理の自動化やAIの進化により、ルーチンワークを駆逐する恐れ（笑）があるフレームワークが増えてきました。こういったDX化に関わると、業務の複雑さやそれまで積み上げてきた中途半端な自動化処理が垣間見えます。中途半端だとけなすつもりはなく、やろうとしているだけでも十分に良いことです。Very Goodです。

問題なのは、このRPAと付き合っている人たちが本来の業務に無頓着であることです。根底には"仕事"そのものを所有しているかどうかに意識が集中しているため、その仕事が生み出す効果や業務そのものの目的には関心がないことがあるのだと思います。そんな彼らにはDX化もRPAも仕事を奪う可能性のある邪魔者でしかありません。

## 仕事はなぜ属人化してしまうのか？
さてここでいったん本題に戻ります。上記の通りDX化やRPAをはじめとした業務改善／見直しはなるべくしたくないことです。ネガティブなこの発想をこのように言語化している人はあまりいないと思いますので確証を得るのが難しいですが、根底にはこの意識が意識的か無意識的にあるのだと考えています。
"仕事"をなるべく複雑化して例外をたくさん取り入れ自分だけが評価される、自分しかできない"仕事"の牙城を築きたくなるわけです。

## どうすればいいの？
私が教えてほしいくらいですがもやもやした概念から言語化がやや難しい程度には固まってきました。ここに至るまで様々な書籍や記事を読んだり、採用人事に関する情報を入手したりと、エンジニアとは程遠いことをしてました。（趣味で）

- 責任を明確にする
- 業務を標準化する
- 隠さず公開する
- 兎も角スキルアップ

業務の目的そのものに責任を持たせる、所謂ロールを与えることです。
極論言ってしまえばルーチンは手段なのであればラッキー程度に思っておき、責任を重視することです。

「言うは易く行うは難し」ですが、少し難しい仕事も誰もが行えるようにすることが本来その業務をする人の責務です。

やましいことがあるから公開できないのです。公開するところで仕事しましょう。こっそりやっているそれは本当に仕事ですか？黒塗りの領収書と同じですよ。

自覚している人はもう自覚しているので改めて私が言うことではないですが、スキルは高ければ高いに越したことはありません。スキルが高い人のほうが自由度の高い仕事を選べるに決まってます。ばばを引きたくなければ努力しましょう。


## 最後に
ここまで読んでいただいた方、ありがとうございます。独断と偏見が多分にあるかと思いますが日本はこの悲しき土壌がしっかり育まれてしまったのではないでしょうか？私のそして皆さんの周りが良くなりますように。
VSCodeで定義に移動できない

# はじめに
こんにちは、ユーゴです。今回は、VSCodeを使ってUnityのC#を編集しようとした時に遭遇した問題を紹介します。
VSCodeは、一度導入すると比較的楽なのですが、最初のセットアップでコケたり、稀に動作しなくなることがあります。今回は、稀に動作しなくなる方でした。

# 問題
定義に移動できない。
例えば、GameManagerクラスを作り、他クラスのスクリプトから定義へ移動を試みると、定義が存在しないと言われる。

# 原因
今回は、まさかのUnityのバージョンが悪かったようです。バージョンを変えると難なく動きましたが、戻すとまた定義へ移動できなくなりました。

# 解決
Unityのバージョンを変えると直ります。

変更前：2021.3.24f
変更後：2022.3.15f

# 調査
興味がある方は調査フェーズもご覧ください。

まず、C#のログを見ます。以下の画像に示す手順で確認できます。

![vscode.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2607452/a35d8153-2174-fbd1-d07d-bb9adbbe29b3.png)

今回の問題は、どうもslnファイルが読み込まれていない(？)ことが原因のようでした。
一生「<ins>/Users/{ユーザー名}/UnityWorks/tmp/tmp.sln</ins> を読み込んでいます...」で止まっていることがわかります。
(ちなみに、「tmp」が本記事のために作ったUnityプロジェクトの名前です。)

![slnファイルが読み込まれない 2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2607452/21d78499-fe2b-c1bf-8def-cc5c90e3417e.png)

あくまで予想ですが、slnファイルはVSCode側で使われるものの、生成はUnity側が行なっているのではないかな...？と思っています。そのため、Unityのバージョンによってはslnファイルが破損しており、VSCodeでslnファイルを読み込めず、定義へ移動できないようなバグが起きているのではないかと思います。

# まとめ
いかがだったでしょうか。今回は、VSCodeの使い方に焦点を当てた紹介をしました。
このように、開発ツールの使い方から、GAS, AWS, 量子コンピューティングなど、様々な内容について紹介していきます。ぜひお役に立てましたら、いいね, フォローなどよろしくお願いします！
オープンソースLLM「Llama 3.1 8B」、GPT 3.5 Turboと同等レベルの言語モデルをローカルPC(GPUなし、CPUのみ)で動かせる！

GPT 3.5 Turboと同等レベルの言語モデルを、ローカルPC(GPUなし、CPUのみ)で動かせるようになってきており、驚きました！
インターネット接続は不要で、質問した情報も漏れることはありません。
GPT 3.5 Turboは、通常利用可能なレベルの文章を生成できるものでしたので、これがローカルPC(GPUなし、CPUのみ)で動かせるようになってきたのは、凄いです！

導入方法は、Ollamaをインストールするだけで、OKでした。
「Llama 3.1 8B」または「Llama 3.1 70B」モデルを使用します。

今後、これらの言語モデルを、各自/各社の資料やデータと共に利用して、各自の固有の情報を説明するオリジナルChatGPTが、各自のローカルPCで動くようになりそうな気がしています。(希望)


# ローカルPCでLLMを動かす、Ollamaのインストール方法

ローカルPCでLLMを動かす、Ollamaのインストール方法: (Windows版)  
https://note.com/masayuki_abe/n/na6b4fc388fb5
* .exeをダウンロード、インストール:
  * https://ollama.com/download/windows
* コマンドを実行(DOS command-line): 「ollama run llama3.1:8b」
  * 「ollama run llama3.1:70b」等でもOK(中規模版)
* コンソール上で質問を入力: 例: 「Why sky is blue?」
  * ⇒文章生成OK
* 生成時: CPU 50%～, メモリ使用量 5.6GB～, 生成時間 10s～

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/606924/f1f14054-a6aa-c0de-6cd2-ae9548feebbe.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/606924/49be8d69-6387-4aea-e4a4-42c8511099ed.png)


# 感じた特徴

Llama3.1 8B (ローカルPC、Ollama使用):
* PyTorch不使用
* コードなし(バイナリをインストール)
* コマンドラインから利用可
* 遜色ない高速な文章生成
* 通常利用可能なレベルの文章を生成
* GPUなし、CPUのみでも動作可
* 英語での応答が最も良い
* 日本語でも応対は可能

# 参考記事

記事: 史上最強のオープンソースLLM「Llama 3.1」登場。405B, 70B, 8Bモデル全てを実際に使ってみる方法  
https://notai.jp/llama-3-1-405b-70b-8b/
* 2024年7月23日、Metaがオープンソースの大規模言語モデル「Llama 3.1」シリーズをリリース。
* オープンソースモデルが商用モデルに追いついた歴史的瞬間。
* 「Llama 3.1 405B」は、GPT-4oやClaude 3.5 Sonnetなど、OpenAIやAnthropicなどの他社が商用・非公開で開発している主要な最上位モデルたちと、肩を並べる性能を示す。
* 小型軽量な70Bと8Bモデルについては、超高速なAI専用クラウドコンピューティング「Groq Cloud」で無料で利用できる。

Ollama: (モデルのダウンロード元)  
https://ollama.com/library/llama3.1:8b

Model evaluations: (Llama3.1 8BはGPT 3.5 Turboと同等レベル)  
https://ollama.com/library/llama3.1:8b
![ad042a1c-bbc7-47de-bbbf-78a3cfc13485.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/606924/e036c167-6c0d-3f85-db6b-0ce9618b8106.png)

詳細な評価を紹介した論文:  
https://ai.meta.com/research/publications/the-llama-3-herd-of-models/
良記事紹介しちゃうよ〜！

あくまで備忘録。
あとで読む！！！！！！！

【川邊健太郎×田中邦裕】管理職の言動が組織を腐らせる？「不機嫌な上司」の弊害と回避術
https://type.jp/et/feature/26332/

「本を読んでも身に付かない」はどう解消する？ 七つの“読書術”を岩瀬義昌が伝授
https://type.jp/et/feature/26375/

FF14が“愛され長寿”なのは「たまたまじゃない」【ひろゆきが吉田直樹に聞く】
https://type.jp/et/feature/26308/

エンジニアの本当にあった怖い話「ヒヤリハット」から学ぶミス・トラブルの防ぎ方＆対処法
https://type.jp/et/feature/26387/

フリーランスお断り企業が急増！ その笑えない実態と「切られる前」にすべき対策とは？【久松剛解説】
https://type.jp/et/feature/26395/

平日はSE、休日は麻雀のプロ。一瀬由梨が「どっちも全力」を貫く理由
https://type.jp/et/feature/26445/

“優秀なエンジニア”ってどんな人？ 著名エンジニア・識者が示す五つの素養
https://type.jp/et/feature/26412/

「マネジメントの悩み」解消に役立つ！ エンジニア組織の管理職者に贈る五つのアドバイス
https://type.jp/et/feature/26468/

米国の解雇事情から浮かび上がる「肩たたきされるエンジニア」の特徴
https://type.jp/et/feature/26503/
QMLでGstreamerをMacで動かす


* brew で gst-plugins-good を インストールしても qml6glsink が含まれていないため動かせません。  

### でも、プラグインを自分でビルドすれば動かせます。

Gstreamer の ver 1.24.5 で試しています。

![mac-qml6sink.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/117164/71ab0f7e-4e73-8104-c11c-2e1a73a65bd8.png)

qml6glsinkプラグインのソースコードは[こちら](https://gitlab.freedesktop.org/gstreamer/gstreamer/-/tree/1.24/subprojects/gst-plugins-good/ext/qt6?ref_type=heads)にあります。  
そして公式のサンプルコードは[こちら](https://gitlab.freedesktop.org/gstreamer/gstreamer/-/tree/1.24/subprojects/gst-plugins-good/tests/examples/qt6/qmlsink?ref_type=heads)にあります。  

まとめたものがこちらにあります
https://github.com/hexaforce/mac-on-qml6glsink

### まず、シェーダをコンパイルします。サンプルコードでも使います
```bash
cd qt6/

qsb --glsl=100,120 --batchable --output vertex.vert.qsb vertex.vert
qsb --glsl=100,120 --batchable --output RGBA.frag.qsb RGBA.frag
qsb --glsl=100,120 --batchable --output YUV_TRIPLANAR.frag.qsb YUV_TRIPLANAR.frag

qsb --glsl=100,120 --batchable --output ../qmlsink/vertex.vert.qsb vertex.vert
qsb --glsl=100,120 --batchable --output ../qmlsink/RGBA.frag.qsb RGBA.frag
qsb --glsl=100,120 --batchable --output ../qmlsink/YUV_TRIPLANAR.frag.qsb YUV_TRIPLANAR.frag
```

### 次にプラグインをビルドして確認します
```bash
qmake
make

# ビルドに成功したらgstreamerにコピー
cp libgstqml6.dylib /usr/local/Cellar/gstreamer/1.24.5/lib/

# プラグインのキャッシュをクリア
gst-inspect-1.0 --gst-disable-registry-update --gst-plugin-path=/usr/local/Cellar/gstreamer/1.24.5/lib/

export GST_PLUGIN_PATH=/usr/local/Cellar/gstreamer/1.24.5/lib/

# 確認
gst-inspect-1.0 qml6glsink
# QML debugging is enabled. Only use this in a safe environment.
# Factory Details:
#   Rank                     none (0)
#   Long-name                Qt6 Video Sink
#   Klass                    Sink/Video
#   Description              A video sink that renders to a QQuickItem for Qt6
#   Author                   Matthew Waters <matthew@centricular.com>
```

### そして、サンプルコードで実行してみます。
```bash
cd ../qmlsink 
qmake
make
GST_DEBUG=3 ./build/x86_darwin_generic_mach_o_64bit-Debug/play.app/Contents/MacOS/play
```
### QtCreatorで実行する時はパスを通す必要があります
```
GST_PLUGIN_PATH=/usr/local/Cellar/gstreamer/1.24.6/lib/
```
![GST_PLUGIN_PATH.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/117164/2b499015-bb7b-5083-f571-75ed306ce82f.png)
Turbowarpの『カスタム拡張機能』を使おう【２】

# 本記事について
Turbowarpのカスタム拡張機能をる方法の説明の一部として、拡張機能の定義の例を補足します。


# 拡張機能の定義の例

```
const MyExtensionInfo = {
    id : "MYEXTENSION", // ※1
    name : "独自拡張練習", // ※2
    color1 : '#000000', // ※3
    color2 : '#ffffff', // ※4
    color3 : '#0000ff', // ※5
    blocks : [
        {
            opcode : 'block01', // ※6
            blockType : Scratch.BlockType.COMMAND, // ※7
            text : '[GEAR_IMAGE] ブロック０１', // ※8
            arguments: {
                GEAR_IMAGE : {
                    type: Scratch.ArgumentType.IMAGE,
                    dataURI: GEAR_IMAGE_SVG_URI,
                },
            },
        },
        {
            opcode : 'block02',
            blockType : Scratch.BlockType.COMMAND,
            text : '[GEAR_IMAGE] ブロック０２ [TEXT]',
            arguments: {
                GEAR_IMAGE : {
                    type: Scratch.ArgumentType.IMAGE,
                    dataURI: GEAR_IMAGE_SVG_URI,
                },
                TEXT : { ※ 9
                    type: Scratch.ArgumentType.STRING, ※ 10
                    defaultValue: 'あいうえお', ※ 11
                },
            },
        },
    ],
}
```

## 定義の説明

### ※1 拡張機能のID
他の拡張機能IDと被ってはいけない。

### ※2 拡張機能の表示名称
わかりやすい名称をつけましょう。日本語でも OKです
あまり長すぎる名前は読みにくくなるので適度に短くしましょう

### ※3 ブロック色
文字色は固定で白(#ffffff)であるため、ブロック色を白にすると文字が読めなくなることに留意しましょう。

### ※4 ブロックリストの円周線の色

### ※5 ブロックの周囲の線の色

### ※6 定義するブロックに対応したメソッドの名前
メソッドは ※12にて定義しています
ブロックを実行すると、ここで書かれたメソッドを実行します

### ※7 定義するブロックの種類です。種類には次のものがあります
- Scratch.BlockType.COMMAND : ひとつの処理を実行します。戻り値はありません
- Scratch.BlockType.REPORTER : 値を取り出すブロックです
- Scratch.BlockType.BOOLEAN : 値を取り出すブロックで、真偽値に特化しています
- その他省略

### ※8 ブロック内に表示するテキストです。
[ ] で囲まれた部分は ブロック内に現れる引数を表現しています。
引数は ※9に対応づけて定義する必要があります。

### ※9 引数をMap形式で定義します。Mapのキーは、※8 の [ ] と対応づける必要があります。
ここ(※8/※9)で定義した引数は メソッドの実行時に 第一引数(一般的にargs)として渡されます。

### ※10 引数の種類です。種類には次のものがあります。
- Scratch.ArgumentType.STRING : 文字列です
- Scratch.ArgumentType.NUMBER : 数字です
- Scratch.ArgumentType.BOOLEAN : 真偽値です
- Scratch.ArgumentType.ANGLE : 角度です（角度を選べる時計風のメニューを表示します）
- Scratch.ArgumentType.COLOR : 色です ( 色を指定するメニューを表示します )
- その他省略

### ※11 引数の初期値としてブロックに表示される値です。


# 続き

[次の記事【３】](https://qiita.com/harhid/items/b07e8456c23d4c7a8de3)へ続きます。
Nestjs + Cloud Run + Cloud Trace 

# 1. NestjsのTrace設定方法


```ts
import process from 'process';

import { TraceExporter } from '@google-cloud/opentelemetry-cloud-trace-exporter';
import {
  CompositePropagator,
  W3CTraceContextPropagator,
  W3CBaggagePropagator,
} from '@opentelemetry/core';
import { ExpressInstrumentation } from '@opentelemetry/instrumentation-express';
import { GraphQLInstrumentation } from '@opentelemetry/instrumentation-graphql';
import { HttpInstrumentation } from '@opentelemetry/instrumentation-http';
import { NestInstrumentation } from '@opentelemetry/instrumentation-nestjs-core';
import { PgInstrumentation } from '@opentelemetry/instrumentation-pg';
import { NodeSDK } from '@opentelemetry/sdk-node';
import { BatchSpanProcessor } from '@opentelemetry/sdk-trace-base';
import {
  ParentBasedSampler,
  TraceIdRatioBasedSampler,
} from '@opentelemetry/sdk-trace-node';
import { ConsoleSpanExporter } from '@opentelemetry/sdk-trace-node';

const traceExporter = process.env['NODE_ENV']
  ? new TraceExporter()
  : new ConsoleSpanExporter();
const samplePercentage = 0.1; // sample 10% of traces

export const otelSDK = new NodeSDK({
  traceExporter: traceExporter,
  spanProcessor: new BatchSpanProcessor(traceExporter),
  textMapPropagator: new CompositePropagator({
    propagators: [new W3CTraceContextPropagator(), new W3CBaggagePropagator()],
  }),
  instrumentations: [
    new HttpInstrumentation(),
    new ExpressInstrumentation(),
    new NestInstrumentation(),
    new GraphQLInstrumentation({ depth: 3, mergeItems: true }),
    new PgInstrumentation({ requireParentSpan: true }),
  ],
  sampler: new ParentBasedSampler({
    root: new TraceIdRatioBasedSampler(samplePercentage),
  }),
});

// gracefully shut down the SDK on process exit
process.on('SIGTERM', () => {
  otelSDK
    .shutdown()
    .then(
      () => console.log('SDK shut down successfully'),
      (err) => console.log('Error shutting down SDK', err),
    )
    .finally(() => process.exit(0));
});
```


# 1. Cloud RunでサンプルされたリクエストだけにTraceを付与する

https://cloud.google.com/run/docs/trace

こちらを読むとCloud Runは自動的にTraceをサンプルしています。そのサンプルに合わせて、Traceをアプリケーション側でもつけたい事があると思います。
その場合には、`sampler` に `ParentBasedSampler` というのを使うことができます。

```ts
  sampler: new ParentBasedSampler({
    root: new TraceIdRatioBasedSampler(samplePercentage),
  }),
```

これにより、Parentがsampledにしたがってサンプルすることができます。

This is a composite sampler. ParentBased helps distinguished between the following cases:
- No parent (root span).
- Remote parent with sampled flag true
- Remote parent with sampled flag false
- Local parent with sampled flag true
- Local parent with sampled flag false

`root: new TraceIdRatioBasedSampler(samplePercentage),` これは親がなかった場合の挙動を設定するもので、ここではsamplePercentageを与えたTraceIdRatioBasedSamplerというものを設定しています。


# References

1. https://www.npmjs.com/package/@opentelemetry/sdk-trace-base#parentbasedsampler
1. https://github.com/nakamasato/nest-graphql-training/blob/main/docs/02-tracing-nestjs.md
高速で【次の値を含む】アレイを抽出する【アレイのフィルターを使わない】


## 【問題】処理スピードが遅いアレイのフィルター

※この記事は私の記事の中では少し難しめとなっています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3111714/e7d99568-0c46-0938-2b26-02d3607a607d.png)

例えば下記のように、顧客から
①arrayというドメインリストがある。
②array2のメールアドレスと氏名のリストのメールアドレスにドメインが含まれているかどうかを調べたい
といわれた時、基本はアレイのフィルター処理で合致するデータを探すのが一般的だと思います。


```json:array
[
  {
    "ID": "docomo.com",
    "Type": "domain"
  },
  {
    "ID": "satokaihatsu.com",
    "Type": "domain"
  },
  {
    "ID": "au.com",
    "Type": "domain"
  }
]
```


```json:array2
[
  {
    "ID": "AyaAkita@docomo.com",
    "Name": "秋田彩"
  },
  {
    "ID": "HarukoSuzuki@satokaihatsu.com",
    "Name": "鈴木春子"
  },
  {
    "ID": "TomokiFuyuki@au.com",
    "Name": "冬木智樹"
  },
  {
    "ID": "NatsukoMaToba@au.com",
    "Name": "的場奈津子"
  }
]
```

このぐらいのデータ数ならば処理スピードには問題ないのですが
件数が5000件、10000件となってくると話しは変わってきます。
For eachでLoopさせながらデータを吐き出すので何時間とかかるんです…:joy:


そういった場合はXMLのXpathなどを利用するように言われており、
XMLの【に等しい】時のmargeの仕方は
多分下記のポールさんが一番最初に教えてくださっていたと思います。
※余談ですが彼は今も私のあこがれの存在です。I really into his solution as always!

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

一方で、【次の値を含む】際の
Xpathの書き方も業務では意外と必要だったのですが、
誰も記載している様子がなかったので紹介したいと思います。

上記２つのアレイを結合した結果としては下記のとおりです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3111714/ff8d19a8-a851-c0ba-c233-c88f028c782d.png)



## やり方

先の動画のポールさんのやり方を参考に
Array、Array2を作成し、Prepare Array、XMLという作成アクションを作ります(ここまでは全く同じです)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3111714/74638088-e277-43cd-f703-8e19fe1d8122.png)


```ruby:prepare array
{
  "Root": {
    "Array": @{outputs('Array2')}
  }
}
```
```ruby:XML
@{xml(outputs('Prepare_Array'))}
```


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3111714/9f35eddd-9b23-fc35-e407-61f357702e9c.png)

さて、ここからが皆さんが確認したいところかと思います。

上記画像を参照してください。
Select(選択)のアクションを追加し、
開始にarrayアクションを入れて、マップのKeyにJoinNameとJoinID、そしてValueにXPathコードをそれぞれ埋め込みます

```ruby:Select:IDを含む項目の中のNameを取り出しているjoinName
//Array/ID[contains(text(),"item()?['ID']")]/following-sibling::Name/text()
```

```ruby:Select:IDを含む項目のID(mail)を取り出しているjoinID
//Array/ID[contains(text(),"item()?['ID']")]/text()
```
上記はもう一つのArray2をJoinするためのXpathコードにitem()?['ID']を埋め込んでいます。

そして最後に再度選択アクションを追加し
MailとNameのキーを作成し
それぞれ下記のように記載します。
```ruby:Select2:MailとNameのValue
xpath(outputs('XML'),item()?['joinID'])
xpath(outputs('XML'),item()?['joinName'])
```

大体Xpathのコード内容は、選択を２度使うのではなく、
Concatを使ってitem()?['ID']とXpathのコードをくっつけて一度に書いてしまうことも多いのですが
Xpathコードを流用したり直したりもするので、変更しやすいように選択に直接ベタ書きしています。
そのほうが複雑にならなくて楽なんですよね。

以上が【次の値を含む】アレイを抽出する際に使用するやり方となります。


## 最後に
上記の含むデータを加工して含まないデータも作成できると思います。
Xpathの使用の仕方はDesktopの方が紹介されているものが多いですが
PowerAutomateのクラウドでも利用できるので、
応用して使ってみるとスピードの大幅改善になったりもします！
【AWS】中途半端な権限ポリシーでMFA登録解除・削除を行うとどうなるか

IAMアクションで`iam:DeactivateMFADevice` の権限をもっていて、`iam:DeleteVirtualMFADevice`　の権限を持っていないユーザーが、マネジメントコンソールからMFAの削除を実行したら少し面倒な状態になるので、どういった状態になるか紹介します。

## 参考ドキュメント

[How can I troubleshoot the "entity already exists" error when an IAM user tries to create a new MFA device?](https://repost.aws/knowledge-center/mfa-iam-entity-error)

## 実際にためしてみる

今回qiitaというIAMユーザーに対して、MFAデバイス名もqiitaというMFAを割当ています。

またこのqiitaユーザーにはMFAの登録解除（`iam:DeactivateMFADevice`）の権限はもっているが、MFAデバイスの登録削除（`iam:DeleteVirtualMFADevice`）権限をもたないポリシーを作成しアタッチしました。

この条件のユーザーで自分の認証情報の画面からMFAの削除を実行します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1670622/5e87c1c7-4d8a-f47c-33b1-2eac16b2643b.png)

削除を選択

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1670622/76a72043-d192-de88-f03a-b68654a00a51.png)

エラーが発生しました。

>User: arn:aws:iam::xxxxxxxxxxxx:user/qiita is not authorized to perform: iam:DeleteVirtualMFADevice on resource: arn:aws:iam::xxxxxxxxxxxx:mfa/qiita because no identity-based policy allows the iam:DeleteVirtualMFADevice action. 仮想 MFA デバイスは非アクティブ化されていますが、削除されていません。CLI または API を使用してデバイスを削除するよう管理者に依頼してください。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1670622/7aeb6070-0b1c-ad31-d673-f41cfc3e72f1.png)

画像を確認してもらうとわかりますが、自分の認証情報からMFAの登録は消えており一件しただけだと正常に消えているようにみえます。

ただし、エラーメッセージを読む、CLI または APIで削除するように管理者に依頼となっています。

## この状態で同名のMFAデバイスを登録しようとどうなるか

先ほどはqiitaというデバイス名だったので、同名で作成しています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1670622/03d36e27-052e-fd46-88ae-5c856d69f573.png)

エラーが発生しました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1670622/d18fe2ea-d1b8-cb8b-509b-a23a5f6d49cf.png)

先ほど削除したはずですが、`MFA device already exists.`が発生します。

これはどういう状態化というと、

ユーザーからMFAデバイスの登録は外れていますが、MFAデバイス自体は削除できておらず残っている状態となっています。

前述したエラーメッセージは管理者にデバイスの削除を依頼とメッセージにでていましたが、この状態になるとマネジメントコンソールからMFAデバイスの削除は現状無理なようです。

## 管理者でaws-cliからMFAデバイスを削除する

[How can I troubleshoot the "entity already exists" error when an IAM user tries to create a new MFA device?](https://repost.aws/knowledge-center/mfa-iam-entity-error)

re:PostのナレッジにMFAのdeactiveとdeleteについて記事があるのでこちらを参考にして削除していきます。

まずはqiitaとは違い、MFAの参照と削除も行える管理者権限でログインしてCloudShellからMFAデバイスの登録を確認していきます。

```bash
aws iam list-virtual-mfa-devices
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1670622/f488ece6-e37e-b621-e187-ead7d781796e.png)

今回登録したMFAデバイスqiitaのデバイスがまだ残っている事が確認できます。

マネジメントコンソール上では出てきませんが、このように裏では残っている状態となっています。

こちらを下記のaws-cliコマンドから削除していきます。

```bash
# 先ほど参照してmfaのシリアルナンバーをパラメータとして実行
aws iam delete-virtual-mfa-device --serial-number arn:aws:iam::xxxxxxxxxxxx:mfa/qiita

# 削除できたか再度一覧を取得し確認
aws iam list-virtual-mfa-devices
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1670622/b3e305a6-7475-61c1-6b50-20adae1dcb55.png)

## 総評

MFA周りの権限ポリシーをいじっていたら、このような状態が発生したので忘備録としてメモ

MFAデバイスはユーザーから無効化するdeactiveといった状態と、MFAデバイス自身を削除するdeleteといった状態の2種類がある事を認識していないと、最初すこし混乱する気がします。
CloudBlast.ioの紹介: クラウドホスティングの新時代

![cloudblast-shortbanner.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3824912/e917585a-177c-9828-e801-006c3a90624d.png)

https://cloudblast.io/

CloudBlast.ioは、独自の提供内容とユーザーフレンドリーなアプローチで業界に波風を立てている革新的なクラウドホスティングプロバイダーです。この投稿では、CloudBlast.ioの特長と、なぜそれがあなたのクラウドホスティングニーズに最適なソリューションであるかを掘り下げていきます。
CloudBlast.ioの主な機能

1. 時間単位の請求: CloudBlast.ioの際立った特徴の一つは、時間単位の請求モデルです。これにより、ユーザーは使用したリソースに対してのみ支払うことができ、企業の規模を問わずコスト効率の高いソリューションとなります。 2. 高性能ハードウェア: CloudBlast.ioは、高性能で信頼性の高いAMD EPYCプロセッサを活用しています。これにより、ユーザーはアプリケーションに最適なパフォーマンスを享受できます。 3. 強力なDDoS保護: 2.5 TbpsのDDoS保護により、CloudBlast.ioは大規模攻撃に直面してもアプリケーションのセキュリティと可用性を確保します。 4. 高速接続: すべてのVPSインスタンスには10 Gbpsの接続が付属しており、アプリケーションに対して迅速かつ信頼性の高いネットワークパフォーマンスを提供します。 5. ユーザーフレンドリーなコントロールパネル: コントロールパネルは非常に使いやすいように設計されており、技術に精通していない人でもアクセスしやすくなっています。このユーザーフレンドリーなインターフェースにより、クラウドリソースの管理が容易になります。
CloudBlast.ioを選ぶ理由
コスト効率: 時間単位の請求モデルにより、使用した分だけ支払うため、非常にコスト効率が高いソリューションとなります。これは、予算を慎重に管理する必要があるスタートアップや中小企業に特に有益です。 パフォーマンスと信頼性: 高性能なAMD EPYCプロセッサと強力なDDoS保護により、CloudBlast.ioはパフォーマンスと信頼性を提供します。これにより、高い稼働率と高速なパフォーマンスを必要とする企業には最適です。 使いやすさ: ユーザーフレンドリーなコントロールパネルにより、技術的な背景がなくてもクラウドリソースを簡単に管理できます。この使いやすさは、クラウドインフラストラクチャの管理に伴う学習曲線を削減し、時間を節約します。


CloudBlast.ioは、信頼性が高く、高性能でコスト効率の良いクラウドホスティングソリューションを探している人にとって魅力的な選択肢です。時間単位の請求、高性能ハードウェア、強力なDDoS保護、ユーザーフレンドリーなコントロールパネルを備えたCloudBlast.ioは、幅広いユーザーのニーズに応える包括的なパッケージを提供します。スタートアップ、中小企業、大企業のいずれであっても、CloudBlast.ioはあなたのクラウドホスティングニーズをサポートするための機能とパフォーマンスを備えています。

https://cloudblast.io/
VSCodeでSalesforce認証ができない時の対処法

# 概要

VSCodeからSalesforceサンドボックスに接続できない。もしくは接続できても組織にデプロイもしくは取得できない時の対処法です。
なお、下記はコンテナ環境を前提にしていますが、必要に応じて読み飛ばしてください。


# 事象

以下はVSCodeでの事象になります。

- サンドボックスにログイン時に本番組織のURLになる
- サンドボックスにログイン時に「OAUTH_APPROVAL_ERROR_GENERIC」になる
- 認証完了後にも関わらずデフォルト組織が空のまま
- 認証完了後＋デフォルト組織も設定されたが、サンドボックスにデプロイもしくは取得時に「組織に認証していません」になる

# 対処法

- 組織のURLを指定してログイン
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/30522/7e2bdc5c-5a3c-49b9-579e-29bce444f042.png)
    もしくは`sfdx-project.json`の`sfdcLoginUrl`を設定する
    参照：https://developer.salesforce.com/docs/atlas.ja-jp.sfdx_dev.meta/sfdx_dev/sfdx_dev_ws_config.htm
- 「接続」をすべて「取り消し」する
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/30522/cc352470-92bc-6b24-fd9c-1d1f3ba5a740.png)
- `.sfdx`、`.sf`フォルダを削除する
- cliのバージョンを最新版にする（コンテナ版の場合はコンテナイメージを差し替えてください）
- VSCodeのキャッシュを削除
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/30522/01acb548-2c78-0099-e8ac-aab708204921.png)


## コンテナ

- 開発環境のコンテナとボリュームの削除し、コンテナを再作成する（永続化されていないデータは削除されるので、ご注意ください）
- [salesforce/cli](https://hub.docker.com/r/salesforce/cli/tags)の最新版を使用する
robloxでassistant その152

# 概要
robloxでassistantやってみた。
練習問題、やってみた。

# 練習問題
InsertServiceを使え。

# サンプルコード

```

local InsertService = game:GetService("InsertService")
local page = unpack(InsertService:GetFreeDecals("doragon", 0))
for i = 1, page.TotalCount do
	local item = page.Results[i]
	print(item.Name .. ": " .. item.AssetId)
end

```

# 実行結果

```

  11:55:58.855  Hello world!  -  サーバー
  11:56:00.184  Shen Doragon (Awakened): 11839086674  -  クライアント - LocalScript:5
  11:56:00.185  Tentai no arekuruu doragon: 89277189  -  クライアント - LocalScript:5
  11:56:00.185  Doragon: 1330773850  -  クライアント - LocalScript:5
  11:56:00.185  doragon: 15290684587  -  クライアント - LocalScript:5
  11:56:00.185  Shen Doragon: 10017370248  -  クライアント - LocalScript:5
  11:56:00.186  Fusion Of Kenji and Doragon. KenGon.: 127367998  -  クライアント - LocalScript:5
  11:56:00.186  North Petoria: 12521295302  -  クライアント - LocalScript:5
  11:56:00.512  Hello world!  -  クライアント



```

以上。
【UiPath】意外と知らない？パッケージ更新の仕様

# はじめに

- 本記事は、筆者がたまたま調べたパッケージ更新の挙動（仕様）を備忘までに記したものです。
- 記事の内容は、個人の見解または確認結果であり、UiPath の公式見解ではありません。
- 製品仕様や参考画像は 24.10 バージョンのもので構成しています。

# 共通部品（ライブラリパッケージ）を扱う人は要チェック

|No.|オペレーション|結果（pkg更新時の挙動）|
|:-:|:-:|:-:|
|1|引数の追加|影響なし|
|2|ツールチップの追加|影響なし|
|3|引数のデータ型の変更|対象引数に警告マークが点灯|
|4|***引数の名称変更***|***既存の対象アクティビティが壊れる***|
|5|***アクティビティの名称変更***|***既存の対象アクティビティが壊れる***|

## 2の補足

ツールチップは対象の引数＞右クリック＞デザインプロパティから設定できます。

![pkg更新時の挙動確認2.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3301444/e43afd0a-e34c-bfdd-f3da-061a53c0dc35.jpeg)
![pkg更新時の挙動確認3.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3301444/2f04ffdb-ea50-6019-8e3e-c7aa287ad594.jpeg)

↓↓ツールチップが設定されている場合、引数の名称をマウスホバーした際にヒントが表示されます。

![pkg更新時の挙動確認.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3301444/a2c8ff3f-a5b0-4cd4-ad1f-8ce49be92b3b.jpeg)

## 3の補足

数値型だった引数を文字型に変更しパッケージを更新した直後の例↓↓

![pkg更新時の挙動確認5.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3301444/5b8ab6cb-e735-5640-0970-e26b37ca8ad4.jpeg)

## 4の補足

引数の名称を変更後にパッケージを更新すると「このアクティビティは存在しないか、読み込めませんでした。」と表示され、アクティビティの再配置・再設定が必要になってしまいます。

![pkg更新時の挙動確認4.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3301444/dbed30e2-9cdc-2cfe-fa5c-eca94707a59d.jpeg)

```
## 次の様にXamlを手修正すれば読み込めるようにはなります。
## 前提：引数「返却したい文字列」を「返却したい文字列_変更確認用」に名称変更した例です。

    <表:パルプンテ sap:VirtualizedContainerService.HintSize="354,229.33333333333334" sap2010:WorkflowViewState.IdRef="パルプンテ_1" ログしたい内容="デフォルトの値のままです。" 返却したい数値="[テスト数値]" 返却したい文字列="[テスト文字列]" />

↓↓↓

    <表:パルプンテ sap:VirtualizedContainerService.HintSize="354,229.33333333333334" sap2010:WorkflowViewState.IdRef="パルプンテ_1" ログしたい内容="デフォルトの値のままです。" 返却したい数値="[テスト数値]" 返却したい文字列_変更確認用="[テスト文字列]" />
```

## 5の補足

アクティビティの名称を変更後にパッケージを更新すると「このアクティビティは存在しないか、読み込めませんでした。」と表示され、アクティビティの再配置・再設定が必要になってしまいます。

![pkg更新時の挙動確認6.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3301444/2bea9438-ccba-b171-5490-9e2ffd803f04.jpeg)

```
## 次の様にXamlを手修正すれば読み込めるようにはなります。
## 前提：アクティビティの名称を「パルプンテ」を「パルプンテ_変更確認用」に名称変更した例です。

    <表:パルプンテ sap:VirtualizedContainerService.HintSize="354,229.33333333333334" sap2010:WorkflowViewState.IdRef="パルプンテ_1" ログしたい内容="デフォルトの値のままです。" 返却したい数値="[テスト数値]" 返却したい文字列_変更確認用="[テスト文字列]" />

↓↓↓

    <表:パルプンテ_変更確認用 追加引数="{x:Null}" 追加引数_出力="{x:Null}" sap:VirtualizedContainerService.HintSize="354,334.6666666666667" sap2010:WorkflowViewState.IdRef="パルプンテ_1" ログしたい内容="デフォルトの値のままです。" 返却したい数値="[テスト数値]" 返却したい文字列_変更確認用="[テスト文字列]" />
```

# さいごに

いかがでしたでしょうか。
アクティビティやプロパティの名称は、Xaml内ではキー項目の役割を果たしているため、部品側で変更した際はあわせて編集してあげないと読み込めない様です。
パッケージ更新後に アクティビティが壊れた ＞ 再設定大変だよ、どうしよう！ とおもった方も、この仕様を把握していれば慌てずに済みますよね。
最後までお読みいただきありがとうございます(・ω・)ノ
/etc/fstab を書き換えたあとはreboot前に必ずfindmntコマンドで検証しよう

サーバに対して、swap領域を追加したり、拡張ディスクを追加したりするシーンはよくありますよね。

そんなとき、`/etc/fstab` の書き換えをして、気軽にサーバ再起動をすると、、、、

サーバが起動しなくなった！！

ってなっちゃいますよね。

なので、再起動前に以下のコマンドの実行で、`/etc/fstab` を検証し、エラーがないことを確認しましょう。

```shell
findmnt --verify --verbose
```

コマンドを実行するとこのような出力（環境によって異なる）があります。
```
/
   [ ] target exists
   [ ] FS options: discard,commit=30,errors=remount-ro
   [ ] LABEL=cloudimg-rootfs translated to /dev/nvme1n1p1
   [ ] source /dev/nvme1n1p1 exists
   [ ] FS type is ext4
/boot
   [ ] target exists
   [ ] LABEL=BOOT translated to /dev/nvme1n1p16
   [ ] source /dev/nvme1n1p16 exists
   [ ] FS type is ext4
/boot/efi
   [ ] target exists
   [ ] FS options: umask=0077
   [ ] LABEL=UEFI translated to /dev/nvme1n1p15
   [ ] source /dev/nvme1n1p15 exists
   [ ] FS type is vfat
none
   [W] non-bind mount source /swap is a directory or regular file
   [ ] FS type is swap
/data
   [ ] target exists
   [ ] userspace options: nofail
   [ ] UUID=xxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxxx translated to /dev/nvme0n1
   [ ] source /dev/nvme0n1 exists
   [ ] FS type is xfs

0 parse errors, 0 errors, 1 warning
```
GROWI 7.0.15リリースノート

[オープンソースのWikiであるGROWI](https://growi.org/ja/)の最新版、7.0.15がリリースされました。大きな変更点はありませんが、リリースノートとして主な変更点を紹介します。

## 主な変更点

### MongoDB 4.4への対応

後方互換性を保ちつつ、MongoDB 4.4への対応が行われました。

## アップデート推奨

7.0.13と7.0.14では不具合が確認されています。7.0.15へのアップデートを推奨します。

また、不具合修正と各種メンテナンスも行われています。詳細は[Release v7.0.15 · weseek/growi](https://github.com/weseek/growi/releases/tag/v7.0.15)を参照してください。

## まとめ

GROWIはオープンソース、かつDocker composeなどで手軽に導入できます。ぜひ社内・研究室・自宅などで利用してみてください。
Seleniumテスト実行時にChrome v.127の 「Choose your search engine」ダイアログを消すには？

After upgrading chrome driver version to v127 you might see after test run, popup windows ask to choose search engine.

![AJCpCJr8.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3839981/f29dd6db-244f-eb2c-014d-1aba1d83d5e5.png)


この問題は、-disable-search-engine-choice-screenという引数を設定するだけで、検索エンジンを選択するポップアップを無効にすることができます。

この引数の設定方法については、この1分間のビデオをご覧ください。

https://youtu.be/PJ6MApFBG5k