OmniAICreator/Qiita-1.07M huggingface dataset:
AtCoder 勉強記録[C++] その14

AtCoderで入茶を目指して勉強しています。
勉強を継続するために投稿を始めました。
もともとアカウントを作成していましたが、今年の4月から本格的に勉強を始めました。
一応自分用に解法を書いていますが雑です、自分で読み返して困ったら修正します。
[私のアカウント](https://atcoder.jp/users/nanami_brother)
[解いた問題](https://kenkoooo.com/atcoder/#/table/nanami_brother)
# 本日解いた問題
## B - 81
[B - 81](https://atcoder.jp/contests/abc144/tasks/abc144_b)
解答
```c++
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using vec = vector<ll>;
#define rep(i, n) for (int i = 0; i < (int)(n); i++)

int main() {
  ll n;
  cin >> n;
  for(int i = 1; i <= 9; i++){
    for(int j = 1; j <= 9; j++){
      if(i*j == n){
        cout << "Yes" << endl;
        exit(0);
      }
    }
  }
  cout << "No" << endl;
}
```
### 解法
`1`から`9`までの掛け算のループを行い`N`と一致したら`Yes`、一致しなかったら`No`を出力する。
## B - Count ABC
[B - Count ABC](https://atcoder.jp/contests/abc150/tasks/abc150_b)
解答
```c++
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using vec = vector<ll>;
#define rep(i, n) for (int i = 0; i < (int)(n); i++)

int main() {
  ll n;
  cin >> n;
  string s;
  cin >> s;
  ll res = 0;
  for(int i = 0; i < n - 2; i++){
    if(s[i] == 'A'&&s[i+1] == 'B'&&s[i+2] == 'C') res++;
  }
  cout << res << endl;
}
```
### 解法
文字列の最初の要素から`ABC`になっているか判定する。
## B - ATCoder
[B - ATCoder](https://atcoder.jp/contests/abc122/tasks/abc122_b)
解答
```c++
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using vec = vector<ll>;
#define rep(i, n) for (int i = 0; i < (int)(n); i++)

int main() {
  string s;
  cin >> s;
  ll n = s.size();
  ll i = 0, res = 0, tmp = 0;
  for(int i = 0; i < n; i++){
    if(s[i]=='A'||s[i]=='C'||s[i]=='G'||s[i]=='T') {
      tmp++;
      res = max(tmp, res);
    }
    else{
      tmp = 0;
    }
  }
  cout << res << endl;
}
```
### 解法
文字列の最初から`ACGT`のどれかであればカウントして、違う場合はリセットして続ける。カウントしたものの最大値を出力する。
## C - Digits in Multiplication
[C - Digits in Multiplication](https://atcoder.jp/contests/abc057/tasks/abc057_c)
解答
```c++
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using vec = vector<ll>;
#define rep(i, n) for (int i = 0; i < (int)(n); i++)

int main() {
  ll n;
  cin >> n;
  ll a = sqrt(n);
  ll tmp = 0, res = INT_MAX;
  for(int i = 1; i <= a; i++){
    if(n%i!=0) continue; 
    ll b = n / i;
    string sta = to_string(i);
    string stb = to_string(b);
    ll diga = sta.size(), digb = stb.size();
    tmp = max(diga, digb);
    res = min(res, tmp);
  }
  cout << res << endl;
}
```
`A`が1から`N`の平方数までの値で`A×B`となる要素を全探索する。桁数は文字列に変換して文字数にして求める。
## C - Half and Half
[C - Half and Half](https://atcoder.jp/contests/abc095/tasks/arc096_a)
解答
```c++
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using vec = vector<ll>;
#define rep(i, n) for (int i = 0; i < (int)(n); i++)

int main() {
  int a, b, c, x, y;
  cin >> a >> b >> c >> x >> y;
  int res = INT_MAX;
  int n = max(x,y);
  for(int i = 0; i <= n; i++){
    int dx = max(0, x-i);
    int dy = max(0, y-i);
    int tmp = c*2*i + a*dx + b*dy;
    res = min(tmp, res);
  }
  cout << res << endl;
}
```
### 解法
`AB`ピザの枚数を0から`X`と`Y`のうち大きいほうの値まで全探索する。そのうちの最小値を出力する。
Sequence Makerの商標登録を確認してみる

## はじめに
Sequence MakerはExcelから測定器を制御可能にするアドインです。「Sequence Maker」は商標登録されています。この記事ではそのあたりを見ていきます。Sequence Makerについての詳細は以下の記事を参照ください。

https://qiita.com/sequencemaker/items/8e6a370ab0a793a06a3b

:::note warn
***お断り***
本記事の内容はSequence Maker開発元の公式見解ではなく、あくまでも個人が趣味の範囲内で執筆しているものです。記事の内容について開発元へ問い合わせることはお控えください。ご質問・要望などは各記事のコメント欄へお願いいたします。
:::

## 商標登録について
Sequence Makerのオンラインマニュアルなどを見ると、Sequence Makerのロゴの右上にⓇが付いています。これは「Sequence Maker」が商標登録されていることを意味しています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3821782/bd2ae527-2907-e3e4-742f-d4ed5aa784c3.png)

（https://sequencemaker.hioki.com/manual/ja/ より引用）

また、オンラインマニュアルの一番下を見ると以下の記載があります。

> Sequence Makerは、日置電機株式会社の登録商標です。

## 商標検索
それでは、どのような形で商標登録されているのかを確認してみます。
商標検索はJ-PlatPat（特許情報プラットフォーム）のサイトで検索することができます。

https://www.j-platpat.inpit.go.jp/

簡易検索の「商標」にチェックを入れて「Sequence Maker」を検索してみます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3821782/f417620b-c523-2af2-5019-fc8f65647705.png)
（J-PlatPatのサイトより引用）

1件ヒットしました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3821782/16d5fa72-84f6-e1cb-57c4-9832bc507aaf.png)
（J-PlatPatのサイトより引用）

登録番号をクリックすると詳細が確認できます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3821782/5fa3302c-5bbd-de57-7be2-26c3a49da54e.png)
（J-PlatPatのサイトより引用）

読み方（称呼）は何パターンかあるようです。

- シークエンスメーカー
- シーケンスメーカー

出願は令和3(2021)年6月1日で、令和4(2022)年2月24日に登録となっています。令和14年まで有効です。

## まとめ
今回は「Sequence Maker」の商標登録を確認してみました。J-PlatPatのサイトでは、他にも特許や実用新案、意匠などをサクッと簡単に検索できるのでおススメです。
Power Platformの有償ライセンスの自動割り当てをオフにする


Power Platformなどの有償ライセンスの自動割り当てがオンになっていると、気づいたらライセンスがユーザーに割り当たっているなどの事象が起こります。

ここを制御するためのMicrosoft 365管理センターの設定でテナント全体のライセンスの自動割り当てを設定する方法、Power Platform管理センターで環境単位でのPower Apps有償ライセンスの自動割り当てを設定する方法がありますので紹介します。


::: note
こちらの記事は投稿時点の情報です。
最新情報は公式ドキュメントMicrosoft Learnでご確認お願いいたします。
:::

# テナント全体のライセンス自動割り当て設定（Microsoft 365管理センター）
Microsoft 365管理センターにてライセンスの自動割り当てを設定する方法についてご紹介します。

Microsoft 365管理センターで設定をするとすべてのPower Platform環境で、その自動割り当ての設定が反映されます。

::: note

これを操作するには「グローバル管理者」のロールが必要です。
:::
https://learn.microsoft.com/ja-jp/microsoft-365/commerce/licenses/manage-auto-claim-policies?view=o365-worldwide&wt.mc_id=365admincsh_inproduct

Microsoft 365管理センターの[請求]を開き、[ライセンス]をクリックします。
（https://admin.microsoft.com/）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2883014/10795712-8d2a-b660-f819-5da6c0d43590.png)

[自動要求ポリシー]のタブを選択し、制御したいライセンスを選択します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2883014/0062a49d-0b46-3860-7408-e018d84dbe72.png)

[設定をオフにする] ボタンを選択します。[保存]ボタンで保存し、完了です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2883014/6fdd91fb-b3de-e328-dfbc-ded89c9406ae.png)

# 環境単位のライセンス自動割り当て設定（Power Platform管理センター）
Power Platform管理センターでの設定項目もあります。
上記のMicrosoft 365管理センターの設定で自動割り当てをオフにすると、全環境でオフにすることができますが、Power Platform管理センター側で環境の種類で絞り込みをする（環境単位で）制御することができます。

[Power Platformの管理センターの[設定]](https://admin.powerplatform.microsoft.com/tenantsettings
)を開きます。

[Power Appsの自動割り当てポリシー]を選択します。

::: note warn

既定では「すべての環境」になってしまっているので、注意してください。

:::

[マネージド環境のみ]を選択します。

::: note
マネージド環境を設定することで、個別で環境ごとに自動割り当てを許可することも可能です。

マネージド環境について詳細は[こちら](https://learn.microsoft.com/ja-jp/power-platform/admin/managed-environment-overview)
:::

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2883014/aac0ff3a-8ef4-b87a-633b-de17b2383555.png)


# 最新・詳細情報

https://learn.microsoft.com/ja-jp/microsoft-365/commerce/licenses/manage-auto-claim-policies?view=o365-worldwide&wt.mc_id=365admincsh_inproduct
体育科出身の僕がLeetCode入門してみた - Day7 2626. Array Reduce Transformation

# 概要
文系（体育科）卒業の僕が、人並みのアルゴリズムを身につけるためにLeetCodeを初めてみました。
日本だとAtCoderが一般的なようですが、海外エンジニアへの憧れを持つ僕はLeetCodeを選びました。

フロントの言語しかほぼ触ったことがないのでJavaScriptでやっていこうと思います。

# 問題
[2626. Array Reduce Transformation](https://leetcode.com/problems/array-reduce-transformation/description/?envType=study-plan-v2&envId=30-days-of-javascript)

問題文
> Given an integer array nums, a reducer function fn, and an initial value init, return the final result obtained by executing the fn function on each element of the array, sequentially, passing in the return value from the calculation on the preceding element.<br>
This result is achieved through the following operations: val = fn(init, nums[0]), val = fn(val, nums[1]), val = fn(val, nums[2]), ... until every element in the array has been processed. The ultimate value of val is then returned.<br>
If the length of the array is 0, the function should return init.<br>
Please solve it without using the built-in Array.reduce method.

問題を整理します。

- 整数の配列`nums
- reducer関数`fn`
- 初期値`init
- val = fn(init,nums[0])→ val =fn(val,nums[1]) → val=fn(val,nums[2])
    - 配列の要素が無くなるまで続く
    - 配列がからの時は初期値のinitをreturnする


まずは、JavaScriptのreduce関数について調べてみます。使った記憶ないかも。

https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array/reduce

> 縮小関数は配列を要素ごとに走査し、それぞれの段階で、前の段階の結果に現在の配列の値を加えていきます (この結果は、それ以前のすべての段階を合算したものです)。


配列の中身を１つずつ足していって合計を求めるということができるみたいです。
[【javascript】reduce - Qiita]([https://qiita.com/chihiro/items/1047e40514a778c08baa#:~:text=%E4%BE%8B%E3%81%88%E3%81%B0%E3%80%81%E3%80%8C%E9%85%8D%E5%88%97%E3%81%AE%E4%B8%AD%E8%BA%AB%E3%82%92%E4%B8%80%E3%81%A4%E3%81%9A%E3%81%A4%E8%B6%B3%E3%81%97%E3%81%A6%E3%81%84%E3%81%A3%E3%81%A6%E5%90%88%E8%A8%88%E3%82%92%E6%B1%82%E3%82%81%E3%82%8B%E3%80%8D%E3%81%A8%E3%81%84%E3%81%86%E3%81%93%E3%81%A8%E3%81%8C%E3%81%A7%E3%81%8D%E3%81%BE%E3%81%99%E3%80%82)

まずは、土台をつくります。
- valに初期値を入れる
- returnでvalを返します

```javascript
/**
 * @param {number[]} nums
 * @param {Function} fn
 * @param {number} init
 * @return {number}
 */
var reduce = function(nums, fn, init) {
    let val = init;
    
    // 処理が入る
    
    return val;  
};
```

> 整数の配列 nums、リデューサー関数 fn、および初期値 init が与えられた場合、配列の各要素に対して順番に fn 関数を実行し、前の計算からの戻り値を引数として渡して、最終的な結果を返す関数を作成します。

とあるので、ループの中で`val = fn(val)`とすることで、実行後の値をvalに入れられそうです。
また、例題から、配列の値も順番に使用しているので`fn(val,nums[i])`とするのが良さそうです。
```javascript
/**
 * @param {number[]} nums
 * @param {Function} fn
 * @param {number} init
 * @return {number}
 */
var reduce = function(nums, fn, init) {
    let val = init;
    
    for (let i = 0; i < nums.length; i++) {
        val = fn(val, nums[i])
    }
    
    return val;  
};
```

実行してみます。

無事にパスしました :congratulations: 
![CleanShot 2024-07-08 at 22.42.58@2x.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/592040/b53411f5-eec2-0d6a-f26c-ceb6a0e63c38.jpeg)
コードレビューを徹底する：スクラム開発での成功体験から学ぶ


## はじめに

こんにちは、皆さん。今回は、スクラム開発における「コードレビューを徹底する」ことの重要性についてお話ししたいと思います。私自身、これまで数多くのプロジェクトでコードレビューを実施してきましたが、その経験から得た知見を共有したいと思います。

## コードレビューの重要性

### 品質向上

コードレビューは、ソフトウェアの品質を向上させるための最も効果的な手段の一つです。レビューを通じて、バグや潜在的な問題を早期に発見することができます。これにより、後々の修正コストを大幅に削減することができます。

### 知識の共有

コードレビューは、チーム内での知識の共有にも大いに役立ちます。異なる視点からのフィードバックを受けることで、新しい技術やベストプラクティスを学ぶことができます。また、レビューを通じて、チーム全体のコードスタイルや設計方針を統一することができます。

### コードの一貫性

コードレビューを徹底することで、コードの一貫性を保つことができます。これにより、コードベースが読みやすく、保守しやすくなります。特に大規模なプロジェクトでは、コードの一貫性が非常に重要です。

## コードレビューのベストプラクティス

### 明確なガイドラインを設定する

コードレビューを効果的に行うためには、明確なガイドラインを設定することが重要です。ガイドラインには、コードスタイル、命名規則、テストの書き方などを含めると良いでしょう。これにより、レビューの基準が明確になり、効率的にレビューを進めることができます。

### 小さなプルリクエストを心がける

大きなプルリクエストは、レビューに時間がかかり、見落としが発生しやすくなります。小さなプルリクエストを心がけることで、レビューが迅速に行われ、フィードバックも得やすくなります。

### 自動化ツールの活用

LintやCI/CDツールを活用することで、コードレビューの一部を自動化することができます。これにより、レビューの負担を軽減し、より重要な部分に集中することができます。

## コードレビューの実践例

### 事例1: バグの早期発見

あるプロジェクトでは、コードレビューを徹底することで、リリース前に重大なバグを発見することができました。レビューを通じて、複数の視点からコードをチェックすることで、見落としがちなバグを早期に発見することができました。

### 事例2: チームのスキル向上

別のプロジェクトでは、コードレビューを通じてチーム全体のスキルが向上しました。レビューを通じて、ベテランエンジニアからのフィードバックを受けることで、新人エンジニアも急速に成長することができました。

## まとめ

コードレビューを徹底することは、スクラム開発において非常に重要です。品質向上、知識の共有、コードの一貫性など、多くのメリットがあります。明確なガイドラインの設定、小さなプルリクエストの心がけ、自動化ツールの活用など、ベストプラクティスを取り入れることで、効果的なコードレビューを実現しましょう。

皆さんも、ぜひコードレビューを徹底して、より良いソフトウェアを作り上げてください。
Arduinoを使った5CH信号生成の実装方法

Arduinoを使って、5つのチャンネル（CH0からCH4）の信号を生成するコードについて解説します。このプロジェクトは、基準信号（CH0）と4つの制御機器（CH1〜CH4）を制御するためのもので、シンプルながらも実用的なタイミング制御の例となります。

## 概要

このコードは、以下の機能を実現します：
- 基準信号（CH0）を生成
- 4つの異なる制御機器（CH1〜CH4）のオン・オフを制御

各チャンネルのピンは次のように定義されています：
- `CH0`: 基準信号用ピン
- `CH1`: 制御機器1用ピン
- `CH2`: 制御機器2用ピン
- `CH3`: 制御機器3用ピン
- `CH4`: 制御機器4用ピン

## コードの詳細

### ピンの設定

最初に、各チャンネルのピンを定義し、`setup`関数内でこれらを出力モードに設定します。

```cpp
const int CH0 = 13;  // 基準信号用ピン
const int CH1 = 12;  // 制御機器1用ピン
const int CH2 = 4;  // 制御機器2用ピン
const int CH3 = 5;  // 制御機器3用ピン
const int CH4 = 6;  // 制御機器4用ピン

void setup() {
  pinMode(CH0, OUTPUT);
  pinMode(CH1, OUTPUT);
  pinMode(CH2, OUTPUT);
  pinMode(CH3, OUTPUT);
  pinMode(CH4, OUTPUT);
}
```

### 信号生成のループ

`loop`関数では、各スロットに対して以下の順序で信号を生成します：
1. 制御機器チャンネルのオン
2. 基準信号のオン
3. 基準信号のオフ
4. 制御機器チャンネルのオフ

```cpp
void loop() {
  for (int slot = 0; slot < 4; slot++) {
    
    // 制御機器チャンネルのオン
    if (slot == 0) digitalWrite(CH1, HIGH);
    if (slot == 1) digitalWrite(CH2, HIGH);
    if (slot == 2) digitalWrite(CH3, HIGH);
    if (slot == 3) digitalWrite(CH4, HIGH);
    
    // 基準信号のオン待機
    delayMicroseconds(20);      
    
    // 基準信号のオン
    digitalWrite(CH0, HIGH);
    delayMicroseconds(100);
    // 基準信号のオフ
    digitalWrite(CH0, LOW);

    // 制御機器チャンネルのオフ待機
    delayMicroseconds(20);

    // 制御機器チャンネルのオフ
    if (slot == 0) digitalWrite(CH1, LOW);
    if (slot == 1) digitalWrite(CH2, LOW);
    if (slot == 2) digitalWrite(CH3, LOW);
    if (slot == 3) digitalWrite(CH4, LOW);

    // スロットの残り時間を待機
    delayMicroseconds(30);
  }
}
```


### 実行結果
CH0　（オシロスコープではCH1)　とCH1(オシロスコープではCH2）の波形

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/208980/f4d56651-ee33-b6f3-50b0-f31621939ab3.png)

全体コード
```cpp
const int CH0 = 13;  // カメラシャッター用ピン
const int CH1 = 12;  // 照明1用ピン
const int CH2 = 4;  // 照明2用ピン
const int CH3 = 5;  // 照明3用ピン
const int CH4 = 6;  // 照明4用ピン

void setup() {
  pinMode(CH0, OUTPUT);
  pinMode(CH1, OUTPUT);
  pinMode(CH2, OUTPUT);
  pinMode(CH3, OUTPUT);
  pinMode(CH4, OUTPUT);
}


void loop() {
  for (int slot = 0; slot < 4; slot++) {
    
    // Light CH1~4 watit
    // delayMicroseconds(10);
    
    if (slot == 0) digitalWrite(CH1, HIGH);
    if (slot == 1) digitalWrite(CH2, HIGH);
    if (slot == 2) digitalWrite(CH3, HIGH);
    if (slot == 3) digitalWrite(CH4, HIGH);
    
    // Cam CH0 wait
    delayMicroseconds(20);      
    
     // CH0をHighに設定
    digitalWrite(CH0, HIGH);
    // CH0の残りのON時間
    delayMicroseconds(100);
    // CH0をLOWに設定
    digitalWrite(CH0, LOW);

    // 照明チャンネルの残りのON時間
    delayMicroseconds(20);

    // アクティブな照明チャンネルをLOWに設定
    if (slot == 0) digitalWrite(CH1, LOW);
    if (slot == 1) digitalWrite(CH2, LOW);
    if (slot == 2) digitalWrite(CH3, LOW);
    if (slot == 3) digitalWrite(CH4, LOW);

    // スロットの残り時間を待機
    delayMicroseconds(30);
  }
}


```

## 結論

このコードは、Arduinoを使って複数のチャンネルの信号を制御する基本的な方法を示しています。基準信号と複数の制御機器を同期して制御することで、様々な応用が可能です。Arduinoの出力ピンを適切に設定し、タイミング制御を工夫することで、多様な信号制御が実現できます。
スクラム開発で依存関係を定期的に更新する重要性とその方法


## はじめに

スクラム開発において、依存関係の管理は非常に重要です。特に、クラウドベンダーのサービスを活用する場合、依存関係の更新を怠ると、セキュリティリスクやパフォーマンスの低下、さらにはプロジェクト全体の遅延につながることがあります。この記事では、依存関係を定期的に更新する重要性とその具体的な方法について解説します。

## 依存関係を定期的に更新する重要性

### セキュリティリスクの軽減

依存関係の中には、セキュリティホールが発見されることがあります。これを放置すると、攻撃者に悪用されるリスクが高まります。定期的に依存関係を更新することで、最新のセキュリティパッチを適用し、リスクを最小限に抑えることができます。

### パフォーマンスの向上

新しいバージョンのライブラリやフレームワークは、しばしばパフォーマンスの改善が含まれています。これにより、アプリケーションのレスポンスが向上し、ユーザーエクスペリエンスが向上します。

### 技術的負債の削減

古い依存関係を放置すると、技術的負債が蓄積されます。これにより、新しい機能の追加やバグ修正が困難になることがあります。定期的に依存関係を更新することで、技術的負債を削減し、プロジェクトの健全性を保つことができます。

## 依存関係を更新する具体的な方法

### 自動化ツールの活用

依存関係の更新を手動で行うのは手間がかかります。そこで、自動化ツールを活用することをお勧めします。例えば、GitHubのDependabotやGitLabのDependency Scanningなどのツールを使用すると、自動的に依存関係の更新を提案してくれます。

### 定期的なスプリントレビュー

スクラム開発では、スプリントレビューを定期的に行います。このタイミングで依存関係の更新状況を確認し、必要に応じて更新作業を行うことができます。これにより、依存関係の更新をプロジェクトの一部として組み込むことができます。

### テストの自動化

依存関係を更新する際には、アプリケーションが正常に動作するかどうかを確認する必要があります。テストの自動化を行うことで、更新後の動作確認を迅速に行うことができます。CI/CDパイプラインにテストを組み込むことで、依存関係の更新がスムーズに行えるようになります。

## まとめ

依存関係を定期的に更新することは、セキュリティリスクの軽減、パフォーマンスの向上、技術的負債の削減といった多くのメリットがあります。自動化ツールの活用や定期的なスプリントレビュー、テストの自動化を通じて、依存関係の更新をプロジェクトの一部として組み込むことが重要です。これにより、スクラム開発のプロジェクトがより健全で効率的に進行することが期待できます。

ぜひ、皆さんのプロジェクトでも依存関係の定期的な更新を実践してみてください。
スクラム開発での障害予測: クラウドサービスを活用したアプローチ


## はじめに

スクラム開発において、障害予測は非常に重要なテーマです。特にクラウドベンダーの多様なサービスを活用することで、障害予測の精度を高めることができます。本記事では、クラウドサービスを活用した障害予測の方法について詳しく解説します。

## 障害予測の重要性

障害予測は、システムの安定性を保つために欠かせない要素です。予測ができれば、事前に対策を講じることができ、ダウンタイムを最小限に抑えることができます。特にスクラム開発では、短期間でのリリースが求められるため、障害予測の精度がプロジェクトの成功に直結します。

## クラウドサービスの活用

### 1. モニタリングツール

クラウドベンダーが提供するモニタリングツールを活用することで、リアルタイムでシステムの状態を監視できます。例えば、AWSのCloudWatchやAzureのMonitorを使用することで、CPU使用率やメモリ使用量、ディスクI/Oなどのメトリクスを収集し、異常を検知することができます。

### 2. ログ分析

ログデータは障害予測において非常に重要な情報源です。クラウドベンダーのログ管理サービス（AWSのCloudTrailやAzureのLog Analyticsなど）を使用することで、ログデータを一元管理し、異常なパターンを検出することができます。

### 3. 機械学習

クラウドベンダーが提供する機械学習サービスを活用することで、過去のデータから障害のパターンを学習し、将来の障害を予測することができます。例えば、AWSのSageMakerやGoogle CloudのAutoMLを使用することで、簡単に機械学習モデルを構築し、障害予測に役立てることができます。

## 実際の導入事例

### 事例1: Eコマースサイト

あるEコマースサイトでは、AWSのCloudWatchとSageMakerを組み合わせて障害予測を行っています。CloudWatchで収集したメトリクスデータをSageMakerで分析し、異常なパターンを検出することで、事前に対策を講じることができました。

### 事例2: 金融機関

ある金融機関では、AzureのMonitorとLog Analyticsを使用してシステムの状態を監視しています。ログデータを分析することで、トランザクションの異常を早期に検出し、迅速に対応することができました。

## まとめ

クラウドサービスを活用することで、障害予測の精度を高めることができます。モニタリングツール、ログ分析、機械学習など、さまざまなサービスを組み合わせることで、より効果的な障害予測が可能になります。スクラム開発においても、これらのツールを活用することで、プロジェクトの成功率を高めることができるでしょう。

## 参考リンク

- [AWS CloudWatch](https://aws.amazon.com/jp/cloudwatch/)
- [Azure Monitor](https://azure.microsoft.com/ja-jp/services/monitor/)
- [Google Cloud AutoML](https://cloud.google.com/automl)
Webサイトの表示画像をWebPにするメリットとその効果

:::note warn
この記事では、画像表示をWebPに切り替えた動機とメリット、その結果Webサイトのパフォーマンスがどのように変化したかについてのみ記述しています。WebPの導入方法についての解説は含まれていませんので、ご注意ください。 by深尾
:::

## そろそろWebPを導入してみたい

IEことInternet Explorerのサポートが完全に終了したことで、フォールバック画像を設定せずにWebPを使用できるか[Can I use](https://caniuse.com/webp)で確認したところ、問題なく使えることが分かりました。ついにこの時が来たと、早速WebPの導入を決めました。

![スクリーンショット 2024-07-07 23.26.04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3831928/73f30948-cabb-e71b-42ac-a4aa60ec3706.png)

## WebP導入のメリット

WebPを導入するメリットは多岐に渡りますが、わかりやすいのは以下の三つです。

1. 画像容量をJPEG,PNG形式よりも20%〜30%削減しつつ同等の画質を保てる
1. ロスレス圧縮だけでなくロッシー圧縮にも対応
1. PNGのように背景の透過処理ができ、GIFのようなアニメーションにも対応

## 導入後のパフォーマンスは？

以下は、私の[ポートフォリオサイト](https://fukao-desu.com)の画像をWebPに切り替えた後のPage Speed Insightsの結果です。スマホ版に関してはお恥ずかしながら78点と決して良いスコアとは言えませんが、スマホ版とデスクトップ版のパフォーマンススコアは共に導入前より5ポイントずつ上昇しました。

![スクリーンショット 2024-07-08 17.36.45.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3831928/152748c8-80fb-a055-f90d-1eff0292bf05.png)

![スクリーンショット 2024-07-08 17.36.59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3831928/6596d1ed-19a6-76d7-0b84-fcd43b989a8a.png)

## まとめ

今回は「Webサイトの表示画像をWebPにするメリットとその効果」について書かせていただきましたが、ちょっと変換作業を行うだけで、パフォーマンスが5ポイント上昇するのならばやる価値があるのではないでしょうか？私のこの結果を1サンプルとしてWebP導入のご検討にご利用いただけますと幸いです。
ABC361Fを解いた

筆者はレート600前後の茶色コーダ

この前開催されたABC361で解けなかった以下の問題を解いていく

https://atcoder.jp/contests/abc361/tasks/abc361_f

# 実装コード

2番目の解説の方針に従い、$b=2$は計算で求め$b \ge 3$以降を全探索的な感じに調べる
$b = [3,60)$ の区間で $a^b$ の値を計算し、$N$より大きくなったら$b$を1増やして最初から、
求めた$a^b$が何らかの数字$c$で$c^2$と表記できない場合は数えるようにして。
区間内の計算が終わったら計算で求めた$b=2$の個数と$b = [3,60)$で探索した結果を合算すればOK

$c^2$で表現できるか確かめる方法は平方根の小数点以下切り捨てで計算した整数値の2乗が元の値になるかで調べるみたい。
その時の平方根は解説の実装ではニュートン法?を使っているっぽい。

```python
import sys
def rI(): return int(sys.stdin.readline().rstrip())
def rLI(): return list(map(int,sys.stdin.readline().rstrip().split()))
def rS(): return sys.stdin.readline().rstrip()
def rLS(): return list(sys.stdin.readline().rstrip().split())
def err(*args, end="\n"): print(*args,end=end, file=sys.stderr)

def sqrt_floor(x):
    l = 0
    r = 2000000000
    while l <= r:
        t = (l + r) // 2
        if t * t > x:
            r = t - 1
        else:
            l = t + 1
    return r

def main():
    N = rI()
    S = set()
    for i in range(3,60):
        for j in range(2,N):
            k = pow(j,i)
            if k > N:
                break
            x = sqrt_floor(k)
            if x**2 != k:
                S |= {k}
    print(len(S)+sqrt_floor(N))
if __name__ == '__main__':
    main()
```

# まとめ
ABC361Fを解いた。
平方根を用いた探索と、ニュートン法を使用した平方根の計算アルゴリズムを実装した

# 感想

今回解いた問題は求める内容こそ単純だが、解法は数学の知識が必要で、簡単に解けそうで難しい問題だった。
このような問題を解けるようして、ABCの記録を伸ばせるようになりたい。
Microsoft Store本体をぶっ壊してしまった際の備忘録

WindowsAppsフォルダの権限やら所有権を弄りすぎて整合性が壊れたのか、
MicrosoftStoreが起動しなくなったが、何とか修復できたようなので備忘録として残します。
WindowsAppsフォルダの一部を削除したのが原因ですが、バックアップしていたので助かりました。

・試したこと
 1. システム修復コマンド系 → 解消せず
 2. ローカルユーザーを作成し治るか → 解消せず
 3. https://windows-waza.com/windows-10-i-cant-find-the-microsoft-store/ を参考にPowerShellでhogehoge. → 解決

システムインストールされているアプリケーションのリスト取得し、Microsoft.WindowsStoreのキーを探す。
```
Get-AppxPackage -allusers | Select Name, PackageFullName
```


キーを置き換えて実行
```
Add-appxpackage -register "C:\Program Files\WindowsApps\（コピーしたキー）\appxmanifest.xml" -disabledevelopmentmod
```

これで解決した。バックアップがないと無理かもしれない。
GitHub Projectでタスク管理してるからボード表示のカラムの種類を増やしたい

個人的「質はともかく継続する」31日目です。

## ボード表示のカラムをオリジナルにしたい

GitHub Projectのボード表示って便利ですよね。
カンバン方式で、Todoの状況をみたりできます。
私は普段、GitHub Projectでタスクを管理しているのですが、
カラムの種類がちょっと足りないなぁと思いませんか？

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/45303/5d46b242-c229-702b-b5b8-0a1b4a9ef763.png)

Status,Priority,Size,Iteration...
圧倒的に足りないですよね。
複数の案件に関わっているときに、いまどの案件のタスクが残っているのか
確認したいなぁ、というときにちょっと不便です。
初めはSizeの項目名を変えて使っていたのですが、
最近、追加する方法がわかったので、同じように困っている人に向けての記事です。

### 設定から追加するだけ

とても簡単でした、プロジェクトの設定から追加するだけ。
プロジェクトの右上から「Settings」を選択します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/45303/3fd2a2ce-4bc8-adfe-d017-3b2fd1d99986.png)

右側中央にある　「+ New Field」 を選択。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/45303/3ca0de38-c243-7e76-34a6-f0c09ff9de96.png)

追加したいカラム名を入れて、 「Single select」 を選びます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/45303/6892f101-5be6-0cbc-e440-ee2bdd17e77b.png)

追加したいオプションを追加して、　Saveします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/45303/134de5d8-c6b6-1a59-0a00-7b9e12c1e193.png)

New Field ７　が追加されました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/45303/6468fdf2-d67e-accb-1fda-9b80df7e4a9b.png)

ボードに移動して、カラムから　NewField7 を選びます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/45303/88944e17-c174-2150-0388-1bd153a6c7d5.png)

ボードのカラムがNew Field7になりました！（もっとマシな名前にすればよかった
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/45303/86161ed7-0717-fc89-186f-293d4a011a1a.png)

