OmniAICreator/Qiita-1.07M huggingface dataset:
SQLfluffをPJに取り入れてみるよ②どんなルールに？

# はじめに
SQLfluffのSQLルールついてまとめてみました。


PJにSQLfluffを取り入れた話はこちら↓

https://qiita.com/Himeka_Kawaguchi/items/a17a98dc1a4a07f809ab



# どんなルールに？
以下を基に作成してみました。まずは最低限のルールにしています。
```
・SELECTする項目のカンマは前に
・エイリアス、修飾子を明示する
・サブクエリはWITH句にしない
```
### 使用したルールまとめ

| Code |Rule|Rule|
|:-----------|------------:|------------:|
| LT05  | layout.long_lines|1行に何文字書くか（改行のタイミング）|
| ST05 | structure.subquery|サブクエリはWITH句に|
| LT04 | layout.commas|コンマの場所|
| AL01 | aliasing.table|テーブル名のエイリアス|
| AL02 | aliasing.column|カラム名のエイリアス|
| RF03 | references.consistent|修飾子を付ける|

```:.sqlfluff
[sqlfluff]
  dialect = snowflake
  templater = raw
  max_line_length = 80
  exclude_rules = L042

[sqlfluff:layout:type:comma]
  spacing_after = single
  line_position = leading

[sqlfluff:rules:aliasing.table]
  aliasing = explicit

[sqlfluff:rules:aliasing.column]
  aliasing = explicit

[sqlfluff:rules:references.consistent]
  force_enable = true

```

## ルールについて解説

### [sqlfluff] 

`dialect = snowflake` 
使用する方言を選択（他にもANSI,BigQuery,Databricksなどに対応）
※参考　https://docs.sqlfluff.com/en/stable/dialects.html

`templater = raw` 
今回はSQLを呼び出すだけなのであまり関係ない
Pythonのコードの中でSQLを呼び出す場合など関数の受け渡しが必要な場合は指定
※参考　https://docs.sqlfluff.com/en/stable/configuration.html


`exclude_rules = L042` 
除外したいルールを指定することも可能


※今回サブクエリはWITH句に変更するルールを除外
実際にはWITH句で書くのが正解かもしれないが、fix時にSQLの構成が大きく変わることは避けたいため

### [sqlfluff:layout:type:comma]　（カンマの場所）

`spacing_after = single` 
カンマの後はスペース1個分間隔をあける

`line_position = leading` 
カンマは行頭に(デフォルトは末尾(trailing))

参考：https://docs.sqlfluff.com/en/stable/layout.html#configuring-layout-and-spacing

### [sqlfluff:rules:aliasing.table]　(テーブルのエイリアス)
`aliasing = explicit` 
テーブル名のエイリアスは明示

### [sqlfluff:rules:aliasing.column] (列名のエイリアス)
`aliasing = explicit` 
列名のエイリアスは明示

### [sqlfluff:rules:references.consistent] (修飾子について)
`force_enable = true` 
修飾子は必須

## まとめ
今回は初めての取り組みだったので必要最小限のルールにしましたが、
これで終わりではなく、更に良いものになるようアップデートしていこうと思います。
参考になれば幸いです。
Pythonで学ぶエクセルの入出力入門

# Pythonで学ぶエクセルの入出力入門

## はじめに
Pythonでエクセルファイルの入出力を行う方法を学びたい方に向けて、基本的な操作方法を解説します。このチュートリアルでは、`pandas`ライブラリを使用して、エクセルファイルの読み書き方法を学びます。

## 事前準備
まず、必要なライブラリである`pandas`と`openpyxl`をインストールします。

```bash
pip install openpyxl pandas
```

## サンプルコード
以下に、Pythonを使ってエクセルファイルにデータを書き込み、その後読み込む基本的なプログラムを示します。

```python
import pandas as pd

# サンプルデータの作成
data = {
    '名前': ['太郎', '花子', '次郎'],
    '年齢': [28, 22, 35],
    '職業': ['エンジニア', 'デザイナー', 'マネージャー']
}

df = pd.DataFrame(data)

# データをエクセルファイルに書き込む
df.to_excel('sample.xlsx', index=False)

# エクセルファイルからデータを読み込む
df_read = pd.read_excel('sample.xlsx')

print(df_read)
```

## コードの解説
- **データの作成**: `pandas`の`DataFrame`を使ってサンプルデータを作成します。
- **エクセルファイルへの書き込み**: `to_excel`メソッドを使って、データフレームをエクセルファイルとして保存します。このとき、`index=False`と指定することで、行番号がエクセルに書き込まれないようにしています。
- **エクセルファイルからの読み込み**: `read_excel`メソッドで、保存したエクセルファイルを読み込みます。

## 実際のエクセル
ちゃんとファイルもできてました。
![スクリーンショット 2024-08-21 16.50.43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/75802/d01f0e17-888a-8d7f-5234-c13ba6becbb0.png)


## まとめ
このチュートリアルでは、Pythonを使ったエクセルファイルの基本的な入出力操作を紹介しました。これを基に、より複雑なエクセル操作に挑戦してみてください。
Windows11 に Node.js インストール(nvm-windows利用)

Windows11 に Node.js インストールしてみる
以前、Node.js を通常インストールしたがバージョン管理の必要が出てきたので nvm-windows より Node のバージョン管理できるようにしたときのメモです
MSのドキュメントにある [Windows での NodeJS のインストール](https://learn.microsoft.com/ja-jp/windows/dev-environment/javascript/nodejs-on-windows) を参考にしてます

やることは大雑把にこんなところ

- Node.js アンインストール
- Node.js(nvm-windows) インストール

:::note info
コマンドプロンプト or Powrshell を使う時は 「管理者として実行」 で起動する
:::

# Node.js アンインストール

MSのドキュメントよりOSに Node.js 入ってる場合はアンインストールを推奨してる
環境変数とか残ったままだとハマりそうなのでアンインストールしておきます

1. 現状の Node.js の存在確認　※無ければインストールに進んでOK！
    コマンドプロンプト or Powrshell で以下を入力して確認
    ※バージョンが出力された場合、有のため次からの作業を実施
    ```Powershell
    node -v
    ```
1. Node のキャッシュをクリア
    コマンドプロンプト or Powrshell で以下を入力(警告は出ても問題なし)
    ```Powershell
    npm cache clean --force
    ```
1. [プログラムの追加と削除] よりアンインストールを実行
    上がってくるダイアログに従い進める、許可などは はい を選択
1. Node関連のフォルダを削除
    コマンドプロンプト で以下を入力して削除
    ＃ 自分の環境では下から2番目のフォルダのみ残ってました．．．
    ```Powershell
    rmdir /s/q "C:\Program Files (x86)\Nodejs"
    rmdir /s/q "%USERPROFILE%\AppData\Roaming\npm"
    rmdir /s/q "%USERPROFILE%\AppData\Roaming\npm-cache"
    rmdir /s/q "%APPDATA%\npm"
    rmdir /s/q "%APPDATA%\npm-cache"
    rmdir /s/q "%USERPROFILE%\.npmrc"
    rmdir /s/q "%USERPROFILE%\AppData\Temp\npm-cache"
    rmdir /s/q "%USERPROFILE%\AppData\Local\Temp\npm-cache"
    ```
1. 環境変数(システム、ユーザ) の PATH よりNode関連の参照を削除
    システム環境変数の編集を開き、環境変数 PATHを確認し、node, npm への参照が無いことを確認
    参照が残っていれば削除
    ＃ 自分の環境では参照はなかったです！
1. Node.js のアンインストール確認
    コマンドプロンプト で以下を入力して何も見つからなければアンイストール完了
    見つかった場合、そのディレクトリを削除
    ```Powershell
    where node
    ```

# nvm-windows インストール (v1.1.12 2024/08/21時点の最新バージョン)

1. 以下より nvm-setup.zip をダウンロード
    https://github.com/coreybutler/nvm-windows/releases
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/51758/019ffb9d-0281-7975-07c8-e4ab786cacd2.png)

1. 解凍して nvm-setup.exe 実行してインストール
    画面に従い進める、許可などは確認して同意、インストール場所とか選んでインストール
    ＃ こだわりなければデフォルトで進んでOK
1. インストール確認
    コマンドプロンプト or Powrshell で以下を入力してバージョンが出力されればOK
    ※コマンドプロンプト or Powrshell はインストール後再起動が必要
    ```Powershell
    nvm -v
    ```

# Node.js インストール (v20.16.0 2024/8/21時点の最新LTS, npm v10.8.1)

1. Node.js の最新LTS(安定板)バージョン確認
    コマンドプロンプト or Powrshell で以下を入力して最新バージョン確認
    ```Powershell
    nvm list available
    ```
1. Node.js の最新LTS(安定板)インストール
    コマンドプロンプト or Powrshell で以下を入力してインストール
    ＃nvm install <version> //インストールするバージョン指定
    ```Powershell
    nvm install 20.16.0
    ```
1. インストール確認
    コマンドプロンプト or Powrshell で以下を入力して取得したバージョンが出力されればOK
    ```Powershell
    nvm ls
    ```
1. 使用するNode.js 設定
    コマンドプロンプト or Powrshell で以下を入力して使用する Node.js 設定
    ＃nvm use <version>  //使用するバージョン指定
    ```Powershell
    nvm use 20.16.0
    ```
1. 使用する Node.js 確認
    コマンドプロンプト or Powrshell で以下を入力してバージョン確認
    バージョンが確認できれば作業終了！
    ```Powershell
    # Node
    node -v
    # Node Package Manager //念のため。。紐づくバージョンに変わる
    npm -v
    ```
PowerVS（PER環境）からPaaS Endpoint(166.8.0.0/14 )への直接通信が可能になりました

