OmniAICreator/Qiita-1.07M huggingface dataset:
なんとなく使ってたnpm iについて(dependencies)

# なんとなく使ってたnpm i　について
## なぜこの記事を書こうと思ったのか
現場内での実装でテストコードに触れることになりました。
ライブラリが必要になった際に毎回npm iを実行しますが、ここについて何も考えず実行していたなぁと思いまして今回の記事を作成しております。
例えば。npm i時に書く、「-D」とかありますよね。毎回ネット記事から拾ったコピペを貼って実行としてたので、この辺りですね、。
デプロイ環境とローカル環境では必要なライブラリだったりが異なってくるので、早見表的な想定でよく見るものを書いてみたいと思います。

## 初学者向きの前提
```
「npm i」 は 「npm install」 の略です
```

## package.json内の、これ。

```javascript
  "dependencies": {
    "@reduxjs/toolkit": "^2.2.5",
    "axios": "^1.7.2",
    "dayjs": "^1.11.11",
    "react": "^18.2.0",
    "react-dom": "^18.2.0",
    "react-hook-form": "^7.51.5",
    "react-modal": "^3.16.1",
    "react-redux": "^9.1.2",
    "react-router-dom": "^6.23.1",
    "reset-css": "^5.0.2",
    "styled-components": "^6.1.11",
    "swiper": "^11.1.4",
  },
  "devDependencies": {
    "@types/react": "^18.3.3",
    "@types/react-dom": "^18.3.0",
    "@types/react-router-dom": "^5.3.3",
    "@types/styled-components": "^5.1.34",
    "@typescript-eslint/eslint-plugin": "^7.2.0",
    "@typescript-eslint/parser": "^7.2.0",
    "@vitejs/plugin-react": "^4.2.1",
    "eslint": "^8.57.0",
    "eslint-plugin-react-hooks": "^4.6.0",
    "eslint-plugin-react-refresh": "^0.4.6",
    "prettier": "^3.3.1",
    "prettier-plugin-organize-imports": "^3.2.4",
    "typescript": "^5.4.5",
    "vitest": "^2.0.5"
    "vite": "^5.2.0"
  }
```

インストール済みのライブラリが一覧で入っていますが、
上段の「"dependencies"」と「"devDependencies"」の違いってなんぞ？と、どういうケースでこう分かれているのか？と。
特に考えてもなかったので知りませんでした。

## "dependencies"について
ここには、「デプロイ環境」と「ローカル環境」の両方で使われるライブラリが格納されています。
例えばaxiosとdayjsをインストールする際は
```
npm install axios dayjs
npm i axios dayjs 
npm install axios dayjs --save-prod
↑上記3種類は全て同じ結果
```
いずれかを、プロジェクト内のターミナルで実行してあげればdependencies側に入ります。
「ユーザーに提供される機能に直接影響するライブラリ」であるということですね。たとえば、reactやaxiosなどのライブラリは、ユーザーがアプリケーションを使用する際に必要となるためdependenciesに含まれます。

## "devDependencies"について
ここには「ローカル環境」のみで使われるライブラリが格納されています。(開発時にのみ必要なライブラリ)
例えばcreate-react-appでは環境構築時にデフォルトでインストール済みのテストツールである「jest」。
vite環境でのテストツール「vitest」はデフォルトインストールがされていないため、手動でインストールする必要があります。vitestをインストールするコマンドは以下です。
```
npm i vitest -D
```
ここでキーとなるのが、割と参照記事なんかで見かけるこの「-D」です。
ここで知らなかったのですが、初学者向き前提として「npm i は npm install」を書かせていただいたのと同様にこのケースでの「-D」も短縮系なんだということがわかりました。
デプロイの構造なんかがわかるとより理解が深まりそうな気もしますね。
```
npm i vitest -D
npm install vitest --save-dev
↑2種類どちらで実行しても結果は同じ
```

## 感想
Reactのコードを書くことはなんとなく出来ている気がするので、今後はこういうところも焦点を置いて学習していきたいなぁと思います。
ありがとうございました。
島探し (paizaランク S 相当)：

[島探し (paizaランク S 相当)](https://paiza.jp/works/mondai/s_rank_skillcheck_sample/search-island)


https://paiza.jp/works/mondai/s_rank_skillcheck_sample/search-island

## 背景
列の数がM、行の数がNの表があります。表の各マスは白か黒で塗られています。
黒で塗られたマスが上下左右で隣接している時、その黒マスの塊をまとめて「島」と呼びます。
例えば、以下のような4列×5行の表（M=4、N=5）があった場合
![スクリーンショット 2024-08-29 6.26.41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/527611/7bcfb3eb-e3d0-c1da-4fdd-279745ef69f4.png)
この表には以下の(1)～(3)のように3つの島が存在します。

![スクリーンショット 2024-08-29 6.26.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/527611/7fe05ea1-7530-c92e-39f9-2309ab7c8ca4.png)
島の数を計算して出力するプログラムを作成して下さい。




この問題は、2次元グリッド上の「島」（上下左右で隣接する黒いマスの塊）を数える問題です。DFS（深さ優先探索）またはBFS（幅優先探索）を用いて、各島を探索して数える方法で解決できます。ここではDFSを用いた解法を示します。

### 解法の考え方

1. **グリッドの入力と準備**:
   - 入力からグリッドのサイズ（列数 `M`、行数 `N`）と、各セルの状態（白か黒）を読み取ります。
   - `1` は黒（島の一部）、`0` は白（空き地）を表します。

2. **探索の初期化**:
   - 島の数をカウントするための変数 `island_count` を初期化します。
   - 訪れたマスを記録するために、2次元リスト `visited` を初期化します。

3. **深さ優先探索（DFS）による島の探索**:
   - グリッド内の各セルを順に見ていき、まだ訪れていない黒マス（`1`）を見つけたら、DFSでその塊全体を探索します。
   - 新しい島を見つけるたびに `island_count` をインクリメントします。
   - DFSを用いて、見つけた黒マスからつながっている全ての黒マスを探索し、訪れたマスを `visited` に記録します。

4. **結果の出力**:
   - 最終的に `island_count` を出力します。

### 実装コード

以下にPythonでの実装例を示します：

```python
def count_islands(M, N, grid):
    def dfs(x, y):
        # 範囲外チェックと白マスまたは既訪問チェック
        if x < 0 or x >= N or y < 0 or y >= M or grid[x][y] == '0' or visited[x][y]:
            return
        # 現在のマスを訪問済みとする
        visited[x][y] = True
        # 上下左右に移動して再帰的にDFSを行う
        dfs(x + 1, y)
        dfs(x - 1, y)
        dfs(x, y + 1)
        dfs(x, y - 1)

    # 訪問チェック用のリスト
    visited = [[False] * M for _ in range(N)]
    island_count = 0

    # 全てのマスを確認
    for i in range(N):
        for j in range(M):
            if grid[i][j] == '1' and not visited[i][j]:
                # 新しい島を見つけた場合、DFSを開始して全ての連結する黒マスを訪問する
                dfs(i, j)
                island_count += 1

    return island_count

# 入力の読み込み
import sys
input = sys.stdin.read
data = input().splitlines()

M, N = map(int, data[0].split())
grid = [line.split() for line in data[1:]]

# 結果の出力
print(count_islands(M, N, grid))
```

### 入力例

```
4 5
0 1 0 1
1 1 0 0
0 0 1 0
1 0 0 1
1 1 1 0
```

### 出力例

```
3
```

### このコードのポイント

- DFSを用いて、グリッド全体を探索し、島の数を効率的にカウントしています。
- 各セルについて、隣接するセルを再帰的に探索することで、島全体を訪問し、再び探索することを防いでいます。
- `visited` リストを使うことで、すでに訪れたセルを記録し、二重訪問を防止しています。
Gmailのログインのポップアップ表示がうっとおしい。

自分への忘備録として残しておきます。

気になってた方いますか。

これ

<br>

![スクリーンショット 2024-08-29 051027.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2698531/57089573-e550-47dd-cc94-733cf688d4a0.png)

<br>

どういう仕組みでこうなってしまうのかは

割愛させていただきます（調べてもよくわからない）

設定変更をどこからしていいものか

今まで知りませんでした。

日本語で検索しても結局出なかったので

英語で検索したらいくつかヒントが得られました。

<br>

<br>

https://myaccount.google.com/connections/settings

<br>

上のリンクに移動します。

Gmailでサインインしておく必要があります。

<br>

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2698531/b708ff0c-01c3-8ae3-df69-fc6d42fdeec9.png)

<br>

<br>

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2698531/a189f3d6-d0ad-7b85-8928-74469e359f2c.png)

<br>

<br>

ログイン・メッセージの項目がデフォルトの状態では

オンのままになってると思います。

オフに切り替えておきましょう。

「セキュリティー」→「サードパーティ製のアプリとサービス」

→「右にある歯車アイコン」からでもこの画面に辿り着きます。

**Pinterestのサイトに移動してみることにします。**

<br>

<br>

<br>