それぞれのオプションは、右上の ... から編集画面に移動し、
色をつけたり説明をつけたり編集できます。お好みに。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/45303/e9d48cd1-bbc0-608c-27ae-a7245b299884.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/45303/6f418283-7e9f-6a22-7fa7-b29e2cb0f4d0.png)

## まとめ

最近、タスクの管理をGitHubでやっています。
MSのTodoやPlanner,TodistやTrelloやら色々と試したものの、
どれもしっくりこず。
Notionがかなり良かったのですが、会社が契約していないので
セキュリティ的に細かい情報は載せられないという問題があり、
どうしようかなぁ...と、途方に暮れていたところ、
GitHubと契約した！ということだったので、
GitHubでのタスク管理をしていくことになりました。
Notionのほうが何かとまとめられていいのですが、
セキュリティの問題を出されると断念です。
GitHubでのタスク管理も悪くないので、
しばらくこれでやっていこうと思います。
とっても簡単！Viteで環境ごとに設定を分ける方法

## はじめに
ビルドする環境によって、設定する環境変数を変えたいというのはよくあることです。

本番環境が`production`、開発環境が`development`と大まかには分かれていますが、他にも`staging`であったり、他にもいろいろな環境があるかと思います。

Viteを使ってそれらすべての環境に別々の環境変数を設定する方法を紹介します。