PowerVS（PER環境）からPaaS Endpoint(166.8.0.0/14)への直接通信が可能になりました。IaaS Endpoint(161.26.0.0/16)へはこれまでも通信できましたので、PowerVSのワークスペースがPERに対応していればたものであれば、IBM Cloudサービスにアクセスするために、VPCにVPEを作ったり、VSI for VPCを立ててreverse proxyのように使うことは基本的に不要になったと言えそうです。

```
例：

# ping private.jp-tok.power-iaas.cloud.ibm.com
PING power-iaas-tok.jp-tok.serviceendpoint.cloud.ibm.com (166.9.42.40): 56 data bytes
64 bytes from 166.9.42.40: icmp_seq=0 ttl=57 time=1 ms
64 bytes from 166.9.42.40: icmp_seq=1 ttl=57 time=0 ms
64 bytes from 166.9.42.40: icmp_seq=2 ttl=57 time=0 ms
```
ACCESS VBAでテーブルが既に存在する場合削除したい

何気によくやる処理なのでメモです。
```
Sub DeleteTableIfExists(tblName As String)
    Dim dbs As DAO.Database
    Dim tdf As DAO.TableDef

    ' データベースの参照を取得
    Set dbs = CurrentDb()

    ' テーブルが存在するかどうかを確認
    On Error Resume Next
    Set tdf = dbs.TableDefs(tblName)
    If Err.Number = 0 Then
        ' テーブルが存在する場合、削除
        dbs.TableDefs.Delete tblName
        MsgBox "テーブル '" & tblName & "' が削除されました。"
    Else
        ' テーブルが存在しない場合
        MsgBox "テーブル '" & tblName & "' は存在しません。"
    End If
    On Error GoTo 0

    ' オブジェクトの解放
    Set tdf = Nothing
    Set dbs = Nothing
End Sub
```
データエンジニアは料理人だ！ 〜キッチンから学ぶスキルセット〜


# データエンジニアは料理人だ！ 〜キッチンから学ぶスキルセット〜

データエンジニアリングを学ぶのは難しい、と感じたことはありませんか？ でも、もしデータエンジニアを料理人に例えると、どうでしょうか？ キッチンでのスキルをそのままデータエンジニアリングに応用してみると、意外とその共通点に驚くかもしれません。今回は、データエンジニアとしての成長を、料理のプロセスになぞらえて考えてみましょう。

## 1. **レシピ（設計）を理解する力**

料理の基本はレシピです。どんな料理でも、適切なレシピがなければ美味しく作れません。データエンジニアにとってのレシピとは、データパイプラインやアーキテクチャの設計図です。

- **SQL** は、あなたの「レシピ本」。美味しい料理を作るために、複雑なクエリを組み立て、データを最適に処理する方法を知る必要があります。
- **データモデリング** は、材料選び。どのデータを使うか、どのように整理するかが、最終的な成果物の味を左右します。

## 2. **食材の知識（データの理解）**

優れた料理人は、食材の特性を熟知しています。データエンジニアも同様に、データの種類や特徴を理解しなければなりません。

- **構造化データと非構造化データ**: 例えば、ジャガイモ（構造化データ）は扱いやすく、レシピ通りに調理できます。一方で、エビ（非構造化データ）は、殻をむいて下処理が必要です。
- **クラウドストレージ**: AWSのS3やGoogle Cloud Storageは、データの保存庫として、あなたの冷蔵庫のような存在です。食材を新鮮な状態で保存するには、適切な管理が求められます。

## 3. **調理技術（プログラミングスキル）**

レシピがあっても、調理技術がなければ料理は台無しです。データエンジニアにとって、プログラミングはまさにその「技術」にあたります。

- **PythonとJava**: 包丁やフライパンのように、これらの言語は料理の基本ツールです。スクリプトを書くことで、データという「食材」をうまく調理し、価値ある情報へと変換します。
- **ETLプロセス**: ETLは料理の手順そのものです。データを洗浄し、切り分け、最終的な料理（データセット）に仕上げます。

## 4. **タイムマネジメント（パフォーマンス最適化）**

料理では、タイミングが命です。同時に複数の料理を作る際には、火加減や調理時間を厳密に管理しなければなりません。データエンジニアリングでも同じことが言えます。

- **パフォーマンス最適化**: 大量のデータを効率よく処理するには、クエリの最適化やインデックスの設計が必要です。火力を上手に調整することで、データパイプラインのパフォーマンスを最大限に引き出します。
- **並行処理とスケーラビリティ**: 大規模なデータパイプラインでは、複数の処理を並行して進める必要があります。これは、複数の料理を一度に作るのと同じ技術です。

## 5. **プレゼンテーション（データ可視化）**

料理が完成したら、見た目も大事です。データエンジニアリングにおいても、最終的な成果物をどのように見せるかが重要です。

- **データ可視化ツール**: TableauやPower BIなどのツールを使って、データを視覚的に美しく仕上げるのは、料理の盛り付けと同じです。視覚的に訴えることで、データの価値が一層引き立ちます。

## まとめ

データエンジニアリングのプロセスは、料理に例えることで、その本質が分かりやすくなります。レシピ（設計）、食材（データ）、調理技術（プログラミング）、タイムマネジメント（パフォーマンス最適化）、そしてプレゼンテーション（データ可視化）という5つのスキルセットが、データエンジニアとしての成功を支える基盤となります。

これからデータエンジニアを目指す皆さんも、自分のキッチンでの経験を活かして、データの世界でも美味しい成果を上げてみてください。

---

この記事が、皆さんのデータエンジニアリングの理解を深め、興味を持ってもらえるきっかけになれば幸いです。コメントやフィードバックをお待ちしています！
ACCESSランタイム用開発で2GBの壁に苦戦した話

## 経緯
ACCESSのクエリやマクロで半自動化されてた既存のシステム（複数DBを組み合わせて使われてた）をランタイムで動かせるように統合してたら2GBの壁にぶつかった。
テーブル作成クエリ、追加クエリの処理が重たい。

## やってみたこと
### [NG]重いテーブルを別DBに分けてリンクテーブルにしてみた
　一番よく見る対処方法で、私も「A.accdb」のテーブルを別DB「B.accdb」にすれば容量は問題なくなると思っていた、時代がありました。

残念ながらVBAで処理を実行すると「B.accdb」のリンクテーブルにテーブル追加するクエリの処理で「A.accdb」の容量が増えてました。「A.accdb」を最適化すれば容量は減りましたが、「A.accdb」のVB実行中に「A.accdb」の最適化をする処理が作れずどうしようもなくなりました。

### [NG]SELECTクエリにしてVBでクエリの結果を取得→別DBに書き出しを行った
 テーブル作成クエリを使うと容量が増えてしまうかと思い、VBで「B.accdb」へクエリの結果を書き込もうとしました。とても時間をかけてしまいましたが、容量というか処理が重すぎてACCESSは先に進まなくなってしまいました。

### [OK]テーブル作成クエリ、追加クエリを参照のみのクエリにした
既存の動きはクエリ1の結果をテーブル1に書き出し、クエリ2の結果をテーブル2に書き出し、クエリ3はテーブル1とテーブル2を参照していました。
このクエリ1、2の書き出しがそもそも要らなくて、テーブルを作成せずにデータを参照する「選択」タイプのクエリに変更し、クエリ1、2をクエリ3から参照するように変更しました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1058523/22f4c94a-0886-28ae-31d8-cbddc66b05ef.png)
すると長いものだとクエリ1つで2時間くらいかかっていたものが3つ合わせて20分、容量も食わないという驚きの事実がありました。。


私が初心者なので分からなかっただけでACCESSを勉強してきた人にはもしかしたら常識なのかもしれないけれどこの方法をGoogle先生に教えてもらえてたらどれだけよかったかと思います。
NoMethodError: undefined method `chrome' for Selenium::WebDriver::Remote::Capabilities:Class ってなエラーが出た場合

6.1のサポートがぁぁぁあということで、7.0へ引っ越し作業中に

```
NoMethodError: undefined method `chrome' for Selenium::WebDriver::Remote::Capabilities:Class 
```

ってエラーが発生

```
Capybara.register_driver :chrome_as_pc do |app|
  caps = Selenium::WebDriver::Remote::Capabilities.chrome(
    loggingPrefs: { browser: "ALL" },
    chromeOptions: {
      w3c: false,
      args: [
        "no-sandbox",
        "headless",
        "disable-gpu",
        "window-size=1200,800",
        "user-agent=Mozilla/5.0 (Windows NT 5.1) AppleWebKit/535.11 (KHTML, like Gecko) Chrome/17.0.963.79 Safari/535.11",
        "disable-dev-shm-usage",
        "lang=ja",
      ],
    }
  )
  Capybara::Selenium::Driver.new(app, browser: :chrome, desired_capabilities: caps)
end
```

↓↓↓↓↓↓↓

```
Capybara.register_driver :chrome_as_pc do |app|
  options = Selenium::WebDriver::Chrome::Options.new
  options.add_argument("--headless")
  options.add_argument("--no-sandbox")
  options.add_argument("--disable-gpu")
  options.add_argument("--disable-dev-shm-usage")
  options.add_argument("--window-size=1200,800")
  options.add_argument("--user-agent=Mozilla/5.0 (Windows NT 5.1) AppleWebKit/535.11 (KHTML, like Gecko) Chrome/17.0.963.79 Safari/535.11")
  options.add_argument("--lang=ja")
  Capybara::Selenium::Driver.new(app, browser: :chrome, options:)
end
```

でとりあえず動きました。
rpc error: code = PermissionDenied desc = Missing or insufficient permissions.

## エラー全文
```
rpc error: code = PermissionDenied desc = Missing or insufficient permissions.
```
## 状況
cloudRunからdatastoreモードのfirestoreへアクセスするプログラムをgoで作成しました

## 原因
cloudRunがdatastoreへアクセスする権限がない

