OmniAICreator/Qiita-1.07M huggingface dataset:
時系列データコンペの取り組み方

ChatGPTを使って、時系列データコンペの取り組み方にまつわる記事を書いてもらったので、投稿してみる。

## 時系列データコンペとは
時系列データコンペとは、時系列データを使用して予測モデルを構築する競技プログラムです。この種のコンペティションでは、通常、過去の時系列データが与えられ、未来の値を予測する必要があります。例えば、将来の株価や、将来の天気、将来の販売量などを予測することが求められる場合があります。

## データの前処理
時系列データコンペでは、通常、次のような前処理が必要です。

- 欠損値の処理
- ノイズの削除
- 特徴量エンジニアリング
- 外れ値の除去
- スケーリング
これらの前処理を行うことにより、モデルの精度を向上させることができます。

## モデルの選択
時系列データコンペで使用されるモデルやアルゴリズムは多岐に渡ります。代表的なものには、ARIMAモデル、LSTMモデル、Prophetモデルなどがあります。これらのモデルは、それぞれ異なるアプローチを取るため、どのモデルが最適であるかは問題によって異なります。また、ハイパーパラメータの調整も重要であり、適切なチューニングを行うことが必要です。

## 評価指標
時系列データコンペで使用される代表的な評価指標には、RMSE、MAE、MAPE、SMAPEなどがあります。これらの評価指標は、予測値と実際の値の差を計算し、その平均値または合計値を計算します。

## 予測結果の可視化
時系列データコンペでは、予測結果を可視化することが重要です。可視化によって、モデルの予測が正しいかどうかを直感的に理解することができます。代表的な方法には、次のものがあります。

- 実際の値と予測値を重ねてグラフ化する
- 予測値の信頼区間をグラフ化する
- 予測値と特徴量の相関関係をグラフ化する
- 残差プロットをグラフ化する
これらの方法を使用することによって、モデルの予測が正しいかどうかを視覚的に確認することができます。

## アンサンブル学習
時系列データコンペでは、複数のモデルを組み合わせることで、より正確な予測を行うことができる場合があります。これをアンサンブル学習と呼びます。アンサンブル学習には、多数決アンサンブル、重み付き平均アンサンブル、スタッキングアンサンブルなどの種類があります。どの方法を使用するかは、問題によって異なります。

## コンペの戦略
時系列データコンペでは、一般的にデータが時間的に連続しているため、クロスバリデーションが行いづらいことがあります。そのため、過去のデータをトレーニングに使用し、最後のいくつかのデータをテストに使用する方法が一般的です。また、時系列データコンペでは、直近のトレンドと季節性を考慮することが重要です。これらの要素を考慮に入れない場合、予測精度が低下する可能性があります。

## まとめ
時系列データコンペは、一般的な機械学習コンペとは異なる点がありますが、適切な前処理、モデルの選択、評価指標の理解、可視化、アンサンブル学習、戦略の検討などを行うことによって、高い予測精度を達成することができます。

ChatGPTすごすぎ
Goで辞書型配列の値の長さでソートする

## やりたいこと

`map[string]string`な配列で、値の長さでソートしたい。

[この記事](https://zenn.dev/sinozu/articles/c02cecbab039795d071a)によるとGolangのmapは明確な順序を持たないので、値の長さでソートしたキーを配列として取得することにする。

## どうやったか

mapのままソートする方法がわからなかったので、一度構造体に落とし込んだ後にsortする。

非常に冗長で汚いので、もっとわかりやすく明確でスマートな方法があったら教えてほしいです。

## コード

```golang
package main

import (
	"sort"
	"fmt"
)

var FoodList = map[string]string{
	"Menu1": "Orange",
	"Menu2": "Banana",
	"Menu3": "Apple",
	"SpecialMenu": "YakisobaCake",
}

func SortWithValueLen(baseMap map[string]string)([]string){
	var rtn []string
	
	type temp struct{
		index string
		value string
	}

	var tempList []temp
	for index, value := range baseMap{
		tempList = append(tempList, temp{index: index, value: value})
	}

	sort.Slice(tempList, func(i, j int) bool {
		return len(tempList[i].value) > len(tempList[j].value)
	})

	for _, temp := range tempList{
		rtn = append(rtn, temp.index)
	}
	return rtn
}

func main(){
	fmt.Println(SortWithValueLen(FoodList))
}
```

## 結果

値の長い順にKeyがソートされる

`[SpecialMenu Menu1 Menu2 Menu3]`
WSLでもサクラエディタを使いたい人のための.bashrc

## 実行環境

- Windows 11 22H2
- WSL バージョン: 1.0.3.0

## WSL上で編集するファイルをサクラエディタで開きたいッッッ

以下の内容を.bashrcに書きましょう。
※ `C:\path\to\sakura.exe` はご自身の環境のパスに変更してください

`sakura` コマンドを実行することでWSL上のファイルが開けるようになります。

```sh
function sakura() {
  sakura_arg=()
  for p in $@; do
      if [ -f "$p" ]; then sakura_arg+=("`wslpath -w $p`"); fi
  done
  (
    /mnt/c/Windows/System32/cmd.exe /c 'C:\path\to\sakura.exe' $sakura_arg[@] >/dev/null 2>&1 &
    sleep 2
    pid="$!"
    if [ -x "/proc/$pid" ]; then kill $pid; fi
  )
}
```

2023/02/18 追記
サクラエディタを終了するまで、cmd.exeだけがバックグラウンドプロセスに残り続けてしまうことに気づきました。起動する毎に塵も積もれば…でメモリを消費し続けてしまうので、起動直後にkillするようにしました。

## なぜこんな回りくどい書き方なの？alias使えばよくない？

`alias sakura=/mnt/c/path/to/sakura.exe` ではダメなのでしょうか？
ダメなのです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/164949/fd05eb33-de9c-7fe7-40ca-af605d43108e.png)

aliasに設定することで直接 `/mnt/c/path/to/sakura.exe` を叩くのと同じようにしてみました。 **なんとタスクバー上のアイコンが、虚ろな目をしたペンギンになってしまいました。** 

WSL上で直接Windowsの実行ファイルを叩くと、プロセスがWSLにぶら下がるためか、このようにおかしなことになるようです。

