OmniAICreator/Qiita-1.07M huggingface dataset:
MUIのアスタリスクの色だけを変えたりする(MUI v5)

MUIで`TextField`にrequiredを付与したときにアスタリスクが表示されます。このアスタリスクを強調するために色を変えたいと思います。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/256853/e9c2206d-e35b-104c-b4cb-0d32d70c2467.png)

僕はMUIのテーマ設定コンポーネントを作ってProviderとして使っていますのでこんな感じに追記してあげます。
`createTheme()`を使えば既存のMUIコンポーネントをオーバーライドできます。
```tsx:ChangeTheme.ts
import React, { FC, ReactNode } from 'react'
import { GridProps } from '@mui/material'
import { createTheme, ThemeProvider } from '@mui/material/styles'

interface Props {
    children?: ReactNode
}

const ChangeTheme: FC<Props & GridProps> = ({ children }) => {
    const theme = createTheme({
        components: {
            // 追記
            MuiFormLabel: {
                styleOverrides: {
                    asterisk: { color: '#FF6A61' },
                },
            },
        },
    })

    return <ThemeProvider theme={theme}>{children}</ThemeProvider>
}

export default ChangeTheme


```

## 結果
こんな感じでまとめて適用できました〜〜〜
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/256853/e2e9b3f1-b651-7453-d1ef-e1d6884da9ef.png)


参考

https://stackoverflow.com/questions/54936644/how-to-change-the-asterisk-color-in-required-field
Visual Studio アセンブラでwsprintfを使ってみた

# 環境
Windows 11 Pro (64bit)
Visual Studio Community 2022

# x86

## バッチファイル

```dev32.bat
@echo off
path %path%;D:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.34.31933\bin\Hostx64\x86
set lib=%lib%;C:\Program Files (x86)\Windows Kits\10\Lib\10.0.19041.0\um\x86
cmd
```

## アセンブリ ソース

```wsprintf.asm
comment *
ml /c /Fl /Sa wsprintf.asm
link /subsystem:console wsprintf
*
includelib kernel32
includelib user32

.model flat

NULL equ 0
STD_OUTPUT_HANDLE equ -11

ExitProcess proto stdcall :dword
GetStdHandle proto stdcall :dword
WriteConsoleA proto stdcall :dword,:dword,:dword,:dword,:dword
wsprintfA proto c :dword,:dword,:vararg

.const
fmt	db	'[%x]',0dh,0ah,0

.data?
hConOut	dd	?
buf	db	1024 dup (?)
len	dd	?

.code
start proc c
	invoke	GetStdHandle, STD_OUTPUT_HANDLE
	mov	hConOut, eax
	invoke	wsprintfA, addr buf, addr fmt, 0cafebabeh
	mov	len, eax
	invoke	WriteConsoleA, hConOut, addr buf, len, NULL, NULL
	invoke	ExitProcess, 0
start endp
end start
```

## 実行例

```
D:\Projects\msvc>ml /c /Fl /Sa wsprintf.asm
Microsoft (R) Macro Assembler Version 14.34.31935.0
Copyright (C) Microsoft Corporation.  All rights reserved.

 Assembling: wsprintf.asm

D:\Projects\msvc>link /subsystem:console wsprintf
Microsoft (R) Incremental Linker Version 14.34.31935.0
Copyright (C) Microsoft Corporation.  All rights reserved.


D:\Projects\msvc>wsprintf
[cafebabe]

D:\Projects\msvc>
```

# x64

## バッチファイル

```dev64.bat
@echo off
path %path%;C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.37.32822\bin\Hostx64\x64
set lib=%lib%;C:\Program Files (x86)\Windows Kits\10\Lib\10.0.22000.0\um\x64
prompt $e[33m$p$g$e[m
cmd
```

## アセンブリ ソース

```printf64.asm
comment *
ml64 /c /Fl printf64.asm
link /subsystem:console /entry:start printf64
*
includelib kernel32
includelib user32

NULL equ 0
STD_OUTPUT_HANDLE equ -11

extern ExitProcess :proc
extern GetStdHandle :proc
extern WriteConsoleA :proc
extern wsprintfA :proc

.const
fmt	db	'hoge %#x %d',0dh,0ah,0

.data?
hOut	dq	?
buf	db	1024 dup(?)

.code
start proc
	sub	rsp, 28h
	mov	ecx, STD_OUTPUT_HANDLE
	call	GetStdHandle
	mov	hOut, rax

	mov	r9d, 59634
	mov	r8d, 0f3c8h
	mov	rdx, offset fmt
	mov	rcx, offset buf
	call	wsprintfA

	mov	qword ptr [rsp+20h], NULL
	mov	r9d, NULL
	mov	r8d, eax
	mov	rdx, offset buf
	mov	rcx, hOut
	call	WriteConsoleA

	mov	ecx, 0
	call	ExitProcess
start endp
end
```

## 実行例

```
Microsoft Windows [Version 10.0.22621.2134]
(c) Microsoft Corporation. All rights reserved.

C:\Projects\msvc>ml64 /c /Fl printf64.asm
Microsoft (R) Macro Assembler (x64) Version 14.37.32822.0
Copyright (C) Microsoft Corporation.  All rights reserved.

 Assembling: printf64.asm

C:\Projects\msvc>link /subsystem:console /entry:start printf64
Microsoft (R) Incremental Linker Version 14.37.32822.0
Copyright (C) Microsoft Corporation.  All rights reserved.


C:\Projects\msvc>printf64
hoge 0xf3c8 59634
```
Rでテキストマイニングしよか（初心者向け）

# はじめに
watnowアドベントカレンダー5日目担当のしんいちです。今回はテキストマイニングについて書こうと思います。

# テキストマイニングとは
テキストマイニングとは複数のテキストを分析してその中から有益な情報を取り出すことです。
結構色々なところで使われていてお客さまアンケートとかの分析、チャットボットなどに使われています。