<br>

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2698531/cd124b36-a8c8-a3be-f0dd-599f33794295.png)

<br>

Gmailアカウントでログインするうす気味悪いプロンプトが

画面右上に全く表示されなくなりました。

誰なんだよ。こんな風にシステム全体の改悪をすすめようとする勢力は～。

本当にいい加減にしてくれよ。

散々あれこれ右往左往して振り回されてきて

疲弊しまくりくたびれ果てて

うんざりしてます。

解決方法くらい載せとけよ。

悪質極まりないだろうが。

マジで許さん。
BeamerでTikZを使ってスライドの左下角の座標を取得したい

## やりたいこと
Beamerでスライドを作成する時に，「左下角の座標を取得したい」って思うことありますよね．たとえばこんなふうに，スライドの左下隅に定義された座標を使って，うまいこと文字列を`node`で配置したいことがあるわけです．

![ScreenShot 1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/453674/9ea2baac-ab7b-c1a3-0574-5f7a4384ce4c.png)


## どうやるの？
ポイントは，`\tikz{...}`を入れる前に
```
  \tikzset{every picture/.style={remember picture, overlay}}
```
を入れることです．それから，`current page.south west`と`[anchor=south west]`をよく理解して使いましょう．

- `current page.south west`は，nodeの配置場所を現在のページの南西の座標(つまり，スライド左下)を指定しています．
- `[anchor=south west]`は，文字列の左下の座標をそこに合わせるように指定しています．

上のスライドは以下のソースから出力できます．

```LaTeX
\documentclass[fleqn,aspectratio=169,t]{beamer}
\usetheme{metropolis}
\usecolortheme{seahorse}
\setbeamercolor{structure}{fg=brown}
\setbeamersize{text margin left=3mm,text margin right=3mm}
\setbeamertemplate{frametitle}[default][center]
	
\begin{document}%
	\begin{frame}[plain]%
		\frametitle{What I want to say is...}
        \tikzset{every picture/.style={remember picture, overlay}}
		\tikz{
			\node at (current page.south west) [anchor=south west] 
                { It is useful to comment on the corner of the page. };
		}
	\end{frame}%
\end{document}%
```

このソースコードを`main.tex`等と名前をつけて保存し，
```
$ lualatex main
```
を2回実行すると，上図の`main.pdf`が得られます．
[IDMC]設定すると良いパラメータ - 文字化けを防ぐ "OdbcDataDirectNonWapi = 0"

## はじめに
Informatica Intelligent Data Management Cloud(IDMC/旧称IICS)でのちょっとしたTipsを纏めていきます。日々の活動の中で検証した結果記録であり、忘れやすい自分のためのメモですが、少しでも皆様のお役に立てればと思い公開していきます。記述方法など試行錯誤しており随時更新するかもしれません。

## 設定すると良いパラメータ
どのような環境でも必ず設定しておくと良いパラメータ、よく忘れてしまうのでメモとして記事にします。今後シリーズ化するかもしれません。

## 日本語文字列の文字化けを回避
IDMCを利用してデータ連携処理やプロファイリングを実施した際に、画面上の日本語文字列がうまく表示されなかったり、連携された先のデータが文字化けしてしまう現象が発生したら、まずこの設定を試してみるとよいと思います。

管理者->ランタイム環境 から 該当のSecureAgent設定画面を開き、”システム構成の詳細”から「Data Integration Server」サービスの以下のパラメータを設定します。

:::note
OdbcDataDirectNonWapi -> 0
:::

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2985453/7ce353cb-6fe3-64bc-6808-f7df424379ce.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2985453/25591302-501f-b735-cfa1-5bd22f02d74f.png)

デフォルトではこのパラメータは 1 が設定されており、その場合日本語のデータ処理時に文字化けが発生する事があります。
個人的にはこのパラメータは日本語データを扱う場合は常に0に設定することを推奨してしまいます。
おまじない。

### 補足
尚、このパラメータを設定すると希にパフォーマンスに影響がでることがあります。その場合以下のパラメータもセットで設定すると解消します。こちらも併せて設定して置くと良いかもしれません。おまじない。

:::note
OdbcDataDirectWapiWithSQLWChar -> 0
:::
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2985453/f37f20ed-b774-1af0-17b6-1a8370259774.png)


## まとめ
IDMCで新たにSecureAgentをインストール/設定する場合などに必要な情報をメモしておきます。主に自分用ですが皆様のお役に立ちますように。
簡単ですが以上です。

###### 検索用
Informatica / IDMC / Intelligent Data Management Cloud / IICS / Data Integration / CDI / CMI / CDIR / Mass Ingestion / CDQ / CDP / Profiling / CDGC / CDMP / CLAIRE / AI / SecureAgent / ランタイム
文字化け / パラメータ / 初期設定
zsh, PowerShell備忘録

## この記事について
Lightroomで管理しているフォルダの構造を、年＞年月日、から、年＞年月＞年月日、に変更するのに伴い、年月のフォルダの作成と、年月日のフォルダの移動をターミナルでやってみたので、自分用の覚えがき。

:::note info
（例によって、2年くらい放置されていたので、自分で検索するために公開します。）
:::

## やりたいこと

```:tree
#以下のような、YYYY > YYYY-MM-DDのフォルダ構造を
2021
├─2021-01-01
├─2021-01-02
├─2021-01-03
├─2021-01-04
├─2021-01-05
├─2021-01-06

#以下のように、YYYY > YYYY-MM > YYYY-MM-DDというフォルダ構造に修正したい
2021
├─2021-01
│  ├─2021-01-01
│  ├─2021-01-02
│  ├─2021-01-03
│  ├─2021-01-04
│  ├─2021-01-05
│  ├─2021-01-06

```

```Zsh:Zsh
mkdir 2021-{01..12}
#{開始..終了}
```

```PowerShell:PowerShell
New-Item -ItemType Directory (1..12 | % {"2021-{0:D2}" -f $_})
```
https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_operators?view=powershell-7.2#range-operator-
### for ループ

```Zsh:Zsh
for i in {01..12}
do
mv 2021-$i-* 2021-$i
done
# for 変数 in リスト
# do
# 処理
# done
```
参考にしたページ
https://shellscript.sunone.me/for.html


```PowerShell:PowerShell
foreach ($i in 1..12){
get-childitem -filter ("2021-{0:d2}-*" -f $i) | move-item -destination (".\2021-{0:d2}" -f $i)
}
```
参考にしたページ
https://qiita.com/zaki-lknr/items/506bb446ba510e40a776#%E6%95%B0%E5%80%A4-1
フロントエンドカンファレンス北海道2024に初めてスタッフとして参加しました！

今回、3回目のカンファレンスで初めてコアスタッフとして参加しましたので、レポートにまとめていこうと思います。

![IMG_9825.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3721753/fe539171-523d-0689-c505-a53ac904aa95.jpeg)
（自動ドアにカンファレンスロゴ表示するのがすごい！）
## 開催概要
開催日時
2024.08.24(Sat.) 10:00~18:00
会場
(8階) Deep Tech CORE SAPPORO
(6階) HOKKAIDO xStation01

## コアスタッフになった流れ
実行委員長のOyuさんとは春先のSapporo Engineer Baseさんのイベントで初めてお会いして、スタッフに参加させていただきました。

## 私の担当したこと
私は制作物チームとして、LPとルーム名ロールアップバナーの作成に携わりました。

https://x.com/kengo20_03/status/1828051529674436693

ロールアップバナーを作成する際に初めてAdobe Illustrator使用してデザインを作成しました。操作が全く慣れず苦戦しましたがなんとか試行錯誤して完成させました。
LP作成のことについてのっとさんがLTを行い、一瞬だけスライドに登場しました。
![IMG_9821.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3721753/4c88aa89-8340-8b96-ebc7-f6ac047b8377.jpeg)

# 当日
カンファレンス当日は8階カケハシルームの担当だったので基本的に8階にいました。8階も6階もたくさんの方が来場されてとても活気にあふれていました。
## スポンサーブース
セッションの合間に全てのスポンサーブースを訪れました。どの企業様のブースも魅力的なノベルティを配っていてとても嬉しかったです。
数日前にXの投稿で拝見したサイバーエージェントさんのアイス用スプーンが欲しかったのでいただけてとても嬉しかったです。
![IMG_9826.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3721753/a0f8228b-0a19-4f66-88a9-4277656f4308.jpeg)

## 謝辞
参加者・スポンサー様・スタッフの皆様・その他お手伝いいただいた皆様、**このようなイベントを開催・運営に携わらせていただき本当にありがとうございました。**

https://x.com/_n13u_/status/1827712057917239786

次回もあるようなのでまた参加したいです！
SEOを意識したWebP画像の活用とRuby on Railsでの実装方法

## SEO上、Webpが有利

WebPは、従来の画像フォーマットよりもファイルサイズが小さく、ページの読み込み速度を向上させるため、SEOに有利です。これにより、モバイルフレンドリー性が向上し、ユーザーエクスペリエンスが改善され、結果的に検索エンジンでの評価が高まります。