実のところ、私はサクラエディタではなく [Mery](https://www.haijin-boys.com/) というテキストエディタを愛用していますが、同じアイコンになってしまうのは同様です。

## 上記の書き方を使うことによる便利な点

もちろん、虚ろなペンギンをタスクバーに出さないためだけにこのような設定をするのではありません。

引数となるファイルパス `$1` に `wslpath` を噛ませていますよね。こうすることで、WSL上のファイルであってもWindows側から覗くことのできるパス表記に変換されるため、WSL上のファイルをすんなりサクラエディタで開くことができます。

以上、サクラエディタだけでなく、秀丸でも、私が愛用するMeryでも、WindowsアプリでWSL上のファイルを扱いたいときには便利な小技でした。
WPFにおける、PCの左右手利きの設定がPopupの位置を不正にする問題と解決方法

## 現象
タッチ機能のある入力デバイス（タッチスクリーンなど）を使用する場合、WPFアプリケーションの`Popup`が異なるユーザー間で位置が異なる場合があります。

また、同じPC上で別のユーザーの場合でも、`ContextMenu`の方向が異なる場合があります。


## 原因

この問題は、以下のいずれかの要因によって引き起こされる可能性があります：

1. タッチ機能のある入力デバイス（タッチスクリーンなど）を使用する場合。

2. セカンダリディスプレイが右側にあり、プライマリディスプレイが左側にある場合。

## 解決方法

コード内で、`SystemParameters._menuDropAlignment`プロパティをリフレクションを使用して設定し、ポップアップメニューの位置を手動で修正します。

たとえば、次のコードを使用できます：


```c#
typeof(SystemParameters).GetProperty(
    "_menuDropAlignment", 
    BindingFlags.NonPublic | BindingFlags.Static)
.SetValue(null, 1);
```
DateTimeFormatter class

ofPatternの中のパターン文字ではない値は''で囲う
Locale.Category.DISPLAYは何が変わるのか不明
Locale.Category.CATEGORYは通貨日付に影響
```java
public class SampleProject {
    public static void main(String args[]) {
        method();
        Locale.setDefault(Locale.US);
        method();
        Locale.setDefault(Locale.Category.DISPLAY,Locale.JAPAN);
        method();
        Locale.setDefault(Locale.Category.FORMAT,Locale.JAPAN);
        method();
    }
    static void method() {
        System.out.println("----------------");
        
        LocalDateTime ld = LocalDateTime.now();
        System.out.println(DateTimeFormatter.BASIC_ISO_DATE.format(ld));
        System.out.println(DateTimeFormatter.ISO_DATE.format(ld));
        System.out.println(DateTimeFormatter.ISO_TIME.format(ld));
        System.out.println(DateTimeFormatter.ISO_DATE_TIME.format(ld));
        DateTimeFormatter f1 = DateTimeFormatter.ofPattern("yyyyねんMMがつddひe");
        DateTimeFormatter f11 = DateTimeFormatter.ofPattern("yyyyねんMMMがつddひee");
        DateTimeFormatter f12 = DateTimeFormatter.ofPattern("'eee'yyyyねんMMMMがつddひeee");
        DateTimeFormatter f15 = DateTimeFormatter.ofPattern("yyyy'ねん'MMMM'がつ'dd'ひ'eeee");
        DateTimeFormatter f13 = DateTimeFormatter.ofPattern("yyyyねんMMMMMがつddひeeeee");
//        DateTimeFormatter f14 = DateTimeFormatter.ofPattern("yyyyねんMMMMMMがつddひeeeeee");   //err  too many M  too many e
        DateTimeFormatter f2 = DateTimeFormatter.ofLocalizedDate(FormatStyle.FULL);
        DateTimeFormatter f3 = DateTimeFormatter.ofLocalizedDate(FormatStyle.LONG);
        DateTimeFormatter f4 = DateTimeFormatter.ofLocalizedDate(FormatStyle.MEDIUM);
        DateTimeFormatter f5 = DateTimeFormatter.ofLocalizedDate(FormatStyle.SHORT);
        System.out.println(f1.format(ld));
        System.out.println(f11.format(ld));
        System.out.println(f12.format(ld));
         System.out.println(f15.format(ld));
       System.out.println(f13.format(ld));
        System.out.println(f2.format(ld));
        System.out.println(f3.format(ld));
        System.out.println(f4.format(ld));
        System.out.println(f5.format(ld));
    }
}
```
```
----------------
20230305
2023-03-05
12:27:21.5919478
2023-03-05T12:27:21.5919478
2023ねん03がつ05ひ1
2023ねんMarがつ05ひ01
eee2023ねんMarchがつ05ひSun
2023ねんMarchがつ05ひSunday
2023ねんMがつ05ひS
Sunday, March 5, 2023
March 5, 2023
Mar 5, 2023
3/5/23
----------------
20230305
2023-03-05
12:27:21.7482069
2023-03-05T12:27:21.7482069
2023ねん03がつ05ひ1
2023ねんMarがつ05ひ01
eee2023ねんMarchがつ05ひSun
2023ねんMarchがつ05ひSunday
2023ねんMがつ05ひS
Sunday, March 5, 2023
March 5, 2023
Mar 5, 2023
3/5/23
----------------
20230305
2023-03-05
12:27:21.7482069
2023-03-05T12:27:21.7482069
2023ねん03がつ05ひ1
2023ねんMarがつ05ひ01
eee2023ねんMarchがつ05ひSun
2023ねんMarchがつ05ひSunday
2023ねんMがつ05ひS
Sunday, March 5, 2023
March 5, 2023
Mar 5, 2023
3/5/23
----------------
20230305
2023-03-05
12:27:21.7482069
2023-03-05T12:27:21.7482069
2023ねん03がつ05ひ1
2023ねん3月がつ05ひ01
eee2023ねん3月がつ05ひ日
2023ねん3月がつ05ひ日曜日
2023ねん3がつ05ひ日
2023年3月5日日曜日
2023年3月5日
2023/03/05
2023/03/05
```
nodejsでaws-sdkを使った時にハマったこと

# はじめに

`AWS Lambda` `runtime: nodejs`を使って
`S3`にファイルをアップロードしようとした際につまづいたことをメモ。

# 環境

* aws-lambda
    * runtime: nodejs 14.*

# 結論

#### `aws-sdk`には<font color="red">V2</font>と<font color="red">V3</font>がある

#### そして、私の環境ではV2だと動きませんでした。

クラメソにも記事がありました。

https://dev.classmethod.jp/articles/aws-sdk-for-javascript-v2-v3-diff/

# 導入方法の違い

```bash
// V2
$ npm install aws-sdk

// V3
$ npm install @aws-sdk/client-s3
```

# S3へオブジェクトをuploadするときの違い

## V2の場合

```typescript
import * as AWS from 'aws-sdk'

AWS.config.apiVersions = {
  s3: '2006-03-01',
};

const putObject = async () => {
  var s3 = new AWS.S3();
  
  var params = {
    Body: <Object>, 
    Bucket: <Bucket名>, 
    Key:  <Object名>,
  };
  
  s3.putObject(params, (err, data) => {
    if (err) console.log(err);
    else console.log(data);
  });
}
```

## V3の場合

```typescript
import { S3Client, PutObjectCommand } from '@aws-sdk/client-s3';

const putObject = async () => {
  const s3 = new S3Client({
    region: 'ap-northeast-1'
  })
  
  const command = new PutObjectCommand({
    Body: <Object>, 
    Bucket: <Bucket名>, 
    Key:  <Object名>,
  })
  
  await s3.send(command)
}

```

# 最後に

V2は2023年にメンテナンスモードになるらしいので、V3を使いましょう
システムエンジニアにとってのツイッター

こんにちは、ツイッターはROM専よりも発信に使っている小野歩です。
最近、ツイッターで開発のトレンド調べる云々という話を聞いて、「たしかにあるかも！」と思いました。

実際、TwitterAPIが使えなくなった、AWSの障害情報などは、ツイッターから情報を得ることが多いです。
「速さ」ファーストな媒体ですからね。

しかし、開発の云々までツイッターで調査することはないです。
「しない！」と断言しても良いでしょう。

というのもツイッターって、情報がストック型じゃないんですよね。
ストックの逆で、フロー型で流れていくんですよね。

## ツイッターはトレンドニュースに向いている

ツイッターはトレンドの情報を取得するには、良いでしょう。
冒頭でも書いたように、APIの停止やAWSの障害情報です。

技術以外でも、最近話題のニュースや事件、ゲームアプリのイベント情報など、そういう鮮度が大事なものはツイッターが良いです。
営業もしているエンジニアには最近の話題は大事ですけど、営業ではない人にはそこまで必要じゃないかもしれないですね。

### ストック型ビジネスとフロー型ビジネスを参考に

**ブログはストック型の情報であり、ツイッターはフロー型の情報だと思っています。**

ブログは”ググる”という行動から、必要な情報を見つけるのに向いています。
しかし、ツイッターで”タグる”という行動からは、トレンドで話題の情報ばかり見つかります。

**ブログやQiitaは”検索される”情報が蓄積していくので、良い情報は長期的に残してくれています。**
LaravelとReact.jsの環境構築とか、artisan コマンドとか、使えるメソッドなどなどは、調べやすくていいですね。
PHPも開発の時に困ったら、まずは公式のマニュアルを読みますしね。

そして、一言。
**PHPを使っている人は、まず公式マニュアル見るの癖つけるのオススメですよー。**
最近はエンジニアの技術系ブログも増えていますが、間違った情報や古い情報もあったりするので、まず公式マニュアルでチェックするの大事です。

https://www.php.net/manual/ja/index.php


### さいごに

ツイッターは速さを。
ブログからは、よく使う or たまに使うまとまった情報を。

ブログは「信頼できる情報がストックされているもの」と捉えると良いでしょう。
だが、足りないものがあります。

それは ... 

...

......

.........

*何よりも速さが足りない！！！*
オンライン受験Ｑ＆Ａまとめ（Azure/ピアソンVUE）


# ○概要
- 英語試験官はそんなに英語喋れなくても大丈夫
- カメラは外付けがおすすめ
- PCは私物推奨
- 部屋が汚い場合、適当な布をかぶせて隠せばOK


# ○はじめに
先日、Azure資格をピアソンVUEのオンラインで受験しました。日本語試験官と、英語試験官の両方を経験したので、受験前に知りたかったことをまとめます。

## -受験までのスケジュール
試験を予約すると、予約確認メールが届きます。
システムテストの案内が記載されていますので、こちらに沿って準備を進めます。

具体的には以下のようなイメージです。
1. アプリDL、システムが動作するか確認（前日まで）
2. チェックインの実施（身分証の撮影とか。当日、予約時間の30分前から）
3. 試験スタート

1、2とも30分くらいで終わりました。
2のチェックインはなぜか一度やり直しになったので、早めに始めるのがよいと思います。

## -Q＆A
## Q1_英語喋れないけど大丈夫？
⇒あらかじめ突っ込まれそうなポイントを排除しておきましょう。そうすると予定外のコミュニケーションをとらなくて済みます。

私は以下の点に気をつけました。
- なるべく音がしない環境にする
- 机に何も置かない
- 背景に文字が含まれたものを映さない

あとは以下２点がなんとなく聞き取れれば大丈夫だと思います。
- 「机の4隅を画面に全部入れて映して（Please Show your desk〜とか聞こえた気がする）」
- 「君のPCを後ろから映して（〜behind laptop とか聞こえた気がする）」


## Q2_PC内蔵のカメラでも大丈夫？
⇒なんとかなりましたが、外付けの方が楽でした。
「机の４隅を全部入れて映して」という指示が、内蔵カメラだと難易度が高いです。
机にカメラ向けると画面を確認できないので。


## Q3_PCは私物のほうがよい？
⇒専用のアプリをダウンロードします。これは避けられないので、私物の方が楽だと思います。

## Q4_部屋を片付けるのが面倒くさい。
⇒わかります。布メソッドはどうでしょうか。
100均などで適当な布を購入し、気になるところを覆って受験する記事がありました。
私は一時的にカーテンを外して本棚にかけておきました。取り外しが面倒ですが、原状復帰は早いです。

参考：https://blog.usize-tech.com/aws-certificate-examination-at-home/


## Q5_予約後に日時変更はできる？
⇒できました。私のときは予約の24時間前までなら変更OKでしたが、都度変わると思うので、キャンセルポリシーをご確認ください。

- 日本語試験官
⇒予約が埋まっていることが多く、直前だと予約が取れないことが多かったです。ご注意を。

- 英語試験官
⇒深夜帯であれば直前でも空いていることが多いように思います。
Databricksワークフローによるdbtオーケストレーションの正式提供

[Orchestrate Production dbt Projects on the Lakehouse With Databricks Workflows \- The Databricks Blog](https://www.databricks.com/blog/2023/02/14/announcing-general-availability-orchestrating-dbt-projects-databricks.html)の翻訳です。

:::note warn
本書は抄訳であり内容の正確性を保証するものではありません。正確な内容に関しては原文を参照ください。
:::

[Databricksワークフロー](https://www.databricks.com/jp/product/workflows)におけるdbtプロジェクトのオーケストレーションサポートの正式提供(GA)を発表できることを嬉しく思っています。[パブリックプレビュー](https://qiita.com/taka_yayoi/items/884f06c9a9efc3d328d5)以来、数百のお客様がDatabricks SQLのデータをコラボレーティブに変換、テスト、ドキュメント化を行うためにdbtのインテグレーションを活用しています。

ワークフローにおけるdbtサポートによって、お使いのdbtプロジェクトがGit[リポジトリ](https://qiita.com/taka_yayoi/items/b89f199ff0d3a4c16140)から取得され、dbt-coreとプロジェクトの依存関係がインストールされたシングルノードクラスターが起動されます。dbtによって生成されたSQLはサーバレスSQLウェアハウスで実行され、容易なデバッグと優れたパフォーマンスを提供します。また、失敗したジョブの[復旧](https://qiita.com/taka_yayoi/items/1456e0d9a4ebe0291e41)や、dbtタスクが失敗した際にSlackやwebhookを通じたアラートの送信のような堅牢かつ運用向けの機能、[Jobs API](https://docs.databricks.com/dev-tools/api/latest/jobs.html#section/Authentication)を通じたログのようなdbtアーティファクトの取得やジョブの管理機能もあります。

GAによって、既存のサーバレスSQLウェアハウスのサポートに加えてSQL Proウェアハウスのサポートも追加しています。さらに、Databricks on Google Cloud Platform (GCP)でのサポートを発表できることを嬉しく思っています。dbtプロジェクトで定義された変換処理のリネージも自動で[Unity Catalog](https://qiita.com/taka_yayoi/items/11e76ea5b051fd483b7b)で記録されます。最後になりますが、[dbt\-artifacts](https://docs.getdbt.com/reference/artifacts/dbt-artifacts)のようなdbtコミュニティのパッケージもDatabricksで動作するようになっています。

Databricksでdbtを使い始めるには、シンプルに`pip install dbt-databricks`を実行するだけです。これによって、dbt Labsとその他のコントリビューターによって開発されたオープンソースのdbt-databricksパッケージがインストールされます。サンプルプロジェクトで利用を開始するには[詳細なガイド](https://docs.databricks.com/integrations/prep/dbt.html)を参照することができます。ソースコードをgitリポジトリにコミットすれば、プロダクション環境でご自身のdbtモデルを実行するためにDatabricksワークフローを活用することができます。(ドキュメントもご覧ください。[[AWS](https://docs.databricks.com/workflows/jobs/how-to-use-dbt-in-workflows.html) | [Azure](https://learn.microsoft.com/en-us/azure/databricks/workflows/jobs/how-to-use-dbt-in-workflows)| [GCP](https://docs.gcp.databricks.com/workflows/jobs/how-to-use-dbt-in-workflows.html)])

### Databricks 無料トライアル

[Databricks 無料トライアル](https://databricks.com/jp/try-databricks)
Puppeteerでボタンをクリックしてもダイアログがでないとき

ボタンを押すとダイアログが出て、OKするとページ遷移のシナリオなのでこんなコードを書くのですが、たまにダイアログが押せなくて、テストが失敗するときがあります。

```js
page.once('dialog', dialog => dialog.accept());
await Promise.all([
  page.waitForNavigation(),
  page.click('button')
]);
```

そういうとき、こんなコードでダイアログがでるまでクリックしながら待っています。

```js
const button = await page.waitForSelector('#button');
let dialog = null;
page.once('dialog', d => dialog = d);
while (!dialog) {
    await button.click().catch(() => false);
    await new Promise(ok => setTimeout(ok, 2000));
}
await Promise.all([
    page.waitForNavigation(),
    dialog.accept()
]);
```

同様にボタンをクリックするとFileChooserが出てくるはずなのに、上手くでてこないので、出るまでクリックしながら待つときはこんな感じ

```js
const button = await page.waitForSelector('#add');
let dialog = null;
while (!dialog) {
    await Promise.allSettled([
        page.waitForFileChooser({ timeout: 2000 })
          .then(chooser => dialog = chooser)
          .catch(() => false),
        button.click().catch(() => false)
    ]);
}
dialog.accept([file])
```
ChatGPTにLambda（Node.jsランタイム）で環境変数を参照する方法を聞いてみた

# やったこと
ググるのがめんどくさかったのでChatGPTに聞いてみました。

## 質問

```
> LambdaのNode.jsランタイムで環境変数の参照の仕方を教えて
```

## 回答
AWS LambdaのNode.jsランタイムでは、環境変数を参照するために `process.env` オブジェクトを使用します。このオブジェクトには、Lambda関数の実行時に設定されたすべての環境変数が含まれます。

以下は、Lambda関数内で環境変数を参照する方法の例です。

```
exports.handler = async (event, context) => {
    // 環境変数の参照
    const myVar = process.env.MY_VAR;
    console.log(`MY_VARの値: ${myVar}`);
    
    // 他の処理
    // ...
};
```

上記の例では、`process.env.MY_VAR` を使用して、`MY_VAR` という名前の環境変数の値を参照しています。Lambda関数が実行される前に、AWS Management ConsoleやAWS CLIなどの手段で環境変数を設定することができます。

なお、環境変数によってLambda関数の挙動を変更したり、外部サービスの認証情報を保護することができます。環境変数に格納する情報はセンシティブな情報である場合が多いため、AWS Secrets ManagerやParameter Storeなどのサービスを使用して、環境変数の値を安全に保管することが重要です。

# 所感
もちろん上記が正しいことは確認済みです。

この程度であればググってもすぐに見つかりますが、チャットベースかつ、数秒でサンプルコード付きで回答されるのはすごいですね！

しかも、初心者プログラマーがやりがちな認証情報のハードコーディングについても注意されたのに驚きました（笑）
ESLintのdisableコメントに注釈（コメント）を付ける方法

コメントの付け方を知らないとdisableコメントの上にコメントを書き2行になってしまいます。
ですが、disableの後に続けてコメントを記載する方法があります。
方法は`disable`コメントの後に` -- `（スペース、ハイフン2つ、スペース）をつけるとコメントを記述することができます。

```javascript:
// hogeは使わない
// eslint-disable-next-line @typescript-eslint/no-unused-vars
const hoge = 'hoge'
```

```javascript:
// eslint-disable-next-line @typescript-eslint/no-unused-vars -- disableする理由も書けてスマートです
const hoge = 'hoge'

/* eslint-disable @typescript-eslint/no-unused-vars -- 囲む場合も同様です */
const hoge = 'hoge'
/* eslint-enable @typescript-eslint/no-unused-vars -- 上下どちらにもコメントできます */
```
ABC086A	Product　AtCoderの問題をRubyで解説

# 正解の解答例
```
a,b = gets.split.map(&:to_i)

if a * b % 2 == 0
  puts "Even"
else
  puts "Odd"
end
```

1行目では入力、入力値を配列に入れる、配列の入力値を数値オブジェクトに変換する処理を行なっています。
他の解答例でsplit(" ")と解答している方もいらっしゃいますが、splitの記述だけでスペースは区別できるようです。

if文ではaとbの積を2で割ることで余りが出るか判別しています。
2で割り切れればEvenを出力します。
そうでなければ奇数なのでOddを出力します。

■参考サイト
https://leokun0210.hatenablog.com/entry/2019/08/25/162033
設計から実装を開始するまでの間に作成するドキュメント一覧

## はじめに
今回紹介するドキュメントの一覧は、あくまで自分の就業先で作成したものになります。
就業先によっては、多少内容が違うことも多いので、そこはご了承ください。

## 作成物一覧
設計から実装に入るまでに作成するドキュメントはこちらになります。
##### 設計書を書く前に作成するもの
・全体工程表
・議事録
・QA票
・文書管理台帳
・プロジェクト計画書
##### ○基本設計書
##### ○詳細設計書
##### ○ユニットテスト仕様書
##### ○結合テスト仕様書
1つずつ説明していきます。

## 基本設計の前に作成するもの

**プロジェクト計画書**
この計画書は、プロジェクトの目的やスケジュール、開発計画などを書いていくものになります。一番はじめに作成するものがこの計画書で、プロジェクトの元になるものなので、大切なドキュメントになります。

**全体工程表**
この表は、設計からリリースまでの工程を記入するものになります。工程を進める上で、変更が加わる事もよくあります。

**議事録**
ミーティングの内容などをまとめておくメモ的なものです。相互の認識の違いなどが無いようにするために必要なものであったりするので、結構重要なものになります。

**QA票**
要求定義書を見て、仕様に対しての疑問点を洗い出して、顧客に質問する要件をまとめる表になります。
これが結構大切で、ここでしっかり顧客とやり取りをして、記録として残しておかないと、仕様で揉めたりした時に、言った言ってないになってしまいます。

**文書管理台帳**
これは各設計書などを作成した日時などをまとめるものになります。

## 基本設計
※基本設計書の具体的な内容はこちらの記事にまとめてあるので、今回は割愛します。
https://qiita.com/hukuryo/items/97797a91d7e2ee0bcabc

**技術調査報告書**
技術調査を行った場合に作成して、顧客先に見せる報告書になります。技術調査は、実際にこれからやろうとしているプロジェクトに際して、技術的に実現できそうかどうかを判断するための調査であり、非常に重要な工程になります。

**レビュー票**
顧客先と基本設計についての読み合わせを行なった内容をまとめるために作成するドキュメントになります。ここに、読み合わせの内容をしっかり記録しておくことで、何かあった時の証拠にもなりますし、設計や実装を進めていくうえで役に立ちます。

**検討課題表**
基本設計の読み合わせで出た検討すべき課題をまとめるためのドキュメントです。

## 詳細設計書
詳細設計書は、基本設計の内容を掘り下げて、実装するときに使用するデータなどを記述していきます。
詳細設計の中で作成する、クラス図とシーケンス図についてはこちらの記事をぜひご覧ください。

クラス図について↓
https://qiita.com/hukuryo/items/4d8c3d1f3d3e0cab6589

シーケンス図について↓
https://qiita.com/hukuryo/items/431e58fe7d077db882c5

## ユニットテスト仕様書
単体テストの仕様書を書きます。
ユニットテストの説明に関しては、こちらのサイトがわかりやすかったです。
https://www.techmatrix.co.jp/t/quality/unittest.html

## 結合テスト仕様書
結合テストの仕様書を書きます。
結合テストの説明に関しては、こちらのサイトをご覧いただくとわかりやすいです。
https://products.sint.co.jp/obpm/blog/join-test

## 最後に
繰り返しにはなりますが、現場によって作成するドキュメントは変わってくるので、あくまでも参考程度にしていただければ幸いです。
以上になります。
【Laravel】入力した生年月日から年齢を抽出する

## 入力した生年月日から年齢を抽出する
DBに生年月日を登録し、そのデータを使って年齢もDBに登録がしたいと考えた。

### Carbonを使って実装する
```
$Birthday = '1994-07-02';
$years = Carbon::parse($Birthday)->age;
   
dd($years);
```

これを使ってLaravelで実装する。
```
public function update(Request $request, $id) {

    $user = User::find($id);
    $user->birthday = $request->birthday;
    $user->age = Carbon::parse($user->birthday)->age;
    $user->save();

    return redirect()->route('users.index')->with(
        'message', 'ユーザー情報を登録しました'
    );
}
```
parse関数の引数に生年月日を入れてあげればOK。
今回はDBに登録する`$user->birthday`を使ってやってみたが成功。

以上
React状態管理ライブラリRecoilとは

# Recoilとは
RecoilはFacebook社が作成した**状態管理ライブラリ**です。Context APIの成約を解決するために開発されたみたいです。
Reactにおける**状態管理ライブラリ**の一つ。代表的なものに「Redux」という状態管理ライブラリもある

# 状態管理ライブラリとは
![状態管理.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/462658/151979c1-2cac-9ccf-2d0e-3af132f30c11.png)
通常だとpropsで渡していくバケツリレー方式だが、
状態管理（画像ではStore）を使用することで、バケツリレーを行わなくてもどこからでも値をStoreから参照できるようななります。

### どんな時使用されるか
例えばユーザがログインしているのかしていないのかの情報。
- ログインしていればページを見せる
- ログインしていないのであればページを見せないログインページにリダイレクト
上記に関しては基本的にどのコンポーネントでも必要な情報になる。

そのためこのようなものに関しては状態管理から参照してどこでも使用できるようにしておいた方が良い

# Reduxについて
状態管理ライブラリのReduxについては簡単に言うと1つのstoreがあってそこから参照するパターンになります
- 値を取り出すとき（参照するとき）にはuseSelectorを使用します
- 逆にコンポーネントから値の更新したいときはuseDispatchを使用します
![状態管理Redux.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/462658/fcf895c3-bb77-416f-a45e-35670adeba6c.png)

# Recoilについて
状態管理ライブラリのRecoilについては簡単に言うとStoreをいくつも持つことができ、そこから参照するパターンになります。
Store一つ一つがatomと呼ばれています。Store同様一つのatomはどこでも参照することができます。
- Stateを参照する場合useRecoilStateを使用します
- Stateの値だけを参照する場合useRecoilValueを使用します
- Stateのset関数だけを使用する場合、useSetRecoilStateを使用します


![sample-component-tree.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/462658/5adea4a1-6094-cbed-f76e-2fb66838a4ea.png)

## なぜ複数atomが必要なのか？
atomが複数ある理由、つまりrcoilのメリットについてですが
まず一つのStoreから参照するReduxの場合、
空のオブジェクト渡し更新した場合、Storeから値を参照している他のコンポーネントでも空オブジェクトになってします。
つまり、すべて上書きされてしまうわけです。
もし間違って更新された場合にすべてページ見れなくなってしまったりするなんてことが起きてしまったります。

その点、Recoilの場合は複数に細分化しているため更新を分けることができる。

# Recoilまとめ
- バケツリレー（親コンポーネントのStateを孫コンポーネントで扱いたい場合、親コンポーネント->子コンポーネント->孫コンポーネントの経由をする必要がある）をしなくて済む。
- RecoilでState管理をする場合は、storeというディレクトリを切ってその中で管理していくのが一般的。
- RecoilのStateを参照する場合、useRecoilStateを使用する（useStateと同じ感覚で使える）
- RecoilのStateの値だけを参照する場合、useRecoilValueを使用する。
- RecoilのStateのset関数だけを使用する場合、useSetRecoilStateを使用する。
Oracle Analytics Cloud Classic：分析をはじめる。Dashboard、Answersで分析をはじめる。ダッシュボードページにダッシュボード・プロンプト、分析を貼り付ける

はじめに
---
Oracle Analytics Cloud Classic：Dashboard、Answersは、Enterprise Editionで利用できるものです。エンタープライズ・セマンティック・モデルのサブジェクト領域をつかって、Answersで分析を作成します。その後、Dashboardで、Answersで作成した分析を貼り付けます。
凡そ、以下の流れでDashboard、Answersで分析を作成していきます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2516153/765da6c0-80f2-de2b-9de9-d7492d98cf5b.png)

前提
---
OAC、ADWサービスをプロビジョニングし、作成している
サブジェクト領域を作成、保存、デプロイしている

本記事では[「Oracle Analytics Cloud インデックスページを作成してみました。」](https://qiita.com/tni38/items/534a39c1231b23c617f4])の以下を実施しています。
Oracle Analytics Cloud のサービス作成
お試し用にADWでSHスキーマをもとにSHJPスキーマを作成する。
セマンティックモデラー(Semantic Modeler)を試す。
Dashboard、Answersで分析をはじめる。表ビューを作成する。
Dashboard、Answersで分析をはじめる。表ビューにグラフを追加する。
Dashboard、Answersで分析をはじめる。ダッシュボード・プロンプトを作成する。


ダッシュボードの作成・保存
---
以下のようなダッシュボードページを作成、保存する手順です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2516153/07491f80-75fa-cdff-f77b-8d99da7a2a3e.png)


ダッシュボードの作成
---
右上部の「・・・(縦)」をクリックし、メニューから"クラシック・ホームを開く"をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2516153/5ec4aafa-b0fc-eb43-a87e-399754012ce0.png)

クラシック・ホームが開きます。右上部メニューの"作成"をクリックし、メニューから"ダッシュボード"をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2516153/285923ca-6a4e-73e2-8261-6da560ffed77.png)

名前を入力します。ダッシュボードを配置する共有フォルダを選択します。名前に売上ダッシュボード、場所に、分析を保存しているフォルダ/共有フォルダ/tutorial1/ダッシュボードを選択し、OKをクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2516153/57d26c35-295e-5f4a-3492-3b26d3d5609d.png)


ダッシュボードにダッシュボードプロンプト、分析を貼り付ける
---
ダッシュボードの編集画面が表示されます。
左下部のカタログのところで、ダッシュボード・プロンプト、分析が保存されているフォルダを開きます。共有フォルダの左▲、tutorial1の左▲をクリックします。貼り付けるダッシュボード・プロンプトをドラッグし、右部"コンテンツをここにドロップ"のところにドロップします。"日付範囲プロンプト"をドラッグし、右部にドロップします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2516153/bcec0eb9-6669-992a-74e5-10892643cde1.png)

貼り付ける分析をドラッグし、右部"コンテンツをここにドロップ"のところにドロップします。"製品カテゴリ別売上表グラフ"をドラッグし、右部にドロップします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2516153/5d425e76-080c-7e52-848b-32898356b97d.png)

右上部保存アイコンをクリックします。ｖ保存済と表示されたら、保存アイコンの左の実行▲アイコンをクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2516153/8d259a37-1ad0-ea14-8f5c-e683e3c60c59.png)

