OmniAICreator/Qiita-1.07M huggingface dataset:
【プラクティス紹介】1分でさらっと分かる「アジャイル宣言クイズ」

![quiz.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3526800/2631e3e2-b685-876d-1add-ac495cd449b4.jpeg)

## プラクティス名
アジャイル宣言クイズ

## プラクティスの目的・狙い
* 「アジャイルソフトウェア開発宣言」の内容をチーム全員に浸透させる

## どんな時に使うか
* チーム立ち上げ時、はじめてアジャイル開発を行うメンバーがいる時
* チームに新規メンバーが加入した時

## 実施手順
1. チーム全員で集まり、まず時間を決めてアジャイル宣言と12原則を読み込む
1. 各自、その中から特に大事だと思った箇所をクイズ形式にしてお互いに出し合う
1. 正解数を競ってもよいがそれ自体は重要ではなく、理解が深まったかどうかが大事

単純な穴埋め問題は比較的簡単に出題できる。
選択問題で間違えやすい選択肢を用意するのは少し考える必要がある。
原則に沿った行動/沿わない行動を例示しようと思うと出題者の理解度が試される。
微妙な問題だと「それは正解が間違っているのでは？」と議論になることもあるが、それにより理解が深まる。

## アレンジ例
* クイズの内容を「こんな時はどう行動すべきか？」といったオープンクエスチョンにしてみる
* 定例会議の冒頭で毎回1問ずつ出題する（出題者は持ち回りとする）

## アンチパターン
* 穴埋め範囲が広すぎて誰も正確に答えられない（暗記力を試したいわけではない）
* 不正解の後にアジャイル宣言を読み直さない