## 設定方法
2ステップで簡単に対応できます。

### .envファイルを用意する
設定したい環境に合わせた`.env`ファイルを用意します。
ファイル名は以下のように設定します。
`.env.環境名`

例えば、`production`用であれば
`.env.production`
となります。

### コマンド実行時にmodeを指定する
`vite`または`vite build`のいずれにおいても、以下のオプションを設定します。
`--mode 環境名`

例えば、`production`用であれば
`vite build --mode production`
となります。

### 挙動を確認する
実際に環境別に設定した変数を使用するとどうなるのかを確認します。

3つの環境変数を用意しました。
「.env」、「.env.test」、「.env.development」です。

```properties:.env
VITE_URL=env_url
VITE_ENV=env
```

```properties:.env.test
VITE_URL=test_url
VITE_TEST=test
```

```properties:.env.development
VITE_DEV=development
```

また、環境変数は以下の通り利用します。
```react:App.tsx
const App = () => {
  return (
    <>
      <h3>VITE_URL : {import.meta.env.VITE_URL}</h3>
      <h3>VITE_ENV : {import.meta.env.VITE_ENV}</h3>
      <h3>VITE_TEST : {import.meta.env.VITE_TEST}</h3>
      <h3>VITE_DEV : {import.meta.env.VITE_DEV}</h3>
    </>
  );
};

export default App;
```