ダッシュボード・プロンプト、分析が貼り付けられたダッシュボードページが表示されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2516153/b7085808-6f47-b53e-7826-1761ebab7b19.png)

ダッシュボードは、上部メニュー（グローバル・ヘッダー）のダッシュボードをクリックすると、アクセスできます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2516153/fe276a72-9cf9-508c-a0ac-58c49ce884d7.png)

ダッシュボードは、上部右隅の歯車アイコンをクリックし、メニューからダッシュボードの編集をクリックすると編集画面が表示されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2516153/520fccc2-3ff7-f083-5abe-34590c0336e2.png)

ダッシュボードの編集画面
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2516153/2a94e93c-2dea-1d43-a168-3aabf0a2730c.png)


以上
Nuxt3 / Vue3 – typescript + ref で配列を定義するには？ ( 型 'string' を型 'never' に割り当てることはできません。 ) 

文字列を値に持つ配列を定義したい

# エラー

このコードだとVsCodeで以下のエラーが

>型 'string' を型 'never' に割り当てることはできません。


```ts
<script setup lang="ts">
const fruits = ref([])

fruits.value = ["Apple"]
fruits.value.push("Banana")
</script>
```

# 追記 - 解決

```ts
const fruits = ref<string[]>([])
```

と書けば良いようだ