## 参考資料
[アジャイルソフトウェア開発宣言＆その背後にある原則](https://agilemanifesto.org/iso/ja/manifesto.html)

[【IPA資料】アジャイル宣言の読みとき方PDF](https://www.ipa.go.jp/jinzai/skill-standard/plus-it-ui/itssplus/ps6vr70000001i7c-att/000065601.pdf)

## こぼれ話（私的コメント）
アジャイル未経験者に「アジャイル宣言、これ超重要だからよく読んでおいてね！」と伝えると2分後ぐらいに「読みました♪」って返事が返ってきて、うーん、どうしよう・・・文字通り、ただ「読んだ」だけだろうな・・・ってなるんですよね。どうしたら深く読み込んでもらえるだろうかと悩んでいたら、CSM研修の冒頭でこのプラクティスを実施されていて、なるほど、と思いました。自分のチームでも試してみたところ、思いのほかウケが良く、継続的にやりましょう、となりました。

　[アジャイルプラクティス一覧へ戻る](https://qiita.com/kakashi_h5/items/20584998c5ca4594b9ea)
[Go]シャドーイング、制御構文

# 概要

* [前回のつづき](https://qiita.com/hasesiu/items/ec3db4576ba94f17a0b6)
* 今回は、変数のシャドーイング（隠蔽）や、制御構文、関数についての学習
* 今回もJavaやts（typeScript）と比較しつつ、進める。

インプット資料

https://www.oreilly.co.jp/books/9784814400041/

# シャドーイング

* ブロックの外と内で同じ変数を宣言した場合の動作
    * 内では、外の変数はシャドーイング（隠蔽）される。そのため、外の変数はアクセスできなくなる
    * 内を抜けたら、外の変数が参照される
* バグの温床になるので、シャドーイングはしない。

```go
	x := 10
	{
		fmt.Println(x) //10
		x := 5
		fmt.Println(x) //5 -> x:=10のシャドーイング発生
	}
	fmt.Println(x) // 10 → x:=10のシャドーイング解除
```

* （補足）Javaの場合
    * ブロック外と内での変数宣言は、重複ローカル変数となり、コンパイルエラーになる。
    * クラス変数とローカル変数で同じ変数を宣言した場合は、`this`で区別する。
    * シャドーイングが発生するのは、継承関係にあるクラスのクラス変数が重複した場合。
        * ※Goではクラスの継承自体がないので、そもそもで発生しない。

# 制御構文

* 共通して、条件を記載する箇所に`()`は不要。

## if

* if文の条件の前に、変数を宣言できる。
* 宣言した変数は`if-else`内のブロックスコープとなる

```go
	rand.NewSource(time.Now().UnixNano())
	// ブロック内のみ有効な変数「n」
	if n := rand.Intn(10); n == 5 {
		fmt.Println("nは5",n)
	} else if n < 5 {
		fmt.Println("nは5未満",n)
	} else {
		fmt.Println("nは5より上",n)
	}
	// ブロック外ではエラーとなる
	//fmt.Println("nは",n)
```

## for

* 繰り返しはfor文でのみ行う。whileはない。（代替する書き方はもちろんある。）
* 他の言語同様、breakやcontinueもある。gotoやラベル遷移もあるが、処理が追いづらくなるので、使用箇所には注意する。
* for文には以下の4種類ある。
    * 通常のfor文
    * 拡張for文
        * `for-range`構文。配列やsliceなどを走査する場合に利用する。
        * 引数を2つ（indexとvalue）とる。index不要の場合は、変数名を`_`にする（tsと同様）
        * for-rangeで宣言した値はコピーであるため、変更しても元の配列には影響しない（　＝イミュータブル）
    * 条件のみfor文
        * while文の代わり
    * 条件なしfor文
        * 無限ループ

```go
	// 通常のfor文
	for i := 0; i < 5; i++ {
		fmt.Println(i)
	}

	// 拡張for文
	evenVal := []int{1,2,3,4,5,6}
	// index不要の場合「_」にする。なお、2つめ（value）が不要の場合は宣言しないでよい。
	for _, v := range evenVal {
		if v % 2 == 0 {
			fmt.Println(v)
		}
	}

	// 条件のみfor文（while文）
	i := 2
	for i < 10 {
		fmt.Println(i)
		i = i * 2
	}

	// 条件なしfor文（無限ループ）
	n := 1;
	for {
		fmt.Println(n)
		if n > 5 {
			break
		}
		n++
	}
```

## switch

* switch内で有効となる変数宣言ができる
* csse文ではbreak記載しない。フォールスルーしたいときは、カンマで区切って、一つのcase式で複数の値を列挙する
* switch文に条件式を書かなくてもよい。（ブランクswitch）その場合、case文に条件式を書ける。
* 特定の変数に対する条件分岐の場合は、if文より、switch文を推奨

```go

	rand.NewSource(time.Now().UnixNano())

	// ブロック内のみ有効な変数「n」
	switch n := rand.Intn(12); n {
	case 2,4,6,8,10:
		fmt.Println("10までの偶数です。",n)
	case 1,3,5,7,9:
		fmt.Println("10までの奇数です。",n)
	default:
		fmt.Println("その他。",n)
	}
	// ブロック外ではエラーとなる
	//fmt.Println("nは",n)

	// ブランクswitch
	// switch内で条件式を書かず、case内に書くこともできる
	switch n := rand.Intn(12); {
	case n % 2 == 0 && n <= 10:
		fmt.Println("10までの偶数です。",n)
	case n % 2 != 0 && n <= 10:
		fmt.Println("10までの奇数です。",n)
	default:
		fmt.Println("その他。",n)
	}

```

# おわりに

* 制御ブロック内のみで有効な変数を宣言できるのは便利
* while文をfor文に統合したのは、シンプルでよいと思う。
    * 元々while文はbreak条件の見通しが悪いから使用頻度も低いので。
* switch文が便利で使いやすくなったが、if文との使い分けが難しくなりそう。
Daskでスレッド数を指定して計算するには

Pythonの並列処理ライブラリであるdaskで計算処理を行うと、デフォルトでは最大コア数分のスレッドを使って計算を行います。スレッド数を変えて計算するには次の方法があります。

# num_workersで指定

`compute`メソッドを呼び出すときに`num_workers`というキーワード引数で計算の並列数を指定できます。デフォルトではスレッドを使って並列計算を行うので、これでスレッド数が指定できることになります。

```python
import dask.array as da

z = da.random.normal(0, 1, (1000, 1000))
x = da.sum(z, axis=1)
x.compute(num_workers=2) # 2スレッドで計算
```

# dask.configで指定

computeメソッド呼び出し時に個別にスレッド数を指定するのではなく、まとめて指定したい場合には次のようにします。

```python
from multiprocessing.pool import ThreadPool
import dask
dask.config.set(pool=ThreadPool(20))
```

# 参考文献
* [Scheduler Overview](https://docs.dask.org/en/stable/scheduler-overview.html "Scheduler Overview")
* [How to specify the number of threads/processes for the default dask scheduler](https://stackoverflow.com/questions/40621543/how-to-specify-the-number-of-threads-processes-for-the-default-dask-scheduler "How to specify the number of threads/processes for the default dask scheduler")
【無限スクロール】ブラウザバックするとスクロール位置が初期位置に戻されてしまう問題

# はじめに

Reactで無限スクロールを実装する際、次の画面へ遷移してからブラウザバックするとスクロール位置が初期位置に戻されてしまう問題が発生していました。この記事では、この問題の原因と解決策について触れていきます。

# 問題の原因

無限スクロールを実装したコンポーネントでは、画面遷移によってコンポーネントがアンマウントされてから、ブラウザバックにより再びマウントされます。つまりそこで再レンダリングが行われています。そのため、スクロール位置が初期化されていました。

# 解決策

今回はセッションストレージに状態を保存する方法を採用しました。保存したのは、

- 無限スクロール中に表示したアイテム
- 無限スクロールは継続中か判断するフラグ
- DynamoDBを使用していたのでlast_evaluated_keyの内容
- スクロール位置

以上、4点です。この内容を次の画面へ遷移する前にセッションに保存します。その後画面を遷移させます。

## セッションに保存するロジック

画面遷移時にセッションストレージに保存します。

```javascript
const handleItemClick = (caseItem) => {
  const stateToSave = {
    savedCases: cases,
    savedHasMore: hasMore,
    savedLastKey: lastKey,
    scrollPosition: containerRef.current ? containerRef.current.scrollTop : 0,
  };
  sessionStorage.setItem('セッションに保存する時の名前', JSON.stringify(stateToSave));
  navigate(`/***/***/${***}`);
};
```

## セッションから取得するロジック

ページがロードされた際にセッションストレージからスクロール位置を取得し、復元します。

```javascript
useLayoutEffect(() => {
  const savedState = sessionStorage.getItem('セッションに保存した時の名前');
  if (savedState) {
    const { savedCases, savedHasMore, savedLastKey, scrollPosition } = JSON.parse(savedState);
    setCases(savedCases);
    setHasMore(savedHasMore);
    setLastKey(savedLastKey);

    if (containerRef.current) {
      containerRef.current.scrollTop = scrollPosition;
    }
  }
}, []);
```

## 取得した内容を再レンダリングの内容と突合するロジック

ここで、セッションの内容と再レンダリング時に取得した内容とを比較して重複を削除します。

```javascript
const removeDuplicates = (newCases, existingCases) => {
    return newCases.filter(
        (product) => !existingCases.some((caseItem) => caseItem.name === product.name)
    );
};
```

## TOPページに遷移した際のセッション削除

セッションなので、ブラウザを閉じれば削除されるものの、無限スクロールするアイテムが変更される場合にはセッションストレージからデータを削除してください。別のカテゴリのアイテムが混ざるとバグの原因になります。

```javascript
  useEffect(() => {
    sessionStorage.removeItem('セッションに保存した時の名前');
  }, []);
```

# useLayoutEffectを採用した理由

この記事のコード例では**セッションから取得するロジック**のところで、`useLayoutEffect`を使用しています。`useLayoutEffect`はDOMの更新が画面に描画される前に実行されるため、スクロール位置の復元など、描画に直接関連する処理を行う際に有用です。

# まとめ

今回は無限スクロールを実装する際に発生するスクロール位置の初期化問題を、セッションストレージを使用して解決することができました。これでUXも向上したと思います。
そもそもではありますが、無限スクロールを採用する理由の１つに、ユーザーが没頭できるようにするというのが挙げられますが、ブラウザバックしたらスクロール位置が初期化されていては、ユーザーは没頭するどころかストレスを溜めてしまうでしょう。ユーザーフレンドリーなつくりにしたいものですね！

ではでは、今回はこのへんで👋
Chromebookにfirefoxを入れる際に発生したエラー、error: nothing matches org.mozilla.firefox in remote flathubを解決する。

chromebookでPC版のfirefoxをインストールする際に発生したエラー「error: nothing matches org.mozilla.firefox in remote flathub」を解決するのに苦労したので、書き記したいと思います。以下の内容は、Linux開発環境をONにしている前提で書いています。

## スペック表
機種: HP Chromebook x2 11-da0013QU
OS: Chrome OS
CPU: Qualcomm® Snapdragon™ 7c
RAM: 8GB
※今回のエラーの原因は、CPUがQualcomm製であるが故に発生したものです。

## エラーが起きた経緯
firefoxをインストールする一般的な方法は、flatpakからインストールする方法です。しかし、flatpakをchromebookにインストールしてもflatpakからfirefoxをインストールできない場合があります。インストールできない場合、コマンドでfirefoxをflatpak経由で入れようとすると「error: nothing matches org.mozilla.firefox in remote flathub」というエラーが出て、入れることができません。 ~~原因としては、私が使用していたchromebookのCPUがQualcommであったため発生したものです。~~ (原因は、完全に憶測で書いてしまっていましたので、訂正線を引いています。原因に関しては、参考しないでください。) 以下に、エラーが発生したパターンのコマンドを記載しておきます。

:::note alert
以下のコマンドは、error: nothing matches org.mozilla.firefox in remote flathub が発生するまでの流れです。
:::

```shell
#flatpakのインストール
$ sudo apt install flatpak
$ flatpak --user remote-add --if-not-exists flathub https://dl.flathub.org/repo/flathub.flatpakrepo
#firefoxのインストール
$ flatpak install flathub org.mozilla.firefox
Looking for matches…
Remote ‘flathub’ found in multiple installations:

   1) system
   2) user

Which do you want to use (0 to abort)? [0-2]: 1
#以下のエラーが発生
error: Nothing matches org.mozilla.firefox in remote flathub
```

## 解決方法
解決方法は、firefoxのESR(Extended Support ReIease)版を入れる方法です。以下にfirefox ESRをインストールする方法を記しておきます。

:::note
以下のコマンドでfirefox ESRをインストールできます。
:::

```shell
sudo apt update
sudo apt upgrade
sudo apt install firefox-esr
```

### 参考文献
https://support.mozilla.org/bs/questions/1374419

https://www.techradar.com/how-to/how-to-install-firefox-on-a-chromebook

https://flatpak.org/setup/Chrome%20OS

https://support.mozilla.org/ja/kb/install-firefox-linux#w_flatpak-karainsutorusuru
Ubuntu CUI ネットワークの初期設定

# UbuntuのServer vs Desktopネットワークサービスの違い
Ubuntu のServer版とDesktop版の主な違いは使用目的にあります。 Server版は、アプリケーション、ウェブサイト、データベース、さまざまなサービスの環境を提供できます。 一方、Desktop版は日常業務向けの幅広いアプリケーションを提供します。

Server版とDesktop版でネットワーク管理簡易化ツールはそれぞれsystemd-networkd、NetManagerと異なるので設定方法も違います。

今回、Server版の初期設定でネットワーク接続に躓いたのでメモしました。

## Server (CUI)
##### systemd-networkd
```
sudo nmtui
```
参考リンク
[Ubuntuでネットワーク設定をCUIから行う](https://pcvogel.sarakura.net/2023/03/21/38180)

## Desktop (GUI)
##### NetManager

参考リンク
[Ubuntuのネットワーク設定](https://gihyo.jp/admin/serial/01/ubuntu-recipe/0708)
TableauDesktop/hexmapの作り方（アメリカ編）

# 事前準備

## 州の位置のデータ
州を座標に置き換えたデータを作成します。
Row、Columnが州の位置となっています。

左：以下のデータ、右：地図
![hex.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3531257/975c0a4b-cd3c-d2ee-366b-409c1ebf4c4a.png)

以下のデータをファイルとして保存します。
~~~
Row	Column	State	Abbreviation
0	0.50	Alaska	AK
6	7.50	Alabama	AL
5	6.00	Arkansas	AR
5	3.00	Arizona	AZ
5	2.00	California	CA
4	3.50	Colorado	CO
3	11.00	Connecticut	CT
5	12.00	District of Columbia	DC
4	9.50	Delaware	DE
8	8.50	Florida	FL
7	8.00	Georgia	GA
8	0.50	Hawaii	HI
3	5.00	Iowa	IA
3	2.00	Idaho	ID
3	6.00	Illinois	IL
3	7.00	Indiana	IN
5	5.00	Kansas	KS
4	6.50	Kentucky	KY
6	5.50	Louisiana	LA
2	10.50	Massachusetts	MA
4	8.50	Maryland	MD
0	11.50	Maine	ME
2	7.50	Michigan	MI
2	4.50	Minnesota	MN
4	5.50	Missouri	MO
6	6.50	Mississippi	MS
2	2.50	Montana	MT
5	9.00	North Carolina 	NC
2	3.50	North Dakota 	ND
4	4.50	Nebraska 	NE
1	11.00	New Hampshire 	NH
3	10.00	New Jersey 	NJ
6	3.50	New Mexico 	NM
4	2.50	Nevada 	NV
2	9.50	New York 	NY
3	8.00	Ohio 	OH
6	4.50	Oklahoma 	OK
4	1.50	Oregon 	OR
3	9.00	Pennsylvania	PA
2	11.50	Rhode Island 	RI
6	8.50	South Carolina 	SC
3	4.00	South Dakota 	SD
5	7.00	Tennessee 	TN
7	4.00	Texas 	TX
5	4.00	Utah 	UT
5	8.00	Virginia 	VA
1	10.00	Vermont 	VT
2	1.50	Washington 	WA
2	5.50	Wisconsin 	WI
4	7.50	West Virginia 	WV
3	3.00	Wyoming	WY
~~~


## 六角形のアイコン(png)
六角形のアイコンをインストールディレクトリーの配下に保存じます。
形状フォルダー配下は、アイコンが管理しやすいようにフォルダー分けします。

C:\[インストールディレクトリー]\Documents\マイ Tableau リポジトリ\形状\xx


![hex3.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3531257/2b047e4e-e96c-896a-7581-d95546b944da.png)


# Hexmap作成

１．列シェルフにcolumn、行シェルフにrow、マークカードにstateを配置します。
２．グラフを計上し、サイズを調整します。
３．最後にグリッド線等を消すと出来上がります。

![hex4.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3531257/36fe6f05-75ff-7720-4f79-34c5af6601a2.png)
最小限なrequirements.txtの作成方法

#### 内容
requirements.txtを作成する際に、そのままだと対象のコードと関係ないライブラリもたくさん含まれてしまいます。関係ないライブラリを手動で取り除くのは面倒です。ライブラリを使って必要最小限のrequirements.txtを作成する方法を紹介します。

#### 使用するライブラリ
- pipreqs

https://pypi.org/project/pipreqs/

### 実行した環境
- Windows10
- コマンドプロンプト

#### 手順
2. pipreqsをインストール
   ```
   pip install pipreqs
   ```
3. プロジェクトのディレクトリを指定してpipreqsを実行
   ```
   pipreqs /path/to/project/
   ```
4. 生成されたrequirements.txtを確認

#### 実行時のエラーと解消方法①
- エラーメッセージ：`UnicodeDecodeError: 'cp932' codec can't decode byte`
  - 原因: pipreqsファイルのエンコーディングが正しく認識しない。
  - 解消方法: pipreqsのソースコードを**UTF-8**に設定する。

  修正前:
  ```
  with open(file_path, 'r', encoding=encoding) as f:
  ```
  修正後:
  ```
  with open(file_path, 'r', encoding='utf-8') as f:
  ```
#### 実行時のエラーと解消方法②
- エラーメッセージ: 明らかに想定しないライブラリが書かれたrequirements.txtが生成された。
  - 原因: 対象にするディレクトリ全体を探索するため関係ないコードのライブラリも拾ってしまった。
  - 解消方法: 対象の.pyファイルのみ別ディレクトリに移動させて（対象のファイルを絞って）からpipreqsを実行する。

#### 感想
とても便利で感動しました。
今後もこのライブラリを使い続けるためにもコードを書き続けなければ・・・。
golangでmap関数っぽいもの

何度も同じコードを書くので備忘録として。


```
// mapArray T型配列をR型配列に変換する
func mapArray[T any, R any](values []T, conv func(t T) R) []R {
	results := make([]R, len(values))
	for i, v := range values {
		results[i] = conv(v)
	}
	return results
}
```

使い方
```
intValues := []int{1, 2, 3, 4}
strValues = mapArray(intValues, func(v int) string {
		return strconv.FormatInt(int64(v), 10)
	})
```
Leetcode 63. Unique Paths II

https://leetcode.com/problems/unique-paths-ii/description/

# アプローチ
- DP

```java
class Solution {
    public int uniquePathsWithObstacles(int[][] obstacleGrid) {
        int height = obstacleGrid.length;
        int width = obstacleGrid[0].length;
        int[][] dp = new int[height][width];

        for (int i = 0; i < height; i++) {
            if (obstacleGrid[i][0] == 1) {
                break;
            }
            dp[i][0] = 1;
        }

        for (int i = 0; i < width; i++) {
            if (obstacleGrid[0][i] == 1) {
                break;
            }
            dp[0][i] = 1;
        }

        for (int i = 1; i < height; i++) {
            for (int j = 1; j < width; j++) {
                if(obstacleGrid[i][j] == 1){
                    continue;
                }

                dp[i][j] = dp[i - 1][j] + dp[i][j - 1];
            }
        }

        return dp[height - 1][width - 1];
    }
}
```
Syntax error or access violation: 1068 Multiple primary key defined っていわれても主キーを1つしか設定してないよ…

それはmigrateをするときでした。

```php
SQLSTATE[42000]: Syntax error or access violation: 1068 Multiple primary key defined
```

すでに主キーが設定されてるから二重登録はできんよ〜ということですね。

migrateファイルを確認しても主キーの設定は一つしかしてないし、他のmigrateファイルの影響でもなさそうだし…も〜わけがわからん！と1時間ぐらいうなってました…

原因はしょうもないことです…

`smallInt('hoge')`　に桁数の指定がしてあったんですね…

`smallInt('hoge', 8)` こんな感じで…

桁数の指定はできないよね〜。

指定するとなぜがAUTO_INCREMENTになってPRIMARY_KEYになってしまってたみたい。

なので上記のエラーが吐き出されたというわけでした…

こういうこともあるんですね〜…
MockとSpyの違い（Mockito）


MockとSpyの違い（Mockit）

# TL;DR

| 機能/特徴          | Mock                          | Spy                               |
|-------------------|------------------------------|-----------------------------------|
| 基本的な特性      | 完全にモックされたオブジェクト  | 実際のオブジェクトのラッパー       |
| デフォルト動作    | 全てのメソッド呼び出しがモック動作 (通常はnullやデフォルト値を返す) | 実際のメソッドが呼び出される       |
| メソッドのオーバーライド | 指定したメソッドだけモック動作を設定可能 | 任意のメソッドの動作をモックに変更可能 |
| 使用シナリオ      | 実際のオブジェクト/メソッドの動作を完全に避けたい場合 | ほとんどの実際の動作を保持しつつ、一部のメソッドの動作だけをカスタマイズしたい場合 |
| メモリ使用        | 実際のオブジェクトは作成されないので、通常は軽量 | 実際のオブジェクトが存在するため、そのオブジェクトのメモリを使用する |
| 初期化            | `@Mock` アノテーションまたは `Mockito.mock()` を使用 | `@Spy` アノテーションまたは `Mockito.spy()` を使用 |
| 副作用  | 実際の副作用は発生しない | メソッドがモックされていない場合、実際の副作用が発生する可能性がある |


``` java:sample
package com.example;

import static org.junit.jupiter.api.Assertions.assertEquals;

import org.junit.jupiter.api.Test;
import org.mockito.Mockito;

public class SpyAndMockExampleClass {

	@Test
	public void testSayHelloWithSpy() {

		SampleService spiedService = Mockito.spy(new SampleService());

		SampleService mockedService = Mockito.mock(SampleService.class);

		Mockito.when(spiedService.sayHello()).thenReturn("Mocked Hello");

		Mockito.when(mockedService.sayHello()).thenReturn("Mocked Hello");

		assertEquals("Mocked Hello", spiedService.sayHello());
		assertEquals("Goodbye", spiedService.sayGoodbye());

		assertEquals("Mocked Hello", mockedService.sayHello());
		assertEquals(null, mockedService.sayGoodbye());

	}

	public class SampleService {
		public String sayHello() {
			return "Hello";
		}

		public String sayGoodbye() {
			return "Goodbye";
		}
	}
}
```
SE4BSについて理解する！アジャイルマインドで価値駆動のためのプロセス


# 概要


とあるきっかけで[SE4BS](https://se4bs.com/sites/)という、新たなプロセスを見つけたので、サイト内を読みつつ学習したことを記事化する。

個人的な見解が多く入っているので、詳しく[SE4BS](https://se4bs.com/sites/)を知りたい方は公式サイトを読むと良いです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/330768/0335b7c4-eab0-895f-9711-39f77944929c.png)



# SE4BSとはなんぞや？


従来
 - 開発の効率化や品質の向上に重点を置く
 - 論理的な考え方や経験、データに裏付けられた手法を積み重ねる


これから
 - ソフトウェアにビジネスや社会形成上の価値想像がより一層求められる
 - 様々な人々に寄り添う考え方や、新たな社会を構想する捉え方の重要性が増す
 - ソフトウェア開発者にビジネスや社会に対する期待が高まり、価値観や責任が強く問われる


**つまり**

従来の工学的な知識体系に加えて、人々の意識や価値観、感情をソフトウェアの開発運用に取り組むことで、ソフトウェアを「個人・社会・ビジネスのために、柔軟で創造的な未来の価値を生み出すもの」と捉えることができる




# SE4BSを理解する上で重要な概念

以下3つのバランスを意識して価値駆動開発を行うことが大事と書かれている

| 項目                   | 説明                                                                                                               |
|-----------------------|-------------------------------------------------------------------------------------------------------------------|
| 知（Cognitive, Intelligence）  | 知覚・知性に基づくロジカルシンキングであり、従来のソフトウェア工学の手法の多くが該当する。                               |
| 情（Affective, Emotion）      | 相手や対象に対する感情・情的な過程であり、ソフトウェアを使う人が感じる魅力や、ソフトウェアを導入した企業が得られる価値を考えること。   |
| 意（Conative, Will）          | 道徳的評価に基づく意志やコンセプチュアルシンキングであり、価値を生み出そうとしている主体自身の意志。                            |

※ https://se4bs.com/sites/introduction/ から引用


一般的に用いられる「知情意」の解説はこちらの記事が詳しいので、載せておこう

https://motivation-up.com/whats/chijoui.html


# 価値駆動開発という新しい言葉ができてたけどこれは何？

この図がとてもわかりやすい。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/330768/1f826953-0467-179d-3f19-67d6e13aa125.png)

出典:図1.5-1 SE4BS価値起動開発プロセスの全体像（2022.7時点） https://se4bs.com/sites/introduction/


## この価値駆動開発の何が良いのか



**従来のプロセス**
 - 依頼元からの要求に対する意味や根底になる目的が開発者に伝えられていない
 - 開発者は、お客様にとって本当に必要な機能、使いやすい体験を提供しているのか疑問に思う機会が多い
 - 分業体制で開発することが多い日本の開発現場では、お客様の声を聞くのが現実的でないことがある


**価値駆動開発のプロセス**
 - 知・情・意のバランスをとりながら、チームとステークホルダーのニーズをすり合わせるため再現性が高い
 - エンジニアとしての社会的責任を重視した価値駆動プロセスのベースとなる思考法は日本人特有の志や情に通じるものであり日本人にあっている
 - ソフトウェアのライフサイクルにわたって価値を考えられるようになることで、開発者もステークホルダーと一緒にソリューションを追求することができる
 - ステークホルダーと一緒に達成感を得ることができる


# まとめ
これから流行っていきそうな考え方と読んでいて思います。

[実践トライアル編](https://se4bs.com/sites/practice/)もあるので、開発者は今自分が関わっているプロジェクトを実践トライアル編の内容に従ってまとめてみると新たな発見があるかもしれません！
csvファイルとChatGPTの連携

ChatGPTのCodeInterpreterでのExcelの処理がまだまだだったので、Excelの内容をPythonで取得して、ChatGTPに聞くような仕組みにしてみました。

変数から分かるとおもいますが、論文のアブストラクトの一覧がExcelに入っており、全部読むのが大変なのでChatGTPで楽をしようという取り組みの一部でこの連携を使用しました。

```
import csv
import openai
openai.api_key = ""
prompt = ""

def get_pico_from_gpt(abstract):
    response = openai.ChatCompletion.create(
            model="gpt-3.5-turbo",
            messages=[
                {"role": "system", "content":prompt},
                {"role": "user", "content":abstract},
            ]
        )
    return response["choices"][0]["message"]["content"].strip()
    
def main():
    input_filename = 'input.csv'  
    output_filename = 'output.csv'
    
    with open(input_filename, 'r', newline='', encoding='utf-8') as infile, open(output_filename, 'w', newline='', encoding='utf-8') as outfile:
        reader = csv.reader(infile)
        writer = csv.writer(outfile)
        
        # ヘッダーを処理
        header = next(reader)
        writer.writerow(header) 
        
        # 以降の行を処理
        for row in reader:
            abstract_content = row[0]
            pico_content = get_pico_from_gpt(abstract_content)
            row[1]=pico_content 
            writer.writerow(row)

if __name__ == '__main__':
    main()

```
【プラクティス紹介】1分でさらっと分かる「インセプションデッキ」

## プラクティス名
インセプションデッキ

## プラクティスの目的・狙い
* プロジェクト目的とチーム方針の明確化
* 共同作業を通じたチームビルディング

## どんな時に使うか
* チームメンバーは集められたばかりで、ベースとなる共通認識がまだ無い
* ステークホルダーが別々の方向を向いており、プロジェクト目的やスコープなどの前提が定まっていない

## 実施手順
チーム全員参加で以下の10の質問と課題に対する回答を作成する。
1～5でプロジェクトの背後にある「Why」を突き詰め、6～10で「How」を考える。

|No|ワーク名|ワークで明確化されること|
|:---:|:----|:----|
|1|我々はなぜここにいるのか？|チームのミッション|
|2|エレベーターピッチ|プロダクトのコンセプト|
|3|パッケージデザイン|プロダクトのイメージ|
|4|やらないことリスト|プロジェクトのスコープ|
|5|ご近所さんを探せ|ステークホルダー,関係者|
|6|技術的な解決策の概要|システムアーキテクチャー|
|7|夜も眠れなくなるような問題は何？|リスク|
|8|期間を見極める|スケジュール|
|9|トレードオフ・スライダー|優先順位・判断基準|
|10|何がどれだけ必要なのか？|リソース・コスト|

ワークを行うことでメンバーの認識が揃い、チームが機能するための下地が整う。文章は短くシンプルにまとめた方がよい。作成したインセプションデッキはいつでも参照できる場所に置き、新規メンバー加入時には必ず説明する。

## アレンジ例
* 上記に加え「俺たちのＡチーム」というチームに必要なスキル・役割を明確化するワークを行う
* プロジェクトの期中や別のシーンでもここで使えそう、というところで単品で使用する
* 「3.パッケージデザイン」に「利用者の声（架空のレビュー評価）」を付け足してみる

## アンチパターン
* 誰かが1人で書き上げてメンバーに説明する（＝ワークを通じた共通認識が生まれない）
* プロジェクトの冒頭で作成し、以降まったく更新しない（＝古新聞と化していく）

## 参考情報
インセプションデッキはRobin Gibson氏によって考案され、Jonathan Rasmusson氏の著書『アジャイルサムライ』で紹介され広まりました

https://www.ohmsha.co.jp/book/9784274068560/

書式のテンプレはオリジナル版が[Github](https://github.com/agile-samurai-ja/support)に挙がっていたり、その他の形式でも色々な方が公開してくれていますが、質問数や文言などバリエーションかあるのでお好みのものを。フォーマット自体はシンプルなので自作も可能です。

インセプションデッキのより詳細な説明としては定番のAgileStudioさんのサイトをオススメします。

https://www.agile-studio.jp/post/apm-inception-deck

## こぼれ話（私的コメント）
アジャイル開発は自由度が高い分、最初にきちんと背骨を通しておかないとプロジェクトが迷走しがちです。なので10枚きっちり書き上げて踏み固めておきたい！・・・ところですが、実は僕自身は今まで10枚書かせてもらったことが一度もありません。時間がないから全部はムリだねって話になって、1,2,4,5,9だけやろっか、みたいな感じで絞られてしまうのです。いつか10枚ちゃんと書ける日が来るといいなぁ、と常々思っています。新規プロダクトであればまだ推しやすいのですが、既存プロダクトだとスキップされがちなプラクティスです。

余談ですがアレンジ例にある「俺たちのＡチーム」は1980年代の米テレビドラマ「特攻野郎Aチーム」（正義の4人組がそれぞれの専門スキルを活かして悪の組織と戦う）から来ているようなのですが、この元ネタが分かるかどうかでチーム内の世代格差が明らかになってしまいそうです。ちなみ僕は知ってる派です。

　[アジャイルプラクティス一覧へ戻る](https://qiita.com/kakashi_h5/items/20584998c5ca4594b9ea)
PPAを使ってGoのバージョンを上げる方法

## はじめに

WSLのUbuntuにインストールしているGoのバージョンを上げる時に、PPAを利用した手順をよく忘れるので忘備録的な記事です。

## 上げ方

やり方自体はGoリポジトリのWikiにあります。

https://github.com/golang/go/wiki/Ubuntu

まず、各種パッケージの取得・更新をサクッとしましょう。

```sh
sudo apt update && sudo apt upgrade -y   
```

次にPPAを利用して、Ubuntuの公式リポジトリからダウンロードできないGoのバージョンを取得します。
(普通に `sudo apt install golang`すると結構前のGoがインストールされてしまうので)

```sh
sudo add-apt-repository ppa:longsleep/golang-backports
sudo apt update
sudo apt install golang-go
```

あとはGoのバージョンを確認してください。

```sh
go version
>>> go version go1.20.7 linux/amd64
```


### 補足1 PPAとは

:::note info
PPAとは

> PPAはUbuntuユーザーのチームや個人がそれぞれ管理している非公式のApp Storeのようなもので、Ubuntuの公式レポジトリからはダンロードできないソフトウェアや最新のバージョンのソフトウェアを手に入れることができます。

:::

https://allabout.co.jp/gm/gc/438675/

### 補足2 `add-apt-repository` が入っていない場合

```sh
sudo add-apt-repository ppa:longsleep/golang-backports
>>> sudo: add-apt-repository: command not found
```

のようなエラーが出るので、下記対応をしましょう

```sh
sudo apt-get install software-properties-common
sudo apt-get update
```

### 補足3 Golang Backportsとは

> システムのソフトウェアソースに ppa:longsleep/golang-backports を追加することで、この信頼できない PPA からサポートされていないパッケージを使ってシステムをアップデートすることができます。

https://launchpad.net/~longsleep/+archive/ubuntu/golang-backports

上記から取得できるバージョンを確認できます。

## おわりに

めっちゃ楽。ただし、マイナーバージョンのリリース直後は`Golang Backports`に最新版が入っていないこともあるので、その場合はwgetなりcurlなりして取得する必要があります。
せんせー、垂直農業ってなに？

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3194265/2c47de5a-d81a-78f9-53c1-4d31d8398c36.png)

キーンコーンカーンコーン...
授業が始まります

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3194265/be1492ca-910f-2708-d0fa-8fcfcf14af73.png)

せんせー、垂直農業ってなに？

# 垂直農業とは

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3194265/da229491-9c49-fb7a-a542-417180e256a7.png)

垂直農業って、たてに高く積み上げた棚のようなものに、野菜や植物を植えて育てる方法のことを言います。

普通の農業は、大きな土地に広がるように野菜や果物を植えますよね。
でも、都市や街の中では、広い土地がなかなか取れないことがあります。

そこで考えられたのが、上に上にと植物を育てる「垂直農業」。
部屋の中でも、窓の近くや特別なライトの下で、棚のようなものにいろんな植物を植えて、
おいしい野菜や果物を育てることができるんです。

つまり、垂直農業は「スペースをうまく使って、上に上にと野菜を育てる魔法のような農業」と言えます。

# まとめ

垂直農業って、たてに高く積み上げた棚のようなものに、野菜や植物を植えて育てる方法のこと
DockerDesktopからOrbStackに乗り換えてみる


## 概要

[OrbStack](https://orbstack.dev/)に乗り換えてはや1ヶ月！開発環境が快適になったので記事書きます！

## OrbStackとは？　なぜ興味を持った？

社内で勧めてくれた人がいたから！がズバリ回答なのですが、公式サイトに書かれていることが魅力的なんですよね！

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/330768/83fa55a6-e761-f57f-88d0-be6aa2f89e37.png)

以下の特徴があるらしい。たまにdocker環境が重くなることがあるのでちょっと試して見たくなった

 - 起動速度が速い
 - CPU使用量が少ない
 - Memory消費量が少ない
 - Network速度が速い


## 早速使ってみる



[Downloadリンク](https://orbstack.dev/download)からダウンロード


dockerと同じようにコマンドを打つと...！OrbStackに反映される！！
```
docker run -it -p 80:80 docker/getting-started
```
https://docs.orbstack.dev/quick-start


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/330768/fda6cc2e-d08e-0954-d9dd-20fc53c65f52.png)


## 乗り換えできるか？

実務で使用しているDockerコンテナに関して特に何もいじらず起動できました！

**Use Docker like it’s native**と書いている通り、本当に何もせずです！


## 早くなったのか？

詳しく計測していないが、ストレスを感じなくなったので開発体験は上がっている！





## まとめ

DockerDesktopちょい重いかも？と思っている方はぜひ乗り換えてみては？ということでこの記事を締めます！！
Nuxt3でFirebase Hostingデプロイ時に Error: Failed to find location of Firebase Functions SDK. エラー

Nuxt3をSSRでFirebase Hostingにデプロイしようとしたときにエラーになり詰まったのでメモ


:::note info
バージョン
- Nuxt 3.3.3 
- Firebase 9.9.1
- Firebase functions 4.4.1
:::

# エラー
CDから`firebase deploy`でデプロイしようとしたところ以下のエラーが発生

```
=== Deploying to 'project'...

i  deploying functions, hosting
i  functions: preparing codebase default for deployment
i  functions: ensuring required API cloudfunctions.googleapis.com is enabled...
i  functions: ensuring required API cloudbuild.googleapis.com is enabled...
i  artifactregistry: ensuring required API artifactregistry.googleapis.com is enabled...
✔  functions: required API cloudfunctions.googleapis.com is enabled
✔  artifactregistry: required API artifactregistry.googleapis.com is enabled
✔  functions: required API cloudbuild.googleapis.com is enabled

Error: Failed to find location of Firebase Functions SDK. Please file a bug on Github (https://github.com/firebase/firebase-tools/).
```

`firebase deploy --debug`で詳細を見てみる

```
[2023-08-11T09:35:49.979Z] Building nodejs source
[2023-08-11T09:35:49.981Z] Could not find functions.yaml. Must use http discovery

Error: Failed to find location of Firebase Functions SDK. Please file a bug on Github (https://github.com/firebase/firebase-tools/).
```

# 対応
`functions.yaml`がないとのことだが、諸々調べてみたところ以下の様に、手動でファイルをコピーすれば良さそうとのこと

https://github.com/nuxt/nuxt/issues/13962#issuecomment-1397323740

https://zenn.dev/ytr0903/articles/b77927580cf03c

コメントを参考に以下を実行してから `firebase deploy`で問題なくデプロイできた
```sh
$ mkdir .output/server/node_modules/.bin
$ cp -r node_modules/.bin/firebase-functions .output/server/node_modules/.bin
$ rm -rf .output/server/node_modules/firebase-functions/node_modules/protobufjs
$ cp -rfu node_modules/firebase-functions/ .output/server/node_modules
```
【Linux/ハウスキープ】沢山のファイルを一括で移動できない時点で草

# みなさん、お部屋の掃除していますか

システムエンジニアになると「ハウスキープ」って用語が良く出てきます

新しいシステム開発をする場合、マスタやトランザクションの初期件数と増加傾向見込みから
必要とされるリソースの見積をすることが多かったりしますよね。

まずはシステムは動かすのが最優先、ひとまず何かしら動けばいいとか思っていませんか。
それは駄目。

世の中スピード命。そう。時間と戦いましょう。最後の日まで残り時間はあと少しです。

## 時間の経過とともに成長して太る（表現

マスタデータやトランザクションはDBやらs3やらに格納することは多いと思います。
日に日にデータ量が増加すると売り上げ拡大に繋がることが実感して嬉しいものの
画面の描画がやけに遅くなったりして不平不満が増える時期かも。

postgreSQLなら顕著に問題が出るので vacuum full とか実行したくなったり
pg_repack とか実行したくなったりしますよね。

Oracle なら想定外の性能劣化を避けたいので統計情報固定化したくなったり
統計情報によらず性能維持したいからヒント句を書いたりしたいかも

mySQL はあまり何もしないかと思ったら、やっぱり Oracle みたいなヒント句だらけ。

とはいえ。 DB は他に譲るとして今日はデータファイル自体が一杯になったお話です。
某システムのディスク容量が突然 90%を超過。夜中に電話でたたき起こされる罠。


## ディスクの空き具合とは。

ひとまず端末に接続はできたので容量を確認。

```shell
yamada% df -u
Filesystem      Size  Used Avail Use% Mounted on
/dev/xvdf       250G  225G   25G  91% /data

```

うむむ。残り10%を切ってはいるけど25GBもあるなら ~~急がなくていいんじゃね。~~
たぶん監視レベル間違い。アラートの前に警告とかないのか、とか気になりつつ。

ひとまず容量を占有するホルダを探すことに。適当に awk とか。

```shell
yamada% du -h | awk '{if($1 ~ /G/){print $0}}' | sort -n -r | head -n 5
180G    /data/path/to/campaigns
20G     /data/path/to/work
6.8G    /data/path/to/logs
1.3G    /data/path/to/customers
1.2G    /data/path/to/shell

```

どうしたキャンペーンホルダ。何故 180G。何をキャンペーンしている。

```shell
yamada% cd /data/path/to/campaigns
yamada% ls -lt | wc -l
bash: /bin/ls: Argument list too long

yamada% find . -name '*' -type f -ls | wc -l
bash: /bin/find: Argument list too long

```

ひとまず数を調べようとしたらエラー吐いて落ちるw 
too long ってなんだ。

```shell
yamada% ls -lt | tail -5
-rw-rw-rw- 1 root root 10485763 Apr  9  2017 テストプロモーションキャンペーン(第一弾).log.1
drwxr-xr-x 2 root root        6 Mar 31  2017 log
-rw-rw-rw- 1 root root     1515 Mar 31  2017 テストプロモーションキャンペーン(第二弾).log
-rw-rw-rw- 1 root root     3933 Mar 29  2017 suzuki.zip
-rw-rw-rw- 1 root root     5548 Mar 28  2017 22898.stack

```

それはそれとして 2017年から古いファイルが沢山残っていること確認。
ていうかファイル名が日本語。なんだこれ。
ファイル名にかっことかつけた奴でてこい。
鈴木さん zip とかいらないし。自分の名前でなくてよかった。
もしや（略

ハウスキープのコツは「そのファイルを手につかんで、ときめくか」。
ときめかない（断言）

ひとまず日付を指定して圧縮。
「削除していいかどうか分からない」と鈴木さんがあなたの心に語り掛ける。

```shell
# 件数の確認
yamada% find . -name '*' -newermt '2017/01/01' ! -newermt '2018/01/01' -type f | wc -l
1212

# 圧縮を実行
yamada% find . -name '*' -newermt '2017/01/01' ! -newermt '2018/01/01' -type f | xargs gzip
gzip: ./鈴木-1948-01-31: No such file or directory
gzip: プロモーション.txt: No such file or directory
　；
（大量に同件が発生）

```

むむ。エラーが出た。ファイルを探してみると

```shell
yamada% ls -lt 鈴木-1948-01-31*
total 1515
-rw-rw-rw- 1 root root     1515 Mar 31  2017 鈴木-1948-01-31 プロモーション.txt

```

何故ファイル名に空白をいれるのだ、鈴木さん。
find の結果が２個のファイルと勘違いされた模様。

ただし諦めない。
こんな対策をすれば解決。

```shell
# ファイル名に特殊記号を含む場合は -print0 を指定。xargs には -0 を指定。
yamada% find . -name '*' -newermt '2017/01/01' ! -newermt '2018/01/01' -type f -print0 | xargs -0 gzip

# 同じホルダにまとめて移動したい場合は mv に -t を指定
yamada% find . '*.gz' -type f -print0 | xargs -0 mv -t /data/work/backup/

```

いつも心に太陽を。
夏休みなのにハウスキープをして少し大人になったからOK。

※ただし二度と電話してくるなw
せんせー、 テラヘルツ通信ってなに？

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3194265/2c47de5a-d81a-78f9-53c1-4d31d8398c36.png)

キーンコーンカーンコーン...
授業が始まります

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3194265/be1492ca-910f-2708-d0fa-8fcfcf14af73.png)

せんせー、テラヘルツ通信ってなに？

# テラヘルツ通信とは

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3194265/da229491-9c49-fb7a-a542-417180e256a7.png)

テラヘルツ通信って、ちょっと難しそうな名前だけど、
簡単に言うと「特別な波を使って、情報をすごく早く送る方法」です。

みんな、Wi-Fiやスマートフォンを使って、動画を見たり、ゲームをしたりすることがありますよね。
それは、見えない波を使って、情報を送ったりもらったりしてるんです。

テラヘルツ通信は、その見えない波の中でも、特別な部分を使って、もっとたくさん、
もっと早く情報を送ることができる技術なんです。

例えば、たくさんの人が同じ場所でスマホを使っても、動画がすぐに見られるようになるかもしれません。

だから、テラヘルツ通信は「特別な波で、もっと早くたくさんの情報を送るスペシャルな方法」と考えるとわかりやすいです。

# まとめ

特別な波を使って、情報をすごく早く送る方法
【ChatGPT無】の嘘吐きを利用しよう

:::note info
本記事は、ChatGPT（無料版）で
行なっております。GPT4での確認
はできておりません。あしからず。
:::

　どうも、カーブミラーです。

　今回は、
　　タイトルどおり、
　　　ChatGPTさんの嘘吐きを
　　　　**わざと**使いますw

　なぜ？

　決まっているでしょう？
　　遊ぶためですw

　だいたい、
　　ChatGPTさんは、
　　　ウソを吐かせて
　　　　なんぼのツールですよ。
　　　　　（んな、アホな）

　とにかく、
　　アイディア出しをさせるなら、
　　　ウソを吐かせなきゃ、
　　　　平均的なアイディアしか
　　　　　出てきません！
***
　ということで、
　　やってみました。

>日本で有名な電化製品を、事実5個と推測5個と想像5個を箇条書き（説明不要）で出してください。


ChatGPT
>もちろんです。以下に日本で有名な電化製品を、事実5個、推測5個、想像5個の合計15個を箇条書きで示します。
>
>事実5個：
>1. SonyのPlayStationゲームコンソールシリーズ
>2. Panasonicのテレビや家電製品
>3. Canonのデジタルカメラ
>4. NintendoのSwitchゲームコンソール
>5. Toshibaのノートパソコン
>
>推測5個：
>1. Sharpの次世代スマート家電
>2. Mitsubishiの電気自動車充電インフラ
>3. Hitachiの高性能ロボティクス
>4. Casioの未来型ウェアラブルデバイス
>5. Pioneerの革新的な音響技術
>
>想像5個：
>1. NeoTech社の量子コンピュータ家庭用キット
>2. Zenith CorporationのAI搭載スマート冷蔵庫
>3. Sunbeam Innovationsの折りたたみ式スマートテレビ
>4. NovaLifeの感情認識ロボットコンパニオン
>5. AeroTechの浮遊するスピーカーとホログラフィックディスプレイ
***
　こんな感じですね。

　ちなみに、
　　推測の部分は、
　　　やってても
　　　　おかしくないですね。

　　想像の部分の会社は
　　　実在します。
　　　　業務内容とは、
　　　　　全然、違うけとw

　嘘吐きをさせるポイントは、
　　ウソを吐け、と言わずに、
　　　想像とか、
　　　　ありえそうにないとか、
　　　　　曖昧な言葉を
　　　　　　使うことです。
Javaで「ファイルやディレクトリが存在するか確認する(Files.exists)」の動作を確認してみた

# 概要
Javaで「ファイルやディレクトリが存在するか確認する(Files.exists)」の動作を確認してみました。以下のページを参考にしました。

https://www.javadrive.jp/start/file/index8.html

# 実装
以下のファイルを作成しました。
```JSample8_1.java
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.Files;

class JSample8_1{
  public static void main(String[] args){
    Path p1 = Paths.get("doc/memo1.txt");
    Path p2 = Paths.get("doc");
    Path p3 = Paths.get("doc/report.txt");

    checkFile(p1);
    checkFile(p2);
    checkFile(p3);
  }

  private static void checkFile(Path p){
    System.out.print("名前:"  + p.getFileName() + "は");

    if (Files.exists(p)){
      System.out.println("存在します");
    }else{
      System.out.println("存在しません");
    }
  }
}
```
以下のコマンドを実行しました。
```
$ javac JSample8_1.java 
$ java JSample8_1 
名前:memo1.txtは存在します
名前:docは存在します
名前:report.txtは存在しません
```

# まとめ
何かの役に立てばと。
MDwiki+CloudRunで、簡単に認証つきドキュメントサイトをホスティング

# やること
- ドキュメントをWebで見れるようにする（[こんな](http://dynalon.github.io/mdwiki/#!index.md)見た目）
- ページにはBasic認証をつける
- ドキュメントはMarkdownで管理する
- CloudRunでデプロイする（[無料枠](https://cloud.google.com/run/pricing?hl=ja#tables)でそこそこ使えます）
- ほんとは個別にIAMを管理したいけど、手っ取り早くやりたい

# ファルダ構成

用意するのはDockerfile・index.html・navigation.mdだけです

```
docs/
 ├ markdown/ (ドキュメントはここに入れる)
 │ ├ category_a/ (markdownはカテゴリに分けられる)
 │ │ └ a.md (カテゴリに分けたmdファイル)
 │ └ index.md (トップページのドキュメント)
 ├ Dockerfile (cloudrunに上げるため)
 ├ index.html (MDwiki本体)
 └ navigation.md (ページの構造)
 ```

 
 # ３つのファイルを用意
 
 `Dockerfile`は以下をコピペし、ユーザ名・パスワードを設定してください
 ```docker:Dockerfile
 FROM nginx

# Basic auth
ARG USERNAME=🔒ユーザ名🔒
ARG PASSWORD=🔒パスワード🔒

# Copy the docs to the nginx root
COPY index.html /usr/share/nginx/html
COPY navigation.md /usr/share/nginx/html
COPY markdown /usr/share/nginx/html

# apply basic auth
RUN apt-get update && apt-get install apache2-utils -y
RUN htpasswd -c -b /etc/nginx/.htpasswd ${USERNAME} ${PASSWORD} && cat /etc/nginx/.htpasswd

# edit nginx config
# add basic auth under http block
RUN sed -i "s|http {|http {\n\tauth_basic \"Restricted Content\";\n\tauth_basic_user_file /etc/nginx/.htpasswd;\n|g" /etc/nginx/nginx.conf
```

MDwikiの`index.html`は[ここからダウンロード](https://github.com/Dynalon/mdwiki/releases
)します
https://github.com/Dynalon/mdwiki/releases

`navigation.md`（サイトマップ）は以下を参考に設定してください
```markdown:navigation.md
# サイトのタイトル
[カテゴリ名]()
- [項目名](category_a/a.md)
```

# デプロイ
Dockerfileのあるディレクトリ下でcloudrunに上げるコマンドを叩けば完了です
※gcloudCLIを入れていない場合は[こちら](https://cloud.google.com/sdk/docs/install?hl=ja)を参考にいれてください
```bash
cd docs
gcloud run deploy docs --source . --project 🔒プロジェクト名🔒 --region asia-northeast1 --allow-unauthenticated --port 80 --memory 128Mi --max-instances=50 --cpu 1
```
以上です
VSCodeのおすすめ拡張機能一覧とその使い方


## VSCodeのおすすめ拡張機能一覧とその使い方

Visual Studio Code（以下、VSCode）は、多くの拡張機能を導入することで、開発作業を効率化し、より便利な環境を提供します。以下では、私のおすすめ拡張機能を紹介し、それぞれの使い方について説明します。

### 1. Error Lens

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3527006/424fb531-afef-c879-ed64-261d5cd22e6e.png)


Error Lensは、コード内のエラーや警告を視覚的に強調表示する拡張機能です。エラーや警告の詳細情報を表示することで、問題箇所を素早く特定できます。

使い方：拡張機能をインストールすると、コード内のエラーや警告が色でハイライトされ、エラーの詳細が表示されます。エラー箇所をクリックすると、該当する詳細情報がポップアップ表示されます。

### 2. ESLint

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3527006/23f58d61-6e83-9a74-3ece-1d7fe6d83fe4.png)


ESLintは、JavaScriptやTypeScriptのコードにおける潜在的な問題を検出し、コーディング規約に従っているかをチェックするための拡張機能です。

使い方：拡張機能をインストールし、プロジェクトのルートディレクトリにESLintの設定ファイルを配置します。VSCodeでコードを編集する際、ESLintが問題を検出すると、問題箇所がハイライトされ、指摘内容が表示されます。

### 3. File Tree Generator

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3527006/4103a545-957e-c486-d78f-7fa089dec3cd.png)


File Tree Generatorは、ファイルやフォルダの階層構造を視覚的に生成する拡張機能です。プロジェクトの構造を理解しやすくするのに役立ちます。

使い方：拡張機能をインストールし、右クリックメニューから「Generate Folder Tree」を選択します。ファイルやフォルダの選択後、ツリー構造がテキストとして生成されます。

### 4. GitLens
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3527006/e8196e24-6cb7-fe82-539b-5942c9702a98.png)


GitLensは、コード内の各行の変更履歴や作者情報、ブランチの情報などを表示する拡張機能です。コードの変更履歴を追跡しやすくなります。

使い方：拡張機能をインストールし、コード内で行番号の左側をクリックすると、その行の変更履歴や作者情報が表示されます。

### 5. PostgreSQL
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3527006/1559da95-d3e2-240c-94a8-9906dcca262b.png)



PostgreSQLは、VSCode内でPostgreSQLデータベースとの連携をサポートする拡張機能です。SQLクエリの実行やデータベースの操作が容易になります。

使い方：拡張機能をインストールし、設定で接続情報を指定します。エクスプローラーサイドバーにデータベースと接続するためのアイコンが表示されるので、それをクリックして操作します。

### 6. Japanese Language Pack for Visual Studio Code
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3527006/b1ab1f2b-1206-1e76-0c68-d4d6db8cf457.png)


Japanese Language Packは、VSCodeの日本語言語パックです。インターフェースを日本語化することで、より使いやすくなります。

使い方：拡張機能をインストールし、VSCodeの表示言語を日本語に変更します。これにより、メニューやエラーメッセージなどが日本語で表示されます。

### 7. Todo Highlight
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3527006/9b7a750f-53e9-2f25-9fd2-fb13d5416fb8.png)


Todo Highlightは、コード内のTODOやFIXMEなどのコメントをハイライト表示し、タスク管理を支援する拡張機能です。

使い方：拡張機能をインストールすると、コメント内に含まれる特定のキーワードがハイライト表示されます。これにより、未完了のタスクを見つけやすくなります。

### 8. Zenkaku
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3527006/8a33dff7-66c9-6b92-481c-3d5ced80e413.png)


Zenkakuは、全角スペースや全角文字をハイライト表示する拡張機能です。日本語の文字幅の違いを確認しやすくなります。

使い方：拡張機能をインストールすると、全角スペースや全角文字がハイライト表示されます。テキスト内の文字幅の違いを視覚的に確認できます。



### バックエンドエンジニア向けのおすすめ拡張機能:

1. **Docker**: コンテナ化されたアプリケーションの開発とデバッグを支援します。Dockerコンテナ内でアプリケーションを実行する際に役立ちます。

2. **Remote - SSH**:リモートサーバーにSSH経由で接続し、VSCode内でコードを編集・デバッグするのに便利です。

3. **REST Client**:VSCode内でHTTPリクエストを簡単に作成・テストするためのツールです。APIのテストやデバッグに役立ちます。

### フロントエンドエンジニア向けのおすすめ拡張機能:

1. **Live Server**:HTML、CSS、JavaScriptのコードを編集する際に、リアルタイムで変更をブラウザに反映させるためのローカルサーバーを提供します。

2. **Prettier**: コードフォーマットを統一するためのツールです。コードを美しく整形して読みやすくするのに役立ちます。

3. **CSS Peek**:HTML内でCSSセレクタにマウスオーバーすると、そのセレクタに対応するスタイルルールをプレビュー表示します。
【プラクティス紹介】1分でさらっと分かる「ニコニコカレンダー」

![nico.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3526800/f75c9f92-9c56-80c9-5708-dd8228a374dc.jpeg)

## プラクティス名（別名）
ニコニコカレンダー　（ニコカレ、Mood Marbles）

## プラクティスの目的・狙い
* メンバーの体調管理
* モチベーション可視化
* コミュニケーション促進

## どんな時に使うか
* メンバーの体調（士気）が分からず、突然、体調不良で休む人が多い
* メンバー間のコミュニケーションが希薄で他人の状況に関心がない

## 実施手順
1. プラクティスの目的を説明し、やることを全員で合意する（重要！）
1. 全員が見られる場所（目につく場所）にニコカレを貼る
1. 就業開始時に今日の気分を示す顔シールを貼る（3色程度に色分け）
（タイミングは就業終了時でもよい。チームでどちらかに統一する）
1. 貼られたシールを見て誰かが何かしなければいけないわけではない
（けど本当に声がけの１つも起きない時は趣旨が理解されていないかも）

## アレンジ例
* デイリースクラムをシールを貼りながら軽く雑談するところから始める
* レトロスペクティブでスプリントをふりかえる際の参考情報にする

## アンチパターン
* 青シールが続いているメンバーがいるのに誰も声をかけない
* 判を押したように黄シールを貼り続ける人がいる（＝参加していない？恥ずかしい？）
* マネージャーが監視ツールとして一方的に導入する

## こぼれ話（私的コメント）
[Wikipedia](https://ja.wikipedia.org/wiki/%E3%83%8B%E3%82%B3%E3%83%8B%E3%82%B3%E3%82%AB%E3%83%AC%E3%83%B3%E3%83%80%E3%83%BC)にも載っている日本発祥のプラクティス。
僕が最初に体験したプラクティスがこれでした。当時はまだ普通にウォーターフォール開発でしたが、なんか面白いやり方あるなぁ、とアジャイルなんて言葉も知らずに違和感なくやってました。ニコカレってやってみないと本当の良さが分からないプラクティスの筆頭だと思うんですよね。やる前は「ええ～？」っていう人も多いのですが、いざやってみると「おお～！」に変わるという。

近年テレワークが当たり前になってきたので、ますますこのプラクティスをやる価値が上がっている気がします。

ちなみにシールの3色は好きに決めていいのですが、僕自身は画像に貼ったように赤＞黄＞青を使っています。オリジナルは黄＞赤＞青なんですが、なんとなく赤の方が元気そうに見えてしまうので・・・。信号機のイメージで緑＞黄＞赤というパターンもあるのですが、そうすると黄＝要注意、みたいに捉えてしまう人も出そうです。昔、シールの色で1時間ぐらい議論したのは今となってはいい思い出です。色のイメージって本当に人それぞれなんですよね。

　[アジャイルプラクティス一覧へ戻る](https://qiita.com/kakashi_h5/items/20584998c5ca4594b9ea)
[100万人に届けたい！私のお気に入りガジェット] 買ってよかったガジェット

# はじめに
今年に入ってくらいからPC環境等を改善したいと思い始め、いくつかガジェットを購入しました。その中で買ってよかったと思ったものを3個取り上げたいと思います。

# 骨伝導イヤホン(Shokz OPENRUN)
最初からPC関係ないと言われるかもしれませんが、良かったので紹介します。
何となく気になって購入しました。価格は今は2023年3月頃に購入したときと変わっていましたが、当時で17,000円しないくらいだったと思います。

周囲の音が通常のと比べて聞き取りやすい等メリットはありますが一番良かったのが、**iPhoneで使ってもうるさくない**ことです。
iPhoneと普通のワイヤレスイヤホンの組み合わせだと音量が大きすぎて耳が痛くなり使うのを避けていました。それが改善され耳が痛くなることがなく、ワイヤレスイヤホンの恩恵を受けることができるようになったのが一番良かったです。

短所として、マルチポイントペアリングをしているときにPCから離れるなどにより接続が不安定になるとビープ音が鳴り、意外と目障りに感じる所があります。

あと、サイズはちゃんと測った方がいいです。(サイズが分からずに通常サイズを買ったら少し大きかったです。使えないことはないですが少し気になる...)


https://jp.shokz.com/products/openrun

https://cdn.shopify.com/s/files/1/0271/5389/1376/files/Find_your_size_JP.pdf

# モバイルモニター(Intehill U16NA)
環境的に一般的なサイズのモニターを設置できないためコンパクトなモバイルモニターを購入しました。
ノートパソコンが4Kなので同じ解像度のものを探し、色々なモニターがある中でデザインに気に入ったのと、VESAマウントに対応しているため今後モニターアームで固定できるのも魅力だと感じました。
あと、ケーブルの種類は分からない(**明記されてはいない**ですが多分thunderbolt3/4程度の性能があると推定)ですがType-CのPDで充電できるケーブルが2本ついてくるのは使い道はいくらでもあるので良かったです。

ただ価格がクーポン等があっても3万と普通のサイズならゲーミングモニターが買えるくらいだと思うので、コスパを考えたらあまりいいとは言えないと思います。

https://www.amazon.co.jp/dp/B0BYRWQSPY

# ノートパソコンスタンド
目線を高くすることで体の負担は減ったような気がします。
実はこれ以外にも安いスタンドを購入したことがありますが、これは高さ調整等が柔軟にできるため圧倒的使いやすいです。
これより安くて似たものがあると言われるかもしれませんが、この製品はスタンディングでも使えるくらいの高さ(公式サイトによると最大約40cm)まで調整出来ます。この点は他製品よりも結構柔軟だと思います。

欠点として値段が高いです。筆者は公式オンラインストアではなくヨドバシカメラで9000円しないくらいで、少しだけ安く購入しましたが、それでもノートパソコンスタンドにしては少し高いです。

https://kingjim.com/products/nps15


# おわりに
今回は買って良かったものを紹介しました。
また何か買ったら追記していきたいと思います。
最後まで読んでいただき、ありがとうございました。
UIライブラリとCSSフレームワークの違い

# 結論

UIライブラリは主にコンポーネントを提供し、CSSフレームワークは主にスタイルやレイアウトを提供する。

# UIライブラリとは

### 目的

完全なUIコンポーネントやUIウィジェットを提供するための一連の**JS**と**CSS**

### 内容

- ドロップダウン、モーダル、スライダーなどのコンポーネント
- 高度なウィジェット(カレンダー、カラーピッカーなど)

※コンポーネントはUIを構成する基本的な部品であり、それ自身は情報や機能を持たない。一方、ウィジェットはUIを構成するツールのようなものであり、それ自身が特定の情報や機能を持つ。

### 例

- Material-UI (React)
- Chakra UI (React)

# CSSフレームワークとは

### 目的

スタイルや定義を提供するための一連の**CSSクラス**と**スタイル定義**

### 内容

- グリッドシステム
- ボタンなどの基本的なUIコンポーネントのスタイル
- ユーティリティクラス(margin、padding調整用のクラス)

### 例

- Bootstrap
- Tailwind CSS
GPTで使われるtemperatureパラメータとは

## はじめに

GPTなどの言語モデルで文章生成を行う際に使用されるtemperatureパラメータについて調べました。

## temperatureパラメータとは

生成されるテキストの**多様性**を制御するパラメータ。

### 詳細

GPTや他の多くの言語モデルは、次に来る単語を予測するために確率分布を使用しており、各単語には次に来ると予測される確率が割り当てられている。

この確率分布は一般的にはピークがある(一部の単語のみが確率が高くなる)形状をしている。

temperatureパラメータはこの確率分布を調整している。

- temperatureが高い場合
    - 各単語の出力確率分布がフラットになり、全ての単語の選ばれる確率が等しくなる ⇒生成されるテキストはより多様性があり、予測が難しい
- Temperatureが低い場合
    - 一部の単語が選ばれる確率が高くなる ⇒生成されるテキストは一貫性があり、予測が簡単になる

## temperatureの使用例

### 高いtemperature (多様性が高く予測困難)

新しいアイデアやクリエイティブな結果が必要な場面で役立つ

- 創作物(小説、詩、映画の脚本など)
- ブレインストーミングやアイデア生成

### 低いtemperature (一貫性が高く予測可能)

予測可能で一貫性のある結果が必要な場面で役立つ

- 法的/規則に関連する文書生成
- 教科書や学術的な記事の生成
インフラ弱者にもわかりやすく Terraform についてまとめてみた

インフラもterraformも全くわからん人に向けて簡単にまとめてみました。
ここではクラウドインフラ（特にGCP）を例に説明します。

# TL;DR
- AWSやGCPのようなクラウドインフラはコンソール画面からボタンをポチポチして扱うサービスを管理したり設定値を変更することができます
- しかしそれだと下記のような問題点があります
    - 「いつ、誰が、どのような設定を変更したのか」が把握できない
    - 新しい環境（ステージング環境など）を作成する際に、コンソール画面から手動で同じ手順を踏まないといけない
    - ドキュメントが更新されていないと既存のインフラの環境を把握が困難
- terraform を使えば**インフラの設定をコードで管理**することができます。それにより下記のようなメリットがあります。
    - コードで管理できるので変更の履歴を確認できる
    - １つ環境を作ってしまえば他の環境にも設定を使いまわせる（手動でポチポチしなくてもいい）
    - コードが読めれば既存のインフラの環境を把握できる

# terraformとは
- HashiCorp社によって開発されたOSSで、**IaCツール**の１つである。
- IaCツールとは、`Infrastructure as Code`の１つで、AWSやGCPなどクラウドなどシステム開発に必要なインフラを、コードを記述することにより自動で構築できる。
- つまりインフラも開発と同様にコードで管理することができます

# コードでインフラを管理するとは？
いまいちイメージが湧きづらいと思うので、どうやって管理するのか見てみましょう。terraform ではHashiCorp Configuration Language (HCL) という独自の言語を使用して設定ファイルを記述します。

実際にGCPのプロジェクトをterraform で管理するには下記のような手順を踏んで設定できます。

## 1. プロバイダの設定（どのクラウドベンダーを使用するか）
最初にTerraformにGCPを使用することを伝え、認証情報を指定します。
```hcl
provider "google" {
  credentials = file("<PATH_TO_YOUR_SERVICE_ACCOUNT_KEY_JSON>")
  project     = "<YOUR_PROJECT_ID>"
  region      = "us-central1"
}
```

## 2. 使用するリソースの定義
次に使用するリソースの定義を書いていきます。ここではGCEの仮想マシンインスタンスを作成します。
```hcl
resource "google_compute_instance" "default" {
  name         = "terraform-instance"
  machine_type = "n1-standard-1"

  boot_disk {
    initialize_params {
      image = "debian-cloud/debian-9"
    }
  }

  network_interface {
    network = "default"

    access_config {
      // 外部IPを持つように設定
    }
  }
}

```
上記のコードでは、n1-standard-1のマシンタイプでdebian-9のイメージを使用して、名前がterraform-instanceの仮想マシンインスタンスを作成します。


## 3. インフラの適用

以下のコマンドを実行して、インフラの変更を計画し、実際にリソースを作成します。

```hcl
terraform init   # プロジェクトの初期化
terraform plan   # 変更の確認
terraform apply  # インフラの変更の適用
```

# terraform を使うメリット
個人的にterraformを少し触ってみて感じたメリットです。

## 1. インフラが身近なものに感じた
普段はコードをガリガリ書いて開発しており、インフラ周りにはあまり詳しくありませんでした。AWSやGCPはコンソールでよくわからん画面をぽちぽちしながら構築していくイメージだったのですが、コードで管理されていることによって、「今のプロジェクトのインフラ構成ってこうなってるんだ」と理解することができました。インフラ構成図を使えば視覚的に把握はできてわかりやすいのですが、構成図が古いままだったり、細かな設定値までは図だけでは理解できないので、コードから追っていくことでより詳細に理解できるようになったと思います。

## 2. 新しい環境をすぐに用意することができる

新しい機能を開発する際に「既存のプロジェクトの他に、ステージング環境用に別のプロジェクトを立ち上げたい」時に非常に便利だなと感じました。定義されたコードに基づいて一貫してインフラをデプロイできるので、新しい環境のセットアップやテスト環境、ステージング環境の準備が簡単になりました。

## 3. インフラの変更が管理しやすい

インフラをコンソール画面だけで管理していると、「誰がどのタイミングでどんな変更を施したか」を把握できなくなってしまいます。TerraformのコードはGitのようなバージョン管理システムで管理できるため、変更履歴が追跡可能です。これにより、どの変更がいつ、誰によって行われたかを確認することができます。また、Terraformのplanコマンドを使用すれば、変更が適用される前にその変更が何をもたらすかを予測することができます。


# 参考
https://www.terraform.io/

https://cloud.google.com/docs/terraform?hl=ja
【Python】*argsと**kwargs

# 【Python】*argsと**kwargs

`*args`とは・・任意の数の引数を受け取る関数名
(argumentsの略)
`**kwargs`とは・・呼び出し側のキーワード引数をまとめて受け取れる関数名
(keyword argumentsの略)

ちなみに、argumentとはIT業界では、`関数やメソッドを呼び出す際に、引き渡される値や変数のこと`みたいです。

## *argsについて
```py:args
def number(*args):
    print(args)


number(1, 2, 3, 4, 5)
number(6, 7, 8, 9, 10)
```
```py:実行結果
(1, 2, 3, 4, 5)
(6, 7, 8, 9, 10)
```
※引数をタプルとして受け取っています。

```py:残りは任意の引数を受け取る方法
def number(a, b, *args):
    print('a:', a)
    print('b:', b)
    print('rest:', args)

number(1, 2)
number(1, 2, 3, 4)
```
```py:実行結果
a: 1
b: 2
rest: ()
a: 1
b: 2
rest: (3, 4)

```

---

## **kwargsについて

```py:kwargs
def number(**kwargs):
    print(kwargs)


number()
number(a=1, b=2)
```
```py:実行結果
{}
{'a': 1, 'b': 2}
```
※キーワード引数は辞書で受け取っています。

```py:デフォルト引数との組み合わせ
def number(a=0, **kwargs):
    print('a:', a)
    print('kwargs:', kwargs)

number()
number(a=1, b=2)
number(a=1, b=2, c=3, d=4)
```
```py:実行結果
a: 0
kwargs: {}
a: 1
kwargs: {'b': 2}
a: 1
kwargs: {'b': 2, 'c': 3, 'd': 4}
```

---

## *argsと**kwargsの組み合わせ

```py
def number(*args, **kwargs):
    print('args:', args)
    print('kwargs:', kwargs)

number()
number(a=1, b=2)
number(1, 2, c=3, d=4)
```

```py:実行結果
args: ()
kwargs: {}
args: ()
kwargs: {'a': 1, 'b': 2}
args: (1, 2)
kwargs: {'c': 3, 'd': 4}
```
配列の最後の要素を取り出す

### ＜問題＞下記の配列の最後の要素を取り出すには？
```ruby
shiritori = ["りんご", "ゴリラ", "ラッパ", ...(途中は省略)... ,  "みかん"]
puts  [A]
```
### ＜回答＞
```ruby
shiritori = ["りんご", "ゴリラ", "ラッパ", ...(途中は省略)... ,  "みかん"]
puts shiritori[shiritori.length - 1]
```
### ＜解説＞
この問題のポイントは**配列の要素の数が分からない**という点です。
最後の要素は[配列の要素数 - 1]で取得ができます。
そこで**lengthメソッド**を使います。lengthメソッドを使えば正確に配列の要素数がわかります。プログラムは**0**から始まるため、「-1」をすることで配列の最後の要素を取り出すことができます。
2023: Week 32 - HR Month - Reshaping Generations/Preppin' Data/Tableau Prep

# Challenge Preppin'Data 2023:Week 32

## 概要
世代区分名を生成し、従業員のdate_of_birth(誕生日)から世代区分名を従業員データに付加します。
![変換１.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3531257/a8f45020-ce54-3fe9-ff66-73c66cce71cf.png)

date_of_birth(誕生日)から年代に区分します。
![変換2.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3531257/37620a6c-709a-f345-5457-46e8ee2554c1.png)



## 問題のページ（英語）※ここからデータをダウンロード
https://preppindata.blogspot.com/2023/08/2023-week-32-hr-month-reshaping.html

## 出題者の回答のページ（英語）※動画あり
https://preppindata.blogspot.com/2023/08/2023-week-32-solution.html

## 自分の解決法

![preppindata_week32_20230812.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3531257/3250d155-6fff-7e9f-116c-145706bb1dc4.png)


## ポイント
### 年齢の計算
IF DATEADD('year', DATEDIFF('year', [date_of_birth], [month_end_date]), [date_of_birth]) > [month_end_date] 
	THEN DATEDIFF('year', [date_of_birth], [month_end_date]) -1
ELSE
	DATEDIFF('year', [date_of_birth], [month_end_date])
END

### 年代の計算（5歳刻み）
IF [employee's age] < 20 THEN "Under 20 years"
ELSEIF [employee's age] >=70 THEN "70+ years"
ELSEIF ISNULL([employee's age]) THEN "Not Provided"
ELSE STR(div([employee's age],5) * 5)  + "-" +  STR(div([employee's age],5) * 5 + 4) +  " years"
END
Azure API Management Service での CORS設定

API Management ではPolicyを使ってCORSの設定を行う。

CORSの設定は、API単位でも設定可能だが、Operation単位でも設定可能。

以下、Operationに追加する場合のXML例。

```xml
<policies>
    <inbound>
        <cors allow-credentials="false">
            <allowed-origins>
                <origin>https://sample1.com</origin>
                <origin>https://sample2.com</origin>
                <origin>https://sample3.com</origin>
                <origin>https://sample4.com</origin>
            </allowed-origins>
            <allowed-methods>
                <method>GET</method>
            </allowed-methods>
            <allowed-headers>
                <header>*</header>
            </allowed-headers>
        </cors>
        <base />
    </inbound>
    <backend>
        <base />
    </backend>
    <outbound>
        <base />
    </outbound>
    <on-error>
        <base />
    </on-error>
</policies>
```

全てのクライアントに対して許可する場合は次の通り。

```xml
<policies>
    <inbound>
        <cors allow-credentials="false">
            <allowed-origins>
                <origin>*</origin>
            </allowed-origins>
            <allowed-methods>
                <method>GET</method>
            </allowed-methods>
            <allowed-headers>
                <header>*</header>
            </allowed-headers>
        </cors>
        <base />
    </inbound>
    <backend>
        <base />
    </backend>
    <outbound>
        <base />
    </outbound>
    <on-error>
        <base />
    </on-error>
</policies>
```

注意点
* `<cors>` の後に `<base />` を書く必要がある。