今日は、Ruby on RailsのActiveStorageを使って、どのようにWebpを使っていくかを説明します。

## そもそもWebPとは

WebP（ウェッピー）は、Googleが開発した画像フォーマットで、主にウェブでの画像配信を最適化するために設計されています。WebPは、静止画とアニメーション画像の両方をサポートし、以下のような特徴があります。

### 特徴

1. **高圧縮率**
   - WebPは、従来のJPEGやPNGよりも高い圧縮率を提供します。これは、画像の品質を保ちながら、ファイルサイズを小さくすることができます。
   - **ロスレス圧縮**: PNGと同様に、画質を一切劣化させない圧縮が可能です。
   - **非可逆圧縮**: JPEGのように、多少の画質劣化を伴うが、ファイルサイズをさらに小さくする圧縮も可能です。

2. **透過性のサポート**
   - PNGのように、WebPは透過性（アルファチャンネル）をサポートしています。これにより、背景が透明な画像を作成できます。

3. **アニメーションのサポート**
   - WebPはGIFの代替としても利用でき、アニメーション画像をサポートしています。アニメーションWebPは、GIFよりも高圧縮率でファイルサイズを小さくすることができます。

4. **ブラウザのサポート**
   - WebPは、Google Chrome、Firefox、Microsoft Edge、Operaなど、主要なウェブブラウザでサポートされています。ただし、すべてのブラウザが完全にサポートしているわけではないため、互換性の問題が発生する場合もあります。

5. **用途**
   - WebPは主にウェブサイトで画像の表示速度を向上させるために使用されます。ファイルサイズが小さいため、ページの読み込み時間が短縮され、ユーザーエクスペリエンスが向上します。


## Ruby on RailsのActiveStorageでWebPを活用する

### 1. ActiveStorageの設定
まず、ActiveStorageをセットアップします。Rails 5.2以降では、ActiveStorageが標準で組み込まれているため、rails active_storage:installコマンドでマイグレーションを作成し、データベースを更新します。

```bash
rails active_storage:install
rails db:migrate
```

### 2. WebP形式での画像保存
次に、WebP形式で画像を保存するための設定を行います。ActiveStorageはデフォルトでWebPをサポートしているため、特別な設定は不要ですが、必要に応じて画像をWebPに変換する処理を追加することができます。

### 3. 画像のアップロードと変換
ユーザーが画像をアップロードするときに、WebP形式に変換するためには、以下のようにActiveStorageのバリアント機能を活用します。

```ruby
class User < ApplicationRecord
  has_one_attached :avatar

  def avatar_webp
    avatar.variant(format: :webp).processed
  end
end
```

このコードでは、ユーザーのアバター画像をWebP形式に変換しています。variantメソッドを使用して、任意のフォーマットに変換することが可能です。

### 4. ビューでの表示
WebP画像をビューで表示する際には、以下のように呼び出します。

```erb
<%= image_tag user.avatar_webp %>
```

これで、ユーザーのアバターがWebP形式で表示されるよ
うになります。WebPを使用することで、ページの読み込み速度が向上し、ユーザーエクスペリエンスが向上します。

## 複数のサイズのバリアントを定義

※ バリアント（variant）とは、元の画像から異なるバージョンの画像を作成するための機能です。Ruby on RailsのActiveStorageでは、画像をアップロードした後に、その画像のサイズ変更やフォーマットの変換を行って、複数のバージョン（バリアント）を生成できます。

複数のサイズのバリアントを定義
まず、異なるサイズやフォーマットのバリアントをモデル内で定義します。たとえば、thumbnail, medium, largeの3つのサイズをWebP形式で定義する場合は、以下のように記述します。

```ruby
class User < ApplicationRecord
  has_one_attached :avatar

  # WebP形式のサムネイル（100x100）
  def avatar_thumbnail_webp
    avatar.variant(resize_to_fill: [100, 100], format: :webp).processed
  end

  # WebP形式の中サイズ（300x300）
  def avatar_medium_webp
    avatar.variant(resize_to_fill: [300, 300], format: :webp).processed
  end

  # WebP形式の大サイズ（600x600）
  def avatar_large_webp
    avatar.variant(resize_to_fill: [600, 600], format: :webp).processed
  end
end
```

**※ もっと良い書き方があるのですが、ここでは省略します。**

ここで、`resize_to_fill`オプションを使用して指定したサイズに画像をリサイズし、`format: :webp`でWebP形式に変換しています。

2. ビューでバリアントを表示
それぞれのバリアントをビューで表示する際には、次のように呼び出します。

```erb
<%= image_tag user.avatar_thumbnail_webp %>
<%= image_tag user.avatar_medium_webp %>
<%= image_tag user.avatar_large_webp %>
```
このコードにより、ユーザーのアバターが指定した3つの異なるサイズでWebP形式で表示されます。

※ その他
複数のバリアントを作成する場合、各バリアントが最初にアクセスされたときに生成され、サーバーにキャッシュされます。これにより、同じバリアントが再度アクセスされたときには高速に提供されるようになります。
JavaScriptバイナリデータを扱うためのクラスまとめ

![JavaScriptバイナリデータを扱うためのクラスまとめ.drawio (2).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/79394/cf26e765-8ca2-224d-2882-84cfa8be7270.png)
<!-- https://app.diagrams.net/#G1YE57XRTA6I8Jnv4a6-qxsiS90CFmVbHK#%7B%22pageId%22%3A%22Zr-MIxYXZsLY1nKM5K9r%22%7D -->

# [File](https://developer.mozilla.org/ja/docs/Web/API/File)
ファイルを表すクラス。Blobを継承している。
name, lastModified, sizeなどのプロパティを持つ。

`<input type="file" id="file1">`の`document.getElementById("file1").files` はFileListクラス。FileListはFileの配列のようなクラス。

# [Blob](https://developer.mozilla.org/ja/docs/Web/API/Blob)
Fileと似たようなクラス。プロパティとしてsize, type（MIMEタイプ）を持つ。
Fileと同様、FileReaderで読み込める。
`await blob.arrayBuffer()`でArrayBufferに変換できる。
`new Blob([array])`でArrayBufferやUint8Arrayなどから変換できる。

# [FileReader](https://developer.mozilla.org/ja/docs/Web/API/FileReader)
FileやBlobを読み込むためのクラス。
readAsText()で文字列として読み込む。
readAsArrayBuffer()でArrayBufferとして読み込む。

# [Uint8Array](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Uint8Array)
バイト列をuint8の配列として扱うためのクラス。TypedArrayの一種。内部にArrayBufferを持っている。
`.buffer`でArrayBufferを返す。

# [ArrayBuffer](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/ArrayBuffer)
最も基本的なバイト列。
ArrayBuffer の内容を直接操作することはできない。new Uint8Array(buffer)やnew Uint16Array(buffer)などで変換して扱う。

# [TextEncoder](https://developer.mozilla.org/ja/docs/Web/API/TextEncoder)
`.encode()`で文字列をUTF-8のUint8Arrayに変換できる。それ以外の文字コードには対応していない。

# [TextDecoder](https://developer.mozilla.org/ja/docs/Web/API/TextDecoder)
`.decode()`でUint8Arrayを文字列に変換できる。sjis等にも対応している。
ファイルやAPIから取得したSJISのバイト列を文字列に変換するために使える。

# Buffer
Node.js独自のクラス。
Uint8Arrayのサブクラス。
SQL Serverのウィンドウ関数（順位付け）をまとめる

## はじめに

SQL Serverのウィンドウ関数は、実業務を行う以上高頻度でお世話になる機能です。
業務でよく使用されるROW_NUMBER, RANK, DENSE_RANKおよび順位付けの仲間NTILEの4つの関数を具体例を交えてまとめておきます。

### 参考

https://learn.microsoft.com/ja-jp/sql/t-sql/functions/ranking-functions-transact-sql?view=sql-server-ver16

## 具体的なSQL例

### ROW_NUMBER() 関数
ROW_NUMBER()は、結果セット内の各行に一意の連続した整数を割り当てます。
下記例では、給与の高い順番に各従業員の順位付けを行っています。
```sql:ROW_NUMBER()
SELECT 
    employee_name,
    department,
    salary,
    ROW_NUMBER() OVER (ORDER BY salary DESC) AS salary_rank
FROM 
    employees;
```

### RANK() 関数
RANK()は、順位を付けますが、同じ値の場合は同じ順位を割り当て、次のランクをスキップします。
下記例では、各部門内で給与に基づいて順位付けを行っています。同じ給与の従業員は同じランクになります。
```sql:RANK()
SELECT 
    employee_name,
    department,
    salary,
    RANK() OVER (PARTITION BY department ORDER BY salary DESC) AS dept_salary_rank
FROM 
    employees;
```

### DENSE_RANK() 関数
DENSE_RANK()もRANK()と同様に順位を付けますが、同じ値の場合は同じランクを割り当て、次のランクをスキップしません。
下記例では、各製品カテゴリー内で売上高に基づいて順位付けを行っています。同じ売上額の製品は同じランクになりますが、次のランクは連続した数字になります。
```sql:DENSE_RANK()
SELECT 
    product_name,
    category,
    sales_amount,
    DENSE_RANK() OVER (PARTITION BY category ORDER BY sales_amount DESC) AS category_sales_rank
FROM 
    products;
```