```ts
<script setup lang="ts">
const fruits = ref<string[]>([])

fruits.value = ['Apple']
fruits.value.push('Banana')
</script>

```

# とりあえず解決

文字列の配列の型をいちど定義しておいてから、それをrefに割り当てることでエラーが収まった
(これで良いのだろうか)

```ts
<script setup lang="ts">

const stringArray: string[] = [];
const fruits = ref(stringArray)

fruits.value = ["Apple"]
fruits.value.push("Banana")
</script>

```


# チャットメンバー募集


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

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


# Twitter

https://twitter.com/YumaInaura
MeCabとNEologdで形態素解析できるようにする【Mac】

## 概要
MeCabとは、オープンソースの形態素解析エンジンです。そして、その性能を大きく左右するのが辞書です。

今回は、MeCabのインストールからmecab-ipadic-NEologd (インスタ映え、鬼滅の刃など最新の単語情報が載っている辞書)をデフォルト辞書に設定する方法をまとめました。

おそらく全て書いてあるのは他にないです。

2022年11月現在の情報です。
少し長いですが、基本的にコピペで完了できます。




## MeCabのインストール

HomebrewでMecabをインストールします。
```
brew install mecab
```

次にMeCabのためのIPA辞書をインストールする必要があります。
```
brew install mecab-ipadic
```

