OmniAICreator/Qiita-1.07M huggingface dataset:
GoでExcelデータを読み込む方法

Excelに一覧として持っているメールアドレスや会社名などの情報を読み込み、処理に使用するよう構造体へ格納する、ということを行ったため、Goで実装する方法をまとめます。

# GoでExcelの操作をするには
[excelize](https://github.com/qax-os/excelize) というライブラリを使用します。

# excelizeのインストール
下記コマンドを実行して、excelizeをインストールします。

```cmd
$ go get github.com/xuri/excelize/v2
```

# Excelファイルを読み込む
Excelファイルを読み込みます。
今回は以下のような、リストを持つファイルをあらかじめ作成しました。

ファイル名: 宛先.xlsx
| 会社名       | 担当者名   | メールアドレス             |
| ------------ | ---------- | -------------------------- |
| 株式会社A    | 田中太郎   | tanaka@example.com         |
| B株式会社    | 山田花子   | yamada@example.com         |
| C企画有限会社 | 佐藤一郎   | sato@example.com           |

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1098117/9447e2ff-d92d-4c01-9681-573f4260123e.png)

```golang:main.go
package main

import (
    "fmt"

    "github.com/xuri/excelize/v2"
)

func main() {
    f, err := excelize.OpenFile("./excel/宛先.xlsx")
    if err != nil {
        fmt.Println(err)
        return
    }
    defer func() {
        if err := f.Close(); err != nil {
            fmt.Println(err)
        }
    }()
    
    // リストが載っているシートすべての行を取得
    rows, err := f.GetRows("Sheet1")
    if err != nil {
        fmt.Println(err)
        return
    }
    
    // 取得した行の各カラムを表示
    for _, row := range rows {
        for _, colCell := range row {
            fmt.Print(colCell, "\t")
        }
        fmt.Println()
    }
}
```

```cmd
$ go run main.go

        会社名  担当者名        メールアドレス
        株式会社A       田中太郎        tanaka@example.com
        B株式会社       山田花子        yamada@example.com
        C企画有限会社   佐藤一郎        sato@example.com
```

# 読み込んだセルの値を構造体に格納
読み込んだセルの値を後の処理で使用できるように、構造体に格納します。

```golang:main.go
package main

import (
	"fmt"

	"github.com/xuri/excelize/v2"
)

type atesakiType struct {
	CompanyName string
	Name        string
	Mail        string
}

func main() {
	f, err := excelize.OpenFile("./excel/宛先.xlsx")
	if err != nil {
		fmt.Println(err)
		return
	}
	defer func() {
		if err := f.Close(); err != nil {
			fmt.Println(err)
		}
	}()

	// リストが載っているシートすべての行を取得
	rows, err := f.GetRows("Sheet1")
	if err != nil {
		fmt.Println(err)
		return
	}

	// 構造体リストに格納
	var atesakiList []*atesakiType
	for index, row := range rows {
		// 1行目はヘッダーなので除外
		if index < 1 {
			continue
		}

		atesaki := &atesakiType{
			CompanyName: row[0],
			Name:        row[1],
			Mail:        row[2],
		}
		atesakiList = append(atesakiList, atesaki)
	}

	for _, atesaki := range atesakiList {
		fmt.Println("会社名: " + atesaki.CompanyName)
		fmt.Println("担当者名: " + atesaki.Name)
		fmt.Println("メールアドレス: " + atesaki.Mail)
	}
}
```

```cmd
$ go run main.go
会社名: 株式会社A
担当者名: 田中太郎
メールアドレス: tanaka@example.com
会社名: B株式会社
担当者名: 山田花子
メールアドレス: yamada@example.com
会社名: C企画有限会社
担当者名: 佐藤一郎
メールアドレス: sato@example.com
```

# おわりに
Excelの値をGoで読み込む方法をまとめました。
この読み込んだ値をもとに、各宛先へテンプレートに従ったメールを作成したのですが、そちらについてはまた後ほどまとめたいと思います。
Railsでの命名　単数複数形使い分け

### モデル名

- **形式**: 単数形
- **例**: User, Product, Order
- **理由**: モデルは1つのオブジェクトを表すため
- **参考コマンド**: ```rails generate model Post content:text```
    （postsテーブルにtext型のcontentカラムを作成）

### コントローラー名

- **形式**: 複数形
- **例**: UsersController, ProductsController, OrdersController
- **理由**: コントローラーは複数のリソース(モデルのインスタンス)を扱うため
- **参考コマンド**: ```rails generate controller Posts home about```
    （home,aboutアクションを持つPostsコントローラーを作成）

### テーブル名

- **形式**: 複数形
- **例**: users, products, orders
- **理由**: 1つのテーブルには複数のレコードが格納されるため

### カラム名(属性名)

- **形式**: 単数形
- **例**: name, price, created_at
- **理由**: カラムは1つのレコードの属性を表すため

### ルーティング

- **形式**: 複数形
- **例**: /users, /products
- **理由**: ルーティングはリソース全体を表すため
viteを使用してみた

## vite
> 現代の Web プロジェクトのために、より速く無駄のない開発体験を提供することを目的としたビルドツール 

https://ja.vitejs.dev/guide/

### 環境
```shell-session
$ node --version
v18.15.0

$ npm -v         
9.5.0
```

### 導入
```shell-session
$ npm create vite@latest

Need to install the following packages:
  create-vite@5.2.3
Ok to proceed? (y) y
✔ Project name: … frontend
✔ Select a framework: › React
✔ Select a variant: › TypeScript + SWC
```

#### 補足）SWC
- [ドキュメント](https://swc.rs/)
> 次世代の高速開発ツールのための拡張可能な Rust ベースのプラットフォーム

:::note info
これで「frontend」という名前のフォルダが作成され、viteを無事構築完了
:::


### 動かしてみる
```shell-session
$ cd frontend
$ npm install
$ npm run dev
```

http://localhost:5173/

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3329005/95ca25a1-66b6-b3db-e742-05715d2db246.png)

# 次回予告

https://qiita.com/Qiitakumin/items/914602de042e029ba7f4

# 参考
Golangの関数におけるポインタレシーバーと値レシーバーの違い

Golang（Go言語）では、関数を定義する際に、ポインタレシーバー（Pointer Receiver）と値レシーバー（Value Receiver）の2つのオプションがあります。これらは、メソッドを構造体に関連付ける方法を定義します。

### 値レシーバー（Value Receiver）

値レシーバーは、関数が特定の型の値をレシーバーとして受け取ることを示します。このような関数は、そのレシーバーが持つ値のコピーに対して動作します。つまり、レシーバーのフィールドの変更は、元のオブジェクトには影響を与えません。値レシーバーを使用することで、メソッドがオブジェクトを変更しないことを保証することができます。

### ポインタレシーバー（Pointer Receiver）

ポインタレシーバーは、関数が特定の型のポインタをレシーバーとして受け取ることを示します。つまり、関数はそのポインタが指すオブジェクト自体を変更することができます。この場合、関数内での変更は元のオブジェクトに影響を与えます。

```go
package main

import "fmt"

type Rectangle struct {
    width, height float64
}

// value receiver
func (r Rectangle) SetValue(width, height float64) {
    r.width = width
    r.height = height
}

// pointer receiver
func (r *Rectangle) SetPointer(width, height float64) {
    r.width = width
    r.height = height
}

func main() {
    rect := Rectangle{width: 10, height: 5}

    // value receiver    
    rect.SetValue(20, 10)
    // Output: Width: 10 Height: 5
    fmt.Println("Value receiver - Width:", rect.width, "Height:", rect.height) 

    // pointer receiver
    rect.SetPointer(20, 10)
    // Output: Width: 20 Height: 10
    fmt.Println("Pointer receiver - Width:", rect.width, "Height:", rect.height) 
}

```

ポインタレシーバーを使用すると、関数がオブジェクトを直接変更できるため、大規模なオブジェクトの操作やメモリ効率の向上が可能になります。ただし、誤ってオブジェクトを変更する可能性があるため、注意が必要です。


https://go.dev/play/p/e-Nl7qU1aP9
ポートフォリオのLightHouseのスコアを40点アップしてみた

こんにちは、びわ湖の限界大学生兼フロントエンドエンジニアのお茶です。
長年学生をして、だんだんベテラン学生になってきました。
今回は、自分のポートフォリオサイトのlighthouseスコアを40点上げるために取り組んだパフォーマンスチューニングについて書いていきます。
https://お茶.dev

## 技術構成
- フレームワーク:Next.js
- デプロイ環境:Vercel
- CMS:MicroCMS
- CSSフレームワーク:ChakraUI,Mantine
- グラフィックス:Three.js

そこまで特殊な技術構成ではないと思います。
お手軽JAMstackアーキテクチャの構成です。
強いて変わっているところを上げるとThree.jsでパーティクルアニメーションが入っているところだと思います。

## 背景
今回、パフォーマンスチューニングを行ったきっかけとしてはポートフォリオサイトの管理画面を作ろうということで、Bun + TurboRepoのモノレポの新基盤へ移設作業を行なっていました。
もちろんそのまま移設することもできたのですが、せっかくならばこの機会にメンテナンスしておこうといった気分になり今回のチューニングを行いました。

### チューニング前のスコア


![スクリーンショット 2024-04-05 7.53.33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2982370/c44286a8-d0c7-c5d8-2d5e-f8b9546c7a60.png)

![スクリーンショット 2024-04-05 8.31.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2982370/c952c6ee-fe27-dfdc-ca69-0958f9cfc54a.png)


スコアの結果は44点でした。測定結果からすぐに対応できそうな項目を洗い出してみます。

- 画像のサイズがでかい
- 不要なJSがありそう
- ファーストビューが最適化されてなさそう