## 対応
サービスアカウントにdatastoreのオーナー(ユーザーでもいいかも)を付与する
※この際、cloudRunに紐づいているサービスアカウントに権限を付与すること

該当のcloudRunのをクリック　> リビジョンタブ > リビジョンタブ内のセキュリティタブのサービスアカウント
に表示されているプリンシパルがそのcloudRunのサービスアカウントとなる。
NestJSで特定エンドポイントの並行実行数を制限する

# はじめに

NestJSでは、NestJS公式のThrottleパッケージを使用すれば設定以上の頻度で来るアクセスをブロックできますが、その場合溢れたアクセスはエラーでクライアント側に返ってしまいます。

あくまでも並行実行数を絞りつつ、すべてのアクセスを正常に捌きたいというようなケースについては公式の方法は用意されていませんが、独自にインターセプターを作ることで対応することが可能です。

## 実装

### カスタムインターセプターの作成

まず、並行処理を制限するカスタムインターセプターを作成します。
このインターセプターでは `p-limit`ライブラリを使用して、並行処理の数を制限しています。

```typescript
import { CallHandler, ExecutionContext, Injectable, NestInterceptor } from '@nestjs/common';
import { Observable } from 'rxjs';
import pLimit from 'p-limit';

@Injectable()
export class ConcurrencyInterceptor implements NestInterceptor {
  private limit;

  constructor(concurrency: number) {
    this.limit = pLimit(concurrency);
  }

  intercept(context: ExecutionContext, next: CallHandler): Observable<any> {
    return new Observable((observer) => {
      this.limit(() => next.handle().toPromise())
        .then((result) => {
          observer.next(result);
          observer.complete();
        })
        .catch((err) => {
          observer.error(err);
        });
    });
  }
}
```


### コントローラメソッドにインターセプターを適用

次に、作成したConcurrencyInterceptorを、 `@UseInterceptors` デコレーターを使ってコントローラの特定のメソッドに適用します。

```typescript
Copy code
import { Controller, Post, UseInterceptors } from '@nestjs/common';
// fromは自分がインターセプターをおいた場所にする
import { ConcurrencyInterceptor } from './concurrency.interceptor';

@Controller('your-endpoint')
export class AppController {
  @Post()
  @UseInterceptors(new ConcurrencyInterceptor(3)) // ★例えば並行処理を3に制限
  async yourEndpointHandler() {
    // ハンドラーのロジック
  }
}
```

# 終わりに

このように、インターセプターを使うことでエンドポイントごとに柔軟にconcurrencyを設定できるようになります。
Throttlingと違い、同時実行制限をしつつリクエストの失敗を防げるため便利です。
※別の言い方をすると、ConcurrencyInterceptorはエンドポイントに対するキューイングのようなイメージに近い、ということです。

ただ、言うまでもないですが消化スピードより速いペースで永遠にリクエストが入り続けるとこの方法は破綻するので、そのようなケースではThrottlingによる制限の方を検討したほうがいいと思います。
lambda share