### MeCabとPythonの紐付け
```
pip install mecab-python3
```

インストールが完了したら、以下を実行し、エラーがなければOKです。
```
python3 -c "import MeCab"
```

### 形態素解析を試す
```
echo 'インスタ映え' | mecab
```
とりあえず試したい人はそのままコピペしてください。
```
(出力内容)

インスタ    名詞,一般,*,*,*,*,*
映え  名詞,一般,*,*,*,*,映え,ハエ,ハエ
EOS
```

## 最新の辞書 mecab-ipadic-NEologdを使う

mecab-ipadic-NEologdとは、MeCab用の辞書で毎週2回更新されるため新語や固有表現に強い辞書です。

### インストール
下の3つをコマンドで打ちます。
```
git clone --depth 1 https://github.com/neologd/mecab-ipadic-neologd.git
```
```
cd mecab-ipadic-neologd
```
```
./bin/install-mecab-ipadic-neologd -n
```
以下でインストール先を確認します。
```
echo `mecab-config --dicdir`"/mecab-ipadic-neologd"
```
インストール先のPathは、例えば　`/opt/homebrew/lib/mecab/dic/mecab-ipadic-neologd`
と出力されます。このPathは次で使います。

### 形態素解析を試す

-dオプションで辞書をし指定し解析します。 
{}の部分はコピペではなく、各自変更する必要があります。
```
echo 'インスタ映え' | mecab -d { 先ほどのインストール先のPath }
```
{ 先ほどのインストール先のPath } の部分には `/opt/homebrew/lib/mecab/dic/mecab-ipadic-neologd` などが入ります。

```
(出力内容)
インスタ映え  名詞,固有名詞,一般,*,*,*,インスタ映え,インスタハエ,インスタハエ
EOS
```

### MeCabのデフォルト辞書に設定

まずmecabrcがどこにあるか探します。
```
mecab-config --sysconfdir
```

すると、`/opt/homebrew/etc`などが出力されます。

このPathからたどって、mecabrcを開きます。
どんなエディタでも編集できればいいですが、僕は
```
cd {mecabrcのある場所. /opt/homebrew/etc など}
```
で移動してから、`code .`でVSCodeを開いて編集しました。

```
# 書き換えるところ 6行目あたり
# 変更前
dicdir =  /opt/homebrew/lib/mecab/dic/ipadic

# 変更後
dicdir =  /opt/homebrew/lib/mecab/dic/mecab-ipadic-neologd
```

これで完了です。
以下のコマンドで試してみましょう。
```
echo 'インスタ映え' | mecab
```
すると、以下のように出力されるはずです。

```
(出力内容)
インスタ映え  名詞,固有名詞,一般,*,*,*,インスタ映え,インスタハエ,インスタハエ
EOS
```

## 終わりに
ずいぶん前に投稿しようと思っていたけど忘れてた、、もったいないので載せておきます。

## 参考記事