以下のコマンドを実行します
```bash
npx vite --mode test
```

実行結果は次のようになります。

<img width='60%' src='https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/251137/96f70ca7-3380-b3fe-fce4-511cda1de3b3.png'>

この実行結果から、以下のことがわかります。
* `.env`ファイルは常に読み込まれる
→`VITE_ENV`が読み込まれている
* `.env`と`.env.環境名`のファイルで変数が競合する場合、`.env.環境名`が優先される
→`VITE_URL`が競合している
* 存在しない環境変数を指定してもエラーにならない
→`.env.development`は読み込まれないため、`VITE_DEV`は存在しないが、エラーになっていない

このように、全環境で共通して読み込みたい環境変数は`.env`に、個別に設定したい変数は環境ごとに設定することで、個別に柔軟な設定をすることができます。

## まとめ
今回は環境ごとにViteで設定を用意する方法を確認しました。
Viteの環境変数にはもっと他にもルールが有るのですが、それはまた別の機会に紹介します。
[Dify]テーブルを解説してくれるチャットフローを作ろう

## はじめに

どうもやまぐちです。
みなさん、Difyでも画像を読み込ませることができることをご存知でしたか？
画像読み込み機能を有効にする方法がわかりづらいので意外と知らない方もいると思います。
今回は画像読み込みの機能に関して設定方法を説明して、最終的にテーブルの解釈をLLMにやってもらうまでを解説しようと思います。