### NTILE() 関数
NTILE()は、指定された数のグループに行を均等に分割します。各行にグループ番号を割り当てます。
下記例では、従業員を給与に基づいて4つの等しいグループ（四分位）に分けています。
正直つかったことないです。
```sql:NTILE()
SELECT 
    employee_name,
    department,
    salary,
    NTILE(4) OVER (ORDER BY salary DESC) AS salary_quartile
FROM 
    employees;
```

### 4つの関数の違い
| 値 | ROW_NUMBER() | RANK() | DENSE_RANK() | NTILE(4) |
| --- | --- | --- | --- | --- |
| 100 | 1 | 1 | 1 | 1 |
| 90 | 2 | 2 | 2 | 1 |
| 90 | 3 | 2 | 2 | 2 |
| 80 | 4 | 4 | 3 | 2 |
| 70 | 5 | 5 | 4 | 3 |
| 60 | 6 | 6 | 5 | 3 |
| 50 | 7 | 7 | 6 | 4 |
- ROW_NUMBER(): 常に一意の連続した数字を割り当てます
- RANK(): 同じ値には同じ順位を割り当て、次の順位をスキップします
- DENSE_RANK(): 同じ値には同じ順位を割り当てますが、次の順位は連続した数字になります
- NTILE(): データを指定された数のグループに均等に分配します

## おわりに
ウィンドウ関数のROW_NUMBER(), RANK(), DENSE_RANK(), NTILE()は、データの順位付けや分析に使えます。
それぞれの関数を理解し、適切に使い分けることで、効果的なデータ分析が可能になります。特にROW_NUMBER()は様々な場面でお世話になります。
RailsでのJWT認証の実装手順ガイド：Gemのインストールからユーザーログインまで

## 1. Gemのインストール
まず、JWTを扱うためのGemをインストールします。gem 'jwt'をGemfileに追加し、bundle installを実行します。


```ruby
# Gemfile
gem 'jwt'
```

```bash
bundle install
```

## 2. 秘密鍵の準備
JWTを署名するための秘密鍵を設定します。これを環境変数に保存するか、Railsのcredentialsに保存します。

```bash
# .envファイルに追加 (dotenv gemを使用している場合)
JWT_SECRET_KEY=your_secret_key
```

## 3. JWTを生成するメソッドの作成
コントローラーやサービスクラスで、JWTを生成するメソッドを作成します。

```ruby
require 'jwt'

class JsonWebToken
  SECRET_KEY = Rails.application.credentials.jwt_secret_key || ENV['JWT_SECRET_KEY']

  def self.encode(payload, exp = 24.hours.from_now)
    payload[:exp] = exp.to_i
    JWT.encode(payload, SECRET_KEY)
  end

  def self.decode(token)
    decoded = JWT.decode(token, SECRET_KEY)[0]
    HashWithIndifferentAccess.new decoded
  rescue JWT::DecodeError
    nil
  end
end
```

## 4. ユーザーログイン時にJWTを生成
ユーザーログイン時にJWTを生成して、クライアントに返します。

```ruby
class AuthenticationController < ApplicationController
  def login
    @user = User.find_by(email: params[:email])

    if @user && @user.authenticate(params[:password])
      token = JsonWebToken.encode(user_id: @user.id)
      render json: { token: token }, status: :ok
    else
      render json: { error: 'Invalid credentials' }, status: :unauthorized
    end
  end
end
```

## 5. 認証フィルターを設定
トークンを検証して、ユーザーを認証するフィルターを設定します。

```ruby
class ApplicationController < ActionController::API
  before_action :authorize_request

  private

  def authorize_request
    header = request.headers['Authorization']
    header = header.split(' ').last if header
    decoded = JsonWebToken.decode(header)
    @current_user = User.find(decoded[:user_id]) if decoded
  rescue ActiveRecord::RecordNotFound => e
    render json: { errors: e.message }, status: :unauthorized
  rescue JWT::DecodeError => e
    render json: { errors: e.message }, status: :unauthorized
  end
end
```

## 6. 認証が必要なコントローラーにフィルターを適用
特定のコントローラーに対して、認証を強制するようにします。


```ruby
class UsersController < ApplicationController
  before_action :authorize_request, only: [:show, :update, :destroy]

  def show
    render json: @current_user
  end
end
```

## おまけ

jwtの実装の際の手順は下記の通り

1. ユーザーがログイン情報を入力
ユーザーがフロントエンドのログインフォームに情報を入力します。

1. POSTリクエストの送信
フロントエンドは、資格情報を含むPOSTリクエストをRailsアプリケーションの/loginエンドポイントに送信します。

1. ユーザーの認証
Railsアプリケーションは受け取った資格情報を使用してユーザーを認証します。

1. JWTトークンの生成
認証が成功すると、ユーザー情報を含むJWTトークンが生成されます。

1. JWTトークンの受信と保存
フロントエンドは、Railsから返されたJWTトークンを受け取り、ローカルストレージなどに保存します。

1. 保護されたエンドポイントへのリクエスト
フロントエンドは、JWTトークンをAuthorizationヘッダーに含めて、保護されたエンドポイントにリクエストを送信します。

1. JWTトークンの検証
Railsアプリケーションは受け取ったJWTトークンを検証します。

1. アクセスの許可または拒否
JWTトークンが有効であればアクセスを許可し、無効であれば拒否します。

1. レスポンスの受信
フロントエンドは、Railsアプリケーションからのレスポンスを受け取り、ユーザーに表示します。
iPhone にあるゲームパッドを無線接続した際のメモ： アローンの「Switch用 スーパーミニコントローラー（ライトブルー ALG-NSWCSMLB）」

## はじめに
以下の製品を入手したのですが、こちらを iPhone に無線接続して、ゲームパッド／キーボードとして動作させてみた時の話を記事に書きました。

●Switch用 スーパーミニコントローラー ライトブルー ALG-NSWCSMLB | 株式会社アローン
　https://140-041.co.jp/product/alg-nswcsmlb

https://x.com/youtoy/status/1823245135993532521

ちなみに買った 1番の理由は「なんとなく面白そうだったから」で、その際に思い浮かべた用途としては、ゲーム用というよりはモノ作り系の展示などで使うという方向でした。

### 記事を書いた理由
このコントローラーは、以下のように様々なデバイスと有線／無線での接続ができる製品と書かれています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50868/70b8953e-a4ce-d1b5-edee-c11618db98c7.png)

この後に出てくる接続のための手順で使うボタンの 1つを、上記の機器に合わせたボタンにしてやれば良いという仕様のようでした。

それで、当初は PC との有線接続を試そうとして思ったようにつながらず（やり方のせいかも？）、次に iPhone との無線接続を試して動作確認ができました。

その際に、思ったよりは手こずったので、手順の一部をメモしておこうと、この記事を書きました。

## iPhone との接続
iPhone との無線接続について、手順の一部のメモです。

### ゲームパッドとしての接続
まずは、ゲームパッドとしての接続についてです。

やり方は、以下の Nintendo Switch用の手順で「Bボタン ⇒ Xボタン」と変える、つまり「STARTボタンと Xボタンを約5秒長押し」とすれば良いのかなと思ったのですが、ちょっと違った感じもしたので、ここをメモしておきます。

![名称未設定.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50868/d5588bf7-efdc-4c8b-a8a7-c4f1476a0e41.jpeg)

まず、コントローラーに線はつながず、バッテリーが充電された状態で、本体下の LED が消灯した状態という前提です。

ここで STARTボタンを押すと、本体下の LED が点滅します。そして、STARTボタンを数秒長押しすると、LED が消灯しました。

LED が消灯した状態で、「X を押した状態にしてから、STARTボタンをポチッと押す」と、STARTボタンを長く押し続けなくても、LED が高速点滅する状態になります。
（※ ここで Xボタンを組み合わせると、「iPhone に対して Bluetooth接続できるゲーム用のコントローラー／ゲームパッド」としてつなげられる状態になります）

iPhone の設定アプリの Bluetooth の設定画面へ進むと、某社のゲームパッドの名称がなぜか表示されます...

そして、この某社のゲームパッドの名前のものをタップすると、iPhone とのペアリングが完了します。

あとは、自分の場合はゲームパッドに対応しているアプリがあったので、それで十字キー操作や、決定・キャンセルの操作が行えることを確認しました。
（iPhone用の Minecraftアプリの、タイトル画面の操作を軽く試しました）

### キーボードとしての接続
次にキーボードとしての接続です。

既に、ゲームパッドとしてペアリングしている場合、その設定登録を解除する必要があります。

iPhone でのコントローラーの登録解除をしてから、上で使った接続手順で「Xボタン ⇒ Rボタン」として操作を進めます。

そうすると、iPhone の設定アプリの Bluetooth の設定画面で、以下の表示が出てきていると思います。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50868/295f48d2-3b56-207a-9aa2-4a51cb46f6fb.png)