[MeCabのデフォルト辞書を変更する【Mac】](https://qiita.com/shimajiroxyz/items/e488e9b28a56e908e7cb)

[MacにMeCabとNEologdをインストールして、形態素解析する](https://zenn.dev/sinozu/articles/44f58dddb25c03f8f05e)

[MacにMeCabを利用できる環境を整える](https://qiita.com/paulxll/items/72a2bea9b1d1486ca751)

[neologd/mecab-ipadic-neologd (GitHub)](https://github.com/neologd/mecab-ipadic-neologd)
AccessのVBAでOSに設定されているプリンター名一覧を取得

# やり方

```vb:サンプルコード
Dim printer_ As Printer

For Each printer_ In Application.Printers
    
    Debug.Print printer_.DeviceName
    
Next
```

例えばOSに設定されているプリンターが下記の場合…
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/21355836-5927-515d-2d7e-cf94bdce39a0.png)

サンプルコードの結果は下記。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/e72f3fab-93b8-a222-4280-efce2a2ed088.png)

# バージョン

Windows 10 Pro 22H2 OSビルド 19045.2604
Microsoft Access for Microsoft 365 MSO (バージョン 2212 ビルド 16.0.16026.20002) 32 ビット
Concrete CMS 用 S3 バケット IAM Policy サンプル


Concrete CMS でファイルマネージャーの中のファイルを、EC2 の EBS や EFS の中では無く、安価な S3 の中に格納できるという、[S3 Storage](https://marketplace.concretecms.com/marketplace/addons/storage-for-amazon-s3) というアドオンがあります。

EBS には Concrete CMS のコードなど最小限のファイルを設置し、ファイルマネージャーは、無制限な S3 を使う方法です。

サーバーを冗長化させる時も有効です。（別途 CloudFront で別(サブ)ドメインでアクセスできるようにする必要あり。）

## 注意事項

2024/2/1 時点の情報

* EC2 の IAM Role は速度が激遅になるので、IAM User の Access Key & Secret での接続をお願いします。
* PutObjectAcl があるのは昔の名残で、必要。いつかは改修予定。
    * ACL のバケットオーナーの、 **リスト・書き込みを共にオン** に設定をお願いします。
    * ブロックパブリックアクセスは **オフ** に設定してください。 (前述の ACL が無効化されるため。)


## IAM Policy サンプル

そのアドオンを使って S3 にあげる際の IAM ポリシーサンプルです。以下のポリシーを IAM User にアタッチしてあげてください。

```
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "ListObjectsInBucket",
            "Effect": "Allow",
            "Action": [
                "s3:ListBucket"
            ],
            "Resource": [
                "arn:aws:s3:::【S3バケット名】"
            ]
        },
        {
            "Sid": "AllObjectActions",
            "Effect": "Allow",
            "Action": [
                "s3:*Object",
                "s3:PutObjectAcl",
                "s3:GetBucketLocation"
            ],
            "Resource": [
                "arn:aws:s3:::【S3バケット名】/*"
            ]
        }
    ]
}
```

`【S3バケット名】` をS3バケット名に置き換えてください。

最初のグループは、S3 バケットの ARN だけですが、2つ目のグループには、S3 バケットの ARN の次に `/*` (スラッシュとアスタリスク)をつける必要があります。
Rails7でDaisyUIを使ったアプリ作成の環境構築

## ■ DaisyUIとは

DaisyUIは、Vue.js、React、Alpine.jsのためのオープンソースのUIコンポーネントライブラリです。DaisyUIは、簡単にカスタマイズできるデザインシステムを提供し、アプリケーションの開発を迅速化することを目的としています。

DaisyUIには、ボタン、カード、フォーム、アラート、モーダルなど、Webアプリケーションでよく使用されるUIコンポーネントが含まれています。また、カラーパレットやフォントファミリーの設定などのデザインシステムを提供することで、開発者がコンポーネントのスタイリングを簡単にカスタマイズできるようにしています。

DaisyUIは、無料で利用でき、さまざまなプロジェクトで使用されています。Vue.js、React、Alpine.jsのいずれかのフレームワークを使用している開発者は、DaisyUIを利用して、簡単かつ迅速にWebアプリケーションの開発を進めることができます。

## ■プロジェクトを作成する

```ruby
rails new myapp -j esbuild --css tailwind
```

新しくRailsプロジェクトを作ります。このとき `-j` と `--css` を指定します。`esbuild` はインストールしておく必要はなく `rails new` でプロジェクト作成中にインストールされます。

ちなみに、-j オプションを指定しない時にimportmapがデフォルトでインストールされるので、確実に指定が必要です。

```ruby
bundle install
```

忘れずにbundle installしてください。筆者はm1Macで開発→本番はRenderで実装予定なので、linux環境でもgemが動いてくれるよう下記コマンドを実行しておきます。

<aside>
💡 `bundle lock --add-platform x86_64-linux`

</aside>

## ■yarnでDaisyUIをインストールする

```ruby
$ yarn add daisyui
```

<aside>
💡 yarn add v1.22.19
[1/4] 🔍  Resolving packages...
[2/4] 🚚  Fetching packages...
[3/4] 🔗  Linking dependencies...
[4/4] 🔨  Building fresh packages...
success Saved lockfile.
success Saved 8 new dependencies.
info Direct dependencies
└─ daisyui@2.50.1
info All dependencies
├─ color-convert@2.0.1
├─ color-string@1.9.1
├─ color@4.2.3
├─ css-selector-tokenizer@0.8.0
├─ daisyui@2.50.1
├─ fastparse@1.1.2
├─ is-arrayish@0.3.2
└─ simple-swizzle@0.2.2
✨  Done in 0.93s.

</aside>

うまくインストールできました。

次にtailwind.config.jsにプラグイン情報を追記します。

```ruby
module.exports = {
  content: [
  .
  .
  .
  ],
  plugins: [require("daisyui")]<= この行を追記
}
```

あとは適当なビューとコントローラーを作成してrootページにDaisyUIが反映されるか確認します。

![スクリーンショット 2023-02-16 18.08.08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3092884/e092bf27-4656-e24d-825e-26e335aa3d14.png)


ここまででデプロイしてJavaScriptの動作確認するのが良いかと思います。
paizaラーニング レベルアップ問題集 二分探索メニュー応用編 JavaScript カードゲーム (paizaランク S 相当)


カードゲーム (paizaランク S 相当)

https://paiza.jp/works/mondai/binary_search_advanced/binary_search_advanced__card_game

# 考え方

好きな順番でカードを出せるので、好きな順にソートできる。
考えやすいように、paizaの手札を小さい順にソートする。

xで二分探索をする。
仮にx=midとして、ゲームをしてみる。

自分のカードの一次関数はx=midを代入し計算して整数値にしておく。
考えやすいように、自分の手札を小さい順にソートする。

ゲームにできるだけ勝つ方法。 
自分のカードを小さい順に見ていく。
相手のカードも小さい方から順に比較する。相手の見ているカードのインデックスを変数posとする。
今見ている自分のカードが、相手のカードより大きければ、勝ち。
勝ったら、相手の次に小さいカードと、自分の次に小さいカードを比較する。
負けたら、相手のカードはそのままに、自分の次に小さいカードを比較する。
これを繰り返す。
このやり方だと、posの値がそのまま自分の得点になっている。

ゲームが終了したら、勝敗判定をする。
自分の得点が過半数N/2得点を超えれば勝ち。
それ以下なら負け。

以上、二分探索が終わったら、xの最小値rightを出力する。

# 解答例(C++の場合参考)
考え方に沿って実装。
```javascript
const fs = require("fs");
const input = fs.readFileSync("/dev/stdin", "utf-8").trim();
const lines = input.split("\n");

const [N] = lines[0].split(" ").map(Number);
//自分のカードA,B paizaくんのカードC
const [A, B, C] = [[], [], []];
for (let i = 0; i < N; i++) {
  [A[i], B[i], C[i]] = lines[i + 1].split(" ").map(Number);
}
//好きな順番でカードを出せるので、考えやすいように昇順ソート
C.sort((a, b) => a - b);

//xについて二分探索
let [left, right] = [-1000000001, 1000000001];//条件より1 ≦ A_i, B_i, C_i ≦ 1,000,000,000 = 10^9なので

while (right - left > 1) {
  const mid = Math.trunc((right + left) / 2);

  //自分のカードについて
  const myCards = [];
  for (let i = 0; i < N; i++) {
    myCards[i] = A[i] * mid + B[i];//一次関数を計算しておく
  }
  myCards.sort((a, b) => a - b);//考えやすいように昇順ソート
  
  //ゲーム開始
  //自分がが出すカードについて順番に見ていく
  //paizaのカードと先頭から比べていく
  let pos = 0;//見ているpaizaのカードのインデックス
  for (let i = 0; i < N; i++) {
    //勝ち
    if (myCards[i] > C[pos]) { //自分のカード＞paiza君のカード
      pos++;//paiza君のカードの次を見る=posの値が自分の得点
    }
  }
  
  //ゲーム終了後、勝敗判定
  //自分が勝ったら、x小さくできる
  if (pos > N / 2) { //自分の得点posが過半数N/2を取れば勝ち
    right = mid;   
  //自分が負けか、引き分けだったら、x大きくする  
  } else {
    left = mid;
  } 
}
//勝ちなのでright出力
console.log(right);
```

# 解答例(pythonの場合参考)
xについて二分探索関数を定義して実装。
```javascript
const fs = require("fs");
const input = fs.readFileSync("/dev/stdin", "utf-8").trim();
const lines = input.split("\n");

const [N] = lines[0].split(" ").map(Number);

const [A, B, C] = [[], [], []];
for (let i = 0; i < N; i++) {
  [A[i], B[i], C[i]] = lines[i + 1].split(" ").map(Number);
}
//あらかじめソートしておく
C.sort((a, b) => a - b);

//xについて二分探索関数を定義
//自分が勝った時は true, paiza 君が勝った時は flase を返す
const check = x => {
  //ab : x の時の自分の整数
  const ab = [];
  for (let i = 0; i < N; i++) {
    ab.push(A[i] * x + B[i]);
  }
  ab.sort((a, b) => a - b);//考えやすいように昇順ソート
  
  let pos = 0;//見ている相手のカードのインデックス
  //自分がが出すカードについて順番に見ていく
  //paizaのカードと先頭から比べていく
  for (let i = 0; i < N; i++) {   
    if (ab[i] > C[pos]) { //勝ち
      pos++;//paizaのカードの次を見る＝見ていたpaizaカードを消す=自分の得点
    }
  }
  
  //ゲーム終了後、勝敗判定
  //自分の半分以上のカードがpaiza君が持っている c の配列のカードより大きい => 自分の勝利
  if (pos > N / 2) { //自分が勝ったら、x小さくできる
    return true;   
  } else { //自分が負けか、引き分けだったら、x大きくする  
    return false;
  } 
};

let [left, right] = [-1000000001, 1000000001];
while (right - left > 1) {
  const mid = Math.trunc((right + left) / 2);
  //ゲーム開始
  if (check(mid)) {
    right = mid;
  } else {
    left = mid;
  }
}
//勝ちなのでright出力
console.log(right);
```
SvelteKit  + Azure Static Web Apps + Azure Blob Storage で "Expected signal to be an instanceof AbortSignal" エラー

# はじめに

SvelteKit は Azure Static Web Apps へのデプロイが簡単にできてとても便利です。

https://qiita.com/fsd-tetsu/items/151a5bc49c8b8acefb04

また、ブラウザから直接 Azure Blob Storage にファイルをアップロードすることも可能です。

https://qiita.com/fsd-tetsu/items/3a76ad8c8b611c78ef31

ですが、`Azure Static Web Apps へのデプロイ` と `Azure Blob Storage にファイルアップロード` を組み合わせたとき、思わぬエラーに遭遇しました。

```:エラーメッセージ
TypeError: Expected signal to be an instanceof AbortSignal
```

どうやら `ContainerClient` の `create()` を実行すると発生するようです。

# 原因

エラー発生箇所は以下です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2773745/be6fbfbb-0a2d-6266-d025-fe976bfa7213.png)

`proto.constructor.name` が `"AbordSignal"` という名前に一致していないためこのエラーが発生していました。

原因は、以下に記載されているように `node-fetch` の問題のようです。

https://github.com/node-fetch/node-fetch/issues/784

# 対策

https://zenn.dev/merutin/articles/0a69e136a746e1

を参考にするとバンドラーの設定でクラス名を変更しないようにすればよさそうです。
しかし、このサイトでは webpack を例にしていますが、SvelteKit は vite を使っています。
どうすればよいものか、、、

<details><summary>追記：一応、同様の設定ができることを確認しましたが、結果は変わらずでした。。。</summary>

参考: https://ja.vitejs.dev/config/build-options.html#build-terseroptions

```:ターミナル
npm i -D terser
```

```diff_javascript:vite.config.js
import { sveltekit } from '@sveltejs/kit/vite';

/** @type {import('vite').UserConfig} */
const config = {
	plugins: [sveltekit()],
	test: {
		include: ['src/**/*.{test,spec}.{js,ts}']
	},
+	build: {
+		minify: 'terser',
+		terserOptions: {
+			// https://github.com/webpack-contrib/terser-webpack-plugin#terseroptions
+			mangle: false,
+			sourceMap: true,
+			// compress: false,
+			// for airtable
+			keep_classnames: /AbortSignal/,
+			keep_fnames: /AbortSignal/,
+			output: {
+				beautify: true,
+				indent_level: 1
+			}
+		}
+	}
};

export default config;
```

</details>

# 強引案

とりあえず `proto.constructor.name` の値を正としちゃいます。正しいかどうかは分かりません。:joy:

`proto.constructor.name` の値は `AbortSignal2` でした。というわけで書換用のスクリプトを作成。

```bash:replace.sh
#!/bin/sh
cat ./build/server/sk_render/index.js | sed 's/return !!(proto && proto.constructor.name === "AbortSignal");/return !!(proto \&\& proto.constructor.name === "AbortSignal2");/g' > temp
mv temp ./build/server/sk_render/index.js
```

build スクリプトの修正

```diff:package.json
	"scripts": {
		"dev": "vite dev",
-		"build": "vite build",
+		"build": "vite build && /bin/sh ./replace.sh",
		"preview": "vite preview",
```

# 結果

とりあえずエラーは発生しなくなりました。

# まとめ

対策が強引すぎて使えないですね。。。
もっと良い方法を知ってたら是非教えてほしいです。:smiley:
チーム開発で失敗しない！プルリクエストの注意点

# はじめに
はじめまして株式会社ナイトレイの渡辺です。
この記事では、実際に弊社の開発チームが実践しているプルリクエスト（PR）を発行する際に気を付けるべきことをまとめてみました。あくまで我々のチームで意識していることですが、何かのお役に立てればと思っています。

# **1. PRの目的を明確にする**

PRを発行する前にその目的を明確にします。目的が明確でない場合、他のチームメンバーがPRをレビューする際に混乱することがあります。
PRのタイトルに気を配ったり、説明欄を詳細に書くなどして、目的を明確にメンバーに伝えるようにします。

# **2. コードレビューを受け入れる姿勢を持つ**

PRを発行する際はコードレビューを受け入れる姿勢を持つようにします。チームメンバーからのフィードバックを素直に受け入れ、改善点を反映することでプロジェクトの品質を向上させることにつながります。フィードバックに対して感謝の気持ちを忘れないように気をつけます。

# **3. コミットメッセージに気を配る**

コミットメッセージが分かりやすく、意味のあるものであることで、チームメンバーがコードを追跡しやすくなります。

以下は、わかりやすいコミットメッセージにするためのアイデアです。
- 簡潔で明確なメッセージを書く
- メッセージの先頭にキーワードを置く
- 複数の変更がある場合はコミットを分けて書く
- メッセージに参照するチケット番号を含める


# **4. PRを発行するタイミングを考慮する**

一日に複数のPRを発行すると、チームメンバーが混乱することがあります。たとえば、一日に複数のPRを発行すると、他のチームメンバーがPRを追跡するのに混乱することがあります。また、一つのPRに多数の変更を含めてしまうと、チームメンバーがレビューに多くの時間を費やすことになります。このため、PRを発行するタイミングは、変更の規模や内容を考慮し、適切に決定する必要があります。


# **5. PRの説明欄を詳細に書く**

PRの説明が詳細であると、チームメンバーが理解しやすく、PRの品質が向上することが期待できます。説明には、何を変更したか、どのような理由で変更したのか、変更したコードの詳細などを含めるようにします。

# **6. 不必要な変更を避ける**

不必要な変更が含まれている場合、チームメンバーがPRをレビューする際に混乱することがあります。また、不必要な変更が含まれていると、プルリクエストのレビューにかかる時間が増えるため、開発の効率が悪化することがあります。

# **7. コード規約に従う**

PRを発行する際は、コード規約に従うことが望ましいです。コード規約に従うことで、チームメンバーがコードを理解しやすくなり、コードの品質が向上することが期待できます。

# **8. タスク管理ツールとの連携**

PRに対応するタスクがある場合は、タスクの詳細をPRの説明に含めることで、チームメンバーがタスクの進捗状況を把握しやすくなります。

# **まとめ**

プルリクエスト（PR）を発行する際には、上記のような点に気を配ることが重要です。これらの注意点を守り、品質の高いコードを開発することが目指されます。また、チーム開発においては、コミュニケーションを密にすることが重要であるため、PRの発行はその一つの手段として活用することが望ましいです！


# 最後に
私たちの会社、ナイトレイでは一緒に自社開発のWebサービスを盛り上げてくれるエンジニアメンバーを募集しています！ 
基本的には直接ユーザーと接することのないポジションですが、セールス部門から
「顧客の声」を教えてもらったり、希望すればユーザーとのMTGに参加することも可能です。
モチベーションの高め方はあなた次第。

このような方は是非Wantedlyからお気軽にご連絡ください（もしくはこちらまで recruit@nightley.jp ）

 ✔︎ 自社Webサービスの開発で事業の発展に携わってみたい
 ✔︎ 自分が開発したサービスで地域活性化に貢献したい
 ✔︎ 位置情報ビッグデータに興味があり、新しい活用方法を提案したい
 ✔︎ 地理や地図が好きで仕事中も眺めていたい 

一つでも当てはまる方は是非こちらの記事をご覧ください 
「受託開発一切なし！自社WEBサービスを社長やセールスチームと一緒に開発！」

 https://www.wantedly.com/projects/467606 

▼ナイトレイとは？

https://www.wantedly.com/companies/nightley
AccessのVBAで全レポートのプリンター名を取得

# 概要

Accessファイル内の全レポートを動的にリストアップ。
そして、各レポートに設定されているプリンター名を取得したい。

プリンター名とは下記に設定されている値。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/8629213f-37eb-8129-ddcb-7440e2c02f0e.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/0dc1bdce-2402-b376-72a3-aa6e5f70a678.png)
 ↓ これ。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/0998c541-0c60-c4f0-9870-59c16e69deef.png)