## Difyでチャットフローを作成する

今回の全体フローは以下です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/376115/98f6a387-bb86-9910-4b14-864e98dee2b5.png)

### 画像アップロード有効化
まずですが、画像アップロード機能を有効にしましょう。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/376115/d37a9ef2-b182-cf1e-228e-736db1d61885.png)

### チャットフロー詳細説明

LLMでの設定として、ビジョン機能を有効にしておいてください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/376115/f7863a6d-5752-c5ed-4681-63a5549691a6.png)

そしてモデルに関してはビジョン機能を持っているものを選択してください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/376115/ed865be8-86ca-4759-8b95-cd8077e73bc0.png)

これで完成です。


## 結果

以下の論文に出てくるTable１を読み込ませて見ました。

https://arxiv.org/pdf/2401.15884

![スクリーンショット 2024-07-08 13.24.19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/376115/0f228efe-4491-f656-d104-6dcf895546e8.png)
(https://arxiv.org/pdf/2401.15884)

こんな感じです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/376115/c963c5fb-f27b-9155-1b3f-29879da0dad6.png)


詳細な出力はこちら↓

```
この表は、いくつかの言語モデル（LMs）およびベースラインモデルの性能を異なるデータセット上で比較したものです。具体的には、PopQA、Bio、Pub、ARCの4つのデータセットにおける精度（Accuracy）やFactScoreの値が示されています。

LMs trained with propriety data:

LLama2-C13B: PopQA 20.0, Bio 55.9, Pub 49.4, ARC 38.4
Ret-LLama2-C13B: PopQA 51.8, Bio 79.9, Pub 56.1, ARC 37.9
ChatGPT: PopQA 29.3, Bio 71.8, Pub 50.1, ARC 75.3
Ret-ChatGPT: PopQA 50.8, Bio 54.7, Pub 75.3
Perplexity.ai: Bio 71.2
Baselines without retrieval:

LLama2-7B: PopQA 14.7, Bio 44.5, Pub 34.2, ARC 21.8
Alpaca7B: PopQA 23.6, Bio 45.8, Pub 49.8, ARC 45.0
LLama2-13B: PopQA 14.7, Bio 53.4, Pub 29.4, ARC 29.4
Alpaca13B: PopQA 24.4, Bio 50.2, Pub 55.5, ARC 54.9
CoVE65B: Bio 71.2
Baselines with retrieval:

LLama2-7B: PopQA 38.2, Bio 78.0, Pub 30.0, ARC 47.8
Alpaca7B: PopQA 46.7, Bio 76.6, Pub 40.2, ARC 48.0
SAIL: PopQA 45.7, Bio 77.5, Pub 47.2, ARC 48.4
LLama2-13B: PopQA 45.7, Bio 77.5, Pub 47.2, ARC 48.4
Alpaca13B: PopQA 46.1, Bio 77.1, Pub 51.1, ARC 57.6
LLama2-7B: RAG PopQA 37.7, Bio 44.9, Pub 9.1, ARC 23.8
CRAG: PopQA 39.8, Bio 47.7, Pub 9.1, ARC 28.1
Self-RAG*: PopQA 29.0, Bio 32.2, Pub, ARC
Self-CRAG: PopQA 49.0, Bio 59.1, Pub 40.0, ARC 39.0
SelfRAG-LLama2-7b: RAG PopQA 40.3, Bio 59.2, Pub 39.0, ARC 39.0
CRAG: PopQA 59.3, Bio 74.1, Pub 56.7, ARC 54.8
Self-RAG: PopQA 49.0, Bio 56.1, Pub 44.1, ARC 67.2
Self-CRAG: PopQA 61.8, Bio 86.2, Pub 74.4, ARC 67.2
この表から、Self-CRAGが多くのデータセットで高い精度を示していることがわかります。
特に、PopQA、Bio、Pub、ARCのすべてのデータセットで高い値を示しています。
```

まあまあいい感じですね。これは普通にChatGPTとかでもできるので凄さはないのですが、Difyで画像読み込みが使えることはできる幅が広がりますね！


## 最後に

Xをやっているので気になる方はフォローお願いします。

https://x.com/hudebakonosoto
[Dify]ローカルDifyでPhi3をOllama経由で使用する。

## はじめに
DifyでローカルLLMを使おうとした時に少し詰まったので記録用に書きます。


## Ollamaでphi3-miniを準備する。
まずは以下からOllama をダウンロードしましょう。

https://ollama.ai/download 

次にphi3-miniをOllamaで実行しましょう。
```
ollama run phi3:mini
```

これだけでphi3-miniがローカルで実行できるようになりました。

ただこれだけではローカルのOllamaとの通信ができないので以下を実行して設定しておきましょう。(Macで環境変数を設定)
```
launchctl setenv OLLAMA_HOST "0.0.0.0"
```

Ollama アプリケーションを再起動します。
※Mac以外の人は以下を参照してください。
https://docs.dify.ai/v/japanese/guides/model-configuration/ollama#faq

## Difyでの設定

以下の画面のように設定してください。
baseURLは`http://host.docker.internal:11434`に設定してください。

![スクリーンショット 2024-07-08 11.17.12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/376115/743225d4-b6ff-c3f6-5c73-e680773cfc09.png)

チャットではこんな感じで設定できます。
![スクリーンショット 2024-07-08 11.19.31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/376115/96ef3d93-1256-03bb-2378-91bd1db0af9f.png)

これでおしまいです。


## 最後に

Xやってるので気になる方はフォローお願いします。
https://x.com/hudebakonosoto
Debounce & Throttling

# Intro
JavaScriptはシングルスレッドです。そのため、画面に多くの処理が連続して表示される場合、画面が次第に遅くなり、ユーザーは画面が止まる不便さを経験することになります。一般的なDOMオブジェクトのイベントリスナーを実行する際、リサイズやインプットなどのイベントはわずかな状況でも継続的にリクエストを実行します。これを特別な対策なしで使用すると、画面に大きなパフォーマンスの問題が発生することがあります。

# Debounceとは何ですか？
特定の時間内にイベントが発生しない場合にロジックを実行します。

# Throttlingとは何ですか？
毎ミリ秒ごとに特定の時間間隔の後、最初のクリックだけを即座に実行します（特定の時間内のイベントは無視されます）。

# Sample Code
``` html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Debounce & Throttling</title>
</head>
<body>
    <h2>Debouncing </h2>
    <input class="searchBar" />
    <h2>Throttling </h2>
    <input class="searchBar2" />
<script>
    //debouncing ブラウザの性能向上のため、単一スレッドであるためよく使われる部分を減らす。 0.3秒間、inputイベントが発生しない場合は実行
    var searchBar = document.querySelector('.searchBar');
    var timer;
    searchBar.addEventListener('input',e =>{
        if(timer){
            clearTimeout(timer);
        }
        timer = setTimeout(()=>console.log('ajax call...',e.target.value),300);
    });

    //throttling
    //-> 毎ミリ秒ごとに特定時間間隔後に最初のクリックだけを直ちに実行させる。 （特定時間の間のイベントは無視する。 そのため、API call が減る。）
    var throttling_timer;
    var searchBar2 = document.querySelector('.searchBar2');
    searchBar2.addEventListener('input',e=>{
        if(!throttling_timer){
            throttling_timer = setTimeout(()=>{
                throttling_timer = null;
                console.log('ajax call.....', e.target.value);
            },300);
        }//既存のスロットリングタイマーが存在すると、ロジックを実行しない。 なければ0.3秒以後ロジックを遂行=>周期的に1回遂行する。
    });    

</script>
</body>
</html>
```

# Result Image
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3824062/790f3b68-d4fe-aefc-1d62-8de90c99dd13.png)

# Summary
簡単な内容ですが、実際にフロントエンド開発をしながらとても役に立つ部分です。 特に、共通コンポーネントを作成する際に、パフォーマンスの問題を減らすために上記の技術を使用しました。
【Outsystems】複数のPDFを結合したい JoinPDF

### 目的
Outsystemsで複数のPDFを結合したい

### この記事を届けたい人
・日本語でのサイトが少なく、苦戦していた過去のわたし
・過去のわたしと同じ状態になっている方

## 0.目次