この名前の部分をタップすると、ペアリング完了です。

あとは iPhone で文字入力が可能な状態にしてコントローラーのボタンを押すと、あらかじめ決められたアルファベットの入力が行われます。

## おわりに
今回、アローンの「Switch用 スーパーミニコントローラー（ライトブルー ALG-NSWCSMLB）」を、iPhone に無線接続してみました。

そして、ゲームパッドとしての動作と、キーボードとしての動作を試しました。

とりあえず、iPhone との間では仕様通りの動作をさせられることが確認できて、自分としては一安心という感じです。
[Excel VBA] マクロでシートの保護(パスワード付き)をすることについて

### 最初から本題
エクセルのシートってパスワードで保護できるじゃないですか。

マクロでその設定をする時、
`Sheets(1).Protect Password:="test@pass"`
みたいに平文で入力するのってリスキーですよね、という話。

VBEにてマクロが見えないようにプロジェクトにパスワードは設定できるので、
マクロからパスワードが漏洩することは防げますけど…(以下、警鐘に続く)

### 警鐘
エクセルのファイルって実はzipファイルみたいなものなんですよね。
だから保存されたファイルの拡張子を書き換えて解凍すると中身が見えるんです。

testFile.xlsm → testFile.zip → testFile (フォルダ)

解凍されたフォルダの中には色々ファイルがあって、
だいたい以下の様になってます(一部省略)

testFile
├_rels
├docProps
└xl
　├_rels
　├ctrlProps
　≈
　├**vbaProject.bin**
　└workbook.xml
 
問題になるのは太字の"vbaProject.bin"です。

こいつをメモ帳やサクラエディタ等で開くと、
ガリガリ文字化けしてますが、所々マクロが見えてしまうんですよね
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3862825/dc4bb835-3ccf-a7ab-fad0-8b3f6cff5441.png)

その中には`test@pass`というさっき設定したパスワードも…

ファイルによっては`.Protect Password:=`の一部が読める状態で表示されることもあり
その後ろにパスワードがあると推測できるものもあります。

今回はパスワードがフルで見えてしまってますが、一部しか見えない場合もあります。
しかし一部でも見えてしまうことは攻撃者へヒントを与えるのと同義です。

### 防ぎたい！
これってなんとかしたいですよね。(私だけ？)

私は以下みたいに分散して、
コードの中でも散りばめるぐらいしか思い浮かびませんでした。
```vb
    p1 = "te"
    p2 = "st"
    ch = Chr(64)
    p3 = "pa"
    p4 = "ss"

    Sheets(1).Protect Password:=p1 & p2 & ch & p3 & p4
```
こんな小細工じゃなくて、根本的に解決できるって情報大歓迎です！

以上！
Stable Diffusionに関する技術について調べてみました

# 1.はじめに

どうも、ARIの名古屋支社に勤務している愛知県民こと、
新藏（にいくら）と申します♪
(/・ω・)/

**2022年頃話題になった画像生成AI**について、当時以下の記事で使い方を紹介しました。

https://qiita.com/Aichi_Lover/items/5c92b1046e45ea4b1eef

簡単な文章を入力するだけで思い通りの画像を作成できる、大変便利なツールです。
あれから2年、最近は画像生成AIを使ってない・・・と思いました。

**そこで今回はStable Diffusionに関する技術について記事にします！**

画像生成AIに興味のある方や、使ったことがある人の参考になれば幸いです。
(*^^)v

# 2.画像生成AIとは
まず初めに、画像生成AIとは何かについてですが、
画像生成AIとは、**入力したテキストをもとに画像を作成するAI**となります。

参考：https://www.hitachi-solutions-create.co.jp/column/technology/image-generation-ai.html

2年前、記事にしたStable Diffusionは英Stability AI社による画像生成AIで、
ソースコードと様々なモデルが公開されています。

上記を基に改造が可能なので、**独自の画像生成AIを作成することも可能です！**

■ソースコード

https://github.com/CompVis/stable-diffusion

■モデル

https://weel.co.jp/media/stable-diffusion-model


# 3. Stable Diffusionで使われる技術
さて、ここからが本題ですがStable Diffusionで使われる技術を3つ説明します。

## 3.1.Diffusionモデル
**Diffusionモデルとは、拡散過程（ノイズを加える過程）と逆拡散過程（ノイズを除去する過程）
を繰り返して、画像を生成するモデルのことです。**

拡散過程により、ノイズが画像に与える影響を学習し、
逆拡散過程により、ノイズ除去の方法を学習することができます。

|![010_拡散過程と復元過程.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1372071/0c46b67e-e006-e46a-5269-3cbbe20bb2c5.jpeg)|
|:--|
出典：https://www.sbbit.jp/article/cont1/128789

:::note info
ちなみに、Diffusionモデルを直訳すると「拡散モデル」となります。
:::

## 3.2.CLIP
**CLIPとはContrastive Language-Image Pre-Trainingの略で、
テキストと画像のペアを学習し、テキストと画像の関連性を評価するモデルとなります。**

2021年にOpenAI社が発表しました。

Stable Diffusionでは主に逆拡散過程で使用されていて、
ノイズを除去した画像が、作成したい画像（テキスト入力）とどのくらい一致しているかを評価します。

より詳細には、テキストと画像からベクトルを作成し、成分を比較することで、
テキストと画像の内容が近いかどうかを評価します。

:::note info
ちなみに、Contrastive Language-Image Pre-Trainingを直訳すると
「対照的な言語イメージの事前トレーニング」となります。
:::

## 3.3.VAE
**VAEとはVariational Auto-Encoderの略で、
対象の画像を圧縮した潜在空間で処理を行ってから
普通の画像に復元することで、処理を軽くできる技術となります。**

VAEがないと画像を生成する際にGPUが大量に必要になり、
画像生成に時間がかかります。

:::note info
ちなみに、Variational Auto-Encoderを直訳すると
「変分オートエンコーダ」となります。
:::

# 4.おわりに
ここまで読んで下さり、ありがとうございます！！！
(^^)

今回はStable Diffusionで使用されている技術について調べてみました。

CLIPが絵の全体を評価しながら生成しているため、
Stable Diffusionは細部を正確に描写することが苦手なようです。
（生成された画像で、人の髪の流れ・指の本数に異常がある画像を見たことがあります。）

逆に、細部が目立たない風景画やシンプルな画像は得意なので、
これを理解して、今後は画像生成AIを使っていきたいと思います！

この記事を書く際に
「先読み!ITxビジネス講座　画像生成AI　深津貴之著」も読んだので、
気になる方は是非、読んでみてください♪
(:3_ヽ)_
【TypeScript】array型とtuple型の違いを表解で解説する

# はじめに

array型とtuple型ともに、配列で表示されることから具体的に何が違うかわからなくなった方もいるのはないでしょうか？自分もその一人でした。そこで本記事では、一見似ているarray型とtuple型の違いについて、備忘録としてまとめておきます。

# array型とtuple型の違い

### 特徴

array型とtuple型の違いは主に下記のようになります。

|型の種類|記法|特徴|
|:-:|:-:|:--|
|array型|(型)[]|初期定義の配列の型制限が**緩い**|
|tuple型|[(型1), (型2),...]|初期定義の配列の型制限が**厳しい**|

次に、型制限の「緩い」「厳しい」について具体的に見ていきます。

### 型制限が緩い/厳しいとは...？

array型は初期段階で配列を定義する型制限が緩く、tuple型は型制限が厳しくなっています。
具体的なソースコードは下記の通りです。

```ts
// array型の配列定義(配列の要素数はいくつでもOK)
const fruits: string[] = ["apple", "banana", "strawberry"];

// tuple型の配列定義(配列の要素数は宣言した型とその数のみ定義可能)
const fruitsInfo: [string, number, boolean] = ["apple", 1500, true];
```

このように、最初に定義した配列について、

* array型(型制限が緩い)：配列の要素数は宣言した型であれば、**いくつでも宣言してOK**

* tuple型(型制限が厳しい)：配列の要素数は宣言した型と、**その個数が対応する必要あり**

といった違いがあります。ちなみにいずれの型も追加/配列/削除を行うことが可能です。

```add.ts
// 追加(array型)
const fruits: string[] = ["apple", "banana", "strawberry"];
fruits.push("grape"); // ["apple", "banana", "strawberry", "grape"]
fruits.push(1000); // 型が異なるのでエラー

// 追加(tuple型)
const fruitsInfo: [string, number, boolean] = ["apple", 1500, true];
fruitsInfo.push("banana"); // ["apple", 1500, true, "banana"]
```
```update.ts
// 追加(array型)
const fruits: string[] = ["apple", "banana", "strawberry"];
fruits[1] = "grape"; // ["apple", "grape", "strawberry"]
fruits[1] = 1000; // 型が異なるのでエラー

// 追加(tuple型)
const fruitsInfo: [string, number, boolean] = ["apple", 1500, true];
fruitsInfo[1] = 1000; // ["apple", 1000, true]
fruitsInfo[1] = true; // 型が異なるのでエラー
```
```delete.ts
// 追加(array型)
const fruits: string[] = ["apple", "banana", "strawberry"];
fruits.pop(); // ["apple", "banana"]

// 追加(tuple型)
const fruitsInfo: [string, number, boolean] = ["apple", 1500, true];
fruitsInfo.pop(); // ["apple", 1500]
```