## 改善したこと
### 画像圧縮
シンプルに画像を圧縮するだけです。使用している画像を全て肉眼で影響の無い範囲で圧縮してwebpへ変換しました。
圧縮にはSquooshが圧縮前後のサイズと画像の劣化具合を比較しながら作業できるので便利です。
https://squoosh.app/

### 画像最適化
今回は、Next.jsとVercelを使っているのでNextImageを使いました。既存のImage部分をNextImageへと置き換えまともに求めらるPropsを埋めるだけで結構マシになります。
トップビューで表示される画像は遅延読み込みされると困るので
`loading=eager`を渡しておきました。
![スクリーンショット 2024-04-05 14.28.11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2982370/b317be1f-2d8a-95de-8042-775d03027b4b.png)


### ChakraUIを剥がす
ChakraUIのスタイリングはemotionに依存しているので結局はCSSinJSでスタイルが当たっています。
今回のポートフォリオサイトは大部分をChakraUIで実装していました。

- JSで動的にランタイム時にスタイルを作るのでもっさりする
- 今回のスタイルの大半がJSで生成されている
- Propsにベキベキにスタイルが渡されていてメンテしづらい

CSSフレームワークが悪いわけでは無いのですが今回は実装コストの高い要素も無かったのでそもそも必要なかったです。コンポーネントごとにスタイルを書くにもPropsを荒らすくらいならCSSModulesで十分なので今回の場合はCSSinJSの優位性は薄いと思います。
Chakraを濫用していた部分をCSSModulesで書き直しただけで大幅にJSをダイエットすることができました。

### 横着に外部からimportしない
ページ内で使用するアイコンやコンポーネントを使用するもののみをimportするようにしました。
```ts
import * as THREE from 'three'
```
このようにthreeを丸ごとインポートするのではなく
```ts
import { SphereGeometry } from 'three'
```
実際に使うものだけをimportすることで少しでも無駄なものを減らしていきます。

### altなどの表示に関係ない要素もきちんと埋める
当然ですが、非視覚要素もきちんと埋めるとアクセシビリティは割と簡単に上がります。
パフォーマンスほどの魔境でもないので極力埋めるようにしましょう。

### PWA化
スコアには関係ありませんが、PWAの項目が一応あります。
Next.jsを使っているのでNext-PWAでPWA化しました。
https://github.com/shadowwalker/next-pwa

## 結果
![スクリーンショット 2024-04-05 7.35.00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2982370/2d5cde65-ae21-6353-266f-455869985c8b.png)


40点アップです！
実際に手元で確認してみても目視でわかる程読み込み速度が改善されていました。
これで通信回線が貧弱であってもスムーズに読み込まれると思います。

### 余談
web-packのwebpack-bundle-analyzerを使えばビルドされたアプリ内の各パッケージ内容を視覚化して表示してくれます。
更なる改善を目指して解析してみたところ...。
![スクリーンショット 2024-03-30 6.24.52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2982370/e693eda5-fd1b-0b7e-7ece-501022db17d0.png)


詰んでいました。トップページのパーティクルアニメーションを実装しているThree.jsで埋め尽くされています。
グラフィックスを表示した上でこれ以上のパフォーマンスアップは難しそうでした。
【Vue3】PropsにEnumで定義した自作型を指定する方法2選(ts2769対策)

# やりたいこと

- Vue3のコンポーネントで`props`の型を定義したい
    - Enumで作った自作型を指定したい
    - コンポーネントはVue3のComposition APIで定義するものとする
        - `<script setup>`内の`defineProps`で`props`を定義する

※`<script setup>`についてはコチラから↓

https://ja.vuejs.org/api/sfc-script-setup

# ダメーな例: ts2769が出ちゃうやつ

筆者が当初、TypeScriptランタイムからトムブラウン風に「**ダメー**」と言われちゃったコードがこちらです。

```vue
<!-- とあるコンポーネント -->
<script setup lang="ts">
import { defineProps } from 'vue';
import { Page } from '@/enums';

const props = defineProps({
  currentPage: {
    required: true,
    type: Page, // No overload matches this call...(ts2769)
  }
});
</script>
```

このコードでは、別ファイルで定義されたEnum型のPageを`props`の`type`に指定しようとしていますが、TypeScriptエラーが発生します。

`defineProps`で定義する際は、`type`に指定する型をVueが提供している組み込みの型で定義してあげる必要があるのですが、どうやらTypeScript特有のEnum型は組み込みに含まれていないようです。それが原因で「**ダメー**」が起きています。

※多分同じことで困っている~~型々~~方々↓

https://stackoverflow.com/questions/69479116/how-to-expect-and-pass-in-enum-as-a-component-property

https://github.com/kaorun343/vue-property-decorator/issues/202

# 解決法

## 方法1. アロー式を使う

Enumで定義した自作型を`type`に指定する方法の一つとして、アロー式を使用する方法があります。

```vue
<script setup lang="ts">
import { defineProps } from 'vue';
import { Page } from '@/enums';

const props = defineProps({
  currentPage: {
    required: true,
    type: String as () => Page,
  }
});
</script>
```

`String as () => Page`が肝です。`as`演算子の後ろで`Page`型(Enum)へ変換するための関数型を記述することで型アサーションを実現しています。

要は**TypeScriptの機能**を用いて解決しているのが、この解決方法と言えます。

## 方法2. PropTypeを使う

もう一つの方法として、Vue3の`PropType`を使用する方法があります。これは、Vue3の組み込みの型指定機能を利用する方法です。

```vue
<script setup lang="ts">
import { defineProps, PropType } from 'vue';
import { Page } from '@/enums';

const props = defineProps({
  currentPage: {
    required: true,
    type: String as PropType<Page>,
  }
});
</script>
```

今度は`String as PropType<Page>`が肝です。当然、PropTypeはVueの組み込みの型なので、当初出ていたエラーは消えます。おめでとうございます。

**Vue.jsの機能**を用いて解決しているのが、この解決方法と言えます。

# どちらを選ぶべきか

Vue.jsのプロジェクトである以上、`props`の定義に際しては「**方法2. PropTypeを使う**」の方が一般的な解決方法なのかと考えています。

公式ドキュメントでも`PropType`の利用を推奨している雰囲気があります。

https://ja.vuejs.org/guide/typescript/composition-api

とはいえ、`props`に関わらない場面で普通に型アサーションを使う機会は多くあるので、その際にはアロー式を使うこともあるはずです。場面に応じて使い分けましょう、と思いました。

# まとめ

TypeScriptたのしいね！！！

![Qiitaに怒られた](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2518330/34577358-0e31-f735-acff-0766e7e8a010.png)
Webアプリケーションにおけるストレージ~cookie,webStorage編~


## **はじめに**

Webアプリケーションを開発する際、サーバーから取得した情報をローカルに保存しておく必要がある場面があります。そのような場合に利用するのがストレージです。ストレージには主に2つの種類があり、それぞれ特徴や利用用途が異なります。本記事では、CookieとWeb Storageについて詳しく解説します。

## **Cookieとは**

Cookieは、JavaScriptの初期から存在するストレージであり、利用が容易である一方、汎用的なストレージとしての利用は推奨されません。Cookieは、サーバーからset-cookieレスポンスヘッダを使ってブラウザに送信される小さなデータで、その内容はブラウザ内に保存されます。ページを遷移したり、ブラウザを再起動しても維持するように設定することができます。ブラウザはサーバーと通信する際に、そのサーバーが保存したCookieがあれば、その内容をリクエストヘッダに含めて送信します。

Cookieの主な利用用途は、セッションの管理やHTTPリクエストのグループ化です。例えば、ログインのためにIDとパスワードを入力しても、次のリクエストの時には持ち越すことができません。Cookieは基本的にサーバー側で利用する情報を保持するためのものであり、クライアント側だけで必要な情報を保持する用途には向いていません。

### Cookieには、以下のような属性を設定することができます：


- path：Cookieを適用するパスを指定します。
- domain：Cookieを適用するドメインを指定します。
- max-age：Cookieの有効期限を秒単位で指定します。
- expires：Cookieの有効期限を日付で指定します。
- samesite：Cookieの送信条件を指定します。

```
// Cookieに保存する値を設定
const value = 'example_value';

// Cookieの有効期限を設定（1日後に設定）
const maxAge = 24 * 60 * 60;
const expires = new Date();
expires.setTime(expires.getTime() + maxAge * 1000);

// Cookieを設定
document.cookie = `my_cookie=${value}; path=/; domain=example.com; max-age=${maxAge}; expires=${expires.toUTCString()}; samesite=lax`;
```

Cookieは同期的に動作し、小容量のデータを扱うのに適しています。ただし、データ容量に制限があり、一般的には4KBまでとされています。また、Cookieはすべてのリクエストに付加されるため、大量のデータを保存するとパフォーマンスに影響を与える可能性があります。

## **Web Storageとは**

Web Storageは、HTML5で導入されたストレージであり、CookieよりもデータのKB制限が大きく、ドメインごとに5〜10MB程度のデータを保存できます。Web Storageには、Local StorageとSession Storageの2種類があります。

Local Storageは、保存したデータが永続的に保持されます。一方、Session Storageは、ブラウザを終了する（タブを閉じる）とデータが削除されます。それぞれのストレージには、グローバル変数のlocalStorageとsessionStorageを通じてアクセスすることができます。

Web Storageは、クライアント側でしか利用されないデータの保持に適しています。例えば、ユーザーの設定情報やアプリケーションの状態などを保存するのに便利です。ただし、Web Storageは値として文字列しか受け付けないため、オブジェクトを保存する場合はJSON.stringify()を使ってシリアライズする必要があります。

### Web Storageでは、以下のようなメソッドを使ってデータの読み書きを行います：

- getItem(key)：指定したキーに対応する値を取得します。
- setItem(key, value)：指定したキーと値のペアを保存します。
- removeItem(key)：指定したキーとその値を削除します。
- clear()：すべてのキーと値のペアを削除します。