1. [PDFHelperのインストール](#1-pdfhelperインストール)
2. [ロジックを作成](#2-ロジックを作成)
3. [画面側の設定](#3-画面側の設定)


## 1. PDFHelperインストール
「pdfhelper outsystems」で検索して上の方に出てくるサイトにPDFHelperをインストールする画面が出てくるので、右上の赤い``Install``ボタンをクリック。

https://www.outsystems.com/forge/component-overview/1819/pdf-helper-o11

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/852394/c697ac6f-e2b8-1815-8c01-de2e2bd535c0.png)

<br>

outsystems側でも``Install``ボタンをクリック。
下の画像のように``Install``ボタンの横にチェックが付いていたらOK

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/852394/516b0fff-d18d-890d-9ab5-5c1bd00f0972.png)

## 2. ロジックを作成


### ①使用するサーバーアクションとリソースを追加
**サーバーアクション**
コンセントマークをクリックして、pdfと検索。
サーバーアクションの``JoinPDF``とストラクチャの``PDFLIST``を選択し、Applyボタンをクリック

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/852394/b625b9b7-8c68-1825-00f9-debadece597d.png)

<br>

**リソース** 
Dataタブのリソースに結合したいリソースをインポートする。
今回は、「Sample1.pdf」「Sample2.pdf」

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/852394/adf16557-0d69-f49a-0ebc-485400201e4e.png)


<br>


### ②ロジック作成
**Logic** タブの **ServerActions** フォルダに「JoinPDFByPDFHelper」という名前のアクションを作る。
アウトパラメータに「JoinPdf」をBinaryData型で設定。
変数に「PDFLIST」をPDFLISTストラクチャList型で設定。


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/852394/b3d2774b-ad8f-9e25-797f-c73f9de7a851.png)


下の画像を参考に、各種項目を設定。

![SNkRZQ42VFxEt6i1720438191_1720438544.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/852394/00a08ce0-fca8-669a-6a6c-995c5a320e06.png)


<br>


## 3. 画面側の設定

「OnClickJoinPDFButton」のクライアントアクションを作成。

作成した「JoinPDFByPDFHelper」サーバーアクションを追加し、
EndをDownloadに変えて、作成するPDFファイル名を設定。

![w31uqdovuLAVUVm1720442585_1720442608.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/852394/525cebf6-5ad6-165b-2b1b-e68e6231fdeb.png)


<br>


画面にボタンをセットし、ボタンのOnClickイベントに「OnClickJoinPDFButton」を設定。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/852394/17580400-9bec-e2ed-a281-fa81cbdf0cec.png)


<br>


## 最後に

誰か一人でも役に立てればいいなって思ってます
【2024年版】うちのネットワーク環境まとめ（適宜更新）

この記事は、うちのネットワーク環境まとめです。
よく、環境とかわからなくなるので個人用のメモです。
2024年の環境は適宜この記事に更新予定。


# ネットワーク環境概要
某社インターネット環境の下にルーターで以下のような設定をして利用中。

# 環境概要図

インターネット
　└ルーター（デフォルトゲートウェイ：x.x.x.1、DHCP範囲:1～200）
　　├無線2.4GHz
  　　　→モバイル機器
　　　→家族利用機器
　　├無線5GHz 
　　　→モバイル機器
　　　→家族利用機器
　　└有線
  　　　├固定IP環境（201～255）
  　　　├サーバ（222）
   　　　　├仮想マシン（Bridge）
　　　　├仮想マシン（NAT）


# 今後こうしたい
・有線はもう1段ルータ入れたい。
　・家族環境と分離したい
　・自分の分のセキュリティの確保を制御したい
データの前処理: 正規化、正則化、標準化の比較と解説

機械学習やデータサイエンスでは、データの前処理が非常に重要です。その中でも似たような言葉である「正規化」「正則化」「標準化」について解説します。　それぞれ全く違う言葉で、比較すること自体おかしいかもしれませんが、個人的にまとめて覚えてしまったので、比較してみます。

---

# 正規化 (Normalization)

**目的**: データの範囲を一定にすること

**詳細**:
- データのスケールを統一することで、異なる尺度の特徴量を同等に扱えるようにします。
- 一般的には0から1の範囲、または-1から1の範囲にスケーリングします。
- 方法の例: 最小値最大値スケーリング (Min-Max Scaling)