# まとめ

今回は、array型とtuple型の違いを解説しました。
最初の配列宣言における**型制限の厳しさ**に違いがあり、配列の追加/更新/削除などはどちらの型も同じように行えることがわかりました。
AppleWatchが欲しかったのでpaizaのSランク問題に挑戦して記事を書いてみた

https://paiza.jp/pages/campaign/paiza-qiita

挑戦した問題はこちら

https://paiza.jp/works/mondai/s_rank_skillcheck_archive/group_popularity

### 工夫した点
問題をそのまま素直に記述するならツリーとかノードとか使いたくなります。
しかし問題文をよく読むと結局**人気度の算出に必要なのは一番高い友好度だけ**だということに気付きます。
それならば予め全ての関係データを友好度で降順にソートしておき、片方の村人のみグループに所属しているデータを上から順に探すという単純な方法で友好度が算出できるでしょう。難しいデータ構造は必要ありません。

この方法では1回の人気度の計算量は *O(M)* になります。

他の人のコードよりもかなりシンプルに記述できているのではないかと思います。


### 苦労した点
友好度データのソートリストの格納に最初はSortedSetを使ってしまったことで、友好度が同じデータが存在する場合にうまくいかずにドツボにハマってしまいました…最終的には普通のListを使いBinarySearchで挿入位置を探しながら整列させています。

### 実装したC#コード
（※VisualStudioでターゲットフレームワーク.NET8.0 で作成したのでそのままpaizaの提出フォームにコピペしてもコンパイルが通りません。usingやMainメソッドの追加やrecordをクラスに変更するなど、少し手直しする必要があります）
```
var nnn = Console.ReadLine().Split();
var N = int.Parse(nnn[0]);	// 村人数
var M = int.Parse(nnn[1]);	// 関係数
var Q = int.Parse(nnn[2]);	// ログ数
// 友好度でソートしたリスト
var sortedList = new List<Data>();
var comparer = new Comparer();
// 降順の有効度リストを作成
for(var i = 0; i < M; i++)
{
	nnn = Console.ReadLine().Split();
	var d = new Data(int.Parse(nnn[2]), int.Parse(nnn[0]), int.Parse(nnn[1]));
    // ソートしながらデータを挿入
	int p = sortedList.BinarySearch(d, comparer);
	if(0<= p)
		sortedList.Insert(p, d);
	else
		sortedList.Insert(~p, d);
}
// 現在のグループ(i番目の村人のグループ参加状況)
bool[] group = new bool[N];
// ログを解読しながら友好度を出力
for(var i = 0; i < Q; i++)
{
	var s = Console.ReadLine();
	int q = int.Parse(s.Substring(2));
	// グループ加入・脱退
	if(s[0] == '+')
		group[q - 1] = true;
	if(s[0] == '-')
		group[q - 1] = false;
    // グループが0人、または全員の時は０
	if(group.All(f => !f) || group.All(f => f))
	{
		Console.WriteLine(0);
		continue;
	}
	// 友好度の高いデータから順に片方の村人だけが加入しているデータを探す
	foreach(var d in sortedList)
	{
        // A加入B非加入 or A非加入B加入
		if(group[d.A - 1] != group[d.B - 1])
		{
			Console.WriteLine((int)d.Value);
			break;
		}
	}
}

/// <summary>
/// 友好度データ
/// </summary>
/// <param name="Value">友好度</param>
/// <param name="A">村人A</param>
/// <param name="B">村人B</param>
public record Data(int Value, int A, int B);
/// <summary>
/// 友好度データの比較用(降順)
/// </summary>
public class Comparer : IComparer<Data>
{
	public int Compare(Data x, Data y)
	{
		// 降順
		return (y.Value - x.Value);
	}
}
```
Oracle 19c se2 audit 設定確認

ChatGPTの回答をのせるだけ

統合監査（Unified Auditing）で監査が設定されているオブジェクトを確認するには、`AUDIT_UNIFIED_POLICIES` および `AUDIT_UNIFIED_ENABLED_POLICIES` ビューを使用します。以下は、統合監査ポリシーとその適用オブジェクトを確認する方法です。

### **作成された監査ポリシーを確認する**

まず、`AUDIT_UNIFIED_POLICIES` ビューを使用して、作成された統合監査ポリシーを確認します。

```sql
SELECT 
    POLICY_NAME,      -- 監査ポリシーの名前
    ENABLED_OPT,      -- 有効化オプション（例: BY USER、BY SYSTEM など）
    SUCCESS,          -- 成功した操作を監査するかどうか
    FAILURE           -- 失敗した操作を監査するかどうか
FROM 
    AUDIT_UNIFIED_POLICIES;
```

### **監査ポリシーが適用されているオブジェクトを確認する**

どのテーブルやオブジェクトに統合監査ポリシーが適用されているかを確認するには、`AUDIT_UNIFIED_ENABLED_POLICIES` ビューを参照します。

```sql
SELECT 
    POLICY_NAME,       -- 監査ポリシーの名前
    OBJECT_SCHEMA,     -- オブジェクトが属するスキーマ
    OBJECT_NAME,       -- オブジェクト名（テーブル、ビューなど）
    OBJECT_TYPE        -- オブジェクトの種類（TABLE、VIEW など）
FROM 
    AUDIT_UNIFIED_ENABLED_POLICIES
WHERE 
    OBJECT_TYPE = 'TABLE';  -- テーブルの監査ポリシーのみを確認
```

### **特定のオブジェクトに適用されている監査設定を確認する**

特定のテーブルに統合監査ポリシーが適用されているかどうかを確認するには、次のクエリを使用します。

```sql
SELECT 
    POLICY_NAME,
    OBJECT_SCHEMA,
    OBJECT_NAME,
    OBJECT_TYPE
FROM 
    AUDIT_UNIFIED_ENABLED_POLICIES
WHERE 
    OBJECT_NAME = 'YOUR_TABLE_NAME'
    AND OBJECT_TYPE = 'TABLE';
```

### **クエリ結果の説明**

- `POLICY_NAME`：オブジェクトに関連付けられている監査ポリシーの名前が表示されます。
- `OBJECT_SCHEMA` と `OBJECT_NAME`：それぞれオブジェクトのスキーマ名とオブジェクト名が表示されます。
- `OBJECT_TYPE`：オブジェクトの種類（TABLE、VIEW など）が表示されます。

これらのクエリを使用することで、どのテーブルが統合監査の対象となっているか、そしてどの監査ポリシーが適用されているかを確認することができます。


従来監査（Traditional Auditing）でどのオブジェクト（テーブルなど）が監査設定されているかを確認するには、`DBA_OBJ_AUDIT_OPTS` ビューを参照します。このビューには、現在のデータベースで監査が有効になっているオブジェクト（テーブルやビューなど）の詳細情報が表示されます。以下にいくつかの重要なクエリを示します。

### **監査が有効になっているすべてのオブジェクトを確認するクエリ**

```sql
SELECT 
    OWNER,        -- オブジェクトの所有者
    OBJECT_NAME,  -- オブジェクト名（テーブル、ビューなど）
    OBJECT_TYPE,  -- オブジェクトの種類（TABLE、VIEW など）
    ALT,          -- ALTER 操作の監査設定
    AUD,          -- AUDIT 操作の監査設定
    COM,          -- COMMENT 操作の監査設定
    DEL,          -- DELETE 操作の監査設定
    GRANT,        -- GRANT 操作の監査設定
    IND,          -- INDEX 操作の監査設定
    INS,          -- INSERT 操作の監査設定
    LOC,          -- LOCK 操作の監査設定
    REN,          -- RENAME 操作の監査設定
    SEL,          -- SELECT 操作の監査設定
    UPD,          -- UPDATE 操作の監査設定
    REF,          -- REFERENCES 操作の監査設定
    EXE,          -- EXECUTE 操作の監査設定
    FBK           -- FLASHBACK 操作の監査設定
FROM 
    DBA_OBJ_AUDIT_OPTS
WHERE 
    OBJECT_TYPE = 'TABLE';
```

### **クエリ結果の説明**

- `OWNER` と `OBJECT_NAME`：監査が有効になっているテーブルの所有者とテーブル名を示します。
- 各操作列（例: `SEL`, `INS`, `UPD`, `DEL` など）：監査が有効になっている特定の操作タイプを示します。
  - `S/S` は成功した操作と失敗した操作の両方が監査されることを示します。
  - `S/-` は成功した操作のみが監査されることを示します。
  - `-/F` は失敗した操作のみが監査されることを示します。
  - `-/-` はその操作に対して監査が無効であることを示します。

### **特定のテーブルの監査設定を確認する例**