## **CookieとWeb Storageの使い分け**

CookieとWeb Storageは、それぞれ特徴や利用用途が異なるため、適切に使い分ける必要があります。以下に、それぞれの特徴をまとめます：

- Cookie
 - サーバーとクライアントの間で情報を共有する
 - 小容量のデータを扱う
 - すべてのリクエストに付加される
 - 有効期限を設定できる
- Web Storage
 - クライアント側だけで情報を保持する
 - 大容量のデータを扱う
 - リクエストに付加されない
 - 有効期限を設定できない（Session Storageを除く）

一般的に、サーバー側で利用する情報を保持する場合はCookieを、クライアント側だけで利用する情報を保持する場合はWeb Storageを使用します。ただし、セキュリティ上の理由から、機密性の高い情報をWeb Storageに保存することは避けるべきです。

## **まとめ**

本記事では、WebアプリケーションにおけるストレージのうちCookieとWeb Storage（Local StorageとSession Storage）について解説しました。Cookieはサーバーとクライアントの間で情報を共有するのに適しており、Web Storageはクライアント側だけで情報を保持するのに適しています。それぞれの特徴を理解し、適切に使い分けることが重要です。

ストレージの選択には、データの容量、保存期間、利用目的などを考慮する必要があります。アプリケーションの要件に合わせて適切なストレージを選択し、データの保存と管理を効果的に行いましょう。
無駄なWebフォントを廃止してパフォーマンスを改善する

# はじめに
サイトスピード改善方法のひとつとして、Webフォントの見直しは効きやすいのでシェア。

# 問題
FCPの値が悪く、RenderBlockingと言われている。
見るとWebフォントがすべて書かれているので、無駄な読み込みをなくしたい。

# 解決方法

まずfont-weightを調べる。
400がregular、700がboldなので、基本はこれだけで良いと思う。
パフォーマンスを重視するなら、この2つだけにする。
（ユーザーは、文字の太さよりも読み込みスピードの方が気になると思う）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2530037/62c7f7ff-90a3-df1c-a500-9db889666bce.png)

# おわりに

実際のところは他の要素と絡まって効きます。
必ずしも、「単純に一瞬で読み込むから考えなくて良い」とはならないです。

また、データ容量の制限や、貧弱な回線まで意識して、ものづくりしたいところ。
ユーザーフレンドリー、頑張りましょう。

# 参考
グラフ機械学習って何？

## グラフ機械学習とは
グラフやネットワークで表わされたデータ・情報を機械学習の手法を使って分析・生成する技術のことです。

## グラフとネットワーク
グラフとネットワークは同じものです。数学ではグラフと呼ばれています。

グラフとは物と物がつながって蜘蛛の巣ネットワークが広がっているイメージです。物のことをノードと呼びます。物と物をつなげている連結線のことをエッジと呼びます。
例としてTwitterのようなソーシャルネットワーク上のフォローする人とフォローされる人のつながりもグラフあるいはネットワークと呼ばれます。
フォロー関係を"->"を表すと、AがBをフォローしている場合は以下のように書かれます。
A -> B
更に、BがCをフォローしていれば、
A -> B -> C
のように記述されます。

グラフの概念は、ソーシャルネットワーク、薬剤発見（ドラッグディスカバリー）、分子間相互作用、交通網や巡回ルート最適化、知識グラフ、経済ネットワークなど様々現象を記述することができます。