$$  \[ X' = \frac{X - X_{\min}}{X_{\max} - X_{\min}} \]$$

**使用例**:
- 画像処理でピクセル値を0から1に正規化
- 機械学習モデルの入力データの前処理

---

# 正則化 (Regularization)

**目的**: モデルの過学習を防ぐこと

**詳細**:
- モデルが訓練データに過剰に適合しすぎないようにするための技術です。
- モデルの複雑さを抑えるために、損失関数にペナルティを追加します。
- 主な方法: L1正則化 (Lasso) と L2正則化 (Ridge)
  - **L1正則化**: 絶対値の和をペナルティとして追加
    $$\[ L = \sum (y_i - \hat{y}_i)^2 + \lambda \sum |w_i| \]$$
  - **L2正則化**: 二乗和をペナルティとして追加
   $$ \[ L = \sum (y_i - \hat{y}_i)^2 + \lambda \sum w_i^2 \]$$

**使用例**:
- 回帰モデルでの過学習防止
- ニューラルネットワークの重みの制約

---

# 標準化 (Standardization)

**目的**: データを標準正規分布に変換すること

**詳細**:
- データの平均を0、標準偏差を1にスケーリングします。
- 標準正規分布 (\( \mu = 0 \), \( \sigma = 1 \)) に従うように変換します。
- 方法の例: Zスコア標準化
  $$\[ X' = \frac{X - \mu}{\sigma} \]$$

**使用例**:
- 機械学習アルゴリズムの前処理
- 特にサポートベクターマシン (SVM) やK-平均クラスタリングなどで効果的

---

# 比較表

| **特徴**           | **正規化 (Normalization)**      | **正則化 (Regularization)**        | **標準化 (Standardization)**       |
|-----------------|-------------------------------|-------------------------------|-------------------------------|
| **目的**         | データ範囲の統一                   | モデルの過学習防止                  | データの平均と標準偏差の統一           |
| **スケーリング方法** | 0から1、または-1から1にスケーリング   | モデルの損失関数にペナルティを追加      | 平均0、標準偏差1に変換                 |
| **使用例**         | 画像処理、機械学習の前処理           | 回帰モデル、ニューラルネットワークの過学習防止 | 機械学習アルゴリズムの前処理、SVMやクラスタリング |
| **代表的な手法**     | 最小値最大値スケーリング              | L1正則化（Lasso）、L2正則化（Ridge） | Zスコア標準化                          |

---

データの前処理は機械学習モデルの性能や精度に大きな影響を与えます。それぞれの手法を適切に理解し、目的に応じて使い分けることが重要です。

---

この記事が、データ前処理の理解を深め、実際のプロジェクトでの適用に役立てば幸いです。
ReactでStoryBookを利用する(Dialogの中でAPI疎通する)

## はじめに
前回までの続きです。コンポーネントの中でAPI疎通をするのはしばしばなので、StoryBookでもできるかなと思い、テストしました。

https://qiita.com/koji0705/items/cf0f69af1235db161040

## 成果物
![dialog_api.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/599049/3183e4de-bb04-0cbe-bb91-9c6ccbde6ca1.gif)


```tsx:src/components/MyDialog.tsx
import type React from "react";
import { useState } from "react";
import Dialog from "@mui/material/Dialog";
import DialogActions from "@mui/material/DialogActions";
import DialogContent from "@mui/material/DialogContent";
import DialogContentText from "@mui/material/DialogContentText";
import DialogTitle from "@mui/material/DialogTitle";
import Button from "@mui/material/Button";

type Props = {
	open: boolean;
	onClose: () => void;
};

const MyDialog: React.FC<Props> = ({ open, onClose }) => {
	const [loading, setLoading] = useState(false);
	const [data, setData] = useState<string | null>(null);
	const [error, setError] = useState<string | null>(null);

	const fetchData = () => {
		setLoading(true);
		setData(null);
		setError(null);
		fetch("https://jsonplaceholder.typicode.com/posts/1")
			.then((response) => response.json())
			.then((data) => {
				setLoading(false);
				setData(data.title); // Assuming we want to display the title of the post
			})
			.catch((error) => {
				setLoading(false);
				setError("Failed to fetch data");
			});
	};

	return (
		<Dialog open={open} onClose={onClose}>
			<DialogTitle>Dialog Title</DialogTitle>
			<DialogContent>
				{loading && <DialogContentText>Loading...</DialogContentText>}
				{error && <DialogContentText>{error}</DialogContentText>}
				{data && <DialogContentText>{data}</DialogContentText>}
				{!loading && !data && !error && (
					<DialogContentText>Click the button to fetch data.</DialogContentText>
				)}
			</DialogContent>
			<DialogActions>
				<Button onClick={onClose}>Close</Button>
				<Button onClick={fetchData} variant="contained" color="primary">
					Fetch Data
				</Button>
			</DialogActions>
		</Dialog>
	);
};

export default MyDialog;
```

```tsx:src/components/MyDialog.stories.tsx
import React from "react";
import type { Meta, StoryObj } from "@storybook/react";
import MyDialog from "./MyDialog";

const meta: Meta<typeof MyDialog> = {
	title: "Example/MyDialog",
	component: MyDialog,
	args: {
		open: true,
		onClose: () => alert("Dialog closed!"),
	},
};

export default meta;

type Story = StoryObj<typeof MyDialog>;

export const Primary: Story = {};
```

:::note info
StoryBookは結構色々できるのですね。
フロント全体をレンダリングすると表示するのに時間がかかったりします。
StoryBookだと早くていいですね！！
:::
[CDK For Terraform]既存のSubnet情報を利用する

# 既存のSubnet情報を読み込んで利用する

VPCのSubnetを別手法で作成済みでIaCでは管理していないが
利用したい場合についてです。

data resourceを利用すればOKなのですが、
CDK for Terraformではどのように記述するのかを記載します。


## サンプルコード

```typescript
	// Subnet ID Get
	const subnets = new aws.dataAwsSubnets.DataAwsSubnets(scope, `subnets-${id}`, {
		filter: [
			{
				name: "tag:Name",
				values: [`sample-private-subnet`]
			}
		]
	})
```

`sample-private-subnet`という名称のSubnet情報をリスト型で *全て* 取得します。


## 実際の指定方法

Lambdaでサブネットを指定する場合は以下のように記述します。

```typescript
	// Lambda
	new Lambda(scope, `lambda-${id}`, {
		functionName: `sample-lambda`,
		description: "Lambda Function",
		handler: "index.lambda_handler",
		runtime: "python3.12",
		sourcePath: sourcePath,
		attachPolicies: true,
		architectures: ["arm64"],
		publish: true, // Versionを作成する
		policies: [
			"arn:aws:iam::aws:policy/AdministratorAccess" // iam:DetachRolePolicyアクションを実行権限が必要になるため、AdministratorAccessを付与
		],
		numberOfPolicies: 1,
		environmentVariables: {
		},
		createCurrentVersionAllowedTriggers: false,  // Latest Version に対してのみトリガーはエラーになるため無効
		triggerOnPackageTimestamp: false, // パッケージのタイムスタンプによるトリガーを無効化
		layers: [
			"arn:aws:lambda:ap-northeast-1:133490724326:layer:AWS-Parameters-and-Secrets-Lambda-Extension-Arm64:11" // キャッシュあんど高速化のため追加
		],
		vpcSecurityGroupIds: [securityGroupWeb.id],
		vpcSubnetIds: subnets.ids
	});
  ```


## 簡単な解説

`sample-private-subnet` というNameタグが付与されている
Subnetを設定しています。

IaCで管理していないため`sample-private-subnet`のサブネットを
別で削除してしまったりした場合はエラーになりますので、
ご注意ください。

一つだけ取得したい場合は`DataAwsSubnet`を利用してください。

https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/subnet?lang=typescript
【PHP】マルチバイト文字をバイト数を指定して取得する場合は、mb_strcut()を使うと良い

## はじめに

業務でマルチバイト文字をバイト数を指定して取得する機会があり、そのときバイトの関係で文字化けしてしまったので、調査した結果を書いておきます。

## コード
```test.php
<?php
$input = "こんにちは";

// mb_strcut()を使用する例
$cut1 = mb_strcut($input, 0, 7, "UTF-8"); // 7バイトまで切り取る
$cut2 = mb_strcut($input, 0, 6, "UTF-8"); // 6バイトまで切り取る
$cut3 = mb_strcut($input, 0, 5, "UTF-8"); // 5バイトまで切り取る

// substr()を使用する例
$substr1 = substr($input, 0, 7); // 7バイトまで切り取る
$substr2 = substr($input, 0, 6); // 6バイトまで切り取る
$substr3 = substr($input, 0, 5); // 5バイトまで切り取る

// 結果を出力
echo "mb_strcut (7 bytes): " . $cut1 . "\n";
echo "mb_strcut (6 bytes): " . $cut2 . "\n";
echo "mb_strcut (5 bytes): " . $cut3 . "\n";

echo "substr (7 bytes): " . $substr1 . "\n";
echo "substr (6 bytes): " . $substr2 . "\n";
echo "substr (5 bytes): " . $substr3 . "\n";
```

## 動かしてみる

mb_strcut()を使うと、バイトのきりの良い所で文字を取得してくれるため文字化けしていません。
substr()の場合は、指定したバイト数まで取得しているため、文字化けする可能性があります。

```
php test.php 

mb_strcut (7 bytes): こん
mb_strcut (6 bytes): こん
mb_strcut (5 bytes): こ
substr (7 bytes): こん�
substr (6 bytes): こん
substr (5 bytes): こ�
```
よく使うエスケープシーケンス一覧

# この記事を書いたきっかけ
Pythonの勉強をしていると、ごくたまにエスケープシーケンスの出番があります。「printで出力するこの文字列を改行したい」とか、「文字列の中に"(ダブルクォート)入れたい」とか、頻繁にエスケープシーケンスを使うわけではないので、ついついその書き方を忘れてしまいます。

忘れてしまうたびに毎回調べるのは面倒なので、使う可能性の高いエスケープシーケンスを一覧にしました。この記事を見て、思い出すようにしようと思います。

あと、バックスラッシュの入力方法もよく忘れるので、それもここに書いておきます。
- Macのバックスラッシュキーは**Optionキーを押しながら「¥」キー**を押します。
- Windowsのバックスラッシュキーは「ろ」の位置にあります。

# よく使うエスケープシーケンス一覧
| 名前 | ES|
|:-|:-:|
|  改行 | \n  |
| キャリッジリターン  |  \r  |
|  タブ  | \t  |
| バックスラッシュ  | \\\  |
|  シングルクォート |  \\'  |
| ダブルクォート   | \\"  |
|  バックスペース  |  \b |


エスケープシーケンスとは、特定の文字を表現するために使用される文字列のことです。バックスラッシュ（\）で始まり、その後に特定の文字や数字が続きます。エスケープシーケンスは、特定の制御文字や特殊文字を文字列内で表現する際に使用されます。
1. 制御文字の表現
改行、タブ、バックスペースなどの制御文字を文字列内で表現するために使用されます。例えば、n（改行）、\t（タブ）など。
2. 特殊文字の表現
通常の方法では文字列に含めることができない特殊文字を表現するために使用されます。例えば、\\（バックスラッシュ）、\"（ダブルクォート）など。
3. 制御シーケンス
特定の動作を実行するためのシーケンスです。例えば、ベル（警告音）を鳴らすための \a や、カーソルを行の先頭に戻すための \r など。


# よく使うエスケープシーケンス詳細
### 改行: \n
**使用タイミング**: テキストを複数行に分割して表示したいとき
**例**: ログメッセージの書き出し、テキストファイルの生成

**\n は "newline" の略で、新しい行を開始する**という意味があります。
```python
print("Hello\nWorld")
# 出力:
# Hello
# World
```
### キャリッジリターン: \r
キャリッジリターン（Carriage Return）とは、テキスト表示やプリンタの動作に関する制御文字の一つで、行の先頭に戻る動作を指します。

**使用タイミング**: 行の先頭に戻り、次の文字で上書きする場合
**例**: プログレスバーの表示、リアルタイムのコンソール出力

```python
print("Hello\rWorld")
# 出力:
# World
```
### タブ: \t

HelloとWorldの間にタブが挿入されます。

**使用タイミング**: テキストをタブで整形したいとき
**例**: 表形式のデータの表示、整形されたログ出力
```python
print("Hello\tWorld")
# 出力:
# Hello   World
```

### バックスラッシュ: \\\
**使用タイミング**: バックスラッシュ自体を文字列内で表示したいとき
**例**: ファイルパスの表示、正規表現の使用
```python
print("This is a backslash: \\")
# 出力:
# This is a backslash: \
```
### シングルクォート: \\'
**使用タイミング**: シングルクォートを含む文字列をシングルクォートで囲むとき
**例**: 会話文の表示、文字列内のシングルクォートを表現

```python
print('It\'s a book')
# 出力:
# It's a book
```
### ダブルクォート: \\"
**使用タイミング**: ダブルクォートを含む文字列をダブルクォートで囲むとき
**例**: 会話文の表示、文字列内のダブルクォートを表現
```python
print("He said, \"Hello\"")
# 出力:
# He said, "Hello"
```

### バックスペース: \b

文字を1つ後退します。
**使用タイミング**: 1文字前に戻り、その文字を削除したいとき
**例**: タイピングのエフェクト、進行中の入力の修正

バックスペースのエスケープシークエンス（\b）は、文字列の一部を削除して新しい情報を表示する必要がある場合に使用されます。特にインタラクティブなアプリケーションやリアルタイムの表示更新において便利です。
```python
print("Hello\bWorld")
# 出力:
# HellWorld
```

# まとめ
基本的には、特殊文字（’とか”とか）を表現したいときには、バックスラッシュ（\）を前につけるだけ。一番よく使うのは改行なので、\nだけ忘れないようにしたいと思います。
PackagingResults: Error: Content is missing from cook. Source package referenced an object in target package but the target package was marked NeverCook or is not cookable for the target platform.


~~~
PackagingResults: Error: Content is missing from cook. Source package referenced an object in target package but the target package was marked NeverCook or is not cookable for the target platform.
~~~

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/249684/2b5444e0-dfe7-152a-e9e4-8a6171934340.png)

ProjectSettingsの「Exclude editor content when cooking 」のチェックを外す
大好きなYouTubeチャネルが更新されたらLINEに通知が届くツールをIFTTTで作成

好きなYoutubeチャンネルで新しい投稿があったら、LINEに通知がくる仕組みをIFTTTを使用して作ってみました。
めっちゃ簡単にできて感動です。

## 使いどころ
例えば1カ月に１本しか投稿しないチャネルだと頻繁にYoutube見に行く習慣がないと見落としてしまいますよね。
そういう時にこのツールは役立つと思います。

## こんな感じの通知が届きます
私が通知を受け取りたいチャンネルは更新が不定期で、いつ新しいコンテンツがアップロードされるか分からないのでテストには使えません。そこで毎日コンテンツがアップロードされているらしい妻の好きなチャンネルで試してみました。

チャンネル↓

https://www.youtube.com/@naresome_yobiko


このチャンネルの動画が更新されると、↓のような通知が来ます。

![RPReplay_Final1720438815.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3770353/8155f62e-abb6-bbd5-1a66-ab0f5b58bf50.gif)



## 超簡単IFTTTでのツールの作り方
15分あれば余裕で作れます。

まずはIFTTTのログイン

https://ifttt.com

そしてLINE Notifyにログイン

https://notify-bot.line.me/ja/


IFTTTとLINEを連携したら下準備はOK
（ここの連携方法を詳しく知りたい方はリンクのページで確認してください。1分でできます。）

https://www.mashilog.com/entry/line-notify-how-to


後はIFTTTでAppletを作成していくだけです。


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3770353/a8e475ea-f8cc-bed4-31a2-bfeccd124d7a.png)