特定のテーブルが監査されているかどうかを確認するには、以下のクエリを使用します：

```sql
SELECT 
    OWNER, 
    OBJECT_NAME, 
    SEL, 
    INS, 
    UPD, 
    DEL 
FROM 
    DBA_OBJ_AUDIT_OPTS
WHERE 
    OBJECT_NAME = 'YOUR_TABLE_NAME'
    AND OBJECT_TYPE = 'TABLE';
```

このクエリは、`YOUR_TABLE_NAME` テーブルに対して `SELECT`、`INSERT`、`UPDATE`、`DELETE` 操作が監査されているかどうかを表示します。
ディレクトリ '/' のリスト取得のエラー。【WinSCP】タイムアウトしました。 (データ用接続) ディレクトリの一覧を取得できません。XserverStatic

![スクリーンショット 2024-08-28 233821.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3863976/29a98256-9fce-7c4f-e04b-183f7e8287a2.png)

下記エラーが出た場合は、パッシブモードを無効にしよう

**切断されました。**

タイムアウトしました。 (データ用接続)
ディレクトリの一覧を取得できません。
ディレクトリ '/' のリスト取得のエラー。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3863976/c3af34d2-b65a-30c6-e6b8-d937448485ab.png)


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3863976/ec73228d-31d0-4314-caa1-dd7743d953b1.png)
NY連銀からプレスリリースを取得する


この記事では、requests、BeautifulSoup、およびdatetimeモジュールを使用して、NY連銀のウェブページからプレスリリースの情報（タイトル、日付、URL）を取得する方法を解説します。

### コードの概要

```python
import requests
from bs4 import BeautifulSoup
from datetime import datetime
```

最初に、必要なライブラリをインポートします。

requests: ウェブページの内容を取得するためのライブラリ。
BeautifulSoup: 取得したウェブページの内容を解析して必要なデータを抽出します。
datetime: 日付をフォーマットするためのライブラリ。

### データ取得の流れ
まず、ウェブページからデータを取得し、その内容を解析します。

```python
def extract_press_releases(url):
    response = requests.get(url)  # ウェブページの内容を取得
    soup = BeautifulSoup(response.text, 'html.parser')  
```

次に、プレスリリースの情報（日付、タイトル、URL）を取得します。

```python
    press_releases = []

    rows = soup.select('tr.Research, tr.Press')  # プレスリリースの行をすべて取得

    for row in rows:
        date_tag = row.select_one('td.dirColL div')
        if date_tag:
            raw_date = date_tag.get_text(strip=True)  # 日付を取得
            try:
                date = datetime.strptime(raw_date, "%b %d, %Y").strftime("%Y-%m-%d")  # 日付をyyyy-mm-dd形式に変換
            except ValueError:
                date = "Invalid date format"
        else:
            date = "Date not found"

        title_tag = row.select_one('td.dirColR div.tablTitle a')
        if title_tag:
            title = title_tag.get_text(strip=True)  # タイトルを取得
            link = f"https://www.newyorkfed.org{title_tag.get('href')}"  # フルURLを作成
        else:
            title = "Title not found"
            link = "Link not found"

        press_releases.append((date, title, link))  # リストに追加

    return press_releases
```

rows: ウェブページからプレスリリースのリストを取得します。
date_tag: プレスリリースの日付を抽出し、datetimeライブラリでyyyy-mm-dd形式に変換します。
title_tag: プレスリリースのタイトルとリンクを取得します。
### 結果の表示
最後に、取得した情報を表示します。

```python

url = 'https://www.newyorkfed.org/press/#press-releases'
press_releases = extract_press_releases(url)

for date, title, link in press_releases:
    print(f"Date: {date}\nTitle: {title}\nURL: {link}\n")
multiprocessingとthreadingの併用


```py
import os
import random
import threading
import time
from multiprocessing import Process, Queue


def write_and_read(q, write_threads_count):
    write_threads = [threading.Thread(target=write, args=(q,)) for _ in range(write_threads_count)]
    read_thread = threading.Thread(target=read, args=(q,))

    for thread in write_threads:
        thread.start()
    read_thread.start()

    for thread in write_threads:
        thread.join()
    read_thread.join()


def write(q):
    for value in ["A", "B", "C"]:
        print(f"Put {value} to queue from {threading.current_thread().name}")
        q.put(value)
        time.sleep(random.random())


def read(q):

    while True:
        try:
            value = q.get(timeout=2)
            print(f"Get {value} from queue.")
        except Exception:
            # queueが空
            break


def main():
    q = Queue()
    write_threads_count = 1
    write_and_read_process = Process(target=write_and_read, args=(q, write_threads_count))
    write_and_read_process.start()
    write_and_read_process.join()


if __name__ == "__main__":
    main()


```
【TypeScript】プロパティ 'hoge' は型 'Fuga' に存在しませんの解決方法

# はじめに
現在Udemyのこちらの講座を受けています。現在TypeScriptを学習しているのですが、表題のエラーが発生しました。こちらの解決策について説明します。

https://www.udemy.com/course/react_stepup/

# 問題点
こちらが、私が書いていたコードです。
user.emailとuser.addressのところにエラーが出ていました。

```react

import { FC } from "react";
import { UserProfile } from "../types/userProfile";

type Props = {
  user: UserProfile;
};

export const UserCard: FC<Props> = (props) => {
  const { user } = props;
  return ( 
    <div> 
      <dl>
        <dt>名前</dt>
        <dd>{user.name}</dd>
        <dt>メール</dt>
        <dd>{user.email}</dd> 
        <dt>住所</dt>
        <dd>{user.address}</dd> 
      </dl>
    </div>
  );
};

```
```react

export type UserProfile = {
  id: number;
  name: string;
  email: string;
  address: string;
};


```
一見何も問題なく設定できているように見えますが、型の設定の仕方を間違えていました。***なぜかアロー関数になっていました。***

```react
//元のコード
export type UserProfile = () => { 
  id: number;
  name: string;
  email: string;
  address: string;
};

```

```react
//修正したコード
export type UserProfile = {
  id: number;
  name: string;
  email: string;
  address: string;
};