# インストール
何事もインストールから始まります。
RとMeCabをインストールします。
私が使っているPCがMacのためMacでのインストールしかわかりません。
## Rのインストール
まずR本体をインストールします
[ここからインストールしてください](https://cran.r-project.org/bin/macosx/)
M1とインテルでインストールするファイルが違うので注意してください。
## MeCabのインストール
次にMeCabをインストールします。
Homebrewを用いたインストールです。
[Homebrewのインストール方法](https://aiacademy.jp/media/?p=2817)
ターミナルで以下を実行してください。
```
brew install mecab
brew install mecab-ipadic
```
これでMeCabと辞書がインストールされました。
インストールできているか確認する場合はターミナルで以下を実行してください。
```
これでバージョンなどが表示してあれば完了です。
mecab -v
```
# ワードクラウド
早速やってみましょう！
ワードクラウドとは形態素解析をわかりやすく表示するもので文書のなかで多く出てくる単語が大きく表示されます。
こんな感じです。
![スクリーンショット 2022-12-02 13.13.06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1391275/289a5d53-f997-c695-1b31-cdca599fa5a5.png)
これは今（2022年12月5日）話題のワールドカップの記事のワードクラウドです。
雰囲気がわかったところで早速やってみましょう！
まずRを起動します。
次にテキストファイルを用意します。テキストファイルは自分で作るのもよし、ネットから取ってくるもよしです。
以下のコードをRで実行してください
```
install.packages ("RMeCab", repos = "https://rmecab.jp/R", type = "source") #RMeCabのインストール
library(RMeCab) #RMeCabを立ち上げる
result1 <- RMeCabText(file.choose()) #ワードクラウドにしたいテキストファイルを選ぶ
result11 <- unlist(sapply(result1, "[[", 1)) #単語ベクトルの作成
```
これでワードクラウドにする下処理は終わりました
```
install.packages("wordcloud", dependencies = TRUE) #Wordcloudのインストール
library(wordcloud) #wordcloudを立ち上げる
wordcloud(result11, min.freq = 2, family = "HiraKakuProN-W3", random.order = FALSE) #先ほど作った単語ベクトルをワードクラウドにする
```
これでワードクラウドができました！

# まとめ
今回はテキストマイニングの入門書的な感じで書きましたがわかりにくい部分が多いかもしれませんごめんなさい。
ワードクラウドを色々なテキストで作るととても面白いのでぜひやってみてください。
以上読みにくい文章にお付き合いいただきありがとうございました。
（AWS）IAMポリシーの実行を特定のEC2インスタンスに制限する

この記事は [セゾン情報システムズ Advent Calendar 2022](https://qiita.com/advent-calendar/2022/sisco) 6日目の記事です。

## はじめに
複数のEC2に同じIAMロールをアタッチしていて、そのなかの特定のEC2にだけ新たなIAMポリシーを適用したいときの方法です。（同じIAMロールを複数のEC2にアタッチしているという状況は変えません。）

IAMポリシーのCondition要素でEC2を指定することで、ポリシーを実行できるEC2を絞ることができます。

以下、S3バケットへのフルアクセスを許可するポリシー（を追加したIAMロール）を２台のEC2にアタッチした上で、片方のEC2のみがS3にアクセスできるようにしていきたいと思います。

## IAMポリシーの作成
いきなりここが肝になりますが、以下のようにIAMポリシーを作成します。
```json
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": "s3:*",
            "Resource": "*",
            "Condition": {
                "StringEquals": {
                    "ec2:SourceInstanceARN": "arn:aws:ec2:（リージョンID):（アカウントID）:instance/（インスタンスID)"
                }
            }
        }
    ]
}
```
Condition要素で、StringEqualsの"ec2:SourceInstanceARN" 条件キーを設定することにより、指定したarnのEC2のみが許可されたアクションを実行できるようになります。

**"ec2:SourceInstanceARN": "arn:aws:ec2:（リージョンID):（アカウントID）:instance/（インスタンスID)"**
上記右側の「arn」から始まる部分がEC2のarn（Amazon Resource Name）になりますが、調べた限りではAWSのコンソール画面やCLIからこれを直接確認する方法はありませんでした。

ARNの構文が[AWS公式](https://docs.aws.amazon.com/ja_jp/general/latest/gr/aws-arns-and-namespaces.html)にありましたので、そちらを参考に上記のように（リージョンID)、（アカウントID）、（インスタンスID)をそれぞれ代入して自分で用意する必要があります。
（※サンプル：arn:aws:ec2:ap-northeast-1:123456789123:instance/i-012345a6789b01234）

このようにConditionを設定すると、仮にアタッチされたとしても、指定したEC2以外はこのポリシーによる許可（又は制限）を受けることはありません。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2920194/75c370a5-e58c-f00c-2527-5dadca1c17e3.png)

ポリシーの確認画面で、画像のように「このポリシーから付与されるアクセス権限はありません。・・・」とエラー表示のようなものが出ますが、こちらは問題ありません。

## IAMロールにアタッチ
こちらは特別な操作はありませんので、ポリシーが必要なロールにアタッチしてください。
![ポリシーのアタッチ.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2920194/15b4817f-d649-1b19-e482-2fd66b8846b8.png)

## いざ確認
上記で作成したIAMポリシーがアタッチされた１つのIAMロールを、以下の２台にアタッチして、想定通りの動きをするか確認します。

〇検証用EC2インスタンス
①test1(allow) ※IAMポリシーで指定したEC2
②test2(deny)
⇒①test1(allow)ではS3にアクセスできて、②test2(deny)ではS3にアクセスできなければ検証は成功です！

### test1(allow) ※IAMポリシーで指定したEC2
![test1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2920194/ea60f977-8811-efef-3393-83089a30ce4b.png)

「aws s3 ls」コマンドでs3バケットの一覧を確認できたので、動作としては想定通りです。（OK！）

### test2(deny)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2920194/75b23c0e-ad51-f221-705a-c4048928505c.png)
同じく「aws s3 ls」コマンドでs3バケットの一覧を確認しようとしましたが、Access Deniedで拒否されました。
こちらも想定通りの動作ですね。（OK!!)



以上、お役に立てば幸いです。
ご覧いただきありがとうございました。
複数のvideoタグを各々制御したい

# 01. はじめに

こんにちは、エンジニアのdoriです。開発で「videoタグを制御したい...しかも複数」となったので色々調べました。しかし、どこも１つのvideoタグを制御する方法ばかり。そこでちょこっと工夫すれば複数のvideoタグを制御できたので、今回はその方法を共有したいと思います。

# 01-2. 前提
・今回は**Vue.js**を用いた方法で実践しております
・Vue.jsやjavascriptをある程度理解している人向けです。

# 02. 基本の処理の流れ
大きな処理の流れを知っておかないとわかりにくいと思うので、まずは大きな処理の流れを書いておきます。
１.動画をクリックした際に、その動画のDOMをクリックイベントの引数に渡す
２.1で渡ってきたDOMからvideoタグのidを取得
３.2で取得したidをもとに、その動画（videoタグ）にあるクラスを取得
４.3で取得したクラスで、特定のクラスがあれば、動画を再生、停止する

このような流れで実装していきます。（ここでわかりにくかったら次へと話を進めていただければ🙏）

# 03-1. 手順1：動画をクリックした際にその動画のDOMをクリックイベントの引数に渡す
先にコードの方だけ載せておきます
```
//.vueファイル。好きなところに以下コードをコーディングしてもらえれば
<video src=[動画URL], 
       width=[各自設定],
       height=[各自設定],
       id="video1",
       @click="operateMovie($event)"//クリックした際に呼ばれるメソッド
</video>
```

●ポイント
・「@click=」の部分は実際は「v-on:click=」です。v-onディレクティブを短縮した形ですね。
・「operateMovie」はのちに実装する関数名です。次が肝なのですが、その関数の引数である「**$event**」がメソッドにDOMイベントを渡す変数になっております。詳しくは以下公式サイトにのっています。
**このようにすることで、クリックした要素のIDを取得できるようになり、それをもとに複数動画の制御が可能になります**。
https://jp.vuejs.org/v2/guide/events.html

つまり現状のコードは「**videoタグをクリックしたら関数operateMovieの引数にDOMイベントを渡す**」というような形になっています。

# 03-2. 手順2：手順1で渡ってきたDOMからvideoタグのidを取得
```
methods: {
    operateMovie: function (element) {
      const videoId = element["target"]["id"];
      const videoElement = document.getElementById(videoId);
```
上記は.vueファイルに記載したものです。
●ポイント
・element["target"]["id"]でvideoタグのidを取得しています。（どうしてこのような書き方になっているかを知りたければ、コンソールでelementの中身を出力させてみるとよい）

# 03-3. 手順3：手順2で取得したidをもとに、その動画（videoタグ）にあるクラスを取得
```
methods: {
    operateMovie: function (element) {
      const videoId = element["target"]["id"];
      const videoElement = document.getElementById(videoId);
      const elementClass= videoElement.classList;//追加したコード
```
●ポイント
「.classList」とすることで、その要素のクラスを全て取得できます。

# 03-4. 手順4：手順3で取得したクラスで、特定のクラスがあれば、動画を再生、停止する
```
methods: {
    operateMovie: function (element) {
      const videoId = element["target"]["id"];
      const videoElement = document.getElementById(videoId);
      const elementClass= videoElement.classList;

      //以下追加コード
      if (elementClass.contains("play") == true) {
        videoElement.pause();
        elementClass.add("pause");
        elementClass.remove("play");
      } else if (elementClass.contains("pause") == true) {
        videoElement.play();
        elementClass.add("play");
        elementClass.remove("pause");
      } else {
        videoElement.play();
        elementClass.add("play");
      }
}
```
ポイント
・特定のクラス「play」「pause」があるかないかによって、動画の「再生」「停止」を使い分ける。（containsメソッドについては今回は触れません🙏）（クラス名は別にお好きなもので問題なし）
今回では「クラスにplayがあれば動画を停止」「クラスにpauseがあれば動画を再生」「何もなければクラスにplayを付与」となっています。

つまり大まかな流れとしては、
動画を最初にクリック
↓
最初はクラス名に「play」「pause」がないので、ビデオが最初にクリックされたとわかる。つまり**そのクリックは再生**と解釈。→クラスに「play」を付与。動画を再生。
↓
動画をクリック
↓
クラス名に「play」がある。つまり動画が再生中であるとわかる。**再生中にクリックされたのだからそのクリックは停止と解釈**される。→クラスに「pause」を付与し、「play」のクラス名は削除。動画を停止。

となっています。


これで完成。あとは複数のvideoタグを配置して試してみてください。それぞれの動画がしっかりと制御されているのがわかります。

# 05. さいごに
ここまで見てくださりありがとうございました。今回のポイントは**特定のclassの有無によって異なる制御をする**です。
色々なところで使えそうな技ですね。それではまた。
フォルダのタイムスタンプをフォルダ内のファイルと合わせる

Windows環境でフォルダをコピーして移動したりすると
フォルダの更新日がコピー操作をした日時になってファイルの管理が面倒なので
フォルダ内のファイルに合わせるスクリプトを作ってみた

実行ファイル形式のものはともかく　スクリプトがすぐに見つけられなかったため自分用メモ

```py
import time
import os

# フォルダのパス raw文字指定なので　エクスプローラーからコピペ可
folder_path = r"D:\TempItems"

def set_folder_timestamp(folder_path):
    latest_timestamp = 0
    for file in os.listdir(folder_path):
        file_path = os.path.join(folder_path, file)
        if os.path.isfile(file_path):
            # 更新日の取得
            timestamp = os.path.getmtime(file_path)
            if timestamp > latest_timestamp:
                latest_timestamp = timestamp
        elif os.path.isdir(file_path):
            set_folder_timestamp(file_path)
    # フォルダのタイムスタンプを設定する
    if latest_timestamp != 0:
        os.utime(folder_path, (latest_timestamp, latest_timestamp))

set_folder_timestamp(folder_path)
```

指定したフォルダの下を再帰的に辿るようにはしている
再帰呼び出しで下の階層の更新日を戻り値にしておいて比較してもいいかも

因みに最近話題のChatGPTに最初書かせてみたのだけれど関数の再帰呼び出しはしてくれなかったので
結局自分で書いた方が速かった
なぜ JavaScript の Fetch API は2回 await しないとJSONが取れないのか？

## 疑問

なぜ JavaScript の [Fetch API](https://developer.mozilla.org/ja/docs/Web/API/fetch) はわざわざ `fetch(...)` で直接JSONなどのレスポンスのPromiseを返さずに、 わざわざ2回awaitさせてJSONを返すのでしょうか？

非同期構文の助けがあるとはいえ、いちいちPromiseにされると面倒です。

```js
// なぜ await を2回も呼ぶ必要があるのか？
const json = await (await fetch("/api/v1/foobar")).json();
```

**結論からいうと、サーバがレスポンスのヘッダ部を返した段階で即時に処理（継続）を再開できるようにするためです。**

たとえば、下記のコードにおいて、サーバ側でレスポンス用のHTTPのヘッダをフラッシュした段階で `console.log("サーバが少なくともヘッダを返した");` が実行されるということですね。

```js
const res = await fetch("/api/v1/foobar");
console.log("サーバが少なくともヘッダを返した");

const json = await res.json();
console.log("サーバがボディ（JSON）も全部返した");
```

## Node.js で実験してみる

本当にそうなっているのでしょうか？ 実験してみましょう。 (`Node.js v18.4.0`)

```js:server.js
// $ node server.js
// # => http://localhost:18080

const http = require("http");

const sleep = (ms) => new Promise((done) => setTimeout(done, ms));

http
  .createServer(async (req, res) => {
    // リクエストを受け取って2秒スリープ
    await sleep(2000);

    // ヘッダを書き出して2秒スリープ
    res.setHeader("X-MyHeader-Value", "MY HEADER!!!!");
    res.setHeader("Access-Control-Allow-Origin", "*");
    res.setHeader("Access-Control-Expose-Headers", "*");
    res.flushHeaders();
    await sleep(2000);

    // ボディを書き出す
    res.write(
      JSON.stringify({
        message: "Hello delayed message!",
      })
    );
    res.end();
  })
  .listen(18080);
```

```js:client.js
const task = async () => {
  const req = fetch("http://localhost:18080");
  console.log(Date(), "Request");
  const res = await req;
  console.log(Date(), "Headers", JSON.stringify([...res.headers.entries()]));
  const json = await res.json();
  console.log(Date(), "Body", json);
};

task();
```

```bash
$ node client.js
Mon Dec 05 2022 16:58:54 GMT+0900 (日本標準時) Request
Mon Dec 05 2022 16:58:56 GMT+0900 (日本標準時) Headers [["access-control-allow-origin","*"],["access-control-expose-headers","*"],["connection","keep-alive"],["date","Mon, 05 Dec 2022 07:58:56 GMT"],["keep-alive","timeout=5"],["transfer-encoding","chunked"],["x-myheader-value","MY HEADER!!!!"]]
Mon Dec 05 2022 16:58:58 GMT+0900 (日本標準時) Body { message: 'Hello delayed message!' }
```

Node.js で fetch を動かしたところ、たしかに下記のようになっているので、

- `16:58:54`: リクエストを発した時刻
- `16:58:56`: ヘッダを受け取った時刻
- `16:58:58`: JSONを受け取った時刻

きちんとヘッダをフラッシュした段階で最初のPromiseが解決され、2秒後のボディの書き込みで続くJSON化の処理が動いていることがわかりました。


## ブラウザで実験してみる

ブラウザ (`Google Chrome 108`) でも同様の動きになるか試してみます。すでにサーバーのコードでCORSが有効になっているので同様のクライアントコードを動かしてみます。

```
Mon Dec 05 2022 16:58:07 GMT+0900 (日本標準時) Request
Mon Dec 05 2022 16:58:09 GMT+0900 (日本標準時) Headers [["access-control-allow-origin","*"],["access-control-expose-headers","*"],["connection","keep-alive"],["date","Mon, 05 Dec 2022 07:58:09 GMT"],["keep-alive","timeout=5"],["transfer-encoding","chunked"],["x-myheader-value","MY HEADER!!!!"]]
Mon Dec 05 2022 16:58:11 GMT+0900 (日本標準時) Body {message: 'Hello delayed message!'}
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1577592/b1723fb0-6da2-4d20-4cdd-4e458b053be4.png)

きちんと2秒差でJSONの内容が表示されました。


## まとめ

Fetch APIの `await` はヘッダがフラッシュされた段階で一旦抜ける柔軟な仕様ということがわかりました。
SvelteKitでVitestを使う

この記事は[SvelteKit Advent Calendar 2022](https://qiita.com/advent-calendar/2022/sveltekit)の6日目の記事です。
@kubotakです。

この記事ではSvelteKitでVitestを用いたテストについて紹介します。

# ライブラリの導入と設定

まずは以下のライブラリを導入します。

```
npm install -D vitest jsdom @testing-library/svelte
```

続いてvite.config.tsを次のように変更します。

```ts:vite.config.ts
/// <reference types="vitest" />
import { sveltekit } from '@sveltejs/kit/vite'
import type { UserConfig } from 'vite'

const config: UserConfig = {
  plugins: [sveltekit()],
  test: {
    globals: true,
    environment: 'jsdom',
	include: ['**/*.vitest.ts'],
  },
}

export default config
```

:::note info
`/// <reference types="vitest" />`
はトリプルスラッシュ・ディレクティブと呼ばれるTypeScriptの構文です。UserConfigの型にはtestがないのでvitestの型を依存性として宣言する必要があるため記述しています。
:::

`include`の指定によりテストファイルの命名規則は`.vitest.ts`と独自に作成しています。
指定がない場合は`['**/*.{test,spec}.{js,mjs,cjs,ts,mts,cts,jsx,tsx}']`がデフォルトとなります。
基本的にはデフォルトのままで問題ないですが、[前回紹介したPlaywrightによるコンポーネントテスト](https://qiita.com/kubotak/items/b74289713a32d8ba3ac3)で`.spec.ts`というテストファイル名をすでに使っているため回避として名前を変更しています。

package.jsonのscriptsにVitestの実行コマンドも用意しておきましょう。

```json:package.json
{
  "scripts": {
    "vitest": "vitest",
  },
}
```

# テスト対象のコード
テスト対象のコードは以下の2つです。
SSR時やCSR時のサーバー処理として行われる`+page.server.ts`とそのコンポーネントに当たる`+page.svelte`です。
SvelteKitでは`+page.server.ts`のload関数で実行された結果をページコンポーネントのPropsのdataとして渡されます。

```html:src/routes/+page.svelte
<script lang="ts">
  import type { OutPutData } from "./+page.server"
  export let data: OutPutData
</script>

<h1>{ data.text }</h1>
```

```ts:src/routes/+page.server.ts
export type OutPutData = {
  text: string
}

export const load = async (): Promise<OutPutData> => {
  return {
    text: 'Hello World!'
  }
}
```

# ページコンポーネントのテスト

それではページコンポーネントのテストから書いていきましょう。
先ほど説明したようにSvelteKitではサーバーで実行された結果がコンポーネントのPropsとなるため、Vitestでは通常のSvelteのコンポーネントテストと同様の扱いでテストが可能です。
※ページコンポーネント内部でXHR等の処理を行っていない場合


```ts:src/routes/page.vitest.ts
import { describe, expect, it } from 'vitest'
import { render } from '@testing-library/svelte'
import TopPage from './+page.svelte'

describe('トップページの表示テスト', () => {
  it('Props通りにトップページが表示されること', () => {
    const { getAllByText } = render(TopPage, { props: { data: { text: 'これはテストです' }} })
    expect(getAllByText(/これはテストです/));
  })
})
```

TestingLibraryのSvelteモジュールを利用してrender関数によりコンポーネントが描画された場合のテキストを取得し、チェックするコードです。

# ページサーバーのテスト

サーバー側の処理はload関数の返り値をテストしています。
ここで外部連携によりデータを取得している場合はVitestの[Mock機能](https://vitest.dev/guide/mocking.html)などを用いてテストすることができます。

```ts:src/routes/page.server.vitest.ts
import { describe, expect, it } from 'vitest'
import { load } from './+page.server'

describe('トップページサーバーのテスト', () => {
  it('返却値のテスト', async () => {
    const result = await load()
    expect(result.text).toBe('Hello World!')
  })
})
```

このようにVitestを利用することでコンポーネントとサーバー側の処理をどちらもテストすることができました。
SvelteKitのページの仕組みとして、ページコンポーネントがサーバー側の処理の結果をPropsとして扱われることによりテストもシンプルに書けることがわかります。
明日のアドベントカレンダーではこのページコンポーネントやレイアウトについての詳細を書きたいと思います！
3人の子持ちエンジニアが働く上で会社の制度の活用例

この記事はWano Group Advent Calendar2022 6日目の記事です。
https://qiita.com/advent-calendar/2022/wano-group

Wanoでプロダクト担当、フロントエンドのエンジニアをしています。
現在37歳、今現在、７歳の息子、４歳と０歳の娘がおります。
妻は現在育休中ですが、育休が明ければフルタイムの共働き世帯です。

3人子供がいると、業務時間外（特に休日）についてはほぼ自分の時間は取れない生活になってしまっています。
正直休日のほうが疲労が溜まってます（笑）

ですが、**子育てが業務の弊害になった事が記憶の上ではほぼ無い**というのは冷静に考えると凄い事なのでは？
と思い、今一度なぜそのような働き方が出来ているのか振り返ってみたいと思います。

## 子育てしやすい会社の制度
会社の制度にかなり助けられています。手前味噌ではありますが、このあたりは弊社は相当子育てしやすい環境が用意されているなと自信を持って言えると思います。
### リモートワーク
※基本は週2回、場合によっては突発的なリモートワークも許可して貰えています。
通勤にそれなりに時間のかかる場所に住んでおり、普段は子供と一緒に夕食を取れる事が少ないのですが、
リモートワークのおかげで夕食時に子供の状況を聞いたり、話せる機会が増えて良いこと尽くしです。

### コアタイム制のフレックス勤務
弊社では12:00～16:00をコアタイムとするフレックス制度があり、これも非常に助かっています。
特に子供関係で役所への手続きへ行ったり、**突発的なお迎えや通院の発生時**もかなり柔軟に対応できるのが身に染みて有難いです。
またリモートワークとも似ていますが、**早めに上がって家族との時間を取ったりといった使い方**も出来ています。

### 時間単位で取れる有給、子供の看護休暇
まさに執筆中の本日も上の娘が熱を出しており、午前中に**看護休暇**を取得させて貰いました。
看護休暇は通常の有給休暇とは別で付与されます。

この制度が無いころは有給はほぼ子供の看護で消化してしまっていました。
午前休、午後休という固定ではなく、**時間単位での取得が可能**というのも、時間を無駄にする事がなくて良い点でした。

### 長期休暇の時期未固定
これ、子連れでの帰省やレジャーでめちゃくちゃ助かってます。
例えばお盆休みが固定の場合が多いと思いますが、
まさにお盆の真っ最中というのはもうとにかく道路にしろ施設にしろ**混みます**。
**混むんです。大人2人で子供3人見ながら行列に並んだり渋滞に巻き込まれたりは親にとっても子供にとってもキツいものがあります。**

弊社の制度では長期休暇は固定時期ではなく、**有給を5日分プラスという形でいつ取ってもいいようになっています**。
（この制度は外国籍の従業員が増えた事もあり、休暇の文化の違いなども加味してフレキシブルに休暇がとれるようにという制度です）
そのおかげで**繁忙期をズラして帰省**したり出来ています。


## 制度の捉え方の変化
小学生、保育園通いの未就学児、乳児という手がかかる時間が皆バラバラの状況での育児ということもあり
**これら制度のおかげで我が家は回っているといっても過言ではありません（マジで）**

子供が生まれる前の若いころだとこれらの制度は
- リモートワークで集中作業時間が取れるなぁ
- 自分の時間が取りやすいなぁ
- 休みを細かく取って色んな所行けるなぁ

といった魅力だったと思いますが、
子供が出来てからは上に書いたように **「安心して業務が遂行できる」制度**として捉えるようになりました。

当然制度の活用だけではなく、チームメンバー、家族の協力にも支えられているのは間違いありません。
ですが、**制度がある事により「（チームメンバーや家族が）イレギュラー対応でなんとかしている」という状況は相当減っている**なと思います。

お子さんがいらっしゃる方でもし転職等を考えている方がいれば、
私の実体験としてこのような制度があると具体的にこういった風に助かりますよという参考にしていただければ幸いです。
Qiita Devトークを募集側としてやってみた

こんにちは。
メグリ株式会社でサーバーサイドエンジニアをしているコジマです。
Qiita Devトークってご存知ですか？
公式によると

> Devトークは、エンジニア同士で気軽に相談や情報交換などができる場です。
> Devトークは面接ではないため、転職意欲は関係ありません。

とのことです。
気軽に外部のエンジニアと話せるのはいいですね。

実際の募集ページはこちら
[若手と中堅の狭間で、くすぶり、もがいている、同志へ](https://jobs.qiita.com/employers/686/dev_talks/193)

## Devトークのテーマとその理由
今回募集したテーマは「若手と中堅の狭間で、くすぶり、もがいている、同志へ」ということで、それなりにエンジニアをやってきたけど、これから先どういうふうになりたいのかと悩んでいるエンジニアは多いはず。
技術について話すコミュニティは結構ありますが、意外とこういったテーマって少ない印象があったので、それならこの場を借りて話してみようよと。
求めている人がいるかどうかは度外視でw

## 実際話してみて
ありがたいことに応募してくれた方がいて、二つ返事で実施しました。
結論から言うと...

#### 思った以上に楽しかった！！！！！

予定は30分だったのですが、90分弱も話しました。
雑談ベースで気兼ねなく思ったことを話していたのですが、自分の考えとは違った視点の意見や悩みが聞けて面白かったです。

## Devトークのよかったこと
まず「採用」ということを考えなくていいのが双方にとって良いと思いました。
所謂、カジュアル面談だと採用が頭をよぎるため、本当に言いたいことも歯止めが効いてしまうのかなと。
ですが、採用だけでなく、自社の上司でも同僚でもなく、意外と他人の方が話しやすかったりするので、変に気負わなくてもただ話す。
そこがDevトークの最大の強みかなと思いました。

## Devトークで気をつけた方がいいこと
Devトークの中では様々なジャンルがあると思いますが、その中でも「雑談」をテーマにしているものは募集者としてはある意味、準備した方がいいかもしれません。
特にアドリブが苦手な方は間が持たずつらいかもしれません...w

## まとめ
いきなり初対面で雑談をすると言う経験は今回が初めてでしたが、とても楽しかったです！
技術系とは違った気づきなどもあり、募集してよかったと心から思いました。
技術系のDevトークも気になりますね。

## ここでちょっと宣伝...
弊社では僕が募集したDevトーク以外もあります！
ちょっとでも気になったら見ていただければと...

[Aurora Serverlessをプロダクション環境で使ってる人と語りたい！](https://jobs.qiita.com/employers/686/dev_talks/499)
[モバイルアプリプラットフォームの楽しい開発チームについて紹介します〜](https://jobs.qiita.com/employers/686/dev_talks/454)
[プロダクトとエンジニアリングチームの理想と現実と変化と成長を語りたい](https://jobs.qiita.com/employers/686/dev_talks/195)
[まだiOSのWebView実装で消耗してるの？](https://jobs.qiita.com/employers/686/dev_talks/51)
[とりあえず好きなお寿司のネタからでも話し始めてみませんか？](https://jobs.qiita.com/employers/686/dev_talks/8)
paiza.ioでelixir その119

# 概要
paiza.ioでelixirやってみた。
練習問題やってみた。

# 練習問題
活性化関数sigmoidをグラフ化せよ。

# サンプルコード

```


IO.puts """
<!doctype html>
<html>
<head>
<style type="text/css">
* {
  margin: 0;
  padding: 0;
  border: 0;
}
body {
  background: #fdd;
  font: 30px sans-serif;
}
</style>
</head>
<body>
<script type="text/javascript" src="https://www.google.com/jsapi"></script>
<div id='chart'></div>
<textarea id="koko0"> 
"""
for i <- 0..100 do 
    v = (1 / (1 + :math.exp(-1 * ((i - 50) / 5))))
    IO.puts(v)
    IO.puts ","
end
IO.puts """
</textarea>
<script type="text/javascript">
google.load("visualization", "1", {
    packages: ["corechart"]
});
var x0 = document.getElementById('koko0').value;
var x = x0.split(",");
var res = [['x', 'sigmoid'],];
for (var i = 0; i < 100; i++)
{
    res.push([i, x[i] / 1]);
}
google.setOnLoadCallback(function() {
    var data = google.visualization.arrayToDataTable(res);    
    var options = {
        title: '活性化関数',
        hAxis: {
            title: 'x'
        },
        vAxis: {
            title: 'y'
        }
    };    
    var chart = new google.visualization.LineChart(document.getElementById('chart'));
    chart.draw(data, options);
});
</script>
</body>
</html>
"""


```

# 実行結果

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/f71e3e39-6e77-ce76-c8f6-a379fe4b36d9.png)


# 成果物

https://paiza.io/projects/trNjdRz2UAhxHEDGTuAgkg?language=elixir

以上。
スクラム開発について

[PONOS Advent Calendar 2022](https://qiita.com/advent-calendar/2022/ponos) の5日目の記事です。
昨日は@kerimekaさんの「[Web決済比較(2022年12月)](https://qiita.com/kerimeka/items/be4cf2743bde4c0ef2a5)」でした。

スクラム開発とは
-
アジャイル開発の一種として用いられる、開発のやり方。
アジャイル開発のいくつかある種類の中で、一番用いられている手法。

そもそもアジャイル開発とは？
-
アジャイルとは、直訳で「すばやい」「俊敏な」という意味の英単語です。
スプリントやイテレーション等と呼ばれる、短い開発期間の小さい単位でリスクを最小限にしてサイクルを回していく手法です。

①**計画**
　→どういったものを作りたいのか、厳密に仕様を決めない
　→厳密に仕様を決めないのは、開発の途中段階で仕様や設計の見直しがあることを前提としているため　

②**イテレーション（反復）**
　→１週間〜２週間ごとの区切りで「計画」→「設計」→「実装」→「テスト」のサイクルを繰り返し回していく

③**リリース**

このサイクルを回していき、細かい単位でタスクを遂行することを目的とします。

ゲーム開発では、「**実際にプレイすると想像していたものよりちょっと違う**」だったり、「**ここはこうすればもっと面白くなる**」だったりに、**後戻りできないタイミングで気づくことを未然に防げたり**します。
いざ実装してみると、あんまり面白くないなんてことは多々あると思いますが、それを実装途中段階で発見できるので、マッチした手法となっています。

アジャイル開発を踏まえた上でのスクラム開発とは
-
スクラムとは、もともとラグビーのプレーの一つの「スクラム」にちなんで、スクラム開発と名付けられています。
アジャイル開発のいくつかのやり方の中でもスクラム開発は、チーム全員が一丸となって開発を進めていく手法のため、
**チーム間のコミュニケーションがより重要になってくる手法**
となっています。

チームとして「**何が必要か**」「**必要になったタスクを誰がやるべきか**」「**いつまでにやるべきか**」という観点からメンバーにタスクを割り振り、メンバーそれぞれがタスクを完遂し、イテレーションを回していくことでプロダクトの完成を目指します。
それぞれのメンバーに、**一つのことだけをまかせるのではなくいろんなタスクをまかせる**ため、**他の人のタスクが他の人のタスクを支えている**ので、チーム間での**密なコミュニケーション**が重要になってきます。![enjin_people.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2991333/39f95ab7-3d03-a1a2-6247-c46ed7f32c22.png)

スクラム開発の役割分担
-
スクラム開発ではチームワークが重要だということは変わりないのですが、最低限の役割を分担しなければ作業効率が悪くなってしまいます。
作業の効率を良くするために、３つの役割があります。

・**プロダクトオーナー**
　→タスクの作成を行う。　
　→仕様に関する決定権を持っている。
　→スプリント終了時に確認作業を行う。
・**スクラムマスター**
　→チームがうまく回っているか、困りごとがないかを確認する。
　→プロジェクトがうまく回っていない原因を排除する、困りごとを解決する。
・**開発チーム**
　→機能を実装し、各自で動作確認までテストする。
　→動作するものを担当のプロダクトオーナーに提出する。

どの役割も欠けてはいけない要素で、各担当者が**自分の役割をしっかりと認識・理解し、遂行すること**がプロジェクトを円滑に進めるために重要なことだと思います。

自分が関わったプロジェクトのスクラム開発について感じたことのまとめ
-
自分が関わったプロジェクトでは、途中から開発形態をスクラム開発に移行しました。
その中で感じたことをまとめていきます。

・**良かったこと**
　→チーム間のコミュニケーションが増え、議論などが活発になった。
　→短期間でタスクを切るので、こまめにゴールがありタスク遂行にやりがいを感じるようになった。
　→チケットでタスクを管理するので、担当者とのやりとりがやりやすくなった。
　→全員がいろんな実装箇所を把握している状況を作られた。（属人化は少なかった）
　→KPTなどで振り返りを行ったりして、うまく回っていない原因を早急に排除するようにしていた。

・**悪かったこと**
　→役割を兼任しているメンバーが一人いた。
　→エンジニアのコミュニケーションは増えたが、他職種とのコミュニケーション量はあまり変わらなかった。
　→エンジニアだけがスクラム開発をしているように感じた。
　→スプリントに対する振り返りがなかった。（想定していた時間よりなぜ早く終わったか、なぜ時間がかかったか）
　→成果物を共有する場がなかった。
　→スクラム開発というより、タスク管理開発寄りになっていた。

まとめ
-

スクラム開発の最大の利点は、**自分の課題を発見できること**だと思います。
チーム全体が一丸となって開発を進めていくので、自分自身では見えにくい課題・問題もすぐに発見できます。
私自身、本プロジェクトを通して初めてスクラムを勉強し始めたので、まだまだ学べることが多々あると思います。
プロジェクトを通して、できたことを継続していき、できていなかったことを今後のプロジェクト業務の中で追求して活かしていきたいです。

明日は @sumborn さんです。お楽しみに！

参考にさせていただいた記事、サイト
-
https://qiita.com/ruby_on_miya/items/c1a2be332d6719a4b01a

https://qiita.com/_lemoo_/items/5ccd4c499ae0f55b2112#%E3%83%87%E3%82%A4%E3%83%AA%E3%83%BC%E3%82%B9%E3%82%AF%E3%83%A9%E3%83%A0

https://note.com/shift_tech/n/ndbad648c0f2b#548c417e-c9e6-4dee-81b4-f545705d80b8
laravel bladeに複数の値が渡されていることをテストする

:::note info
この記事は[miriwoお一人様 Advent Calendar 2022](https://qiita.com/advent-calendar/2022/miriwo)の5日目の記事です
:::

# 概要

- laravelのテストコードにてbladeに複数の値が渡されているかをテストする関数`assertViewHasAll()`の使い方を簡単にまとめる。

# 方法

1. 下記の様に記載することでテストする事ができる。指定したキーがbladeに渡っていた場合、trueになる。

    ```php
    $response = $this->get('テストしたいURL');

    $response->assertViewHasAll([
        'bladeに渡されている値のキー名'
    ]);
    ```

1. 例えば`/user`にgetリクエストを送った時、表示bladeにキー`id`と`name`が渡っていたらtrue、渡っていなかったらfalseを返すことをチェックする場合下記の様になる。

    ```php
    $response = $this->get('/user');

    $response->assertViewHasAll([
        'id',
        'name',
    ]);
    ```

1. キーに加え、値もチェックしたい場合下記の様に記載する。

    ```php
    $response = $this->get('/user');

    $response->assertViewHasAll([
        'id' => 1,
        'name' => 'Hoge Fuga',
    ]);
    ```


# 参考文献

https://readouble.com/laravel/9.x/ja/http-tests.html#assert-view-has-all
イニシャライザにBundleを渡せるView一覧(SwiftUI)

## はじめに

本記事は [SwiftUI Advent Calendar 2022](https://qiita.com/advent-calendar/2022/swiftui) の5日目の記事です。
昨日も私で [ForEachで値のほかにインデックスも使う方法(SwiftUI)](https://qiita.com/uhooi/items/180068e9b27e4b85fc9e) でした。

イニシャライザに `Bundle` を渡せるSwiftUIのViewを、一覧で紹介します。

私はSwift Packages内でリソースを管理することが多いので、 `bundle: .module` を渡せるViewの一覧があると便利だと思いました。

## 環境

- OS：macOS Ventura 13.0.1
- Xcode：14.1 (14B47b)
- Swift：5.7.1

## イニシャライザにBundleを渡せるView一覧

`Text` のように、イニシャライザに `Bundle` を渡せるViewを紹介します。
イニシャライザが複数ある場合、代表的なもののみ載せています。

|View|代表的なイニシャライザ|
|:--|:--|
|[Text](https://developer.apple.com/documentation/swiftui/text)|[Text(_:tableName:bundle:comment:)](https://developer.apple.com/documentation/swiftui/text/init(_:tablename:bundle:comment:))|
|[Image](https://developer.apple.com/documentation/swiftui/image)|[Image(_:bundle:)](https://developer.apple.com/documentation/swiftui/image/init(_:bundle:))|
|[Color](https://developer.apple.com/documentation/swiftui/color)|[Color(_:bundle:)](https://developer.apple.com/documentation/swiftui/color/init(_:bundle:))|

## おわりに

私が調べた限りだと3つのみでした。
@treastrain さんもiOS 16時点ではこの3つのみと言っていたので、おそらく他にはありません。

https://twitter.com/treastrain/status/1599366780476325889

`TextField` や `Label` などのViewでも、 `LocalizedStringKey` と `Bundle` の両方を渡せるようになってほしいです。

現状では `String(localized:)` などを使ってローカライズされた文字列を `String` で取得して渡すか、だいたいのViewには `label:` でテキストのViewを渡せるようになっているので、そこで `Text` を渡すかの2択だと思います。

https://twitter.com/_kebo/status/1599366142237478914

どちらを使うかは好みだと思います。
私は前者が好みですが、いろいろ試すうちに考えが変わるかもしれません。

以上 [SwiftUI Advent Calendar 2022](https://qiita.com/advent-calendar/2022/swiftui) の5日目の記事でした。
明日は @417_72ki さんで「GeometryReaderとSafeAreaの話(仮)」です。
コード上でConstraintLayoutのMATCH_CONSTRAINTを指定する

こういうやつをConstraintSetで指定したい

```.xml
<View
    android:layout_width="0dp"
    android:layout_height="0dp"/>
```

`constrainWidth`と`constrainHeight`を使う↓

```.kt
val constraintSet = ConstraintSet()
constraintSet.clone(layout)
constraintSet.constrainWidth(view.id, ConstraintSet.MATCH_CONSTRAINT)
constraintSet.constrainHeight(view.id, ConstraintSet.MATCH_CONSTRAINT)
constraintSet.applyTo(layout)
```
自分のエンジニアとしてのDay Oneとは

この記事は [Qiita x 日本CTO協会共催！あなたの自己変革について語ろう！ Advent Calendar 2022](https://qiita.com/advent-calendar/2022/qiita-ctoa) の5日目です。

# 自己紹介
デジタルアスリート株式会社の土肥(@tdoi)と申します。

これまで、医用系ワークステーションの開発をしている会社ののち、前職では、創薬分野のクライアント様が多い会社でソフトウェア開発チームの設立から、CTOとして活動し、2022年に現職に最初のエンジニアとしてジョインしました。
この転職に当たり、より知見を広めたり、人脈を広げられればと思い、2022月にCTO協会に入会させて頂きました。

現職では、情報システム部部長という肩書でやらせて頂いておりますが、プロダクト開発、社内情シス、クライアント様向けのシステム構築など、多岐に渡ってやらせて頂いております。

# 自身の責務
さて、システムを構築、運用するというところも一つの自分の責務であると思っていますが、もう1つの大きな責務は、開発体制を整えることであると思っています。

CTO協会に入会して、CTOの方々の話を聞いた際も、悩みどころの大きな一つは、エンジニアの採用とか評価のことと話していたのをよく覚えています。

前職でも、エンジニアの採用から開発組織の立ち上げということを経験していますが、前々職は自社のITプロダクトの開発が主要な事業であり、前職では受託開発やインフラ構築などのITサービスの提供することが主な事業でした。
一方、現職はデジタルマーティングが事業の根幹であり、ITサービスの提供が主たる事業ではない、ユーザ企業での開発体制の構築は、また、違う部分も大きいと感じています。

# ソフトウェア開発の魅力、そして、エンジニアという職業

そんな採用のことを考えていると、ソフトウェア開発ってどんな魅力があるのだろうか、自分は何故この仕事を選択したのだろうかといったことを言語化する必要性にせまられます。

ちょっとカッコつけて書いていみると、

- 思い描いたことをプログラムとして実現できたときの喜び
- 複雑なものを美しい形で表現できたときの心地よさ
- システムによりビジネスの形を変革できる達成感
- 人材不足とそれに起因する好待遇

などかなと思っています。

じゃあ、逆に、エンジニアになりたいという人たちに、その思いを躊躇させてしまう要因は何なんでしょう。

一番、大きいのは「スキルの不安」なんじゃないかと思います。
僕自身もこの業界のトレンドの移り変わりは激しいのを身をもって感じます。

# エンジニアのスキル

エンジニアに求められるスキルも多岐に渡っています。
分かりやすいものだと、Go言語、TypeScript、Pythonなどプログラミング言語が使えることですが、tensorflowやPyTorchといった機械学習ライブラリの使えること、TDDやCI/CDといった技術やいわゆるDevOpsと言われるような仕組みや文化、XPやScrumといったフレームワークやプラクティスに基づくアジャイルな考え方、Lean Startupの仕組みなどビジネス開発や、DXという言葉が代表するビジネス/組織変革、などなど。
その粒度も、範囲も様々です。

これからエンジニアになろうとする人がここまで広く意識はしないかもしれませんが、確かに不安に感じますね。

# 自分の理想のエンジニア像

ちょっと話がそれるのですが、僕がまだ学生時代に、とある大手ITサービス企業の方とお話させて頂くことがありました。その時の言葉が、ある意味僕の理想のエンジニア像を形作ってます。
その言葉とは、

「エンジニアになるのだったら、顧客の顔が見える仕事をしなさい」

というものでした。
聞いた当時はそこまで意識はしていなかったと思うのですが、今、振り返るととてもよい言葉を贈ってもらったと思っています。ここ10年弱の間、アジャイルな考え方を推進していますが、この考え方にとても共感できるのも、根底がここなのかなと思っています。

ちょっと視点を変えて、エンジニア組織の責務について考えてみましょう。
アジャイルでよく言われる言い方をすると、僕は、

「顧客価値を最大化する」

ことだと思っています。
さきほど挙げたスキルは、この目的のために、必要な可能性があるものです。

ちょっと逆説的かもしれないですが、こう考えると、スキルに怯えなくてよいのかと思っています。
つまり、必要な可能性があるスキルは幅広くたくさんありますが、目の前の顧客価値最大化のために必要なスキルを見極めて、そのスキルを習得していけばいい訳です。

# どうやってスキルを磨く？

もう少し、自分の昔話をさせてもらいましょう。

僕自身のスキルの源泉は、cppll(C++ Language & Libraries)というメーリングリストにあると思っています。得に実践的なソフトウェア開発におけるプログラミングにおいては、このコミュニティでのやりとりにあこがれ、やりとりで育ててもらったと思っています。

幸いなことに、大学での専攻も情報科学でしたので、基礎知識を学ぶ機会に恵まれました。大学の研究室での影響は今でも強く受けていますし、より広い意味での自分のエンジニアとしての立ち位置はこのときに作られていると思っています。

そして、近年はアジャイル関連のコミュニティに関わりながら成長させてもらっています。

つまり、一人じゃないということです。


# これからエンジニアになりたいと思う人たちへのメッセージ

最後に、若い方へのメッセージでしめくくりたいと思います。

もし、あなたがエンジニアになりたい、なろうとしているのであれば、学ばなければいけないスキルの大きさや数に気圧されることなくチャレンジしてください。オールマイティな完全無欠のエンジニアになるためには、気の遠くなるようなスキルが必要かもしれませんが、目の前の顧客の価値を最大化するために必要なスキルを身につけていけば、きっと、立派なエンジニアになっていると思います。学ぶことはたくさんあるかもしれませんが、一歩ずつ進んでください。

自分自身でも何からやっていいか分からなくなってしまうこともあります。
そんなときは、僕にとっての今のDay Oneは「顧客価値を最大化する」ためには何をしたらよい？と考えることです。
みなさんもこんな質問を自分で見つけると、迷ったときによい指針を自分で見つけられると思います。

エンジニアの道が簡単だと言うつもりはないですが、既にエンジニアになった人たちもその苦労を知っています。だから、もし、あなたがこの道を進もうとするのであれば、きっと支援をしてくれます。実際、CTO協会にも2022年にエンジニア育成ワーキンググループが発足し、多くのCTOの方がその活動に賛同してくれています。
僕も微力ながら何かできればと思っています。

とりとめのない文章を最後までお読み頂きありがとうございます。
この文章が、誰かの背中をちょっとだけでも押すことができたら幸いです。
Vantageのラインナップ

こんにちは！
今日はテラデータが提供するデータ分析環境の中核となるソフトウェア「Vantage」のラインナップについて紹介したいと思います。
今をさかのぼること40年以上昔に「Teradata RDBMS」として産声を上げたテラデータのデータ分析環境用ソフトウェアがどのように変わったか見てみましょう。

# Vantageの変遷
Teradata Vantageは40年以上前の販売開始から下図のような変遷をたどってきました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2742714/baf899cb-b3d1-2b08-2c46-975d3ee4b66b.png)

Vantageを以前からご利用くださっているユーザー様では今でも「Vantage」という名前よりも「Teradata」という名前の方がなじみがあるかもしれません。販売開始当時は専用ハードウェアを必要としたVantageも以前販売されていた廉価版ハードウェアを提供した際に汎用ハードウェアの利用への道筋がつくられ（この辺りはソフトウェアアーキテクチャのところで少し触れたいと思います）ました。

その後汎用ハードウェアへの展開とそれを転用したパブリッククラウドへの展開を経て、今年全く新しいクラウド・ネイティブのVantageを発表するに至ったのです。

# Vantageのラインアップ
Vantageの現在のラインアップは下記のとおりです。

|名称|概要|
|:-|:-|
|VantageCore IntelliFlex|テラデータが販売する専用ハードウェアIntelliFlexを利用する|
|VantageCore VMWare|VMWareで構築された仮想環境を利用する。ハードウェアを含むVM環境はお客様が用意する|
|VantageCloud Enterprise|AWS、Azure、GCP上で提供されるaaSとお客様契約のEC2を利用するDIYがある|
|VantageCloud Lake|完全なクラウド・ネイティブの特長を持つ新しいaaS。AWSでサービス開始、今後Azure、GCPへ展開予定|

##### VantageCloud
既にデータウェアハウジングの中心がクラウドにあることは否めないでしょう。Vantageにおいてもそれは同様となってきています。
クラウドには
　・ いつでもコンピュートノードを調達できるといったことに代表される**フレキシビリティ**
　・ 安価にオブジェクトを保存できる**ストレージ**
　・ クラウドベンダーが提供する**機械学習などのサービス**
といった特長がありますが、これらの特長を取り込んだ新しいソフトウェア・アーキテクチャを備えたものが「VantageCloud Lake」です。

一方でシステムをクラウドへ移行しながらもデータウェアハウスを以前と同様に企業内のデータ利用の中枢ととらえ、レポーティングからアドホックな分析、また時には業務遂行のためのシステムとしての利用まで様々なワークロードを実行したいというニーズはもちろん存在します。これらにこたえられるのがVantageの誕生から今に続くエンタープライズシステムとしてのアーキテクチャを備えた「VantageCloud Enterprise」となります。

この２つのVantageCloudが存在することでテラデータだけがデータ活用・分析を全方位で支えることができるベンダーとなっています。

##### VantageCore
クラウドでのシステム構築が当たり前となっている現代でもオンプレミス・システムの需要は確かに存在しています。例えばセンサーデータを機械学習モデルにかけ生産ラインの問題をいち早く抽出するような場合ではレイテンシによるわずかな時間の遅れが大きな損害をもたらすこともあります。また非常にセンシティブなデータを扱う分野ではクラウド（特にマルチテナントのシステム）にはデータを置かないということは一般的にあることかと思います。

そうしたニーズにこたえるのが「VantageCore」です。テラデータがVantageの最適なパフォーマンスを引き出すために設計された独自のハードウェア　**「IntelliFlex」** を利用するVantageCore IntelliFlexとVMWare上に構築された仮想マシン環境上でVantageを稼働させることが可能なVantageCore VMWareが用意されています。パフォーマンスをとことんまで追求するのか、運用コストとのバランスをとるのかで選択していただけたらと思います。

# 最後に
いかがでしょうか？
データ活用・分析環境をクラウドとオンプレミスの双方で提供できるベンダは多くありません。しかも最高レベルのパフォーマンスや信頼性を持っているものに限定すればなおさらです。
みなさんのニーズに合わせてどのVantageを選択するのかお決めください。どれを選んだとしても必ず満足できる環境を構築できると思います。

#### Teradata Vantageへのお問合せ
[Teradata Vantage へのお問合せ](https://www.teradata.jp/About-Us/Contact)
素因数分解

## はじめに
こんにちは、ITを勉強している学生です。
皆さんは素因数分解お好きでしょうか
私は高校生の頃QuizKnockさんが作った「wallprime」というアプリにハマっていた時期がありました。
（楽しいのでぜひやってみてください）
今回は素因数分解について語っていきたいと思います。
（写真）

## 素因数分解とは
数を素数の掛け算で表すことです。
(例)12=2×2×3　64=2×2×2×2×2×2

## 素因数分解のやり方
実際に素因数分解をするときは、小さな素数から順に割り算をしていくことで導くことができます。
そのほかにも倍数の判定法を使うことで簡単な素数で構成されている数であれば求めることができます。

## ソースコード
``` html 
<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
    <link rel="stylesheet" href="style.css">

</head>
<body>
    <h1>素因数分解</h1>
    <h2>好きな数を入力してください</h2>
    <input id="prime" type="number">
    <p>結果：<span id="result"></span></p>

    <script>
const box = document.querySelector('#prime');
const result = document.querySelector('#result');

const checkDivisors = () => {
  let value = box.value;
	let exponent = 0;
	let divisors = [];

	for(let number = 2; number <= value; number++) {
		if(value % number === 0) {
			exponent = 0;
      while(value % number === 0) {
      	exponent++;
      	value /= number;
      }
			divisors.push({number, exponent});
		}
	}
  
  box.value = null;
  result.textContent = null;

  divisors.forEach((divisor, index) => {
    if(index === divisors.length - 1) {
    	result.textContent += `${divisor.number}^${divisor.exponent}`;
      return;
    }
    result.textContent += `${divisor.number}^${divisor.exponent}\n*\n`;
  })
}

box.addEventListener('keydown', e => {
	if(e.key === 'Enter') {
		checkDivisors();
  }
})
    </script>
</body>
</html>
```
## つくってみて
google先生で調べながら作ってみましたが、結構素因数分解のソースコードが複雑で大変でした。
素因数分解にはまだ語りきれていない魅力がたくさんあるので、これを機に皆さんも素因数分解始めてみてはいかがでしょうか！
monorepoのNext.jsでsass入れるとnext/babelがないって怒られる

コンポーネントに区切れるNext.js (というかReact) でsass使うメリットあまりないですが、あるにはあるのでほしくなる時があります。
そんな時のため、Nextjsの公式ではこういった案内を用意しています。

これ自体はとてもうれしいんですが、モノレポ環境で`npx create-next-app --ts` で生成したプロジェクトでこれをすると、不思議とエラーで怒られることがあります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/532032/4217d85c-0a2e-9aba-723f-7c804a21ca27.png)


```
Parsing error: Cannot find module 'next/babel'
```

大体これでググると、世の中ではこう案内してくれます。

```.eslintrc.js
module.exports = {
  extends: ["next", "next/core-web-vitals", "prettier", "next/babel"],
  ignorePatterns: ["node_modules", "dist"],
};
```

extends末尾に `next/babel` を追加するという手段です。
`next/babel`が見つからないのであれば、見つかるようにしてあげようという手段ですね。

これはこれでいいんですが、これで解決すると1点問題が生じます
これを使うと、 `next lint` が通らなくなるという問題です。

出てくるエラーはこんなです。

```bash
$ next lint
Failed to load config "next/babel" to extend from.
Referenced from: /Users/ikea_shark/apps/hogehoge/.eslintrc.js
error Command failed with exit code 1.
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.
```

`Failed to load config "next/babel" to extend from.`
まあせやろなって感じですね。

そんなわけで、extendsに`next/babel`を追加するのはあまり良くありません。
次の形で解消できるので、こちらで解消しましょう。

```.eslintrc.js
module.exports = {
  extends: ["next", "next/core-web-vitals", "prettier"],
  ignorePatterns: ["node_modules", "dist"],
  parserOptions: {
    babelOptions: {
      presets: [require.resolve("next/babel")],
    },
  },
};
```
InfluxDB v2: MQTT で受信したデータを書き込む

## プログラム
MQTT サーバーから、次のような　JSON を受信するとします。

```json
{"temperature": 20.4}
```


```py:subscribe_influx.py
#! /usr/bin/python
#
#	subscribe_influx.py
#
#						Dec/05/2022
#
# ------------------------------------------------------------------
import sys
import json
from time import sleep
import paho.mqtt.client as mqtt
import time
import influxdb_client
from influxdb_client.client.write_api import SYNCHRONOUS

# ------------------------------------------------------------------
def influxdb_write_proc(json_str):
#	print(json_str)
	unit_aa = json.loads(json_str)
	value = unit_aa["temperature"]
	print(value)
#
	pp = influxdb_client.Point("data") \
		.field("temperature", value)
	write_api.write(bucket=bucket, org=org, record=pp)

# ------------------------------------------------------------------
def on_connect(client, userdata, flags, respons_code):
#	print('status {0}'.format(respons_code))
	client.subscribe(topic)

# ------------------------------------------------------------------
def on_message(client, userdata, msg):
#	print(msg.topic + ' ' + str(msg.payload,'utf-8'))
	influxdb_write_proc(str(msg.payload,'utf-8'))

# ------------------------------------------------------------------
sys.stderr.write("*** 開始 ***\n")

host = 'example.com'
port = 1883
topic = 'example/test'

bucket = "tochigi"
org = "ekzemplaro"
token = '****VpyyJg6nskHEwcl6bMsjc1vyzY9b11hSyGiQMOg=='
#
url="http://localhost:8086"

db_client = influxdb_client.InfluxDBClient(
   url=url,
   token=token,
   org=org
)

write_api = db_client.write_api(write_options=SYNCHRONOUS)

client = mqtt.Client(protocol=mqtt.MQTTv311)

client.on_connect = on_connect
client.on_message = on_message

client.connect(host, port=port, keepalive=60)

client.loop_forever()

sys.stderr.write("*** 終了 ***\n")
# ------------------------------------------------------------------
```

## テスト用プログラム
MQTT サーバーに 1秒毎にデータをパブリッシュします。

```py:publish.py
#! /usr/bin/python
#
#	publish.py
#
#					Dec/05/2012
#
# ------------------------------------------------------------------
import  sys
import  json
from time import sleep
import paho.mqtt.client as mqtt

# ------------------------------------------------------------------
sys.stderr.write("*** 開始 ***\n")

host = 'example.com'
port = 1883
topic = 'example/test'

client = mqtt.Client(protocol=mqtt.MQTTv311)

client.connect(host, port=port, keepalive=60)

ttx = [20.4,21.3,22.7,23.5,24.5,23.6,22.2,20.1]
for it in range(len(ttx)):
	unit_aa = {}
	unit_aa['temperature'] = ttx[it]
	json_str = json.dumps(unit_aa)
	print(json_str)
	client.publish(topic, json_str)
	sleep(1.0)
#
client.disconnect()

sys.stderr.write("*** 終了 ***\n")
# ------------------------------------------------------------------
```

## 書き込まれたデータの確認
InfluxDB に書き込まれたデータのプログラムは、
[InfluxDB v2: 時系列データの取り扱い例](https://qiita.com/ekzemplaro/items/13fed3578b3a0eb8bc9c)
にある
query_temperature.py
【Python】最長共通部分文字列の問題の解法

# 問題
> 2 個の文字列が与えられたとき, 両方の文字列に含まれる文字列のうち最も長いも のを探し, その長さを答えるプログラムを作成せよ.
ここで, 文字列 s が文字列 t に含まれるとは, t の中に s が連続して現れることをい う. 空文字列, すなわち長さ 0 の文字列は, どんな文字列にも含まれる. 例えば, 文字 列 ABRACADABRA には次の文字列が含まれる: ABRA, RAC, D, ACADABRA, ABRACADABRA, 空文字列など. 一方, 文字列 ABRACADABRA には次の文字列は含まれない: ABRC, RAA, BA, K など.
[JOI 2007/2008 本選 問題2](https://atcoder.jp/contests/joi2008ho/tasks/joi2008ho_b)

２つの文字列が与えられたときに、それらの最長共通部分文字列の長さを答える問題です。ここで部分文字列とは「元の文字列に含まれる連続した文字列」のことを指します。「連続した」という点がLCS問題とは異なる点に注意してください。

# 実装例１
```Python
s = input()
t = input()
n = len(s)
l, r = 0, 0
ans = 0
while l<n and r<n:
  if s[l:r+1] in t:
    ans = max(ans, r-l+1)
    r += 1
  else:
    l += 1
print(ans)
```
ある文字列がTの中に含まれているかどうかは、in を使うことで判定できます。これを利用し、S中のある区間がTに含まれているか判定し、含まれていれば ans を更新し区間を広げる、含まれていなければ区間を狭める or 次に区間へ、と繰り返すことで最長共通連続部分文字列を求めることができます。
# 実装例２
この問題は[LCS問題](https://atcoder.jp/contests/dp/tasks/dp_f)と同じようにDP(動的計画法)を用いても解くことができます。
```Python
s = input()
t = input()

# 先頭に空文字を挿入
s = "#" + s
t = "#" + t

ans = 0

# dp[j]はj番目の文字を含む共通部分文字列の長さ
dp = [0] * len(t)
for i in range(1, len(s)):
  for j in reversed(range(len(t))):
    if s[i] == t[j]:
      dp[j] = dp[j-1] + 1
      ans = max(ans, dp[j])
    else:
      dp[j] = 0
print(ans)
```
ここでは一次元のdpを使い回しています。そのため j のループを逆からにしていることに注意してください。
複利的に効果を発揮するE2Eテスト自動化方法

# Introduction
Openlogiではメジャーリリース前のリグレッションテストの８割の自動化を１年で実現しました。
しかし、ただ自動化しただけでは開発に伴う変更に自動テストを対応させるコストが想像以上に掛かってしまっていました。
ここでは自動化実現と運用にあたって生産性向上に必須のテクニックについて書きます。
最初は各項目の自動化にそれなりに時間が掛かるものの、進めるうちに複利的効果を発揮します。

# 自動化ツール
Ghostinspector を使用
## よく使う機能
- **レコーディングツール**
Chrome addon でテストレコーディングツールが提供されているので、ベースとなるテストステップはコードを書かずに作成することができる。
- **Condition(分岐)**
ページ内の要素の状態による処理の分岐をJavascriptを使って設定することができる。
- **変数**
変数を自由に定義し、任意の値やページ内の指定した要素の値を変数に格納することが可能。
シーケンシャルなテストスイートを組むことで変数とその値を後続のテストに引き継ぐことが可能。

# 生産性を上げるために重要なこと
タイトルにある複利的に効果を発揮するE2Eテスト自動化方法はずばりモジュールの利用です。
ですが、闇雲にモジュールを作ってもメンテナンスコストを下げることができません。
以下にポイントを記します。

1. 汎用性の高いモジュールにすること
1. 柔軟性をもたせること

## 汎用的で柔軟性の高いモジュールにするには

### 1. 重複するテストステップはモジュール化する
まず重要なのが、全てのテスト項目から何度も実施しないといけない重複項目を洗い出します。
この時扱う値が都度変わったりすることもあると思いますが、それは変数で対応できるのでそういった項目もモジュール化の対象にします。

### 2. 分岐ごとのテストステップを作成する
最大公約数的に重複するテストステップを求めるとモジュールがとても小さくなります。そうなるとメンテナンスコストが思うように低減できなくります。
ですので、ある程度の分岐まで含めてモジュール化します。
画像は tab に数字が表示される画面で数字があれば処理を実行する分岐処理です。
↓
![スクリーンショット 2022-12-05 15.36.31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/357158/1f3d318d-b0ce-8f31-3ced-d70649b6dcfe.png)

```
let tab = document.querySelector("#warehousing_detail_main_tab-tab-size > span > span");
return tab !== null;
```
こういった分岐を作っておけば tab の数字を変数にして任意に設定することで、たとえば tab に「2」が表示されたら実行するようにすることも可能です。
![スクリーンショット 2022-12-05 15.43.09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/357158/a322e35a-69eb-7b93-25c6-e8a4156c007d.png)

```
let tab = document.querySelector("#warehousing_detail_main_tab-tab-size > span > span");
return tab === {{tabNumber}};
```

### 3. 変数の設定場所のマネジメント
変数のマネジメントの詳細については[過去の記事](https://qiita.com/T-Com/items/50fb957a89cf8ec6ae38)に記載してありますので、ここでは汎用的なモジュールで変数を扱い易くする方法を書きます。

モジュールはテスト内で呼び出すことになるので、あまり階層の高い場所に変数を設定してしまうとテスト毎に変数を設定し直さないといけません。その手間を避けるためには、モジュールを呼び出すテスト内で変数の値を設定します。
![スクリーンショット 2022-12-05 15.19.01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/357158/01095d7e-8596-0b12-28d7-5a75949bb39e.png)
こうすることでテスト毎に変数の値を調整することもできるので、テストをコピーして変数の値を変えるだけでパターンの異なる自動テストを実施することが可能になります。

# 汎用的で柔軟性の高いモジュールを多用することのメリット
## モジュール化されていないとどうなるか？
メリットを語る前に、まずはモジュール化していないとどうなるかお伝えします。
自動テストは開発するコストもありますが、**システムの成長に伴って発生する変更に対応するコストも地味にQAリソースを奪っていきます。**

特にいざリグレッションという時、リリースされる新機能によって既存要素に変更があった場合テストがFailしてしまって至急対応方法を決めないといけないなんてことがよくありました。
そこで新たに開発する自動テストは汎用性の高いモジュールの開発に力を入れるようにしています。

:::note info
最近は変更にAIがよしなに対応してくれるサービスもありますが、オープンロジではAIの教育方法やどういった動作をするかがブラックボックスになると考え、手動で管理できるツールとして Ghostinspector を選びました。
:::

## 自動テスト運用コストが下がる！！
開発に伴う変更に自動テストを対応させるための修正箇所がモジュール内に収まることで、運用コストは確実に下がります。
最初はそれほど効果を実感できませんが、１つの変更によって影響を受ける範囲が広い場合は、重複している行程としてモジュール化されている可能性も高まります。結果として変更箇所がモジュールだけになることが増えていきます。

合わせてUIに変更が入る開発はQC後にE2E自動テストも実行することで、リグレッションテスト時には変更に対応できているよう運用を改善しました。こういった対応が機能するようになってようやくリグレッションのテスト工数を大幅に削減することができています。

# Conclusion
高い汎用性と柔軟性のモジュールを開発するにはテストシナリオの分析、分岐や変数の設計などそれなりにコストが掛かりますが、使っていくことでコスト削減効果を実感することができます。

自動化はできたけど運用が大変という方は一度試してみてはいかがでしょうか。


# PS

【オープンロジイベント情報】
<12/15(木)19:30〜>
「CTO・VPoEぶっちゃけトーク！　〜失敗から学ぶエンジニア組織論〜」
過去の失敗談をセキララに語りつつ、オープンロジでどんな組織をつくっていくかが語られる予定なので、ご都合合う方は是非ご参加ください！
https://openlogi.connpass.com/event/265230/
Dequeインタフェース実装クラスの速度比較

# 前書き
徹底攻略Java SE 8 Gold問題集を読みながらJavaGoldの勉強をしていたところ、以下のような記述を見つけた。

> __ArrayDeque&lt;E>クラスは、内部で配列を使用したDequeインタフェースの実装__ であり、以下のような特徴があります。
> 　・FIFO(キュー)として用いる場合には、LinkedList&lt;E>クラスを使用するよりも高速である
> 　・FILO(スタック)として用いる場合には、java.util.Stack&lt;E>クラスを使用するよりも高速である

> ArrayDeque&lt;E>クラスやLinkedList&lt;E>クラスは __スレッド・セーフではない__ ため、マルチスレッドのアプリケーションで使用する場合には、スレッド・セーフに設計されているStack&lt;E>クラスが安全です。

なるほど、ArrayDequeが高速で、マルチスレッド環境で利用する場合はStackが速いのか。
ん、なんかConcurrentLinkedDeque&lt;E>ってやつがあるんだけどこれ何？
スレッドセーフなやつっぽい？
じゃあStackとConcurrentLinkedDequeってどっちが速いの？

とか思ってちょっと検索したら何も出て来なかったので実際に色々叩いてみました。

# 最初に結果

|クラス|1億回の出し入れにかかった時間(ミリ秒)|
|:---|:---|
|ArrayDeque&lt;E>|114|
|LinkedList&lt;E>|442|
|Stack&lt;E>|1659|
|ConcurrentLinkedDeque&lt;E>|3961|

# 調べ方
結構適当です。以下のようなプログラムをコメントアウトしたり外したりしながら叩きました。

``` Main.java
	public static void main(String[] args) {
		LocalDateTime startTime = LocalDateTime.now();
		System.out.println("start " + startTime);

		int roopcount = 100000000;
		/*
		Deque<String> ll = new LinkedList<>();
		//Deque<String> ll = new ArrayDeque<>();
		//Deque<String> ll = new ConcurrentLinkedDeque<>();

		for(int i = 0; i < roopcount; i++) {
			ll.addLast("test");
			ll.removeLast();
		}
		*/

		Stack<String> st = new Stack<>();
		for(int i = 0; i < roopcount; i++) {
			st.add("test");
			st.pop();
		}

		LocalDateTime endTime = LocalDateTime.now();
		System.out.println("\r\nend   " + endTime);
		System.out.println("経過ミリ秒 " + ChronoUnit.MILLIS.between(startTime, endTime));
	}
```

# 結論
確かにLinkedListよりもArrayDequeの方が速いので、Dequeとして使う場合はArrayDequeの方がよさそうです。
マルチスレッド環境で利用する場合、Stackの機能で充分な場合はStackを利用し、Dequeの機能が必要である場合はConcurrentLinkedDequeを利用するといった使い分けになるでしょうか。

誰かの参考になれば幸いです。
DataGripのSQL実行ログ

DataGripのSQL実行ログの場所がわからなかったので探して見つけました。

実行ログ
![スクリーンショット 2023-01-31 15.47.05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/685449/eec153f5-5872-f45c-019b-bb526331165d.png)




DataGripのSQL実行ログは以下で確認できます。

`DataGripメニュー > HEPL > Show SQL log in Finder`
![スクリーンショット 2023-01-31 15.48.05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/685449/8e78ccdb-df25-b3f6-9a40-e9e9b595ebcf.png)


ログが保存してあるフォルダが表示されます。
<img width="700" alt="スクリーンショット 2022-12-05 14.19.16.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/685449/444f7f80-8364-4ffd-03cd-feb77c5b069c.png">


ログファイルの中身を確認
![スクリーンショット 2023-01-31 15.50.19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/685449/256c4fe3-82f1-6019-e5d7-a3eacd7725c8.png)


あったあった
よかったよかった


ちなみにconsoleって増えていきませんか？
どんどん増え続けていくconsole.logは以下の手順で不要な物を消せます。
ひどい時は50個とかできてしまいます。

`Database　ExplorerのQLのアイコン > ALL > Show Console Folder`
![スクリーンショット 2023-01-31 15.51.19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/685449/f2d6c5e8-25e1-1f93-4e9b-9df3b1d2f15d.png)


DataGripの右の方にFiles一覧が表示されるので、consoleファイルを選択して右クリック 
`Open In > Finder`
![スクリーンショット 2023-01-31 15.54.27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/685449/a16ce955-7906-087c-3aec-390caad92f04.png)


Console一覧が表示されるので、不要なものを削除します。
<img width="700" alt="スクリーンショット 2022-12-05 14.19.16.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/685449/ce8d4121-1bf8-2108-503d-1d5522287a0b.png">

きれいになった
よかったよかった