こんな感じで、
上はYoutubeのNew video by channelメニューを選択
下はLINEのSend messageメニューを選択

YouTubeのところの Which channel? はチャネルIDを入力します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3770353/b5737193-1340-4b44-cf11-268279e797cd.png)

チャネルIDとはなんだ？と思うかもしれません。
対象のチャネルページに行って、概要の一番下のチャネル共有ボタンからチャネルIDコピーを選択するとIDを取得できます。それを貼り付けるだけです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3770353/8b18cb0b-5b65-0fa3-2fdd-02d7c7755c96.png)


次にLINEのところには、こんな感じで入力すればOKです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3770353/93d81d91-55cc-d6c0-e183-fb930f4a8c61.png)

この設定は、自分宛にアップロードされた動画のタイトル＋説明文＋動画URLが記載されたメッセージを送ることを意味しています。

これで設定は完了で、Connectedの状態にしておけばアップロードされた際に自分のLINEに通知がきます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3770353/bc345922-66ad-18d2-4b03-6ec1ea91c9f5.png)



## 補足
ちなみにテストで使用した動画のケースでは、恐らく動画の説明文が長すぎて通知の文章が途中で切れており動画のURLまで入っていません。
動画にすぐに飛びたいということであれば、URLは届いた方が良いので、Descriptionは載せないでURLを優先させた方が良いかもしれません。
【書評】Terraformの教科書

# 読んだ本

https://book.mynavi.jp/ec/products/detail/id=142721

# 概要

Terraformにふれる機会があり、ちょうど発売された本だったので読んでみました。ちょっとわかりにくい箇所が多かったものの、追加で調べながら読み進めればTerraformについて大枠がつかめました。
AWS、GCP、Azureを横断的に取り扱っているので、いずれかの知識が必須になるので要注意です。

目次は下記になっています。

1章 IaCを知る
2章 Terraformのインストール
3章 Terraformをはじめよう
4章 Terraformへのディープダイブ
5章 Terraform CLI
6章 Terraformのワークフロー
7章 Terraformのモジュール
8章 Terraformの構成ファイル
9章 Terraformスタックを理解する
10章 Terraform CloudとTerraform Enterprise

# おすすめの人

- AWSなどのクラウドをコンソールを操作して環境構築をしている人
- Terraformなどを利用したソースコードがあるが理解しきれていない人
- （クラウドの知識が全くない人にはおすすめできません）

# 次に読むなら

- 自分でイチから構築できるようになりたいので、Terraform Registoryなどを参考に具体的なコードを把握していきたいです

# 感想

業務で使っているため、ざっくりした使用方法は理解していたが、各コードの詳細まで理解しきれておらず、applyの実行に恐怖感がある状態でした。
この本を読んで、完全には消えませんでしたが、もう一歩実行する内容の理解が進みました。
簡易的な内容を別記事でまとめておこうと思います。
React での配列への要素追加方法

## React での配列操作
本記事は以下の記事の続きです。

https://qiita.com/axoloto210/items/cb93a3aebc3521cace3f

## 配列へ要素を追加するには
配列へ要素を追加する方法にはスプレッド構文や配列のメソッドなどいくつかの方法あります。

`useState`が配列の変更を検知できるよう、**新しい配列を返す**ような方法によって要素を追加することが推奨されます。

### スプレッド構文による追加
スプレッド構文`...`によって元の配列を新たな配列に展開し、要素を追加する方法です。
```ts
const array = [1, 2, 3]

const newArray = [...array, 4]

console.log(newArray)
//[ 1, 2, 3, 4 ]

console.log(Object.is(newArray, array))
// false
```

上の例では、別の配列の中に元の配列`array`を展開し、その後ろに`4`を追加しています。
`Object.is(newArray, array)`が`false`となっていることから、`newArray`と`array`が別の値であることが`useState`のset 関数によって検知可能であることがわかります。

元の配列の前後に要素を追加する際に有用ですね。
## 新たに配列を返すメソッド
### `Array.prototype.concat()`
`concat()`を使用して要素を追加することもできます[^1]。

`concat()`は、複数の配列を合併し、**新しい配列を返す**メソッドです。
追加したい要素を持つ配列を`concat()`によって結合することで、目的の配列を取得できます。

```ts
const array = [1, 2, 3]

const newArray = array.concat([4])

console.log(newArray)
//[ 1, 2, 3, 4 ]

console.log(Object.is(newArray, array))
// false
```

`concat()`によって新しい配列が返されているため、`Object.is`によって別の配列であると判定されるようになっていますね。

https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array/concat


## 既存の配列に変更を加えるメソッド
### `Array.prototype.push()`
`push()`は**元の配列の末尾に要素を追加する**メソッドで、返り値は要素追加後の配列の長さになります。

`setState`によって変更が検知されない様子は以下の例でも確認できます。

`add 4`ボタンをクリックすると`state`配列に`4`が追加されるコードとなっています。
```jsx:App.jsx
import { useState } from "react";

function App() {
  const [state, setState] = useState([1, 2, 3]);

  const clickHandler = () => {
    state.push(4);
    setState(state);
  };

  const [triger, setTriger] = useState(true);

  return (
    <div>
      <div>{`${state}`}</div>
      <button onClick={clickHandler}>add 4</button>
      <button
        onClick={() => {
          setTriger(!triger);
        }}
      >
        render
      </button>
    </div>
  );
}

export default App;
```
`add 4`ボタンをクリックしても画面上の表示は`1,2,3`のままで変化が起こりません。
これは、`state.push(4)`によって`state`に変更を加えても、`setState`には同じ配列であるとみなされるため、再レンダリングがされません。

`render`ボタンを押してみると、`add 4`ボタンを押した回数と同じ分だけ`4`が追加されてレンダリングされることが確認できます。
配列`state`には確かに変更が加わっていますが、画面へ反映されていなかったわけですね。

### `Array.prototype.unshift()`
`unshift()`は**元の配列の先頭に要素を追加する**メソッドで、返り値は要素追加後の配列の長さになります。
要素の追加位置は異なりますが、`push()`によく似たメソッドとなっています。

```ts
const array = [1, 2, 3]

const length = array.unshift(4)

console.log(array)
// [ 4, 1, 2, 3 ]

console.log(length)
// 4
```

`unshift`によって`state`を操作した場合にも、変更が検知されないため注意が必要です。

https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array/unshift

[^1]:concat はconcatenate の略で、「連結」の意。
firebaseライブラリの更新でNext.jsのデプロイにfirebase-toolsを使いたい

# はじめに

最近firebaseでNext.jsをVercelのように使えるようになったので、firebase-toolsのあり方も変わりました
そこについて書いていきます

# 問題

いままでのfirebaseコマンドなら以下のようにfirebase-toolsでいい感じにNext.jsをデプロイするかを聞かれていた

```
$ firebase init hosting
=== Hosting Setup
? Do you want to use a web framework? (experimental) (y/N) 
```

しかしfirebaseコマンドのバージョンが変わって聞かれなくなってしまった
どうすれば今までどおりNext.jsをデプロイできるのか、、、

# 解決方法

`firebase.json`の`public: public`をfirebase-toolsでやっていた`source: "."`にすることで使えました

```json:firebase.json
{
  "hosting": {
    "source": ".",
    "ignore": [
      "firebase.json",
      "**/.*",
      "**/node_modules/**"
    ]
  }
}
```

# おわりに

いつ使えなくなるかわからないので、CI/CDの方法を別にもさくしたいなとかんがえまｓ

# 参考

https://qiita.com/Sicut_study/items/4dcff2f23f32f0a47917