# やり方

```vb:サンプルコード
'この変数の型をReportにするとFor Eachで例外になってしまうのでやむなくこの型。
Dim rpt_ As AccessObject

'Accessファイル内の全レポート走査。
For Each rpt_ In CurrentProject.AllReports

    'レポートを開いておかないとReports()で例外になる。
    'デザインモードのレポートが一瞬表示されないようにacHidden。
    DoCmd.OpenReport rpt_.Name, acViewDesign, , , acHidden
    
    'レポートオブジェクト用意。
    Dim report_ As Report
    Set report_ = Reports(rpt_.Name)
    
    '名前と設定されているプリンター名表示。
    Debug.Print rpt_.Name
    Debug.Print report_.Printer.DeviceName
    
    'レポート閉じる。
    '意図しない上書きが起きないようにacSaveNoで保存せず閉じる。
    DoCmd.Close acReport, rpt_.Name, acSaveNo
    
Next
```

例えばプリンターが下記で…
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/25728a84-8a0e-e88f-c932-d5e49b1e343a.png)

レポートが下記の場合…
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/67f7a66b-3ae3-2c35-82fa-03c5ee3ca9bf.png)
アニスフィアはhonyaっていう固定プリンター設定。

ユフィリアは下記のように通常使うプリンター設定。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/41e3b41b-36cd-3d1b-1394-3bee292a210e.png)

結果は下記。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/414e0e64-55df-04d4-23bc-eb00de680771.png)

『通常使うプリンター設定』の場合もプリンター名が取得できる。
（OSで設定されている通常使うプリンター名になる）

# 参考サイトさん

https://qiita.com/waokitsune/items/23f24121fddfd816aaa1

https://learn.microsoft.com/ja-jp/office/vba/api/access.docmd.openreport

https://learn.microsoft.com/ja-jp/office/vba/api/access.acwindowmode

https://learn.microsoft.com/ja-jp/office/vba/api/access.docmd.close

https://learn.microsoft.com/ja-jp/office/vba/api/access.acclosesave

# バージョン

Windows 10 Pro 22H2 OSビルド 19045.2604
Microsoft Access for Microsoft 365 MSO (バージョン 2212 ビルド 16.0.16026.20002) 32 ビット
mysql5.7でjson用カラムをdataclassesで形式を固定する

# 背景
* mysql5.7 DBにjson形式でデータを保存する
* backendだけで処理じゃなくて、aws lambdaも処理するので、保存されるjsonの形式を管理したい


# 対策
* dataclassesでjson形式を固定する
* dataclasses-jsonよりコンバートする
    * request -> dict -> dataclass -> json -> DB
    * DB -> json -> dataclass -> dict -> response