## どうやって学ぶの？
スタンフォード大学でグラフの機械学習のコースがあります。毎シーズンの講義内容がWebに掲載されています。さすが、スタンフォード大学ですね。[講義動画](https://www.youtube.com/watch?v=JAB_plj2rbA&list=PLoROMvodv4rPLKxIpqhjhPgdQy7imNkDn "Lecture 1.1")がYouTubeにありました。

[CS224W: Machine Learning with Graphs](https://web.stanford.edu/class/cs224w/)

おすすめの書籍は以下のものです。
[Graph Representation Learning](https://amzn.to/4cNnWQE) by William L. Hamilton

Network Science by by Albert-László Barabási
[こちら](http://networksciencebook.com/ "オンライン記事")からオンラインでも読めます。
書籍では[英語版](https://amzn.to/3J6vjVP "英語版")と[日本語版](https://amzn.to/3U5SaXR "ネットワーク科学 Albert-László Barabási著")があります。
LinuxでTomcatログを管理する：Logrotateの使い方

TomcatはJavaアプリケーションサーバーとして広く利用されていますが、そのログファイルが肥大化しやすいのも事実です。この問題を解決するために、Linuxシステムでは`logrotate`ツールを使ってログファイルのローテーション（古いログの削除やアーカイブ）を自動化することができます。ここでは、Tomcat 10のログを`logrotate`を使用して効果的に管理する方法をご紹介します。

# Logrotateの基本

`logrotate`は、ログファイルを定期的にローテートし、必要に応じて圧縮、削除、メール送信することができるツールです。これにより、ディスクスペースを有効に管理し、ログファイルがシステムを圧迫するのを防ぎます。

# Tomcatログのローテーション設定

## Step 1: Logrotate設定ファイルの作成

まず、`/etc/logrotate.d/`ディレクトリに`tomcat10`という名前の新しい設定ファイルを作成します。これが、Tomcatのログを管理するための設定ファイルになります。

以下の内容をファイルに追加します（パスやユーザー名は環境に合わせて適宜変更してください）。

```
/opt/apache-tomcat-10.1.19/logs/catalina.out {
    copytruncate
    daily
    rotate 7
    compress
    missingok
    create 0644 tomcat tomcat
    su tomcat tomcat
}
```

この設定では、`catalina.out`ログファイルが毎日ローテートされ、7日間保持された後に圧縮されることを意味します。また、`su`ディレクティブを使用して、ログのローテーションに使用するユーザーとグループを指定します。

## Step 2: ファイルとディレクトリの権限の設定

セキュリティを確保するため、Tomcatのログディレクトリの権限を適切に設定します。

```
chmod 770 /opt/apache-tomcat-10.1.19/logs/
```

同様に、作成したlogrotateの設定ファイルの権限も適切に設定します。

```
chmod 644 /etc/logrotate.d/tomcat10
```

## Step 3: Logrotateの実行とテスト

設定が完了したら、`logrotate`コマンドを使用して、設定が期待通りに機能するかをテストします。

```
logrotate -d /etc/logrotate.d/tomcat10
```

- `d`オプションを使用すると、実際には何も実行されず、どのような操作が行われるかが表示されます。問題がなければ、デバッグモードを外して実行します。

```
logrotate /etc/logrotate.d/tomcat10
```

詳細な実行結果を見たい場合は、`-v`オプションを使用します。

```
logrotate -v /etc/logrotate.d/tomcat10
```

# まとめ

`logrotate`を使用することで、Tomcatのログファイル管理を自動化し、システムの健全性を保ちながらディスクスペースを効率的に利用することができます。上記のステップに従って、ログのローテーションを設定する
Linuxでcpuid/msr情報を取得する

# はじめに
コマンドラインだけで、IntelのCPU情報を取得するcpuid命令や、Model Specific Register (MSR) にアクセスできる。
なお、それぞれの仕様は、Intel Software Developer Manual (SDM) (Vol.2 Vol.4など) を参照のこと。



# 手順
## インストール
```
modprobe msr
sudo apt update
sudo apt install cpuid
sudo apt install msr-tools
```

## 使い方

```
cpuid
```

```
sudo rdmsr
```

```
sudo wrmsr
```

# 参考資料

- [Four-Volume Set of Intel® 64 and IA-32 Architectures Software Developer’s Manuals](https://www.intel.com/content/www/us/en/developer/articles/technical/intel-sdm.html#inpage-nav-2)
  - Volume 2 Instruction Set Reference, A-Z
    - 3.3 INSTRUCTIONS (A-L)
      - CPUID 
  - Volume 4 Model-Specific Registers

## ソースコード
- [tycho/cpuid](https://github.com/tycho/cpuid)
- [index : ubuntu/+source/cpuid](https://git.launchpad.net/ubuntu/+source/cpuid/)
  - [Linux tool to dump x86 CPUID information about the CPU(s)](http://www.etallen.com/cpuid.html) # ubuntuの元コード
- [index : ubuntu/+source/msr-tools](https://git.launchpad.net/ubuntu/+source/msr-tools/)
GASの編集時トリガーを使う際の注意点


# はじめに
こんばんは。
本日は、編集時トリガーを使って値を別シートにコピーする際に、コピーされないことがあることについて話していきたいと思います。

まずは動画をご覧ください。

![GAS注意喚起動画_投稿用.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2731227/15deab5b-65ee-3b14-efe3-7196ebecc805.gif)

コピーが完了したら、黄色がつくようになっています。
正しく情報が書き込まれたかどうかの目安です。

そこから一気にバックスペースで値を削除したところ、
黄色が残り、コピー先のシートにも値が残っていることがわかりますね。
このスクリプトでは、消したら背景が白に戻るようになっています。

# 解決策
もしかしたらやり方はあるかもしれませんが、
今のところ、１つずつ時間を空けて入力することで妥協しています。
素早く処理したいですが、正しく反映されるタイミングを見極めるしかできません。

編集時トリガーでバックスペースやコピペをする際は要注意ですね。
スクリプトの最後で背景色を変えるなどをすることで正しい処理をしたかがわかるようになっていないと、
反映されたかどうかすらわからなくなってしまうと思うので、
編集時トリガーを使う際はお気をつけください。

オープンソースじゃないということで、ソースコードを見られないので、
どうなっているかはブラックボックスです。

「こうやったら改善するかも？」という方がいらっしゃいましたら、コメントしていただけると助かります。
🧶メモリが無限のコンピュータがあったらどんなのに？

実際にはない(と思う)ものの話って面白いですよね！
こういうの好きです。

この記事では、もし無限メモリを搭載したコンピュータがあったら、それはどのようになるか考えてみたいと思います。最後まで読んでいただければうれしいです。

まず、無限のメモリがあるとはいえ、どうやってアドレスを指定するのかという問題が発生します。
でも64ビットで指定できるとしたら（バイト単位でアクセスできるマシンを仮定します）、バイト(2^0バイト)…KB(2^10バイト)…MB(2^20バイト)…GB(2^30バイト)…TB(2^40バイト)…ペタバイト(2^50バイト)…エクサバイト(2^60バイト)…、16エクサバイトまで表せるのでとりあえずは十分そうですね。もっといるなら128ビットで指定できるようにしましょう。

ほぼ無限にメモリがあるので、まずメモリをfreeする必要がなくなりますね。さらにmallocも簡単になります。各スレッドに適当に1TBぐらい割り振っちゃいましょう！なんかすごいのはおいておいて、mallocは各スレッドに割り当てられたメモリを先頭から使ってしまえば速いし簡単です。スタック用にも1TB割り振っておいてもいいかもしれません。もし1TB使い切ったならさらに1TB割り振ることで、もっと使えるようになります。

もしこのメモリが不揮発性メモリ(電源を切っても消えないメモリ、SSDなど)なら、ファイルを消さずにどんどん置いていくこともできます。

こんなメモリが使えたら、プログラミングが簡単になっていいですね。
最後まで読んでいただきありがとうございました。お楽しみいただければうれしいです！
🧶「-x」の速い計算方法：`^x + 1`の解説

この記事では、-xを素早く計算する方法 `^x + 1`（not x + 1）を解説していきます。

ここでは、わかりやすいように、1始まり(個人的には0始まり、16進法が好きですが…コードの行数も0始まりがいい)、int8、big endian (十六と書くときは 0b0001_0000) で説明し、notは「^x」、n乗は「x ** n」と表記します。

最初に、intの仕組みを解説します。すでにご存じの方は、次の"\n\n"まで jmp してください。(次のブロックからお読みください)
正の数の場合は、2つ目から8つ目のビットを使って二進法で表します。
負の数の場合は、-(2 ** 7) + (2つ目から8つ目のビット)と表します。
1つ目のビットは-128の桁、2つ目から8つ目のビットはそれぞれ64、32、16、8、4、2、1の桁です。例えば -2 は 1111_1110 になります。

初めに、^x（not x）をコンピュータっぽくではなく、数学っぽく表現していきたいと思います。
まず、^x は (2 ** 8 - 1) - x です。0b1111_1111 - x の二進法での筆算を想像してください。notすることと同じになります。
これで、^x のシンプルな数学表記ができました！

符号ビット(1ビット目 • sign bit)と他のビット(2ビット目から8ビット目)を分けて、それぞれ s と t とします。t は任意の0から127までの整数で、s は正の場合は0、負の場合は-128を表します。
x が正の場合は s、（s = s）、負の場合は -t + (t - s)、（-t + (t - s) = -s）になりますね。
あとは、正負を反転させたときビット演算を使った速い方法も同じ結果になるということを証明するだけです。

（-正の数s = sの負の数バージョン）
-s = ^x + 1
= (2 ** 8 - 1 - x) + 1
（1ビット目と2から8ビットを分けて）= (-t + (2 ** 7 - 1 - s)) + 1
= -128 + 128 - 1 - s + 1
= -t + t - s
= -t + (t - s)
（ついでに）= -s

これで証明できました！やった！
最後まで読んでくださりありがとうございました！お役に立たればうれしいです！
🧶分岐なしで絶対値を取り取り：a = x >> 63; x ^ a - a

絶対値を取る最も簡単な方法は、ifを使うことだと思います。

でも、これは今のCPUが賢いので遅いです。
なぜかというと、CPUはifの条件にメモリアクセスが必要など、条件がtrueかfalseか計算するのに時間がかかることがあるので、trueかfalseか分岐を予測して実際に計算し終わる前にifの中身を実行するのですが（分岐予測/Branch predictionといいます）、分岐の予測が外れていたら世界を巻き戻さないといけないため、魔法の時計はないから大変なので、ifは使いたくありません。

ifなしで絶対値を取るには、魔法のようにビット演算を駆使します。(int64の場合で説明します)

xが絶対値を計算したい対象だとすると、

1. xを63ビット算術右シフトします。この結果をaとします。これで正の数の場合はすべてのビットが0(=0)、負の数の場合はすべてのビットが1(=-1)になります。

2. xとaをxorして(xが負ならnotされる)、aを引きます(xが負なら-(-1)なので+1される)（notして1足すと正負を反転できます（詳しくは「🧶「-x」の速い計算方法：`^x + 1`の解説」をお読みください））

つまり、xが正なら何もせず、負ならnotして+1するってことです！

これで高速に絶対値が計算できた！やったね！
Web3 Ethパッケージ利用についてのまとめ

こちらはWeb3 4.7.0のパッケージを利用されている
「現時点2024/4/5最新版」でございます

```
  "dependencies": {
    "web3": "^4.7.0"
  }
```

## アカウント情報を取得
```
web3.eth.getAccounts().then(function(obj) {
    console.log(obj)
});
```

## 残高情報を取得
```
web3.eth.getBalance('0xb10549760b07416e4cbd1ab31da9d24165ef3ae6').then(function(value){
    console.log(web3.utils.fromWei(value, 'ether'))
})
```


## アカウントを新規作成
```
let newAccount = web3.eth.accounts.create()
console.log(newAccount);
```

## 大量アカウントを作成して、残高情報を取得
アカウントアドレスの生成はタイムスタンプを入れているようなので、運でお金持ちになるなんて、ありえないです。
```
for (let i=0; i<100; i++) {
    let newAccount = web3.eth.accounts.create()
    console.log(newAccount.address);

    web3.eth.getBalance(newAccount.address).then(function(value){
        if (web3.utils.fromWei(value, 'ether') > 0) {
            console.log(newAccount)
        }
    })
}
```
色（RGB）で理解する単語のベクトル化

## はじめに
人工知能、とりわけ自然言語処理の分野では、 **「単語（自然言語）をベクトル化する」** という表現をよく耳にします。今回は、この「単語のベクトル化」について、身近な色（RGB）の事例を用いて説明していきます。

※自然言語処理では「自然言語」全般を扱うものですが、この記事では「単語レベルでのベクトル化」に焦点を当てています。

## 単語をベクトル化する第一歩
コンピュータが単語を理解するためには、まず、単語を数値情報に変換する必要があります。この最も簡単な方法は、単語のリストに対して、単語の数と同じ次元数のベクトルを作成することです。

具体的には、10万個の単語を持つリストがあるとき、1番目の単語を $ (1,0,0,...,0) $、2番目の単語を $ (0,1,0,...,0) $ と表現することで、すべての単語を数値表現に変換できます。

しかし、このベクトルは単に **単語リストの番号を紐づけただけ** であり、「単語の意味」を持っているわけではありません。これでは、コンピュータが単語を理解しているというにはほど遠いでしょう。また、高次元のベクトルを扱うことには計算コストが高いという問題があります。

:::note info
このようなベクトルを **局所表現（疎なベクトル）** といいます。疎なベクトルとは、**ベクトルの要素に0を多く持つ** = **情報量の少ないベクトル** という意味です。
:::

では、「単語の意味」を持っているベクトルとはいったい何なのでしょうか？

## 「珊瑚色」ってどんな色？
この疑問に答えるために、一つの例としてベクトルから「珊瑚色」がどのような色であるかついて考えてみましょう。

珊瑚色とは、JIS慣用色名で定められている全269色のうちの6番目の色です。これを先ほどの局所表現で表すと、 $(0,0,0,0,0,1,0,...,0)$ のような269次元のベクトルとなります。

うーーーん、これでは珊瑚色がどのような色なのか全くわかりません。

しかし、私たちは色をより低次元のベクトルを用いてどのような色かを理解する方法を知っているはず、そう「RGB」です。

珊瑚色をRGBで表現すると $(255,127,143)$ の3次元ベクトル、Red=255、Green=127、Blue=143となります。このベクトルをみると、光の三原色の特徴から赤が強くて色が薄い、ピンクに近いような色なのではないかと予想できます。

<font color="#FF7F8F">**実際の珊瑚色はこのような色です。どうでしょう、皆さんの予想と同じような色だったでしょうか？**</font>

:::note info
このような低次元で意味のあるベクトルを、局所表現に対して **分散表現（密なベクトル）** といいます。密なベクトルとは、**ベクトルの要素に0をあまり含まない** = **情報量の多いベクトル** という意味です。
:::

これが自然言語処理の分野で用いられるベクトルの正体です。RGBはたくさんの色をたった3次元の情報で表現することができ、似た色は似た情報を持つ意味のあるベクトルになります。単語もこのような「意味を持つ」ベクトルに変換することで、コンピュータが単語を理解できるようになり、機械翻訳や感情分析、文章生成などのさまざまなタスクに応用されるのです。

## おわりに
今回は、自然言語処理の分野でよく耳にする「単語のベクトル化」について、身近な色の事例を用いて説明しました。単語の分散表現を獲得する方法には、Word2Vec、RNN、Transformerなどの様々な方法がありますので、気になった方はぜひ調べてみてください。機会があればこちらについても解説してみたいと思います。
【Oracle Analytics】キャッシュの設定

## 概要
Oracle Analytics Cloud Classicのキャッシュの設定箇所について、システム全体、分析単位、リポジトリの物理表単位でそれぞれ記載します。

## 設定内容
#### 1. システム全体の設定
問い合わせキャッシュをシステム全体で「有効」、「無効」とすることができます。（デフォルトは有効）
※プレゼンテーション・サービス・キャッシュはシステム全体として無効化することはできません。

OACのホームページから左上のナビゲータをクリックし、[コンソール]をクリックします。
<img width=50% src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3582570/bbb6dace-e66d-8ace-4965-de790428249d.png">

[システム設定]をクリックします。
<img width=100% src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3582570/9101618b-fa35-d675-f838-71b59c5e0ab8.png">

[Performance and Compatibility]をクリックします。
 
[Cache Enable]より、キャッシュを有効とする場合は「オン」、無効とする場合は「オフ」を設定します。
<img width=100% src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3582570/15a79b45-26bb-7259-ce7d-b35f336dbda0.png">

[Apply]をクリックします。
<img width=50% src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3582570/a07e9c28-d799-dfcc-9424-895e52d00bf2.png">

#### 2. 分析単位の設定
分析単位で問い合わせキャッシュ、プレゼンテーション・サービス・キャッシュの無効設定ができます。

キャッシュの設定を行う分析を開きます。
[詳細]タブをクリックします。
<img width=100% src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3582570/babb85af-c7ed-2213-dfee-7b13126fbfc9.png">

プレゼンテーション・サービス・キャッシュを無効にするには、下記にチェックを入れます。

Oracle Analytics Presentation Servicesキャッシュをバイパス

<img width=100% src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3582570/5679abde-9c01-3994-31b5-7a700a543ce5.png">

問い合わせキャッシュを無効にするには、「拡張SQL句」の[接頭辞]に以下を入力し、
[SQLの適用]をクリックして設定を反映します。

SET VARIABLE DISABLE_CACHE_HIT=1, DISABLE_CACHE_SEED=1, DISABLE_PLAN_CACHE_HIT=1;

<img width=100% src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3582570/60fb730e-3adf-9afc-ed6e-490865669341.png">



#### 3. リポジトリの物理表単位の設定
問い合わせキャッシュの「有効」、「無効」の設定をリポジトリの物理表毎に設定することができます。
デフォルトはキャッシュが有効となっています。

管理ツールを開きます。
<img width=85% src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3582570/45ac1d86-8dec-cb49-153d-5c704f60bbbe.png">

キャッシュの設定をする物理表のプロパティを開きます。

[一般]タブで「キャッシュ可能」（デフォルトでチェックあり）に有効とする場合は、"チェックあり"、無効とする場合は"チェックなし"とします。

<img width=65% src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3582570/5bc06d23-e3c9-726a-a38c-3a652f8e64ad.png">

キャッシュの有効期限を設定する場合は、キャッシュ永続時間を指定し、有効期限を設定しない場合は、「キャッシュ有効期限なし」を選択します。
<img width=65% src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3582570/c4ac05e4-9187-ef83-727e-8239da8619af.png">




## 参考マニュアル
https://docs.oracle.com/cloud/help/ja/analytics-cloud/ACABI/GUID-C9C7EBEE-4C49-4F7F-980E-92A1DCFE24A3.htm#ACABI-GUID-C9C7EBEE-4C49-4F7F-980E-92A1DCFE24A3

https://docs.oracle.com/cd/E56931_01/trans/F41281-14/advanced-techniques-set-caching-options-your-analysis.html#GUID-B6A1AA3B-C95B-4894-AD35-3B2A7256B724

## ご案内
株式会社ジールは、Microsoft Azure やAWS（Amazon Web Services）、Google Cloud Platform（GCP）、Oracle Cloud Infrastructure（OCI）など、多彩なクラウドプラットフォーム構築・運用の知見を有しています。そのため、複数のクラウドサービスを組み合わせるマルチクラウド環境においても、ベンダーロックインを回避し、お客様のご要望に応じた最適なクラウドプラットフォームの構築・運用への対応が可能です。
https://www.zdh.co.jp/products-services/cloud-data/
【プロジェクトマネジメント】PMPに合格したので、勉強方法をまとめてみる。　2024/3月合格

## はじめに
先日プロジェクトマネジメント資格であるPMP（Project Management Professional）を受験し、無事1度目のチャレンジで合格することができました。
これからPMPの受験を考えている方向けに、勉強方法や受験の感想をまとめてみます。
参考になれば嬉しいです。

## PMPスコアレポート
PMPの合格点は60%程度の正答率だと言われています。
私のテスト結果としては正答率70%弱といったところでしょうか。

![スクリーンショット 2024-04-05 20.50.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3116193/e3dc2a1e-d61c-7383-8301-80b73138a6a3.png)

![スクリーンショット 2024-04-05 20.51.14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3116193/f9190417-c71c-74d4-4052-f7cef1b93c08.png)

ドメイン全てでTargetでしたので、全領域なんとか合格点を超えたくらいの得点率です。


## 勉強の流れ
勉強にはオンライン模擬試験２種類とYoutubeのPMP解説動画を利用しました。
* Udemy　PMP (Project Management Professional) 試験模擬問題集 全360問(2回分)
* PMI Study Hall Essentials
* イトーダさんのYoutubeチャンネル

https://www.youtube.com/playlist?list=PL-ClHPtrHd5BFCt_SBnyoKzvpN489Kuco

過去の合格者の記事などを参考に、
* PMPはシナリオ問題がほとんどで、模擬試験と全く同じ問題は出題されないこと
* 模擬試験より本番の方が少し簡単と感じた人が多い

という情報から、

**「試験前日に初見の模擬試験で65%以上取れること」** を目標に設定しました。　

**模擬試験→わからない用語の検索・間違えた部分の復習→同じ模擬試験で90%以上取れるまで理解する→次の模擬試験→繰り返し**
というアプローチです。

具体的には以下の流れで学習を進めました。
私の場合、PMP受験とは別でプロジェクトマネジメントについて体系的に学びたかったことから、CouseraのGoogle Project Managementを受講していました。この勉強のおかげで、基礎用語は把握できており、勉強がスムーズだったように思います。


1.  CouseraのGoogle Project Managementを修了
1.  35時間公式研修（Udemy）
1.  試験申し込み
1.  Study Hall　模擬試験1を実施して、問題傾向を把握する
1.  Udemyの模擬試験を60問ずつ実施して、少しでも迷った箇所・間違えた問題を復習
1.  Udemyの模擬試験を２回目を実施して全セクション90点以上取れることを確認
1.  Study Hall　模擬試験2にチャレンジし、初見問題で合格点付近取れることを確認
1.  Study Hall　ミニ模擬試験で対応できるパターンを増やす
1.  PMP試験本番

https://qiita.com/ko-hi-san/items/0f3575996ae96cd28e87

Udemyの模擬試験の後半からは初見問題でも70点付近を取ることができ、着実に初見問題に順応できている実感がありました。Study Hall模擬試験の２回目もなんとか66%と個人目標は達成できたので、勢いそのままに試験本番を迎えました。


CouseraのGoogle Project Managementの修了に100時間ほどかかりましたが、それを除くとPMP対策は
**1日4時間を2週間、合計約60時間**
の短期集中で本番に臨みました。

## 受験当日
試験方法にはオンラインとピアソンでのオフライン受験があります。
試験問題以外のことは何も考えたくなかったので、最寄りのピアソン会場で受験を行いました。
準備や手続きは受付の人の言うとおりにすれば良いので、試験のことだけに集中できてよかったと思います。
会場内には他の試験を受験している人もいるので、どうしても雑音が発生することには注意が必要です。
雑音が苦手なかたはオンラインの方が良いかもしれません。

## 受験した感想
事前情報の通り、模擬試験より難易度は低いと感じました。
ただ、少し問題の選択肢のニュアンスが模擬試験と異なるところがあり、合格の自信はあまりなくドキドキで試験結果を受け取りました。
結果は合格でしたが、準備としては少しギリギリすぎたかもしれません。
Study Hallのミニ試験については半分くらい未着手でしたので、やっておけばもう少し安心して本番に臨めたと思います。

## 受験費用
やはりPMPの受験は高く、総額で10万円ほど必要でした。
とはいえ、他の方の受験レポートを見ていた限り、お得に受験できた方だと思います。


| 項目 | 費用 |
| ---- | ---- |
| Udemy<br>PMP Certification Exam Prep 35 PDU Project Management Course | ¥1,800- |
| Udemy<br>PMP (Project Management Professional) 試験模擬問題集 全360問(2回分) | ¥1,800- |
| PMI Study Hall Essentials | ¥8,181- <br>($53.90)|
| PMP受験料(10%割引適用) | ¥55,325- <br>($364.50)|
| PMI年会費 | ¥23,208- <br>($152.90)|
| 合計 | ¥90,314-|

※私の場合はPMP受験前にCouseraのGoogle Project Managementを修了し、その時に受験費用10%クーポンが取得できたことで、少しお得に受験ができました。

## まとめ
私のPMP受験の勉強方法をまとめてみました。
私自身、PMBOK第7版対応になってからの情報が少なく、情報収集に苦労したので、この記事がこれからPMPの取得に向けて勉強する方の参考になれば嬉しいです。

ご拝読ありがとうございました！
Riderの永久ライセンスを手に入れる

## Riderの永久ライセンスを手に入れる

年額払いか月払いを12ケ月分払うことで特定のバージョンを永久ライセンスを取得しることができる。

### 永久 fallback ライセンスとは？

https://sales.jetbrains.com/hc/ja/articles/207240845-%E6%B0%B8%E4%B9%85-fallback-%E3%83%A9%E3%82%A4%E3%82%BB%E3%83%B3%E3%82%B9%E3%81%A8%E3%81%AF

> 永久fallbackライセンスは、有効なサブスクリプションなしで特定のバージョンのソフトウェアを使用できるライセンスです。 ライセンスには、すべてのバグ修正アップデート（具体的には、X.Y.Zバージョンの場合、全てのZリリースが含まれます）が含まれます。

> **年間サブスクリプションを購入すると、購入時に利用可能なバージョンの永久fallbackライセンスがすぐに付与されます。**

![Screenshot from 2024-04-05 22-17-04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/182324/623f1b0e-c193-4333-8765-3e706748d475.png)

年額払いだと19370円で取得できる。
Pixcel 6 API 33で実行

### Android Studio Iguana Kotlin

で実行すると
```
:app:mergeDebugResouces 1 warning
　AGPBI: {"kind":"error","text":"
  ","sources":[{"file":"C:\\Users\\lhssy\\AndroidStudioProjects\\Test\\app\\src\\main\\res\\values
:app:packageDebugResouces 1 warning
:app:writeDebugSigningConfigVersionas UP-TO-DATE6errors
　com.android.build.gradle.tasks.ResourceException:
　com.android.build.gradle.tasks.ResourceException:
　C:\Users\lhssy\AndroidStudioProjects\Toushiup\app\src\main\res\values\strings.xml:2:6
 ```

と出てエラーになります。

activity_main.xml strings.xml MainActivity.ktにはエラーはありません。

 ```
setContentView(R.layout.activity_main)
 ```
の後にKotlinを書き込んでも
 ```
ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main)) { v, insets ->
            val systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars())
            v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom)
            insets
        }
```
の後にKotlinを書き込んでもエラーになります。
ESモジュールとCommonモジュール：Node.jsにおける2つのモジュールシステム


## **はじめに**

Node.jsにおいて、モジュールシステムは重要な役割を果たしています。現在、Node.jsではCommonモジュールとESモジュールという2つのモジュールシステムが存在しています。本記事では、これらのモジュールシステムの概要と違いについて解説します。

## **Commonモジュール**

Commonモジュールは、Node.js誕生当時から使用されていたモジュールシステムです。モジュールをインポートする際には、`require`関数を使用し、エクスポートする際には`module.exports`を使用します。

```javascript
// モジュールのインポート
const myModule = require('./myModule');

// モジュールのエクスポート
module.exports = {
 // エクスポートする内容
};
```
## ESモジュール
ESモジュールは、現在のスタンダードなモジュールシステムであり、多くの開発現場で使用されています。ESモジュールは、ECMAScript標準のモジュールシステムです。

モジュールをエクスポートする際には、export文を使用します。エクスポートには、名前付きエクスポートとデフォルトエクスポートの2種類があります。

```
// 名前付きエクスポート
export const myFunction = () => {
  // 関数の内容
};

// デフォルトエクスポート
export default {
  // エクスポートする内容
};
モジュールをインポートする際には、import文を使用します。


Copy code
// 名前付きインポート
import { myFunction } from './myModule';

// デフォルトインポート
import myModule from './myModule';

```
# CommonモジュールとESモジュールの違い
### 1. 動的vs静的
Commonモジュールは動的なモジュールシステムです。つまり、モジュールの依存関係や公開内容は実行時に解決されます。Node.jsはCommonモジュールの依存関係や公開内容を静的に解析することができません。これは、require関数が実行時に呼び出され、モジュールの読み込みが動的に行われるためです。

一方、ESモジュールは静的なモジュールシステムです。モジュールの依存関係や公開内容は、モジュールのパース段階で解析されます。つまり、import文やexport文は常にモジュールのトップレベルに記述する必要があり、条件分岐やループ内で使用することはできません。これにより、モジュールの依存関係が明確になり、パフォーマンスの向上や最適化が可能になります。

### 2. 同期的vs非同期的
Commonモジュールは同期的に動作します。つまり、require関数を呼び出すと、モジュールの読み込みが完了するまで、その行で処理がブロックされます。これは、モジュールの読み込み順序を制御しやすい反面、大規模なアプリケーションではパフォーマンスの問題につながる可能性があります。

ESモジュールは非同期的に動作します。つまり、import文を使用してモジュールを読み込む際、モジュールの読み込みが完了するまで待機する必要がありません。これにより、アプリケーションの起動時間が短縮され、パフォーマンスが向上します。ただし、モジュールの読み込み順序を制御するには、追加の工夫が必要になる場合があります。

### 3. strictモード
Commonモジュールはデフォルトで非strictモードで動作します。これは、JavaScriptのいくつかの機能（例えば、暗黙のグローバル変数の作成など）が許容されることを意味します。非strictモードは、既存のコードとの互換性を維持するために使用されていますが、予期しないバグを引き起こす可能性があります。

ESモジュールはデフォルトでstrictモードで動作します。strictモードでは、暗黙のグローバル変数の作成などの潜在的な問題を引き起こすコードが禁止されており、より安全で予測可能なコードを書くことができます。これにより、開発者はよりクリーンで保守性の高いコードを書くことが求められます。

## ESモジュールの使用方法
Node.js v13.2.0以降では、package.jsonに"type": "module"を指定することで、.js拡張子のファイルをESモジュールとして実行できるようになりました。ただし、Commonモジュールを使用する場合は、拡張子を.cjsにする必要があります。

## まとめ
Node.jsにおいて、CommonモジュールとESモジュールは共存しています。開発者は、プロジェクトの要件に応じて適切なモジュールシステムを選択する必要があります。ESモジュールは現在のスタンダードであり、多くの開発現場で使用されていますが、Commonモジュールとの違いを理解することも重要です。
出し方がわからない記号一覧 「 └ 」「 々 」...

## はじめに
文章を書いていて「"々"ってどうやって出すんだっけ？」と思い出せず、仕方なく「佐々木」と打ってから消すみたいなことを繰り返していたので備忘録として、出し方のわかりづらい記号・符号の一覧表を作成しました。

:::note info
**使用環境**
- OS：Windows
- IME：Microsoft IME

利用しているOS、IMEの種類やバージョンにより、表示や挙動が異なる場合があります。
:::


## 罫線素片
`┤`や`└`のようなディレクトリ構成図を書くときに使用する記号。
「**けいせん**」と打てば一覧で変換候補が出てきますが、個別で出したい時の読み方は以下。

|記号・符号|入力する文字|
|:------|:------|
|│ ┃|たて|
|┤ ┫ ┥ ┨|たてひだり|
|├ ┣ ┝ ┠|たてみぎ|
|┌ ┏|ひだりうえ|
|└ ┗|ひだりした|
|┏┳━┓ ┗┻━┛|ふとわく|
|┌┬─┐ └┴─┘|ほそわく|
|┐ ┓|みぎうえ|
|┘ ┛|みぎした|
|┼ ╋|まんなか|
|─ ━|よこ|
|┴ ┻|よこうえ|
|┬ ┳|よこした|

## 繰り返し符号
`々`や`ゝ`のような繰り返しに使用する踊り字（符号）。

|記号・符号|入力する文字|備考|
|:------|:------|:------|
|々|おなじ、くりかえし、どう|ノマ字点。漢字の繰り返しに使用。|
|ゝ ゞ|おなじ、くりかえし、どう|一の字点。ひらがなの繰り返しに使用。|
|ヽ ヾ|おなじ、くりかえし、どう|一の字点。カタカナの繰り返しに使用。|
|〃|おなじ、くりかえし、どう|ノノ字点。前の内容の省略。表や箇条書きで使用。|


## 矢印
「**やじるし**」と打てば一覧で変換候補が出てきますが、個別で出したい時の読み方は以下。

|記号・符号|入力する文字|備考|
|:------|:------|:------|
|↑|うえ||
|↓|した||
|←|ひだり|`＜ー` で変換でも可。|
|→|みぎ|`ー＞` で変換でも可。|
|⇔|さゆう||

## その他

|記号・符号|入力する文字|備考|
|:------|:------|:------|
|※|こめ|米印。|
|§|せくしょん||
|／（全角）|すらっしゅ、ななめ|スラッシュ。|
|＼（全角）|すらっしゅ、ななめ|バックスラッシュ。|
|†|だがー|短剣符。中二臭漂うが本来は脚注で使用する。|
AWS SAA取得に向けて

#自己紹介
IT業界:3年目
年齢:33歳
資格:JavaGold,OracleSilver,UMTP L2,基本情報…だけだったはず。
経験工程:基本設計〜結合テスト、システムテスト
経験言語:c#,Java,JavaScript

#AWS SAA取得を目指す経緯
現在のプロジェクトではAWSどころかクラウドを触っているわけではないが、クラウド関連の知識を付けるべくAWS SAAの取得を目指している。
正直無くても困らないが、すこしでも引き出しを増やしたいと思い取得を目指すことにした。

#AWS SAA取得へ向けて
ping-tの問題集でインプットとアウトプットをひたすら繰り返す予定。
ただ、どうしてもただ暗記するだけになりがちなので、qiitaで各サービスごとにまとめ記事を投稿しようと思う。

#AWS SAA取得後
開発スキル向上や顧客折衝の経験などは実務でやるとして、当面はプライベートの学習のメインは資格取得で行こうと思う。
AWS SAAを5月末で取得後は、情報処理安全確保支援士を今秋に取得を狙いたい。
Salesforceリストビュー「最近参照したデータ」「最近参照した○○」調査

本橋孝昭です

今回は「Salesforceリストビューどこまで変えられるか」問題を調査しました
特にある内容として
・リストビューの項目を変えたい
・リストビューを削除したい
などですね
今回はリストビューを調査しました

結論から言えば
・ほとんどのリストビュー→リストビュー画面から項目編集可能、削除可能
・「最近参照したデータ」→オブジェクトから項目編集可能、削除不可能
・「最近参照した取引先」など一部標準オブジェクトに備わるリストビュー→項目編集不可、削除不可

です
それでは早速見ていきましょう



## レベル1 通常のリストビュー　画面から項目編集可能、削除可能

まずは通常のリストビューの項目編集、削除のおさらいです

画像のようにリストビュー右部の歯車マークをクリックすれば画面が現れます
「表示する項目を選択」をクリックすれば項目の並び順が変わり、「削除」をクリックすれば削除可能

これは感覚的に分かりやすい設定ですね
![リストビュー001.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531631/add232a4-6485-1176-1eed-ab6a951a1280.png)


## レベル2 「最近参照したデータ」リストビュー→オブジェクトから項目編集可能、削除不可能

続いてどのオブジェクトにも１つはできてしまう「最近参照したデータ」です
こちらについて「いやいやリストビューなんてどれも設定同じでしょ？レベル1と同じ歯車マーククリックで設定変更できるよね？」
と思ったあなたは残念！

なんと「最近参照したデータ」の歯車マークをクリックしても画像のように編集できるボタンがクリックできません

![リストビュー002.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531631/af96658d-7959-f847-9a5a-a11c901dc7e8.png)


実はこの「最近参照したデータ」リストビューはリストビューから項目並びの編集をすることはできないです
「じゃあどこから編集するのか？」というと、オブジェクトの設定の「検索レイアウト」の並び順=そのオブジェクトの「最近参照したデータ」の並び順です。
こちらの編集から変更することで結果的に「最近参照したデータ」の項目の並び順の変更が可能です

![リストビュー003.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531631/efdd5056-ffbe-c515-ab6c-62105d0580b1.png)

いやはや、まさかこんな場所がリストビューの設定場所だとは、、

なお、この「参照したデータ」リストビューは削除することはできないです


ここのレベル1,レベル2で「カスタムオブジェクト」のリストビューの設定方法の解説は終わりです
しかしながら、まだ標準オブジェクトにはリストビューが存在するのである、、、


## レベル鬼　「最近参照した取引先」など一部標準オブジェクトに備わるリストビュー→項目編集不可、削除不可

なんと、リストビューの中で削除も編集もできない困ったちゃんのリストビューが存在するのです
それは
「最近参照した○○」リストビューだ！
（例：取引先なら「最近参照した取引先」商談なら「最近参照した商談」）
このリストビュー、先ほどのレベル2で紹介した「最近参照したデータ」と名前が似てますがこっちのリストビューはさらに頑固者である

なんと項目編集不可、削除不可なのです

Ideaでは2017年から「何とかしてほしい」と投票されてます

https://ideas.salesforce.com/s/idea/a0B8W00000GdgzzUAB/single-recently-viewed-list-view-in-lightning-per-object


（今後なんとかなることを祈ります）


## おまけ
今回の「最近参照した〇〇」について、「本当に編集できないかな？」と思いClassic画面に変更したりといろいろ試してみたのですが、「列を編集する」をクリックすると非常に惜しい状況までいきましたが結果は残念ながら編集できずでした

![リストビュー004.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531631/de72de5f-f744-ceaf-f116-5a43b1e69f4a.png)


いかがでしたでしょうか
リストビューは一部編集や削除ができないものもありますが、その仕様は仕方ないとして頑張って設定しましょう！
【小ネタ】Copilot Studioの生成型の回答にBing Custom Searchを利用して、2階層以上のサブパスを指定する

# 公開URLを指定する仕様について
Copilot Studioの生成AI機能の1つに公開Web URLを指定し、データソースとして回答を得ることができます。（こちらの機能は先人がたくさんまとめてくれていると思うので、機能の詳細は割愛します）
<br>

公式サイトには、以下のような記述があります。
>この機能は、トップレベルドメインのサブドメインを含む、指定した URL 内の公開コンテンツはすべて、Copilot用のコンテンツを生成します。
例えば、
www.fabrikam.com/engines/rotary を使用する場合、www.fabrikam.com/engines/rotary/dual-shaft のコンテンツも応答を生成するためにCopilotによって使用されますが、www.fabrikam.com/tools のコンテンツは、使用されません。

それに加えて、下記のような記述もあります。
>URL には、最大 2 レベルの深さを含めることができます—スラッシュ / で示されるサブパス。 ただし、末尾のスラッシュは許可されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2975138/c4ec0ac2-0117-25bd-523c-7f1d6ab17b8f.png)

https://learn.microsoft.com/ja-jp/microsoft-copilot-studio/nlu-boost-conversations#url-type-and-structure

つまり、Copilot Studioに公開URLを指定した場合、
* 指定した URL 内の公開コンテンツはすべて、Copilot用のコンテンツを生成する
* 2階層以上は受け付けない


となるため、想定以上にデータソースの範囲が広くなり、意図していない回答が返ってくる可能性があります。
<br>

例えば、下記のようないぬ🐶の一覧サイトがあり、特定の犬種のURLが3階層になってしまう場合、
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2975138/9571f6c2-b35f-3888-9ea9-92fe6763311a.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2975138/57676789-2b5d-e84f-25c2-07a65eb23299.png)


ユーザーはデータソースとなる公開URLを特定のいぬ🐶を表示するURLを指定したいとしても、標準の仕様だと不可能となり、
生成AIのURLに特定の犬種のURLを入力するとエラーとなります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2975138/f3566f3f-f88b-5684-d227-cdf087c7dbea.png)
<br>

その場合、
ユーザーがあいまいな質問をした場合、ソースにできるURL配下（犬の一覧を表示するURLのサブパスつまり全犬種）のデータを取得して、返答してきます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2975138/60da3fd4-72f7-5d81-8fb0-858aa514e738.png)

# Bing Custom Searchを利用する
<br>
<br>
そこで利用するのが、Bing Custom Searchとなります。
Bing Custom Searchを利用することで、URLの最大 2 レベルの深さという制限がなくなります。

https://learn.microsoft.com/ja-jp/microsoft-copilot-studio/nlu-generative-answers-bing

下記のように、特定の犬種を示すドメイン以下が3階層となるURL（秋田犬のページ）を指定します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2975138/25922b45-8290-b104-1453-652bb87c6497.png)

Copilot Studioのトピックを作成し、データソースにBing Custom Searchを選択し、Custom Configuration IDを入力します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2975138/8aaedb14-96d4-3c2e-2fd3-e20e4ea2c876.png)

すると、秋田犬のみをデータソースに指定したことになるので、特定のデータソースから回答を得ることができます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2975138/2bca6609-5822-0e67-a2de-b2bc0f6721f2.png)


<br>
<br>
このように、必要に応じてトピックとデータソースの範囲を限定することで、ユーザーが得たい回答をCopilot Studioから安定・高速に得ることができます。
npmとyarn：JavaScriptのパッケージ管理ツールの比較

# はじめに

Node.jsの開発において、外部のライブラリやパッケージを利用することは非常に一般的です。これらのパッケージを効率的に管理するために、パッケージ管理ツールが使用されます。Node.jsにおける代表的なパッケージ管理ツールとして、npmとyarnが挙げられます。本記事では、これらのツールの概要と違いについて解説します。

## パッケージ管理ツールとは

Node.jsは必要最低限な機能のみを提供し、ユーザーが必要なパッケージを各自でインストールする方式を採用しています。これにより、Node.jsの容量を抑えつつ、柔軟性を維持することができます。npmとyarnは、これらのパッケージを管理するために使用される代表的なツールであり、開発者はプロジェクトの要件に応じて適切なツールを選択することが重要です。

そして、パッケージ管理ツールとは、特定のシステムや言語環境において、パッケージを管理するためのツールです。パッケージとは、様々なシーンで活用するために作成されたプログラムの集合体のことを指します。パッケージ管理ツールは以下のような機能を提供します：

- パッケージの導入
- パッケージの削除
- パッケージのバージョン管理
- パッケージ同士の依存関係の整理

npmとyarnは、Node.js環境で動作するパッケージ管理ツールです。これらのツールを使用することで、開発者はパッケージの管理を容易に行うことができます。

### npmとは

npmは、Node.jsの公式パッケージ管理ツールであり、2010年にnpm社によってリリースされました（2020年にGithub社が買収）。npmは`package.json`ファイルを使用してパッケージを管理し、`package-lock.json`をロックファイルとして使用します（v7以降）。

### yarnとは

yarnは、Facebook社が2016年にリリースした非公式のNode.jsパッケージ管理ツールです。yarnの主な特徴は、パッケージをインストールする速さです。yarnはnpmを介してインストールを行い、`yarn.lock`をロックファイルとして使用します。

## npmとyarnの違い

1. リリース時期と開発元
  - npm：2010年にIsaac Z. Schlueter氏によって開発され、npm社によってリリースされました。2020年にはGithub社に買収されています。
  - yarn：2016年にFacebook社によって開発・リリースされました。Facebookは大規模なプロジェクトを管理する中で、npmの課題を解決するために、yarnを開発しました。

2. 公式/非公式
  - npm：Node.jsの公式パッケージ管理ツールであり、Node.jsをインストールすると自動的に含まれています。
  - yarn：非公式のパッケージ管理ツールですが、npmと互換性があり、npmのパッケージをインストールすることができます。

3. パッケージのインストール速度
  - npm：パッケージをシーケンシャルにインストールするため、大規模なプロジェクトではインストールに時間がかかる場合があります。
  - yarn：並列処理によるパッケージのインストールを行うため、npmと比較して高速にパッケージをインストールできます。また、キャッシュ機能により、一度インストールしたパッケージを再利用することで、インストール時間を短縮できます。

4. ロックファイルの名称
  - npm：`package-lock.json`をロックファイルとして使用します（v7以降）。このファイルには、インストールされたパッケージのバージョンと依存関係が記録されます。
  - yarn：`yarn.lock`をロックファイルとして使用します。このファイルの役割はnpmのものと同様ですが、yarnではより確実にパッケージのバージョンを固定することができます。

5. コマンドの違い

  npmとyarnでは、一部のコマンドが異なります。以下は主なコマンドの比較です：

  | 操作                        | npm                                 | yarn                         |
  |-----------------------------|-------------------------------------|------------------------------|
  | パッケージのインストール              | `npm install`                       | `yarn`                       |
  | パッケージの追加                   | `npm install [package]`             | `yarn add [package]`         |
  | 開発依存パッケージの追加               | `npm install --save-dev [package]`  | `yarn add --dev [package]`   |
  | グローバルパッケージのインストール         | `npm install --global [package]`    | `yarn global add [package]`  |
  | パッケージの削除                   | `npm uninstall [package]`           | `yarn remove [package]`      |
  | パッケージの更新                   | `npm update`                        | `yarn upgrade`               |

  これらの違いを理解することで、プロジェクトに適したパッケージ管理ツールを選択し、効率的な開発を行うことができます。

## まとめ

Node.jsは必要最低限な機能のみを提供し、ユーザーが必要なパッケージを各自でインストールする方式を採用しています。これにより、Node.jsの容量を抑えつつ、柔軟性を維持することができます。npmとyarnは、これらのパッケージを管理するために使用される代表的なツールであり、開発者はプロジェクトの要件に応じて適切なツールを選択することが重要です。
Fortran備忘録(2) 用途別Fortran90/95基本メモ

## ヘッダーとプリプロセッサ

```fortran
!Fortranコードの一部
#include "f_condition_select.h"

#if defined CONDITION_NAME1
		print *, "This is condition1."
#elif defined CONDITION_NAME2
		print *, "This is condition2."
#else
		print *, "Condition is undefined."
#endif
```

この時、ファイルの拡張子を`.F90`とする。`.f90`ではプリプロセッサが認識されず、コンパイル時`-cpp`オプションを加える必要があると何処かで読んだ。
fortranはC/C++と同様、`#ifdef`で一文を区切ることができる。


```condition_select.h
/*ヘッダーファイルの一部*/

/* Condition Selection */

/* #define CONDITION_NAME1*/
#define CONDITION_NAME2
/* #define CONDITION_NAME3*/
```

ヘッダー側で`include`するマクロを決める。

## データを変数に格納
```fortran
integer :: i
integer :: ios
integer :: nm_data
real(8), allocatable :: sample_data(:)    !imported dat file with any row * 1 column array

open(77,file='./input/sample_data.dat')   !Any row * 1 column array per dt_sample hours

! Count data number
nm_data = 0
do
	read(77,*,iostat=ios)
	if(ios==-1) exit
	nm_data = nm_data+1
end do
allocate( sample_data(nm_data) )
rewind(77)

! Read data
do i =1, nm_data
	read(77,*) sample_data(i)
end do
close(77)

!-----
!sample_dataの使用終了後、
deallocate(sample_data)



```
python認定基礎試験3章と4章のまとめ

●pop()

pop()引数が書かれていない場合は最後の末尾を削除する。

●return
```py
def num(a,b):
    return a+b
result = num(20,30)

print(result)

#出力結果
50
```

●range
range(0,4)
0,1,2,3
range(1,4)
1,2,3,

●enumerate
反復可能体・・・リスト、文字列など
```py
#iがindexの番号を格納、aに反復可能体の要素を格納
for i,a in enumerate('word'):
    if i == 2:
        print(a)
#出力結果
r
```

●zip
```py
for n,c in zip([1,2,3,4],['1','4','9','あ']):
    print(c*n)
#出力結果
1
44
999
ああああ
```
VercelとSupabaseを連携させる方法【画像付き】

どうもこんにちは、たくびー(@takubii)です。

今回はVercelとSupabaseを連携させてアプリをデプロイしたのでその手順を書きたいと思います。
Vercel、Supabaseともに非常に簡単な操作で連携することができたので初心者の方でも安心してください。

# Supabaseでの操作

Dashboardから`New project`をクリックし、新しいプロジェクトを作成してください。

![スクリーンショット 2024-03-21 15.54.42.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/557065/d88b02d8-fadb-7923-b08c-eb16db1e3649.png)

プロジェクトを作成する際は下記の画像を参考に項目を入力し`Create new project`をクリックしてプロジェクトを作成します。
（`Region`は任意ですが日本リージョンがあるので変えておきましょう）

![スクリーンショット 2024-03-21 15.55.06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/557065/f29cf271-5348-784a-fc3b-af1bd7833702.png)

# Vercelでの操作

VercelのOverviewから`Add New...`をクリックし、その中から`Project`を選択します。

![スクリーンショット 2024-03-21 16.03.39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/557065/4d266f07-1109-79ce-3517-af774e1673be.png)

プロジェクト作成時にGithubと連携を行うので今回使用するリポジトリを選択してください。

![スクリーンショット 2024-03-21 16.04.04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/557065/407939bf-b989-4ee5-d983-182db378cf12.png)

`Configure Project`画面では特に設定は変えずこのまま`Deploy`で大丈夫です。
これでVercelにデプロイが完了します。

![スクリーンショット 2024-03-21 16.04.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/557065/0890a856-b22c-221f-137f-6ddf5a79e4a5.png)

プロジェクトの設定が完了したら`Settings`タブを選択し、その中から`Integrations`をクリックします。

![スクリーンショット 2024-03-21 16.10.22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/557065/921e0f47-58a4-4ff0-3a7c-fe66ceac3f53.png)

下記の画面から`Integrations Marketplace`をクリックしてください。

![スクリーンショット 2024-03-21 16.10.58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/557065/fb9f2d0b-e766-2b54-7732-dacba7280e3b.png)

左側のサーチボックスで`Supabase`と入力すると検索結果としてSupabase連携が出てくるのでこちらをクリックしてください。

![スクリーンショット 2024-03-21 16.11.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/557065/b039d879-faab-5fe2-1232-2c99424725fc.png)

`Add Integration`をクリックしてVercelに追加しましょう。

![スクリーンショット 2024-03-21 16.12.01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/557065/63fdeed8-3095-41cf-68a5-9639e23bcfb4.png)

インストール画面が出てくるので`Specific Projects`を選択し、セレクトボックスから連携するVercelのプロジェクトを選択してください。
その後`Install`をクリックします。

![スクリーンショット 2024-03-21 16.13.16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/557065/acf2c4d6-84e5-a219-8822-db66112c1f49.png)

下記の画面が出てきたらorganizationを確認し、`Install integration`をクリックします。

![スクリーンショット 2024-03-21 16.13.58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/557065/c8e1f94b-7f17-e115-f5bb-415ebe6e87b8.png)

Supabase、Vercelそれぞれ連携するプロジェクトを選択し、`Connect project`をクリックしたら完了です。

![スクリーンショット 2024-03-21 16.14.41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/557065/4e239e32-1660-95f4-9877-4bb88c79a12b.png)

以上でVercelとSupabaseの連携ができました。
基本的に画面に従い、プロジェクトを選択するだけで連携できてしまいます。素晴らしいですね。

# 終わりに

Vercel、Supabaseともに最近話題のBaaSを使ったプロジェクトの設定方法を紹介しました。
基本的にはドキュメント通りに進めればできると思いますが、備忘録兼初心者向けということで記事に残したいと思いました。

画面が変わっていたり、うまくいかないという方のために公式ドキュメントを添付しておきます。
詳しくは下記をご参照ください。

https://supabase.com/partners/integrations/vercel

それでは今回はこのあたりで締めたいと思います。
ここまで読んでいただきありがとうございます。
また機会があればお会いしましょう。
【React】フラグメントのリストをレンダリングする方法

フラグメントのリストをレンダリングする場合には`<>...</>`とすることはできません。
`<Fragment key={yourKey}>...</Fragment>`と記述する必要があります。

```jsx
import { Fragment } from 'react'

function Blog() {
  return posts.map(post =>
    <Fragment key={post.id}>
      <PostTitle title={post.title} />
      <PostBody body={post.body} />
    </Fragment>
  )
}
```
AWS ECS 上の Route Handlers が毎回同じレスポンスを返す問題

# 問題の内容

ECS 上に Next.js を設置し、Route Handlers を使って AWS の別サービスにリクエストを投げ、そのレスポンスをクライアント(ブラウザー)に返すようにしていました。

ちょうど Route Handlers が API の中継サーバーのような格好になっています。

しかし ECS 上にデプロイした直後はちゃんと動くのですが、しばらくするとデータが取れない問題が発生しました。
Route Handler は 200 OK を返すので内部でエラーが発生しているわけではなく、単純にバックエンド(AWS の他のサービス)からデータが取れていないような感じです。

この問題に丸一日悩み、やっと解決したので記録を残しておきます。

# 結論

Route Handlers が静的コンテンツとしてプリレンダリングされていたのが原因でした。

ファイルの先頭に以下を付けたら解決しました。
```js
export const dynamic = 'force-dynamic'
```

https://nextjs.org/docs/app/api-reference/file-conventions/route-segment-config

## もうちょっと説明

Route Handlers が prerender されるなんてあるのかと思ったのですが、レスポンスが毎回同じ内容になると判断されるとそうなるみたいです。

私の場合には引数なしだったのが災いして、毎回同じと判断され、静的コンテンツとしてプリレンダリングされてしまったようです。

解決方法としては `export const dynamic = 'force-dynamic'` を付けて強制的に毎回レンダリング(？)してやるのが良さそうです。

```ts
export const dynamic = 'force-dynamic'
import { NextResponse } from 'next/server'

export const GET = async () => {
  return NextResponse.json({ message: 'OK' })
}
```

## 判定方法

ビルドしてやると Static か Dynamic かが分かります。
以下の例だと /api/books が Static になってしまっています。

```text
Route (app)                              Size     First Load JS
┌ ○ /                                    135 kB          219 kB
├ ○ /_not-found                          882 B          85.2 kB
├ λ /api/users                           0 B                0 B
└ ○ /api/books                           0 B                0 B
+ First Load JS shared by all            84.3 kB
  ├ chunks/69-87d8c82a62e1ee09.js        29 kB
  ├ chunks/fd9d1056-c8811681137251ad.js  53.4 kB
  └ other shared chunks (total)          1.9 kB


○  (Static)   prerendered as static content
λ  (Dynamic)  server-rendered on demand using Node.js
```