export const handler = async (event) => {
    const originalMessage = event.message;
    
    // 在关键部分添加换行符
    const formattedMessage = originalMessage
        .replace(/"サービス Arn":/g, '\n"サービス Arn":')
        .replace(/"検出内容":/g, '\n"検出内容":')
        .replace(/"環境の Security Hub/g, '\n"環境の Security Hub')
        .replace(/"発生時間":/g, '\n"発生時間":')
        .replace(/"ID":/g, '\n"ID":');

    return {
        formattedMessage
    };
};
Paiza×Qiitaキャンペーン Javaで解説してみた【C 宝くじ 編】

# 問題へのリンク

https://paiza.jp/works/mondai/b_rank_skillcheck_archive/name_card

# 解答コード

<details><summary>詳細</summary>

~~~

import java.util.Scanner;

public class Main {
	public static void main(String[] args) {
		Scanner scanner = new Scanner(System.in);
		final int N = scanner.nextInt();
		final int M = scanner.nextInt();
		scanner.close();

		int page = (M - 1) / N;
		int index = (M - 1) - page * N;

		if ((page & 1) == 0) {
			page++;
		} else {
			page--;
		}
		
		System.out.println((N * page) + (N - index));
	}
}


~~~

</details>



# 解説

<details><summary>詳細</summary>

コードの記述能力ではなく、どれだけ問題を整理できるかです。

まず、Mが何ページ目の何番目にあるかを考えます。

ページ
・先頭のページを1とすると M から N で割った時、端数切り上げにする必要があります
⇒  (M - 1)  / N + 1 
・


</details>
Reactを使った最新検知情報表示アプリケーション

# 制作物について
先日作成した物体検出カメラ(https://qiita.com/shima20913/items/68da0adc80470394d141) に、最新の検知情報を定期的に更新し表示するwebアプリケーションを実装しました。![スクリーンショット 2024-08-21 074737.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3860038/43ec567a-76a3-d4a5-2ad2-acd12378c327.png)

Githubレポジトリは以下となっています。
https://github.com/shima20913/camera_web

# 背景
前回のバックエンド開発においては、人間を検知した際にDiscordへ画像を送信する機能のみ実装しました。その為、既存のアプリケーションに頼らないオリジナルのwebアプリを作成したいと思い、作成しました。

# 開発について
## 技術選定
フレームワークはReactを使用し、デプロイはさくらのvpsに行いました。UIライブラリはChakraUIを使用しています。Reactの選定理由は、高速なレンダリング処理を実現したかったのと、Javascriptを用いた簡単なToDoリストの開発経験があったため、個人的に取り組みやすいと考えたためです。

## つまずいたところ
### 1.サーバーサイドの書き換え
Reactでフロントエンドを開発するにあたって、必然的にGoで書かれたサーバーサイドの変更も必要でした。その中でも特に、検知時間取得方法の変更に関して、特に難易度が高いと感じました。
変更前のコードでは、画像データがサーバ側に蓄積される関係でフロントエンド側に送信されておらず、うまく表示されませんでした。

### 解決策
専用のファイルサーバーを作成し、そこから画像ファイルをHTTPリクエストで送信できるようにしました。

### 2.webアプリの再レンダリング処理
監視カメラというアプリケーションの特性上、常に情報が最新のものに更新される必要があります。ですが、毎回更新ボタンを押して再レンダリングするのは非効率なので、最新の検知情報を受信するたびに、自動的に再レンダリングが行われるよう修正しました。ですが、この処理に関して具体的な実装方法が分からず、作業が止まってしまいました。

### 解決策

以下の記事を参考にし、1秒ごとに自動で再レンダリングを行う処理を実装しました。こうすることによって、新しい情報が来ている際にもリアルタイムで情報を取得することに成功しました。

https://qiita.com/YumaInaura/items/a9b5ba80a447493f51ad

## 追記: pwaに対応しました
以下のようにPWAを利用し、スマートフォン上で検知情報サイトをネイティブアプリのように利用できる機能を実装しました。
![IMG_8757.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3860038/da014521-102a-3882-2dd8-cb6a3d13eb68.png)



# まとめ
フレームワークを用いたフロントエンドの開発は初めてでしたが、UIの実装などを、ライブラリを用いることで簡単に実現できた点が非常にやりやすかったと思います。
今後の課題としては、Reactの利点であるコンポーネントを有効に活用できていなかった為、そちらをもう少し勉強していきたいです。
クエリのSQLをVBAで一部編集（置換）する

## やったこと

クエリをエクスポートに使う際、パラメータ付クエリだとできなかったので、
特定の箇所のみクエリを直接変更して使いたいと思い、以下のようにできました。

```
Sub ReplaceSQLString()
    Dim db As DAO.Database
    Dim qdf As DAO.QueryDef
    Dim originalSQL As String
    Dim newSQL As String
    Dim findStr As String
    Dim replaceStr As String
    
    ' 現在のデータベースを取得
    Set db = CurrentDb()
    
    ' 既存のクエリ "MyQuery" を開く
    Set qdf = db.QueryDefs("MyQuery")
    
    ' 現在のSQL文を取得
    originalSQL = qdf.SQL
    
    ' 置換する文字列を設定
    findStr = "OldValue"      ' 置換対象の文字列
    replaceStr = "NewValue"   ' 置換後の文字列
    
    ' SQL文の文字列を置換
    newSQL = Replace(originalSQL, findStr, replaceStr)
    
    ' 置換されたSQL文をクエリに設定
    qdf.SQL = newSQL

    ' 変更を保存してクエリを閉じる
    qdf.Close
    Set qdf = Nothing

    ' クエリ結果を別DBへエクスポート
    DoCmd.TransferDatabase acExport, "Microsoft Access", "DBのフルパス", acTable, "MyQuery", "出力テーブル名", False
    
    ' 既存のクエリ "MyQuery" を開く
    Set qdf = db.QueryDefs("MyQuery")
    
    ' 実行後、元のSQL文に戻す
    qdf.SQL = originalSQL
    
    ' 変更を保存してクエリを閉じる
    qdf.Close
    Set qdf = Nothing
    Set db = Nothing
End Sub
```

## やってみてわかったこと
- 実際はエクスポート先が動的でない場合は、エクスポート先のテーブルが存在したら削除してからエクスポートしないといけない。
- フォームを作ってたので置換するよりも[こちら](https://qiita.com/m-kinjo/items/139203f2e3598c7cff1e)でフォームと連動するようにクエリにSQLパラメータ指定してる方がスマートだった
Pythonのfor文で分かりにくかった所

# 始めに
例えば1から10までの値を出力したい場合を考える．
pythonでは以下のfor文を利用する事でも実装が可能である．
~~~
for i in range(初期値,条件式,変化式)
~~~

# 本題

~~~:実行内容
for i in range(1,10,1):
    print(i)
~~~

~~~:実行結果
1
2
3
4
5
6
7
8
9
~~~
実行結果からこのforループではiの値が1から10未満まで，1刻みで増加している事が分かる．

~~~:実行内容
for i in range(1,11,1):
    print(i)
~~~

~~~:実行結果
1
2
3
4
5
6
7
8
9
10
~~~
条件式を10＋1にすると欲しい結果が得られた．

 # その他
初期値，変化式は省略が可能である．
その場合，初期値0，変化式は+1となる．
~~~:実行内容
for i in range(10):
    print(i)
~~~

~~~:実行結果
0
1
2
3
4
5
6
7
8
9
~~~

# まとめ
~~~
for i in range(初期値,条件式,変化式)
~~~
pythonのfor文では条件式未満の値で終了する．
※条件式の値ちょうどの場合ではループしない．
つまりi<条件式の値でループが終了する．

ループ回数をキッチリ担保したい場合は条件式をループしたい回数＋1(変化式によって足す値は変化)，もしくは初期値を入力しない方がとよさそう？

他に良い引数の設定や関数があれば是非教えて下さい．
ITエンジニア : AI時代の働き方と人間の集中力


今の時代ではAIが単純な作業をしてくれるようになった。

特にプログラミングの世界ではそれが顕著で、簡単な繰り返し作業であればAIにのるコード補完機能がだいたいやってくれる。

キーボードのひとつのキーを押すだけで次々にコードを入力変更してくれるのだ。

これで、もう飽き飽きするような単調な作業はしなくて良い。無益な単純作業から解放されて、本当に意味のある仕事に集中できるようきなる。喜ばしいことだ。

## だが本当にそうだろうか？

AIが単純作業を引き受けてくれるようになると、人間に残るのは高い集中力を使う仕事だけだ。

しかし人間はフルタイムの間中、高い集中力を維持できるようには出来ていない。

たとえぼ今までは1日の仕事の内訳が、集中力を使う仕事が５割、単純作業が5割だったのが、これからは集中力を使う仕事だけで10割になるかもしれない。

これではとても集中力がもたない。

AIによって空き時間ができる分、人間は遊んだり休息したら良いかというと、社会構造はそれを許さない、ということは歴史が証明している。

つまりAI時代の到来によって、人間は仕事にさらに高い要求をされるようになり、集中力とエネルギーが枯渇しててしまうのではないか？

このようなパラドックスは、今まで人間社会に起こり続けているのだから。

いつだって良いものの全てが良いとは限らない。


# チャットメンバー募集


何か質問、悩み事、相談などあればLINEオープンチャットもご利用ください。

https://line.me/ti/g2/eEPltQ6Tzh3pYAZV8JXKZqc7PJ6L0rpm573dcQ


# プロフィール・経歴

https://github.com/YumaInaura/YumaInaura
001 まだ間に合う、夏休みの宿題の読書感想文の作り方

まだ間に合う、夏休みの宿題の読書感想文を

大規模言語モデルのgeminiに作ってもらう。
最近のLLMは、トークン数が大きくなり200万トークンまで入れられます。
つまり、資料は丸ごと追加学習してしまえばいいわけで、
前段のRAGっぽいものは最小限で済みます。
人力・確１・絶対当たるRAGです。

また、そのまま一度webapiにして、自分で使う資料毎のエンドポイントを用意すれば、ネット経由で何処からでも利用できますし、更にサーバーレスで建てれば維持費もほぼ無料で
メッチャ、お得ですね。

家電の取説や、学校の教科書なんかも全文章を追加学習してあげると、お客様や学生さんは自分のタイミングで大規模言語モデルと会話しながら、自己解決してくれますし、またwebapiなので既存のポータルサイトとの連携も容易ですし、サーバーレスなので、待機時ゼロ円～、バズってもクラウドスペックでスケールアウト、メンテもパッチもセキュアもアカウントも管理も維持もクラウド任せです。
メッチャ、便利ですね。

---


材料
　１，gemini　API
　２，資料：夏目漱石著、吾輩は猫である（著作権フリー、約２０万トークン）
　３，webapi、サーバーレス

---


はい、こちらに既にで出来ています。
あとは、追加学習済みのLLMさんに　読書感想文を書いてもらえば完成です。


https://llm001-v01.bono0.com

https://
llm001-v01.bono0.com/?name=資料のタイトルを表示する、著者の名前を表示する、資料感想文を作成する


引数
?name=資料のタイトルを表示する、著者の名前を表示する、資料感想文を1000文字で作成する

---


import requests

url="https://llm001-v01.bono0.com/?name=資料のタイトルを表示する、著者の名前を表示する、資料感想文を作成する"


response = requests.get(url)

import json
data = json.loads(response.text)
print(data['message'])

---


－完－
ACCESS VBA でクエリにパラメータを指定して実行

クエリにパラメータを設定すると実行時に値を受け取って実行してくれるようになる。
パラメータ指定のクエリSQL例）
```
PARAMETERS [パラメータ名] Text;
SELECT * FROM テーブル名 WHERE フィールド名 = [パラメータ名];
```
手動でクエリを開くとポップアップがでてきて、パラメータを入力できる。
VBAでパラメータ指定して実行する場合以下のようになる


```
Sub RunParameterizedQuery()
    Dim db As DAO.Database
    Dim qdf As DAO.QueryDef
    
    ' データベースオブジェクトを取得
    Set db = CurrentDb
    
    ' クエリ定義オブジェクトを取得（"クエリ名"は事前に作成したクエリの名前）
    Set qdf = db.QueryDefs("クエリ名")
    
    ' パラメータの値を設定
    qdf.Parameters("パラメータ名").Value = "指定したい値"
    
    ' クエリを実行
    qdf.Execute
    
    ' オブジェクトのクリーンアップ
    Set qdf = Nothing
    Set db = Nothing
End Sub
```

もしフォームを使う場合は、フォームとクエリのパラメータをリンクできるのでVBでの上記のような記述が不要になる。
↓
[ACCESSでクエリのSQLパラメータにフォームで入力した値をつかいたい（VB無しで動的なクエリ）](https://qiita.com/m-kinjo/items/139203f2e3598c7cff1e)
SAP HANADBとABAPのSID設定ルール(同一 or 別ホストで異なる)

同一ホストの場合：異なるSID設定が”必須”
別ホストの場合　：異なるSID設定が一般的には”推奨(必須ではない)”
　※管理上の一般的な話です。推奨とはSAPのドキュメントでは見つけられませんでした。
 　 SAP提供サーバで別ホストの場合は分けられていました。

1953429 - 1 つのサーバ上の SAP HANA および SAP NetWeaver AS ABAP
2770989 - SAP HANA データベースインスタンスに対して異なる SID を選択してください。
【リスト】スクラムのプラクティスをまとめてみた

# スクラム系プラクティス一覧

本記事は『[アジャイルプラクティス一覧](https://qiita.com/kakashi_h5/items/20584998c5ca4594b9ea)』からスクラム系のプラクティスだけを抜き出し、再構成したものです。手っ取り早くスクラム概要を知りたい人向けに作成してみました。スクラム全体のフレームワークについては『[公式スクラムガイド（2020）]((https://scrumguides.org/docs/scrumguide/v2020/2020-Scrum-Guide-Japanese.pdf))』にあたるか、『[スクラムの基礎知識を確認するテスト](https://qiita.com/kakashi_h5/items/eb89fad6be450647d250)』を参照願います。


### スクラムイベント
* [スプリント](https://qiita.com/kakashi_h5/items/e5221d5438147ffb1f07)　
* [スプリントプランニング](https://qiita.com/kakashi_h5/items/306808ba744c467bf8e1)　
* [デイリースクラム](https://qiita.com/kakashi_h5/items/8cff3505966d179ea1a8)　
* [スプリントレビュー](https://qiita.com/kakashi_h5/items/258428aa08a01b69a570) 
* [プロダクトバックログリファインメント](https://qiita.com/kakashi_h5/items/035b83d7df16375daa78)　
* [レトロスペクティブ](https://qiita.com/kakashi_h5/items/55928e254097ac28f698)


### 作成物（アーティファクト）
* [プロダクトバックログ](https://qiita.com/kakashi_h5/items/df86ec4be4d996bc2568)　
* [スプリントバックログ](https://qiita.com/kakashi_h5/items/1d006925586959de6c46)
* インクリメント（※プロダクト）

### ゴール定義（コミットメント）
* [プロダクトゴール](https://qiita.com/kakashi_h5/items/42f3ac38477abbac380d)
* [スプリントゴール](https://qiita.com/kakashi_h5/items/c6ccebbd7ffad5f91167)
* [完成の定義](https://qiita.com/kakashi_h5/items/c4e5f9ca036463a00255)　

# スクラムと関係が深いプラクティス
下記は厳密にはスクラムではありませんが、実用上、併せて使われることが多いため紹介しておきます。
* [スプリント0](https://qiita.com/kakashi_h5/items/6fffd450fae38248289b)　
* [プロダクトバックログアイテム分割](https://qiita.com/kakashi_h5/items/1b48021bbc6febadabb5) 
* [ユーザーストーリー](https://qiita.com/kakashi_h5/items/36c5d741b8e74459507b)　
* [受け入れ条件](https://qiita.com/kakashi_h5/items/46cb60496ff9702dde35) 
* [ストーリーポイント](https://qiita.com/kakashi_h5/items/e41915f097762ffdaa1d)
* タスクボード
* ベロシティ計測
* バーンダウンチャート

# こぼれ話（私的コメント）
スクラムのまとめ記事という意味ではすでに良いものがたくさん世の中に出回っているので、今更とも思ったのですが、それでも自分なりにまとめておくのは別の意義があるかも、と思い直し、記事にしてみました。これがあれば、身近なスクラム初心者にひとまずここだけでも読んでおいて、と言えるようになるので。

# 関連記事

アジャイルプラクティス一覧
[【リスト】アジャイル開発で使えるプラクティスを集めてみた　-Qiita](https://qiita.com/kakashi_h5/items/20584998c5ca4594b9ea)

スクラムフレームワークの説明
[スクラムの基礎知識を確認するテストをつくってみた　-Qiita](https://qiita.com/kakashi_h5/items/eb89fad6be450647d250)
【プラクティス紹介】1分でさらっと分かる「スプリントバックログ」

## プラクティス名（別名）
スプリントバックログ　（SBL）

## プラクティスの目的・狙い
* スプリントゴールを達成するための実行計画を立てる
* スプリント中、日々の進捗を検査できるようにする

## どんな時に使うか
* スクラムでは必須作成物（スプリントプランニングで作成）
* スプリントの見通しを立てたい時（作業の進め方、完了見込み）

## 実施手順（取り扱いルール）
SBLはDEVによる、DEVのための計画であり、DEVが主体的に管理する。
ただし認識共有のため作成はチーム全員で行うことが望ましい。
スプリントバックログには以下の３つが含まれること。

* 【Why】今回のスプリントゴール
* 【What】今回のスプリントで対象とするプロダクトバックログアイテム（PBI）
* 【How】PBIを実現するためにタスク分解された作業のリスト（SBI）

■計画時
1. PBIを実現するためにDEVが実行可能な粒度までタスク分解する
1. 実装作業だけでなく、あらゆる付帯作業をリストアップする（申請や調整など）
1. タスク毎の所要時間を見積もり、チームのキャパ（リソース）と比較する
1. SBIの優先順位を決める（PBIの優先度/タスクの依存関係/作業効率などを考慮）

■スプリント中
1. 毎日タスク進捗状況を確認する（タスクボードやバーンダウンチャートなどで管理）
1. 追加タスク/飛び込みタスクがあれば即時SBLに反映する
1. キャパオーバーが見込まれる場合は、スプリントゴールに影響しない範囲でPOとスコープ調整する

::: note info 
作業担当者は日々の状況に応じて柔軟にサインアップすることが望ましいため、計画時は決めない方がよい
:::

## アレンジ例
* 計画時のタスク分解作業はペアワークなどで手分けして行い、事後その結果を全員で共有する

## アンチパターン
* DEV以外の人がタスク分解したり、見積ったりしたSBIをそのままDEVに押し付ける
* 計画時に作業担当者が確定しており、計画した担当者ごとにタスクの粒度がバラバラ

::: note warn
SBIの適切な粒度はチームの成熟度によって異なります。SBIをより詳細に具体化すればDEV間の認識は揃いやすくなりますが、その分アイテム数が増え、管理の手間も増えます。粒度の目安としては1日以内に完了するサイズが良いとされていますが、もしもスプリント中にタスク個別の進捗率まで問われるようであれば、サイズが大きすぎることを意味しています。
:::

## 参考情報
[公式スクラムガイド(2020年日本語版)](https://scrumguides.org/docs/scrumguide/v2020/2020-Scrum-Guide-Japanese.pdf)

SBLのより詳しい説明としてはまずは定番のAgile Studioさんのサイトをおススメします。

https://www.agile-studio.jp/post/apm-sprint-backlog

タスク分解のコツについてはRyuzeeさんの記事が具体的で分かりやすいと思います。

https://www.ryuzee.com/contents/blog/14560


## こぼれ話（私的コメント）
SBL作成時によく取り扱いに困るのがPBIに紐づかないその他系タスク。例えば前回レトロで挙がった環境改善のためのアクションとか。個人的にはそういったタスクも全てSBIとして管理するのがシンプルで好きです。紐づくPBIが無いのが問題になるのであれば、PBIとしても追加しちゃおう、というのがSMとしての僕のスタンスです。が、POやDEVからするとそういったタスクにストーリーポイントを割り振るのって少し抵抗があったりするみたいで、チームによっても温度感が違うので匙加減が難しいです。見える化されていないタスクって知らず知らずのうちにUNDONEタスクとして積みあがってしまうリスクもあるので、そのあたりをきちんとPOと認識合わせできていると良いのかもしれませんね。

---
　[アジャイルプラクティス一覧へ戻る](https://qiita.com/kakashi_h5/items/20584998c5ca4594b9ea)
ついにPostman v11.8でHTTP/2がサポートされました🎉

これまで[長らく渇望](https://github.com/postmanlabs/postman-app-support/issues/2701)されていたPostmanのHTTP/2サポートですが、ついに`v11.8`でサポートされるようになりました！

https://www.postman.com/release-notes/postman-app/

# 全てのAPIリクエストで適用する設定

`Settings(設定)`  > `General(一般)` ＞ `HTTP version`で全てのリクエスト送信で利用するHTTPバージョンを選択できます。`Auto`オプションを選択すると自動でクライアント・サーバー間でプロトコルバージョンのネゴシエーション（ALPSネゴシエーション）がされるようになるので、特別な理由がなければAutoにしておくのが無難かとおもいます。

![Screenshot 2024-08-21 at 15.27.14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/103420/087bf5c5-f301-0c78-8329-29b1f54ee18b.png)

# 個別のAPIリクエストの設定

個別のAPIリクエストでも`Settings(設定)` ＞ `HTTP version`で利用するHTTPバージョンを選択できます。

![Screenshot 2024-09-06 at 7.21.35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/103420/1f738bbd-630c-40d0-1ddf-545f54c5a392.png)

試しに、HTTP versionをHTTP/2に設定して、Postmanアプリからリクエストを送信してみると、リクエストヘッダーから次のように無事HTTP/2で送信されていることがわかります。

![Screenshot 2024-08-21 at 15.00.33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/103420/2cf5af1c-f6f6-4089-ce22-f1068f9fef7d.png)

もし古いバージョンのPostmanアプリをお使いの方で、HTTP/2を試してみたい方は、[こちら](https://www.postman.com/downloads/)より最新バージョンをダウンロードしてください。
コンテナ上のファイルを残して、ローカルのディレクトリをマウントする方法

```bash
IMAGE_TAG=your-image
CONTAINER_NAME=your-container
WORKDIR=/app

sudo docker image build -t $IMAGE_TAG . > build.log 2>&1

sudo docker container run -d --name $CONTAINER_NAME $IMAGE_TAG  
sudo docker container stop $CONTAINER_NAME
sudo docker container cp $CONTAINER_NAME:$WORKDIR/. .
sudo docker container rm $CONTAINER_NAME
sudo chown -R $(whoami):$(whoami) .


sudo docker container run -v $(pwd):$WORKDIR $IMAGE_TAG
```
pipのインストールとリストアップをコマンド化した

<!-- pipのインストールとリストアップをコマンド化した -->

## はじめに

いつもPythonを使っているわけですが、Pythonでは外部ライブラリをpipを用いてインストールする機会がよくあります。

普段使いのコンピュータが一つだけの場合は、一度インストールしてしまえばそれで良いのですが、大体の場合はいくつかのコンピュータを使い分けていると思います。

その場合、ライブラリなどの同期を取りたいわけですが、そのためにはpipのリストを取得して、それを使ってインストールを行うということが手っ取り早いでしょう。

今回はそのためのコマンドを作成しました。Windowsを使っているので、Windows用のコマンドです。

## 想定環境

- pipがインストールされている
- 複数のコンピュータ間で同期されているディレクトリがある(GitやOneDriveなど)
- Windows環境

## コード

```%YOUR_SHARED_DIRECTORY%``` は共有ディレクトリのパスを指定してください。

```bash
@echo off

set c1=%CD%
cd %YOUR_SHARED_DIRECTORY%
pip list --format freeze > requirements.txt
cd %c1%
```

まず、カレントディレクトリを```c1```として記録しておきます。そして、共有ディレクトリへ移動し、```pip list --format freeze```を実行します。これは、現在インストールされているライブラリのリストを取得し、```requirements.txt```というファイルに書き込むというものです。```requirements.txt```はpipのインストール時に使うファイルで、例えば以下のような内容になります。

```requirements.txt
absl-py==0.12.0
argon2-cffi==20.1.0
```

元々```requirements.txt```がある場合は、上書きされます。

最後に、元のディレクトリに戻ります。

次に、作成した```requirements.txt```を使ってライブラリをインストールするコマンドです。

```bash
@echo off

set c1=%CD%
cd %YOUR_SHARED_DIRECTORY%
pip install -r requirements.txt
cd %c1%
```

カレントディレクトリを記録し、作業後に戻るという挙動は先ほどと同様です。共有ディレクトリに移動したら、```pip install -r requirements.txt```を実行します。これは、```requirements.txt```に書かれたライブラリをインストールするというものです。元からあるライブラリに関しては、更新があったら更新されます。

前者のバッチファイルは```plist.bat```、後者のバッチファイルは```pinst.bat```として保存しておきます。名前はわかりやすかったら何でもよいです。バッチファイルがあるディレクトリのパスは環境変数に登録しておきます。

## 使い方

使っているコンピュータのどれかで通常通りpipを用いて何かライブラリをインストールしたら、```plist```を実行し、現在のパッケージリストを保存します。

他のコンピュータで```pinst```を実行すると、```requirements.txt```に書かれたライブラリがインストールされます。これによって、複数のコンピュータ間でライブラリの同期を取ることができます。

## おわりに

これで、複数のコンピュータ間でライブラリの同期が取れるようになりました。これで、別のコンピュータに切り替えたら今まで使っていたライブラリが入っていない、みたいな問題が解決できそうです。
【Unity】【VIVE】VIVE Pro Eyeに映っている画面を外部ディスプレイに表示したい（ミラーリング）．


本記事では，VIVE Pro Eyeに映っている画面をディスプレイにストリーミング（ミラーリング）する話です．
非常に初歩的なことですが，参考になる文献が少なかったので紹介していきます．

技術展示などで体験者がHMDでどんな映像が見えているのか外部ディスプレイに投影し，他の人も見えるようにしたい場面があるかと思います．そんな時に使うのがSteamVRのVRビューです．

このVRビューにたどり着くまでに非常に時間がかかりました・・・涙
というのも，現在VIVEのストリーミングについて検索しても，VIVE Elite XRに対応しているVIVE Streamingに関する記事しかヒットしませんでした．

<!-- 各チャプター -->
<a id="#Chapter1"></a>
# ミラーリング方法
SteamVRを起動し，三本線を選択すると以下の画面になるかと思います．

![スクリーンショット 2024-08-21 135233.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1776719/eaebf764-6235-4bce-3517-298b5a26e5e7.png)

ここでVRビューを表示，と押してみてください．

HMDで見ている画面がディスプレイに表示されるかと思います．

![スクリーンショット 2024-08-21 151744.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1776719/5adf319a-b812-86dd-9448-d962ab2f930e.png)


デフォルトのままだと，右目に映る映像が映ると思いますが，Unityで作成したプロジェクトが左右で異なる映像を提示している場合は，左上のタブから両眼を選択してください．

![スクリーンショット 2024-08-21 151754.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1776719/2a9ffdd3-a334-e5fe-7cb0-701badeae11c.png)



# 終わりに
本記事を書いているのは2024年8月．VIVE Pro Eyeが発売されたのは，2019年6月
この記事を必要としている方は少ないかもしれませんが，私と同じように研究室で保有しているHMDがVIVE Pro Eyeだったので今から始める，という方に役立つを嬉しいです．
生年月日から年齢を計算する方法を各プログラミング言語で書いてみた

# はじめに

プログラミングでよくあるタスクの一つに、生年月日から年齢を計算することがあります。今回は、各プログラミング言語でこのタスクを1行で実装してみました。どの言語でも、標準ライブラリを活用すれば簡単に計算できます。


## Python
```python
age = (datetime.datetime.now() - datetime.datetime(1984, 8, 21)).days // 365
```
Pythonでは、`datetime`モジュールを使い、現在の日付と生年月日との差を日数で計算し、年数に換算しています。

## JavaScript
```javascript
const age = Math.floor((new Date() - new Date('1984-08-21')) / (365.25 * 24 * 60 * 60 * 1000));
```
JavaScriptでは、`Date`オブジェクトを利用して、生年月日と現在の日付の差をミリ秒で計算し、年数に換算しています。

===
ミリ秒意識しない記載方法は以下（推奨）
```javascript
const age = ~~((new Date().toLocaleString('ja', {dateStyle: 'short'}).replace(/\D/g, '') - 19840821) / 1e4);
```



## Ruby
```ruby
age = ((Time.now - Time.new(1984, 8, 21)) / (60 * 60 * 24 * 365)).to_i
```
Rubyでは、`Time`オブジェクトを使用し、現在の時間と生年月日との差を秒で計算し、年数に換算しています。

## PHP
```php
$age = floor((time() - strtotime('1984-08-21')) / (365.25 * 24 * 60 * 60));
```
PHPでは、`strtotime`関数を使って生年月日をタイムスタンプに変換し、現在のタイムスタンプとの差から年数を計算しています。

## Go
```go
age := int(time.Since(time.Date(1984, 8, 21, 0, 0, 0, 0, time.UTC)).Hours() / 24 / 365)
```
Goでは、`time`パッケージを使い、生年月日と現在の日付との差を時間単位で取得し、それを年数に換算しています。

## Java
```java
int age = Period.between(LocalDate.of(1984, 8, 21), LocalDate.now()).getYears();
```
Javaでは、`Period`クラスを使い、生年月日から現在の年齢を計算します。

## C#
```csharp
int age = DateTime.Now.Year - new DateTime(1984, 8, 21).Year - (DateTime.Now.DayOfYear < new DateTime(1984, 8, 21).DayOfYear ? 1 : 0);
```
C#では、現在の年と生年月日の年の差から年齢を計算し、誕生日が過ぎていない場合には1歳減らします。

## Swift
```swift
let age = Calendar.current.dateComponents([.year], from: DateComponents(year: 1984, month: 8, day: 21).date!, to: Date()).year!
```
Swiftでは、`Calendar`と`DateComponents`を使って年齢を計算します。

## Kotlin
```kotlin
val age = Period.between(LocalDate.of(1984, 8, 21), LocalDate.now()).years
```
Kotlinでは、`Period`クラスを使用して、生年月日から年齢を計算します。

## Rust
```rust
let age = Utc::now().signed_duration_since(Utc.ymd(1984, 8, 21).and_hms(0, 0, 0)).num_days() / 365;
```
Rustでは、`chrono`クレートの`Utc`を使い、日数を計算して年齢を算出します。

## TypeScript
```typescript
const age = Math.floor((new Date().getTime() - new Date('1984-08-21').getTime()) / (365.25 * 24 * 60 * 60 * 1000));
```
TypeScriptでも、JavaScriptと同様に`Date`オブジェクトを利用して計算します。

## 終わりに

上記の例は、生年月日から年齢を計算する方法を簡潔に示しています。実際には、誕生日がまだ来ていない場合や閏年などを考慮する必要があるかもしれません。それでも、各言語でこれをどのように実装するかを理解するための良い練習になります。
Paiza×Qiitaキャンペーン Javaで解説してみた【C 野球の審判 編】

# 問題へのリンク

https://paiza.jp/works/mondai/c_rank_skillcheck_archive/umpire

# 解答コード

<details><summary>詳細</summary>

~~~

import java.util.Scanner;

public class Main {
	public static void main(String[] args) {
		Scanner scanner = new Scanner(System.in);
		final int N = scanner.nextInt();

		StringBuilder sb = new StringBuilder();

		Umpire umpire = new Umpire();

		for (int i = 0; i < N; i++) {
			final String S = scanner.next();
			sb.append(umpire.call(S)).append("\n");
		}

		System.out.println(sb);
		scanner.close();
	}

	private static class Umpire {

		private int strike = 0;
		private int ball = 0;

		String call(String judge) {
			if (judge.equals("strike")) {
				return strike();
			} else {
				return ball();
			}
		}

		private String strike() {
			strike++;
			if (strike == 3) {
				reset();
				return "out!";
			} else {
				return "strike!";
			}
		}

		private String ball() {
			ball++;
			if (ball == 4) {
				reset();
				return "fourball!";
			} else {
				return "ball!";
			}
		}

		private void reset() {
			strike = 0;
			ball = 0;
		}
	}
}

~~~

</details>

# 解説

<details><summary>詳細</summary>

審判を作ってしまうとデータ管理が楽です。

call⇒mainではこれしかしません。審判は投げられたボールに対して発声するだけです。

call内の動作
投げられたものが"strike"か"ball"かで動作が変わります。
"strike"⇒strike用発声をします。
"ball"⇒ball用発声をします。

strike時の動作
strikeカウントを増やして判定します
strike == 3 ⇒バッターアウトです。"out!"と発言してresetします
それ以外 ⇒ "strike!"と発言するだけです。

ball時の動作
ballカウントを増やして判定します
ball == 4 ⇒ファーボールです。"foueball!"と発言してresetします
それ以外 ⇒ "ball!"と発言するだけです。

reset時の動作
バッターが変わります。strike・ball両方0にします。

</details>

# 追記
記事が完成してから複数のバッターを考慮する必要がないことに気づきました。
reset部分全部いりませんね！
Ruby Gold模擬試験アプリを作成しました！

# Ruby Gold模擬試験アプリを作成しました！

## はじめに

こんにちは！Rubyが大好きで、将来は日本でRubyエンジニアとして働くことを夢見ている者です。現在、就職活動を進めていますが、自分のRubyへの情熱を言葉だけでなく行動で示したいと考えました。

## Ruby Gold試験への挑戦

そこで、Ruby技術者認定試験（Gold）の受験を考えました。しかし、調べてみると、この試験は日本国内での対面試験のみだということがわかりました。現在中国に住んでいる私にとって、これは大きな壁でした。

## オープンソースの模擬試験リソース

幸いなことに、GitHubで素晴らしいリソースを見つけました。Ruby Associationが公開している[模擬試験問題](https://github.com/ruby-association/prep-test/blob/version3/gold_ja.md)です。これは本当に助かりました！

## Webアプリケーションへの発展

模擬試験問題を解いていくうちに、ふと思いつきました。「これをWebアプリケーションにしたら、世界中のRuby愛好者が自分のスキルをテストできるのでは？」

そこで、この考えを実現するために[Ruby Exam App](https://github.com/suzulang/ruby_exam_app)を開発しました。

## アプリケーションの特徴

- Ruby on Railsで構築
- 模擬試験問題をデータベースに格納し、ランダムに出題
- ユーザー登録機能により、進捗状況を保存可能
- レスポンシブデザインで、様々なデバイスに対応

## 今後の展望

このプロジェクトを通じて、単にRubyの知識を深めるだけでなく、実践的なWebアプリケーション開発のスキルも磨くことができました。今後も機能の追加や改善を続け、より多くの人にRubyの魅力を伝えられるツールにしていきたいと考えています。

## おわりに

Ruby Goldの資格取得は私の目標の一つですが、このプロジェクトを通じて、資格以上に大切なのは実践的なスキルと情熱であることを学びました。これからも、Rubyコミュニティに貢献できるよう努力を続けていきます。

皆さんも、ぜひ[Ruby Exam App](https://github.com/suzulang/ruby_exam_app)を使って、自分のRubyスキルをテストしてみてください！フィードバックもお待ちしています。

## Demo画像
![Snipaste_2024-08-21_14-06-09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3824310/c6ba6a13-02b1-002a-a50a-59fde6109492.png)
![Snipaste_2024-08-21_14-06-49.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3824310/4a8ce320-3f07-79cb-3ce8-545a891e9d60.png)
![Snipaste_2024-08-21_14-06-58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3824310/cab0370f-602d-9d12-8c49-ffb54cefb6b7.png)
![Snipaste_2024-08-21_14-07-06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3824310/08b618b0-6204-4aea-d29a-4f00e20722b5.png)
【ServiceNow】Now Assist機能について（Washington DCアップデート）

## はじめに
みなさんこんにちは、三井情報株式会社です。

今回は、ServiceNowの一機能である「Now Assist」について、Washington D.C.アップデートを踏まえ概要をまとめてみました。
本記事では第一回として、Now Assist機能の概要について説明させていただきます。
後日、実際に利用する際の実装方法や注意点についても解説できればと思います。よろしくお願いします！

というわけで、今回は下記の内容を紹介させていただきます。
・Now Assistとは
・Washington DCでの追加機能

## Now Assistとは
一言でいうと、「ServiceNowで利用可能な生成AI機能群」です。
・タスクの要約
・エージェント支援
・コンテンツ作成
・コード生成
など、種々の機能が利用可能となります。

なお、Now Assistで利用しているLLM（大規模言語モデル）はServiceNow独自のものとなっております。
このLLMは、顧客インスタンスから収集されたデータを基に作成されています。
データの利用ポリシーについては下記に詳細がございますので、ご確認ください。
※学習データに利用されたくない場合はオプトアウトも可能です
[Advanced AIおよびデータ製品のサービス利用規約](https://www.servicenow.com/content/dam/servicenow-assets/public/en-us/doc-type/legal/servicenow-product-specific-terms.pdf "Product‑Specific Terms")
<br>
Now Assistについては[こちらの記事](https://qiita.com/Nanase_Ariyama/items/b6370fa046f075c26830 "【ServiceNow】Now Assist①～Generative AI全体像～")でも詳しく説明しておりますので、ぜひご確認ください！

https://qiita.com/Nanase_Ariyama/items/b6370fa046f075c26830



## Washington DCでの追加機能
Washington DCでは、下記の機能が追加されました。
<b>・ユーザロールによるNow Assist利用制限</b>
　付与するロールに応じて、Now Assistの利用を制限することができます。
 
<b>・Now Assist利用に際する条件設定</b>
　Now Assistの機能を利用可能とする条件を設定できます。
　例：ケースを起票したユーザのみにインシデント要約を許可する
 
<b>・ロールの追加</b>
　ロール[sn_generative_ai.data_steward]が追加されました。
　このロールが付与されたユーザは、Now Assist Adminコンソールより、該当インスタンスがServiceNowにどのようなデータを共有しているか確認することができます。

 これらの機能はNow Assistライセンスに含まれているので、Now Assistのライセンスをお持ちであればすぐに利用可能です。
PDIでは利用不可ですので、ご注意ください。

## おわりに
本記事ではNow Assistの機能、およびWashington DCでの追加機能についてご紹介しました。
次回は実際にNow Assistを利用する際の実装方法、注意点についてご紹介します。
ご覧いただきありがとうございました！
proxy環境下におけるDockerの使い方

# Proxy環境下におけるDockerの使い方

## dockerdのproxy対応
`sudo systemctl edit docker`

```bash
[Service]
Environment="HTTP_PROXY=http://your_proxy"
Environment="HTTPS_PROXY=http://your_proxy"
```

## Dockerクライアントのproxy対応

```~/.docker/config.json
{
  "proxies": {
    "default": {
      "httpProxy": "http://your_proxy",
      "httpsProxy": "http://your_proxy"
    }
  }
}
```

### 補足
環境変数として渡せばいいので以下のやり方でも可能

```docker-compose.yml
services:
  app:
    build:
      context: .
      dockerfile: ./docker/php/Dockerfile
      args:
        http_proxy: http://your_proxy
        https_proxy: http://your_proxy
    environment:
      http_proxy: http://your_proxy
      https_proxy: http://your_proxy
      no_proxy: "localhost,127.0.0.1"
    tty: true
```

- args
  buildプロセスでproxyを使う場合
- environment
  コンテナプロセス内でproxyを使う場合
openSUSE Leap を RaspberryPi にインストール

Raspberry Pi の OS はいくつも公開されているが、一般的には Debian ベースの Raspbian や Raspberry Pi OS が使われる。
今回は Debian ベースではない Linux として、 openSUSE を試してみました。


# 環境

- Raspberry Pi 3
  - Model B
- テスト日時 2024/08/20

# 資料

今回はここを元に作業を行いました。
https://en.opensuse.org/HCL:Raspberry_Pi3

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/a5fae31b-1be9-7242-a60d-5e7eec8a6273.png)

RaspberryPi 3 以外にもそれぞれ解説ページがあるので機種に合わせて読み替えましょう。

資料には、 Leap の最新版として 15.5 を使うようになっています。

しかしながら上記記事のリンクは機能しなかったので、以下のページを見ると、
https://download.opensuse.org/distribution/leap

Leap-15.6 にも RaspberryPi 用イメージは用意されていたので、こちらからダウンロードしました。
https://download.opensuse.org/distribution/leap/15.6/appliances/

RasoberryPi 用には以下のフレーバーが用意されていました。

- E20
- GNOME
- JeOS
- KDE
- LXQT
- X11
- XFCE
- Minimal

このうち、KDE/LXQT/XFCE を試してみました。

# インストール

openSUSE-Leap-15.6-ARM-***-raspberrypi.aarch64.raw.xz

をダウンロード。今回は RaspberryPi 3 なので aarch64 と書いているイメージをダウンロードします。


「Ubuntu Linux で Raspian xz ファイル・zip ファイルを microSD カードに書き込む」
https://qiita.com/nanbuwks/items/2c296549ff72dacf7adc
こちらの記事の通り microSD カードに書き込みます。

microSD を RaspberryPi に装着し、起動します。
![IMG_20240820_194048.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/e719515c-5cdb-fa23-68a5-1fff2192855e.jpeg)





# KDE → NG




> openSUSE-Leap-15.6-ARM-KDE-raspberrypi.aarch64.raw.xz
2024/8/15 14:20
1.3 GB


をダウンロード。
インストールして起動すると、数分経過してマウスカーソルが出現しました。
![IMG_20240820_195417.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/15f11373-53c1-1bbb-8e60-67aec0000532.jpeg)
しかしながらここから進まず。断念。



# XFCE → NG

> openSUSE-Leap-15.6-ARM-XFCE-raspberrypi.aarch64.raw.xz
2024/8/15 14:20
1.3 GB

を試します。


しばらくするとログインウィンドウが出てくるので、 root / linux でログイン

![IMG_20240820_201258.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/6ebb92c6-f33b-0656-78bc-26de89df82cd.jpeg)

しかしながらこの後マウスカーソルだけ出てきて進みませんでした。

![IMG_20240820_204412.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/d37a8e8c-ca03-d0da-868a-fa408f7fd43d.jpeg)



# LXQT → OK

> openSUSE-Leap-15.6-ARM-LXQT-raspberrypi.aarch64.raw.xz
2024/8/15 14:18
1.2 GB


起動中は、KDEは表示が隠されていますが LXQT と XFCE は起動メッセージが表示されます。
![IMG_20240820_204602.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/9111e7d4-e5b9-7631-9884-82c631237a15.jpeg)


XFCE と同じようにログオン画面が出てきたため root/linux でログオンすると無事デスクトップが表示されました。

![IMG_20240820_204925.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/630a5a03-dd54-9f25-3f8e-2e9f8e1f8c5e.jpeg)

今回試した3つの中では唯一まともに動きました
Javaで「UNICODE_CASEフラグ(Unicode準拠の文字でも大文字と小文字を区別しない)」の動作を確認してみた

# 概要

Javaで「UNICODE_CASEフラグ(Unicode準拠の文字でも大文字と小文字を区別しない)」の動作を確認してみました。
以下のページを参考にしました。

https://www.javadrive.jp/start/regex/index22.html

# 実装

以下のファイルを作成しました。
```JSample22_1.java
import java.util.regex.*;

class JSample22_1{
  public static void main(String[] args){
    String target1 = "ｂｏｏｋ";
    String target2 = "ＢＯＯＫ";

    String regex = "ｂｏｏｋ";
    Pattern p1 = Pattern.compile(regex);

    Matcher m1_1 = p1.matcher(target1);
    System.out.println(target1 + ":" + m1_1.find());
    Matcher m1_2 = p1.matcher(target2);
    System.out.println(target2 + ":" + m1_2.find());

    System.out.println("---- ----");

    Pattern p2 = 
      Pattern.compile(regex, Pattern.CASE_INSENSITIVE|Pattern.UNICODE_CASE);

    Matcher m2_1 = p2.matcher(target1);
    System.out.println(target1 + ":" + m2_1.find());
    Matcher m2_2 = p2.matcher(target2);
    System.out.println(target2 + ":" + m2_2.find());
  }
}
```

以下のコマンドを実行しました。
```
$ javac JSample22_1.java 
$ java JSample22_1 
ｂｏｏｋ:true
ＢＯＯＫ:false
---- ----
ｂｏｏｋ:true
ＢＯＯＫ:true
```

# まとめ

何かの役に立てばと。
ブロックチェーンベースのVPNとは？(簡易ver.)


世界中で10億人が仮想プライベートネットワーク（VPN）を使用していることを考えると、VPNは急速に成長していると言えます。従来のVPNの問題を解決し、新しい世代のVPNが市場に登場しています。これらはdVPN（分散型VPN）と呼ばれ、ブロックチェーン技術をインフラに使用しています。

![Screenshot 2024-08-21 at 14.20.01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3672851/ab6e74d7-db65-0cc2-080f-dbdf9a459ed1.png)


## ブロックチェーンベースのVPNとは何か？

従来の中央集権型VPNはユーザーの匿名性を保護しません。インターネットサービスプロバイダー（ISP）からのトラフィックをマスクしますが、VPNプロバイダーがデータを暗号化し、自社のサーバーを経由してルーティングするため、信頼がISPからVPNプロバイダーに移るだけです。このため、従来のVPNには中央集権的な単一障害点があります。

新しいdVPNは、この問題を分散型のアプローチで解決します。信頼を独立した「ノード」のネットワークに分散させ、ブロックチェーン技術を活用します。ブロックチェーンは改ざんされず、検証可能で分散化された情報交換を提供し、大規模な組織でも使用されています。

## VPNはブロックチェーンをどのように使用するのか？

### ノードのインセンティブ化によるスピード、信頼性、稼働時間の向上

分散型VPNプロバイダーは、ネットワークのノードに報酬とインセンティブを与えることで、高品質のサービスを提供します。Nymでは、Cosmosベースのブロックチェーン上のNYMユーティリティトークンを使用し、ノードオペレーターに報酬を支払います。これにより、インフラの最適化とパフォーマンスの向上が促進されます。

### 分散型ディレクトリ権限

VPNのディレクトリ権限は、サーバーの健康状態と構成を監督するシステムです。従来のVPNではこれが中央集権的に管理されていますが、NymVPNではディレクトリ権限がNyxブロックチェーン上で分散管理されています。これにより、単一の故障点が排除されます。

### アクセスと支払い

dVPNはブロックチェーンを使用してアクセスを管理します。例えば、NymVPNではCosmosベースのNyxブロックチェーンにネイティブのNYMトークンを使用し、ユーザーがインターネットにアクセスすることを可能にします。さらに、Nymは匿名資格暗号スキームであるzk-nymsを作成し、支払いとアクセス資格の間のリンク不可能性を確保します。

## 最高のブロックチェーンベースのVPN：NymVPN

NymVPNでは、ユーザーは次世代VPNへのアクセスを得ることができ、2つのモードが提供されます。超高速の2ホップdVPNモードと5ホップミックスネットモードです。これにより、比類のないプライバシー保護とユーザーの選択肢が提供されます。

# 参考リンク

- [Nym公式サイト](https://nymtech.net/)
- [Nymのミキシングネットワーク - Wikipedia](https://ja.wikipedia.org/wiki/Nymミックスネット)
- [Nymホワイトペーパー](https://nymtech.net/nym-whitepaper.pdf)
- [分散型VPN と中央集権型VPN:違いの全て](https://note.com/koko_crypto/n/n71fe7e92b68a)
- [ミックスネットとは何か？ VPNによる比類なきオンラインプライバシー](https://note.com/koko_crypto/n/n302e7516f691?magazine_key=m0129d65e3526)
- [Sphinx暗号-Nymを支える匿名データフォーマット](https://qiita.com/pseudonym2/items/107cf005e9cab0b165b6)
- [ココナッツ認証（Coconut Credentials）とは？- プライバシーを保護するゼロ知識証明技術](https://qiita.com/pseudonym2/items/b2739ae32f4fb29de0b6)

# コミュニティ

- [Nym日本コミュニティ - Telegram](https://t.me/nymjapanese)
- [Nym日本コミュニティ - Discord](https://discord.com/invite/nym)
- [Nym日本コミュニティ - LINEオープンチャット](https://line.me/ti/g2/0YGYYq4EoQZ8fL5FYQmqU4O9SRuE_a6YX19GtA?utm_source=invitation&utm_medium=link_copy&utm_campaign=default)

- [Nymプロジェクト日本語アカウント - X](https://x.com/nymproject_jp)
本番環境でRailsコンソールを開くコマンド

いつも忘れて30分ほど時間を浪費するので備忘録
しかもちょっと違うと全然開けないのが結構きつい。

# 本番環境でRailsコンソールを開く
```
RAILS_ENV=production bundle exec rails c
```

## RAILS_ENVは前
`RAILS_ENV=production`はどちらにせよ末尾につけるのではなく、前につける

## rails ではなくて bundle exec rails
`rails　c`で開こうとしても開けない。
`bundle exec rails c`を使い開く。
【Tableau】比較したい2つのグラフの軸を同期する方法

# やりたいこと
二重軸を使用せず、比較したい2つのグラフの軸を揃えたい！

例.ライバル地域と売り上げを比較したい場合など

:point_up: 完成イメージ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3586761/2be8c3cf-6475-5158-85ed-f6e0bc0c9dd1.png)

## 前提
二重軸を使わず、2つのグラフを比較する場合の軸の同期方法を紹介します。

:::note info
二重軸を使う場合は
Tableauの機能である「軸の同期」にて
二重軸の 2 本の軸を同じスケールを使用するよう揃えることが可能
:::
https://help.tableau.com/current/pro/desktop/ja-jp/multiple_measures.htm



## 準備
担当地域用と、比較地域用に2つずつ作成します。

・パラメータ　×2
・計算フィールド　×2


### パラメータ

・担当地域パラメータ
・比較地域パラメータ

名称以外は同じ内容で問題ないです！

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3586761/59c29a27-9fef-a231-dce6-450c2dbd20a4.png)


### 計算フィールド（売上）
・売上_担当地域
・売上_比較地域

条件のうちパラメータは対応するものに変更してください！

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3586761/16f80b5f-3cf5-7b36-5f69-47b896e8ca0a.png)

### 準備完了

これらから担当地域の年別売上を出してみます

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3586761/70e52044-e994-8f78-2d50-41182a80c480.png)

同じ手順で比較地域も用意し、ダッシュボードを作ってみました！

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3586761/1c9c0a29-9b92-0736-800b-50ea49b7abb7.png)

ぱっと見では上手くいっていそうですが、軸を見て下さい。
これでは同じ尺度で比較が出来ませんね。

## 実践
やっとこの記事の本題にはいります。

### やること
・マーク内の「詳細」に相手の計算フィールドを入れる
・リファレンスラインの追加


この2つで簡単に軸を同期させられます:ok_hand:

### 1. マーク内の **「詳細」** に **相手の計算フィールド** を入れる
担当地域のグラフには「比較地域」の計算フィールドをいれてください

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3586761/89880287-9bd7-4572-f13d-56ddac4150a6.png)


### 2. リファレンスラインを追加
y軸を右クリックするとリファレンスラインを追加できます

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3586761/6b804b52-5468-3200-3d09-9e471ab6f186.png)

範囲：テーブル全体
線：`相手の計算フィールド（上で詳細に入れたもの）`、最大値
ほかは「なし」

### OKボタンを押す

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3586761/316f70e5-1147-eb5c-acb9-2427d65b37c6.png)

いい感じになってきたのでは！
これを比較対象側のワークシートでも設定し、ダッシュボードに戻ると

### :tada: 完成
軸が同期されていることが分かりますね！
これで同じ尺度で比較が出来そうです！

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3586761/382a8f7c-07c8-4e16-89ae-7b5519098742.png)

一応パラメータの値を変更してみました、いい感じですね
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3586761/18e39622-831d-11f4-6482-2b124d1beb3e.png)


## 最後に
グラフを比較するときの軸の同期について
「2つの値にどれくらいの差があるのか」を知る為には有用です。
実力（地域であれば人口や面積など）に差がある2つの地域の比較も可能になります。

しかし値の内訳（成分の割合）を見たい場合は軸を同期しない方が分かりやすいです。

例えば、売上値でなく、売り上げのカテゴリの割合にどんな違いがあるかを見たい場合です。
内訳を見比べるのには右のダッシュボードがいいですよね。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3586761/dfa29110-fb78-012b-fab4-6fe8f964b5b6.png)

「比較」といっても何を見て比べたいのか（値なのか、成分なのか）を考えてグラフを作ることが大切ということが分かりますね。

参考になれば幸いです。
【Tableau】折れ線グラフで選択した"年"を強調させる方法

# やりたいこと
選択した項目を色付けしハイライトする

例：売上推移のうち何年を選択しているかを強調したい

:point_up: 完成イメージ
x軸の「2023」年を選択するとハイライトが付く！

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3586761/1dfd7d60-a595-80b9-8702-f11b7704f8a0.png)


## 準備
・年パラメータ

選択した年を記憶する為にパラメータを用意

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3586761/f192c9fb-3527-f414-7046-8cd6be7258b9.png)

## 実践

### 1.パラメータアクションで、選択した年にパラメータを設定

ダッシュボードに移動しパラメータアクションを設定します。

:::note info
参考
パラメータアクションについて
https://help.tableau.com/current/pro/desktop/ja-jp/actions_parameters.htm
:::

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3586761/c76998a6-7f09-6f89-01a6-df16c394a00a.png)


今回の例では以下になります

**「売上推移」** （ソースシート）の
**「年」** （ソースフィールド）を選択し
**「ハイライト用_年パラメータ」** （ターゲットパラメータ）に設定します

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3586761/d9dffd80-3214-863b-879c-a45fb29dd8ac.png)

:::note warn
注意点
パラメータで設定したフィールド（※1）とソースフィールドは同じものを指す必要があります。
:::

ダッシュボードに移動し、選択した「年」がパラメータの値に設定されることを確認します。
※ダッシュボードアクションなので、ワークシートでの確認は出来ません！

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3586761/e7d973f2-9a4d-691a-e3ce-3fee6bdab86d.png)

### 2.選択年を判別する計算フィールドを作る

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3586761/a2353e1c-a92a-ecdf-24b1-e32db7e57eb3.png)

### 3.リファレンスラインを追加
2で作成したメジャーでリファレンスラインを作ります。
※2で作成したメジャーは「詳細」にいれておくこと

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3586761/874b7747-93b6-5285-fb48-d5f1090d2474.png)

範囲：セルごと
線＞値：`2で作成した計算フィールド`、最大値
書式設定：上を塗りつぶし

## :tada: 完成
選択した年をハイライトさせることが出来ました！

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3586761/c8de5ca1-b8ca-6f20-e9be-f740486ef294.png)