```

これで無事にエラーが、解消することが出来ました。

# 最後に
今回はかなり初歩的なところでつまづいてしまいました。引き続きTypeScriptの学習を頑張っていきます。
Pythonで仮想環境を作成する(venv)

## 目的
いつからか、pythonで開発を行う場合に、pipなどを用いて作業を行うと仮想環境内で作業をしなさいと、エラーが出る様になってしまった。

## 環境の作成
```bash
$ python -m venv 仮想環境名
```

## 端末の起動
```bash
$ source 仮想環境名/bin/activate
```


シェルスクリプトからも使う事が出来ます。
MLを使ってエラーの内容を識別するWebアプリ

## スマホアプリでエラーが出たときの問合せを減らしたい
　社内業務ツールでエラーが出た時の問い合わせ対応って意外と重複した内容が多くて、どうにかならないかなって思っていました。そこで、TeachableMachineを使って簡単に画像判定ができることを学び、エラー画面によって対応方法を識別して提案してくれるアプリがあったら便利だな、と思いました💡


 ### ＜実際の画面＞　
https://x.com/magic___96/status/1828783103009337515


### ＜利用したツール＞
・TeachableMachine
・CodePen

### ＜作り方＞
①[こちら](https://fabcross.jp/topics/special/20230418_teachable_machine.html)のページの手順３まで進めます。



②[CodePen](https://codepen.io/pen/?template=MWMQoag)を開き、Googleアカウントなどでログインします。

③タイトルを変更し、`Save`します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3812441/2802a045-245f-7ade-5396-d60059281090.png)



④画面右下の`Fork`ボタンを押します
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3812441/e27a5ad3-1844-34fc-5eb0-f2f87aa6fbcb.png)

⑤`HTML`の中身を書き換えて`JS`の中にTeachableMachineでコピーした`URL`を貼り付けて`Save`します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3812441/35623095-4ee5-56a9-d11a-1ede08a3dc2a.png)

⑥実際にカメラに識別したい内容を映してチェックすれば完成✨


## やりたかったけどできなかったこと
本当は、LINEbotで画像送付して対応方法を返す、ということをやりたかったんですが、相棒のChatGPTを活用しても、他の記事やネットで調べて同じように実施してもうまくできませんでした…😭
 



 ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3812441/20438d3b-61bb-f19d-c186-62bc447def75.png)


### ＜実際に作ったフロー＞
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3812441/b989410b-90aa-44c9-8b31-3041af742980.png)


### ＜相棒のGPTにも見捨てられた…＞
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3812441/6a37ecd1-0997-f30d-9ac4-6469daaa5517.png)

### ＜参考にした記事＞

https://qiita.com/kuma_ssss/items/098715c74c087a19aa65

https://qiita.com/youtoy/items/287a0782fdd185fc2004

https://qiita.com/kuma_ssss/items/098715c74c087a19aa65#line-developers%E3%81%A7webhook%E3%82%92%E7%99%BB%E9%8C%B2

## 作ってみた感想
::: note info 
<dt>よかった点👍</dt>
まず、Webアプリについては本来であればアプリそのものにわかりやすい案内文を表記すべきですが、マニュアルなどを用意しても結局読まなかったり、「エラーがでた」だけだとわからないので、ツールとしてはアリだな、と思いました。
:::

::: note warn
<dt>あと少し🤏</dt>
やっぱり、LINEbot完成させたかったですね…😭読み取る画像によって回答文を変更するところまではできたので、あとはLINEとの連携ぐらいだと思うんだけど…くぅ…
:::


## ＜ML(機械学習)で解決できること＞
今回はアプリエラー対応を題材にやりましたが、例えば駐車場の入口にカメラを用意して、違法駐車した場合に通知が届く、とかしたいですね🚗
今は警備さんが定期的に巡回して違法駐車をチェックしているんですが、自動になれば人件費も抑えられる…⁉
やりたいことはいっぱいだけど、追い付かない…幸せな悩みだ…✨
【Github 自動化】mainブランチにプッシュさせない【#2】

# はじめに
1. Issueをつくる
1. ブランチを切る
1. 細かくコミットする
1. プルリクエストする

洗練された開発プロセスですね。

今回は
- 「2. ブランチを切る」

をサポートするルールを作成しようと思います。

# 直接のCommitを禁止する
「マージ前にプルリクエストを要求」することで、「ブランチを切る」習慣をつけます。

| `Settings`->`Branches` | 名前・ステータス・ターゲットブランチを設定 |
|:-:|:-:|
| ![スクリーンショット 2024-08-28 20.30.44.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3457770/31daf276-4772-182c-3cda-abfc63c8cb7a.png)  | ![スクリーンショット 2024-08-28 22.38.52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3457770/289455e3-c902-d021-c60b-c1256a61e222.png)|
| **`Require a pull request before merging`を有効化** |  |
| ![スクリーンショット 2024-08-28 22.43.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3457770/586c0caf-2f7a-e640-3d15-7730de93e493.png) |   |

:::note warn
注意事項
- `Create`を押して適用するのを忘れずに
:::

# おわりに

以上、「mainブランチにコミットさせない設定」でした。

「Issueを必須にするルール作り」もオススメです。

https://qiita.com/kohki_takatama/items/417d413386b5f44e9cc1
【Github 自動化】Issueを必須にするルール作り【#1】

# はじめに
1. Issueをつくる
1. ブランチを切る
1. 細かくコミットする
1. プルリクエストする

洗練された開発プロセスですね。

今回は
- 「1. Issueをつくる」
- 「4. プルリクエストする」

をサポートするルールを作成しようと思います。

# 1️⃣ プルリクエスト テンプレートを作る

:::note
この章でやること
- プルリクエスト テンプレートを作成する
- Githubのルールを利用し、プルリクエストにIssueを関連付ける

<details><summary>Issueを関連付ける方法</summary>

[Pull RequestをIssueにリンクする](https://docs.github.com/ja/issues/tracking-your-work-with-issues/linking-a-pull-request-to-an-issue#linking-a-pull-request-to-an-issue-using-a-keyword)

Issueをプルリクエストに関連付けることができます。
具体的には、以下の記述をします。

> KEYWORD #ISSUE-NUMBER

例
- `resolve #1`
- `close #1`
- `fix #1`

</details>
:::


### `.github/pull_request_template.md`を作成

```md:.github/pull_request_template.md
# Issue_number
resolve #

# Summary

```

:::note warn
注意事項

- `.github`は、プロジェクトのルートディレクトリに作成します
- `.github/workflows/`に作成しないよう注意してください
- 複数のIssueを関連付ける場合、都度`KEYWORD #Issue_number`と記述します

:::

# 2️⃣ Github Actionsのセットアップ
:::note
この章でやること
- Github Actionを作成する
- プルリクエストが`#Issue_number`含むかチェックする
:::

### `.github/workflows/check-issue-link.yml`を作成
```yml:.github/workflows/check-issue-link.yml
name: Check Issue Link in PR

on:
  pull_request:

jobs:
  check-issue-link:
    runs-on: ubuntu-latest
    steps:
      - name: Check PR for Issue Link
        run: |
          PR_BODY=$(jq -r '.pull_request.body' "$GITHUB_EVENT_PATH")
          echo "$PR_BODY"
          if ! echo "$PR_BODY" | grep -qiE "(close[sd]?|fix(ed|es)?|resolve[sd]?) #[0-9]+"; then
            echo "Error: PR description must include a linked Issue (e.g., 'resolve #123')."
            exit 1
          fi

```
:::note warn
注意事項
- 先ほどとは違い`.github/workflows`ディレクトリに作成しています
:::

# 3️⃣ ブランチ保護ルールの設定
:::note
この章でやること
- Issueを含まないプルリクエストをマージできないようにする
:::

| `Settings`->`Branches` | 名前・ステータス・ターゲットブランチを設定 |
|:-:|:-:|
| ![スクリーンショット 2024-08-28 20.30.44.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3457770/31daf276-4772-182c-3cda-abfc63c8cb7a.png)  | ![スクリーンショット 2024-08-28 22.21.31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3457770/8ecb75d8-ffc5-1573-63dd-c2f059eabc08.png)  |
| **作成したactionを適用** |  |
| ![スクリーンショット 2024-08-28 22.26.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3457770/dcb76b5f-68ab-9160-7a26-4e61f805ca1c.png)  |   |

:::note warn
注意事項
- `Create`を押して適用するのを忘れずに
:::

# おわりに
以上、「Issueを必須にするルール作り」でした。

「mainブランチにプッシュさせない設定」もオススメです。

https://qiita.com/kohki_takatama/items/5f06d1205ad2be287ae1
Firefox の初期設定をカスタマイズする

Linux で新しいユーザが firefox を使いはじめる時に、デフォルト設定をカスタマイズしておきたい。


# 環境

- Debian Testing
- Firefox 115.12.0esr

# 雛形を作る

まずは初期環境としたい設定を適当に作る。

必要に応じ新規ユーザを作り、firefox を起動。

今回は初期設定にブックマークを追加。



![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/34c6f500-f47f-287d-6228-c507807fa2dc.png)



# 調査

```
$ cd ~/.mozilla/firefox
$ ls -alh
合計 32K
drwx------  6 nanbuwks nanbuwks 4.0K  6月 30 17:27  .
drwx------  4 nanbuwks nanbuwks 4.0K  6月 30 17:27  ..
drwx------  2 nanbuwks nanbuwks 4.0K  6月 30 17:27  02c39h4u.default
drwx------  3 nanbuwks nanbuwks 4.0K  6月 30 17:27 'Crash Reports'
drwx------  2 nanbuwks nanbuwks 4.0K  6月 30 17:27 'Pending Pings'
-rw-rw-r--  1 nanbuwks nanbuwks   58  6月 30 17:27  installs.ini
drwx------ 11 nanbuwks nanbuwks 4.0K  8月 28 22:04  mko62hna.default-esr
-rw-rw-r--  1 nanbuwks nanbuwks  247  6月 30 17:27  profiles.ini
```

***.default がプロファイルかなと思ったら、それらしいのが2つありますね。
profiles.ini の中を見てみます。

```
$ cat profiles.ini 
[Profile1]
Name=default
IsRelative=1
Path=02c39h4u.default
Default=1

[Profile0]
Name=default-esr
IsRelative=1
Path=mko62hna.default-esr

[General]
StartWithLastProfile=1
Version=2

[Install3B6073811A6ABF12]
Default=mko62hna.default-esr
Locked=1

```
mko62hna.default-esr がプロファイルかな?

```
$ cd mko62hna.default-esr 
$ ls
AlternateServices.txt         lock
SiteSecurityServiceState.txt  minidumps
addonStartup.json.lz4         permissions.sqlite
addons.json                   pkcs11.txt
bookmarkbackups               places.sqlite
broadcast-listeners.json      prefs.js
cert9.db                      protections.sqlite
compatibility.ini             search.json.mozlz4
containers.json               security_state
content-prefs.sqlite          sessionCheckpoints.json
cookies.sqlite                sessionstore-backups
crashes                       sessionstore.jsonlz4
datareporting                 settings
extension-preferences.json    shield-preference-experiments.json
extensions.json               storage
favicons.sqlite               storage.sqlite
formhistory.sqlite            times.json
gmp-gmpopenh264               webappsstore.sqlite
handlers.json                 xulstore.json
key4.db
```

この中の、places.sqllite にブックマークが格納されているらしい。

places.sqllite からブックマークを抽出したり、 bookmarks.html から自動復元したりする方法もあるらしいけれども、今回は深く考えずにプロファイルまるごと /etc/skel にぶちこむ。


# プロファイルをひながたに

管理者権限で
```

# cd /etc/skel
# mkdir .mozilla             
# cp -a /home/nanbuwks/.mozilla/firefox .mozilla

```

# テスト

適当に新しいユーザを作り、そのユーザでログオンして firefox を起動します。


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/bd6a21e5-6d1a-5900-3228-089a8cca4df3.png)

ブックマークが反映されていました。