# dataclasses-json紹介
* https://pypi.org/project/dataclasses-json/
* [Pythonのdataclassをdictやjsonと相互に変換する方法を解説！](https://1kara-hajimeru.com/2021/02/1691/#dataclass%E3%82%92dict%E3%81%AB%E5%A4%89%E6%8F%9B%E3%81%99%E3%82%8B%E6%96%B9%E6%B3%95)

# 対応
## dataclasses
```python
from dataclasses import dataclass
from dataclasses_json import dataclass_json

@dataclass_json
@dataclass
class Metrics:
  param1: float
  param2: float

@dataclass_json
@dataclass
class Info:
  name: str
  metrics: Metrics
```

## jsonに変更
```python
metrics = Metrics(1.0, 2.0)
info = Info("test", metrics)
json = info.to_json()
```


## dictに戻る
```python
   info = asdict(Info.from_json(json_info))
```
Pythonで32bitfloatのwavファイルを再生する

# Pythonで32bitfloatのWAVファイルが再生したい

## 結果
結論から言うと出来ました！ただ動作確認したのはLinuxからのみです。

## ハイレゾ音源を再生したい

ZOOM社が販売しているフィールドレコーダー及びマイクトラックシリーズは32bitfloat機と呼ばれており、ゲイン調整無しで録音できます。しかしながら、これらの機種が使用している、超ハイレゾフォーマット（192kHz、32bitフロートのWAVファイル）への対応状況は様々です。音楽用の編集環境であるDAWはほぼ対応しているので編集作業は問題ないのですが、これをPythonからでも再生したりしたいので今回調べてみました。

よく使われるPythonのサウンドモジュールは、16bitまでは再生できるのですが、32bitとなると再生できない場合が多かったです。
pydub等色々試してみましたが音量がおかしくなりほぼダメでしたｗ（そのうち直るかも）

そんな中、紆余曲折しいろいろなモジュールを試してみた中で一番手軽に使える方法がわかったので記事にしました。


## sounddeviceとsoundfileを組み合わせる

必要なパッケージは次のとおりです。
```Python3:必要なインポート
import sounddevice as sd
import soundfile as sf
```

ポイントとしては多くのファイル形式の読み込みに対応したsoundfileを使うことです。
このモジュールはかなり多彩なフォーマットをnumpyの行列に変換してくれます。
というわけで、簡単な再生関数は次の通り

## 32bitfloatで記録されたWAVファイル再生する


```Python3:32bitフロート音源を読み込んで音を再生する関数

def playback(f):
    data, fs = sf.read(f, dtype='float32')
    sd.play(data, fs)
    status = sd.wait()

```

たったこれだけで実現できました。24bitや32bitのWAVファイルが再生できます。

ZOOM社の32bitフロート機を持っている人などは是非ご活用ください。

## おまけ（再生する場所を指定する方法）

`soundfile`で読み込まれた`data`は`numpy.ndarray`になっているので再生する区間を指定する場合はこれをスライスで取り出すことが出来ます。ただし、サンプリングレートはファイルによって違うので秒数で指定する場合は少し計算する必要が有ります。
下の例は`seconds`を指定した場合にファイルの先頭からその部分まで切り出しているデモです。

```Python:再生区間を指定する方法
# 切り出す長さをmsecで表す
msec = seconds * 1000

data, fs = sf.read(f, dtype='float32')
# msec辺りのサンプリングレートに変換する
mfs = fs // 1000

# 最初のseconds秒のみ抜き出し
pdata = data[0:msec*mfs]

sd.play(pdata, fs)
status = sd.wait()
```

`msec`に変換しているのは、細かい位置指定をする場合に対応するためです。
実際に使用した元の関数内では`seconds`は整数を想定されている部分なので、そのまま書いていますが、そこに小数を入れるとエラーになりますので注意です。
一秒以下まで指定する場合は`msec`を使って指定すれば細かく再生位置を指定することができます。
Pythonでお手軽MultiSet！

# はじめに
python勢が一度はぶつかるmultiset、、、

もう何も怖くない！！


# 背景
https://twitter.com/reatoretch/status/1497570398502027264

# 実装
BinaryIndexTree（BIT）を基に実装。

- self.List
    - Setに格納される予定のある、重複のない値のリスト
- self.size
    - self.Listの長さ
- self.length
    - multisetの要素数
- self.tree
    - BIT用のリスト、値の個数が入る
- self.kvlist
    - 値をself.ListのIndexに変換する辞書（座圧とも呼ばれる）、1-Indexed

※Setに入る**値の種類**が分かっている前提でのみ使用可能。

```python
class MultiSet:
    def __init__(self, List):
        self.List   = sorted(set(List))
        self.size   = len(self.List)
        self.length = 0
        self.tree   = [0] * (self.size + 1)
        self.kvlist = {j:i+1 for i,j in enumerate(self.List)}
 
    def add(self, i, x):
        i = self.kvlist[i]
        self.length += x
        while i <= self.size:
            self.tree[i] += x
            i += i & -i
            
    def bisect_left(self, w):
        if w <= 0:return 0
        x=0;r=1;n=self.size
        while r<n: r = r<<1
        while r>0:
            if x+r < n and self.tree[x+r] < w:
                w-=self.tree[x+r]
                x+=r
            r>>=1
        return x
    
    def __getitem__(self, w):
        return self.List[self.bisect_left(w)]
 
    def __len__(self):
        return self.length
```

# 使用方法

リストの長さをNとしたときO(log N)で値の**追加**、**削除**、**参照**が可能。
```python
List = [7,3,3,5,5,5,1]
ms = MultiSet(List)

for v in List:
    # vを1個追加
    ms.add(v,1)

print([ms[i]for i in range(1, ms.size+1)]) # [1, 3, 3, 5, 5, 5, 7]

for v in List:
    # vを1個削除
    ms.add(v,-1)

print([ms[i]for i in range(1, ms.size+1)]) # []
```


## 応用編

二分探索したいとき
```python
from bisect import bisect_left

List = [7,3,3,5,5,5,1]
ms = MultiSet(List)

for v in List:
    # vを1個追加
    ms.add(v,1)

print(bisect_left(ms,5)) # 4 (1-indexed)
```

簡単！

# 検証

## ABC241 D問題

1165ms (2s制限)

https://atcoder.jp/contests/abc241/submissions/38918850


```python
Q = int(input())
List = []
QueryList = []
for _ in range(Q):
    QueryList += list(map(int,input().split())),
    if QueryList[-1][0] == 1:
      List += QueryList[-1][1],
 
from bisect import bisect_right, bisect_left
 
# 番兵
ms = MultiSet(List + [float('inf')])
ms.add(float('inf'),1)
 
for i,*q in QueryList:
  if i==1:
    x, = q
    ms.add(x,1)
  elif i==2:
    if len(ms)==1:print(-1);continue
    x,k = q
    idx = bisect_right(ms,x) - 1
    print([-1,ms[idx-k+1]][0 < idx-k+1 < len(ms)])
  else:
    if len(ms)==1:print(-1);continue
    x,k = q
    idx = bisect_left(ms,x)
    idx += idx==0
    print([-1,ms[idx+k-1]][0 < idx+k-1 < len(ms)])
```

`0 < hogehoge < len(ms)`は1-indexedなのと番兵除外のため


# 参考記事
##### BITの実装

https://ikatakos.com/pot/programming_algorithm/dynamic_programming/inversion

##### BITでの二分探索

https://algo-logic.info/binary-indexed-tree/
StorageGatewayとS3でファイル共有するための設定方法

# 概要
StorageGatewayでS3をベースにファイル共有を実現する方法をまとめる


# 構成概要
+ パブリックサブネットにEC2とStorageGatewayが配置されている
+ StorageGatewayはInternetGateway経由でS3に接続する
※StorageGatewayをPrivateサブネットに配置してVPCゲートウェイ経由でS3へ接続したいがやり方がわからない
※StorageGatewayはPublicサブネットにしか作成できない?

![StorageGatewayとS3でファイル共有.drawio (2).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/423287/004d0ce0-d752-c843-654f-6da215ca8015.png)

# 前提
+ VPCは作成されている
  + VPC内にInternetGatewayが設定されており、インターネット向けにルート設定されている
+ EC2は作成されている
  + Storage Gatewayを配置する同一サブネット内にEC2インスタンスが作成されている

# S3設定
### バケット作成
Amazon S3>バケット>バケットを作成

##### バケット作成画面
+ バケット名：任意のバケット名を入力
+ AWSリージョン：任意のAWSリージョンを選択

### ゲートウェイ作成
Storage Gateway > ゲートウェイ > ゲートウェイを作成

##### 「ゲートウェイをセットアップ」画面
+ 以下の項目を設定し 「次へ」ボタンを押下する
  + ゲートウェイ名：任意のゲートウェイ名を入力
  + ゲートウェイタイプ：Amazon S3 ファイルゲートウェイ
  + プラットフォームオプション：Amazon EC2
  + 仮想プライベートクラウド (VPC) ネットワーク：StorageGatewayを配置するVPCを選択
  + VPC サブネット：StorageGatewayを配置するサブネットを選択
  + キーペア：任意のキーペアを選択
  + 「インスタンスの起動」ボタンを押下する
EC2インスタンスが起動される。(少し時間がかかる)

##### 「AWSに接続」画面

+ 以下を設定し「次へ」ボタンを押下する
  + 接続オプション：IPアドレス
  + エンドポイントのオプション：パブリックアクセス可能

##### 「確認およびアクティブ化」画面
+ 「次へ」ボタンを押下する

### ローカルキャッシュストレージの作成
+ Storage Gateway > ゲートウェイ > 作成したStorageGateway
+ アクション > キャッシュストレージの設定

##### 「キャッシュストレージの設定」画面
+ ディスクIDの「割り当て済み」で「キャッシュ」を選択し、「変更を保存」

### ファイル共有設定
Storage Gateway > ファイル共有 > ファイル共有の作成

##### 「ファイル共有の作成」画面
+ 以下を選択し「ファイル共有の作成」
  + ゲートウェイ：作成したゲートウェイを選択する
  + ファイル共有タイプ：NFS
  + S3バケット：作成したS3バケットを選択

# EC2設定

### マウント設定
+ ディレクトリを作成する
```
mkdir testSTGW
```
+ 作成したディレクトリにマウントする
```
mount -t nfs -o nolock,hard x.x.x.x:/xxxxxxxxxx testSTGW
```
AccessのVBAでレポート一覧取得

# やり方

```vb:レポート名一覧確認サンプル
Dim report_ As AccessObject
For Each report_ In CurrentProject.AllReports
    Debug.Print report_.Name
Next
```

例えば下記のような場合…
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/a2217875-a829-8a96-e68e-b4a5d1dad253.png)

サンプルコードの結果は下記。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/251708e9-c3c3-6087-d6d9-51d586febc92.png)

# Report型が使えない

『Report』っていう型があるので、For Each内はこれで受けようと思った。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/ee5c9b3d-fff6-7e88-a807-13952737223f.png)

でも下記のように例外になってしまう。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/26a83768-e644-6a7c-0819-3a4ca8204f38.png)

理由が分からなかったのでAccessObjectで受けてる。

# バージョン

Windows 10 Pro 22H2 OSビルド 19045.2604
Microsoft Access for Microsoft 365 MSO (バージョン 2212 ビルド 16.0.16026.20002) 32 ビット
書評：Pythonでできる！ 株価データ分析

# Pythonでできる！ 株価データ分析 を読みました

![Pythonでできる！ 株価データ分析](https://www.morikita.co.jp/storage/images/cvr/085711cvr.jpg)
投資については基本的にはインデックスか、流行りのロボ・アドバイザーで自動化しているので自ら学ぶ機会はなかったが、株式投資への再入門のつもりで読んでみた。

# どんな人にお勧めか

1. 株式投資をしたことはないがプログラムが書ける人
1. プログラムは書けないが株式投資をしたことがある人

# どんな本か

株式投資のデータ分析入門書といった感じですね。

# なるほどと思ったこと

株価情報の取得からグラフの作成まで、数ステップで簡単にできるようになっている。 
今はこんなにも簡単に株価分析の資料を作ることができるのかと、浦島太郎でした。
エクセルでもできなくはないが、圧倒的に低コストでできるのが素晴らしい。

# 概要

株価の分析方法とPythonの使い方について紹介されている。
株式投資については初心者向けで、基本的な知識や投資戦略などが詳しく解説されており、初心者には理解しやすくなっている。
ただし、詳細な投資戦略の説明や解説、市況の変化に対する対応策については掲載されておらず、熟練者には物足りない内容になっているかもしれない。
Pythonについても同様に初心者向けで、Pythonの基礎的な使い方から実際のプログラミングの方法までが解説されている。
Pythonの特徴である可読性の高いコードやPythonに特化したライブラリやフレームワークについても解説されており、株価分析アプリを開発したい人にもお勧めだ。主に株価のテクニカル分析について中心に書かれている。

# これが書かれていたらよかった

ファンダメンタルズについて触りの部分でも書いてあればよかった。