OmniAICreator/Qiita-1.07M huggingface dataset:
AWSを初めて触る人必見！！　実際に構築してわかる！AWS勉強法

みなさんこんにちはびび丸です。
今回はAWSを勉強してみたいけど何からやればいいかわからない、そんな人に読んでほしい記事です。

僕もAWSについて何も知らない状態からこの方法でスタートし、無事AWS資格を取得することができました！

# 読んでほしい人
* AWSって聞いたことあるけどどんなサービスか知らない
* どんなものかある程度は知っているが使い方がわからない
* AWS認定資格を取りたいけどその前に基礎を実際に手を動かして学びたい
* なんでもいいからIT系の知識を学んでみたい

上記のようなAWSを学びたいけど全く触ったことのない人、またAWSとは何かを知りたい人に読んでもらいたいです！
# 本題
もったいぶってもしょうがないので結論から書いちゃうと

<font color="Red">**Udemyでハンズオン動画を視聴しながら一緒にAWSを触ってみる**</font>

です。
# ハンズオンって何
ここでハンズオンとは何ぞや？ってなる方もいらっしゃるので説明しておきます。

ハンズオンとは受け身として何かを学ぶのではなく、実際に手を動かして自分でシステムを作っていく勉強法のことです。
例えば今回紹介するAWSに関して言えば実際にサービスを使用してサーバーを立てたり、ファイルをアップロードしたり、実際の業務よりははるかに単純ですがやることは本質的には同じです。
# 頭に残りやすい
ハンズオンの利点として、実際に手を自分で動かしているので頭にとても残りやすいです。動画だけをみて、他人が動かしてるのを見るより自分の頭で考えて実施するほうが当然ですが頭に残りやすいです。

# Udemyとは
Udemyとは色々な分野について学ぶことができる学習サイトです。
講義動画からハンズオン動画、ひいては模擬試験まで販売されており、何かを学ぶには最高の場だといえます。

https://www.udemy.com/

# なぜUdemyか
最近ではYouTubeにもハンズオン動画があふれていますが、僕はあえてUdemyをおすすめします。
もちろんYouTubeのハンズオンはその大半が無料です。
ですがYouTbeのハンズオン動画の中には(個人の意見ですが)素人が作成したものもいくつかあり、初めてAWSをさわる人には優しいものばかりとは言えません。

ですが、**その点Udemyの講座はプロが作っており、またターゲット層もしっかりターゲティングされており、初心者向けのものを購入すればしっかり誰でも理解できるもの**となっています。やはり、お金が発生する以上、きちんと品質も担保されています。

# セールの時に買えば高くない
Udemyでは定期的にセールが行われており、(体感2週間に1回くらい)その時の割引額がものすごいです。
だいたい2000～3000円あればほとんどの講座は購入できます。

# AWS初心者におすすめの講座
UdemyでAWSハンズオンなどで検索すると色々な講義が出てきますがここで僕がAWSを初めてさわる人にぜひおススメしたい講座を一つご紹介します。

それは僕の一番最初に投稿した記事でも紹介した、AWSの基礎を学びつつ、Wordpressを実際に構築することができる「**AWS：ゼロから実践するAmazon Web Services。手を動かしながらインフラの基礎を習得**」という講座です。
(参考までに僕はセールの時に**1300円**ほどで購入しました)

https://www.udemy.com/course/aws-and-infra/?utm_source=adwords&utm_medium=udemyads&utm_campaign=LongTail_la.JA_cc.JP&campaigntype=Search&portfolio=Japan&language=JP&product=Course&test=&audience=DSA&topic=&priority=&utm_content=deal4584&utm_term=_._ag_107181210924_._ad_452531407125_._kw__._de_c_._dm__._pl__._ti_dsa-930814700879_._li_1009311_._pd__._&matchtype=&gad_source=1&gclid=CjwKCAjwl4yyBhAgEiwADSEjeIYEpNzbbkvnGVj0fDbmGM2Ec_xzn225Q8E3XK2TMAXUvXCKD_K21RoC6k8QAvD_BwE&couponCode=LEADERSALE24B

# どんな講座か
この講座の内容ですが、「AWS上でブログサイトであるWordpressを自分で作成する」、といった内容になっています。
またただWordpressを作成するだけでなく、それに付随してAWSの基礎的なサービスを複数学べたり、またインフラにつての基礎知識も学べて、まさに最初に触れるには最高の講座だと思っています。

# 講座学習後
もし、すべての講座を視聴し、ハンズオンを経てAWSに興味が出てきたらぜひ、資格の取得を目指しましょう！
僕は先ほど紹介した講座の終了4日後にAWSの一番基礎的な資格である、**AWS Certified Cloud Practitioner**を取得しました。
このハンズオン講義で使用したサービスについての問題も複数あり、また資格勉強中にも「あっここ講座で出てきたな」のようにすでにある知識と結びつけることによって学習スピードがただ受け身の勉強の時より、速くなります。
# 最後に
AWSのようなクラウドという技術はとてもおもしろく、日々進化しています。そのサービスのプロにならずともその根幹部分を知っておく、というのはどのような業種・業界で仕事をしていても無駄になる、ということは絶対にないと思うのでぜひ少しでも興味をもった方がいらっしゃれば、実際にサービスを使用してみて学んでみてください！
ここまで読んでくださり、ありがとうございました！
Azure Blob StorageとAzure Data Lake Storage Gen2の違い

## はじめに
こんにちは。<br>

いつもは別のクラウド製品上でDWH開発をしているので、その際に纏まっていたら助かると思った仕様の違いを纏めました。

***
整理したいストレージサービスはこの2つ。
* Azure Blob Storage
* Azure Data Lake Storage Gen2<br>
Azure Data Lake Storage Gen1は2024年2月に廃止。
https://learn.microsoft.com/en-us/answers/questions/281107/retirement-announcement-azure-data-lake-storage-ge<br>



## 特徴

関係性のイメージとしてはADLS Gen2 = Azure Blob Storage + ADLS Gen1。
#### Blob Storage：
　ADLS Gen2と比較して安い。仕組みがシンプル。
 　Azureで長く使われているサービスのため、ほかの製品や外部サービスのIF先として接続設定が提供されている可能性が高く、間口が広い（のではないかと個人的に思う）。
#### ADLS Gen2：
　蓄積したデータを扱う際の操作性が良い。
　ディレクトリ単位で操作が可能なことにより、分析ユースケースでのストレージと取得のパフォーマンスが向上し、分析コストが削減可能。<br>
削減イメージとして、例えば同じ量のデータを格納しているストレージに対してBlobは広範囲をスキャンしに行く。それに対しADLS Gen2はパーティション設計するなどして特定の範囲をスキャンしてデータを取得しに行くことができるため、スキャン量を抑えることができる。![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3632589/ea579cdd-dd88-48c3-8123-ef8c0e136a56.png)



上記のように、使いようによってはコストがBlob >  ADLS Gen2になることもあるため用途に適した選定を行う必要がある。

## 採用シナリオ

#### Blob Storage：
初期の頃から提供されているサービス。複雑な設計は対応できない。例えば大量の非構造化データを効率的に保存および管理する目的向け。<br>
＜具体的な採用例＞
　インタフェース領域用
　画像やドキュメントを直接ブラウザに配信する用
 　バックアップと復元、障害復旧、アーカイブのためのデータの保存用
#### ADLS Gen2：
Blob Storageを基に作成された後発サービス。ストレージ機能 + ビッグ データ分析専用の一連の機能を備えている。設計の柔軟性が高く、蓄積層に採用するのはこちらがお勧め。<br>
＜具体的な採用例＞
　モダンなDWHの構築用
 　ビッグデータに対する高度な分析用
　リアルタイム分析ソリューションの構築用


## 特に気になった仕様

#### 階層構造が構成できるか否か

Blob Storage：構成不可
ADLS Gen2：構成可能

フォルダとファイルのように、階層構造を取ることがADLS Gen2は可能だが、Blob Storageはフラットファイル構造のみの提供で構成出来ない。ただし、Blob Storageも疑似的に階層型名前空間を表現できる。これはあくまで階層型で表現されていそうに見せているだけであって実態はフラットな（≒階層構造ではない）状態で保持している。<br>処理を実装する場合の操作イメージが異なるので、設計時は注意したい。

※ この記事が分かり易い。
https://azure.github.io/jpazpaas/2023/11/08/difference-between-flat-and-hierarchical-namespaces.html<br>


## さいごに
執筆中にAzureアカウントの無料クレジットが切れました…追記していきたいので、また今度機会があれば。

## 参考
https://azure.github.io/jpazpaas/2023/11/08/difference-between-flat-and-hierarchical-namespaces.html
https://medium.com/awesome-azure/azure-difference-between-azure-blob-storage-and-azure-data-lake-storage-comparison-azure-blob-vs-adls-gen2-81af5ef2a6e1
https://learn.microsoft.com/ja-jp/azure/storage/blobs/create-data-lake-storage-account
https://learn.microsoft.com/ja-jp/shows/azure-friday/azure-data-lake-storage-gen2-overview
https://azure.microsoft.com/ja-jp/blog/a-closer-look-at-azure-data-lake-storage-gen2/
DataGuardについて（さまざまなサイト）

URLをコレクション

https://qiita.com/sowd/items/4214b0af896af2907417

https://docs.oracle.com/cd/F19136_01/haovw/monitor-oracle-data-guard-configuration.html#GUID-8D8C4054-7140-4025-A1CF-B9E10267B8CE

https://www.ashisuto.co.jp/db_blog/article/20160831_dataguard_sql.html

https://www.reqtc.com/blog/data-guard-managed-recovery.html
kukuluLIVEの配信ダウンロード方法

## 前書き
暇だったのでstreamlinkの標準プラグインではダウンロードできないどこかのサイトの配信をダウンロードできないかなーと思い試してみました

その結果kukuluLIVE (https://live.erinn.biz/) の配信が割と簡単にダウンロードできたので忘れる前にここに方法を書き記しておきます



## 必要ソフトウェア
この方法ではstreamlinkというソフトウェアを利用します

https://github.com/streamlink/streamlink

もしかしたらffmpeg等でも簡単にダウンロードできるかもしれませんがそこはご自由にどうぞ
また、streamlinkの他にkukuLIVEを視聴できる一般的なブラウザが必要です
## streamURLの入手
kukuluLIVEの適当な配信を開き、F12キーやctrl+shift+iでデバッグツールを開きます
その後ネットワークタブを開き検索欄にplayerと入力します

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3793870/9516cc30-46fc-378f-1bd4-615b6a157708.png)
その結果、playerという文字が含まれているサイト内のファイルが表示されるので、この例の1番上の物を右クリックします

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3793870/e03d0809-6a69-793b-a798-f6944a93ff65.png)
そうしてでてくるメニューの１番上の選択肢である、「open in sources panel」をクリックするとソースパネルでそのファイルの中身を閲覧することが出来ます

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3793870/5472d129-f518-2cd2-afd7-e180f8e155f1.png)

その後、ctrl+Fキーで「stream」と検索をかけるとこの様にstreamURLが記入されているのが確認できるのでstreamaddr_hlsの後に書かれているstreamURLをコピーします

##### これにてstreamURLの入手完了です
## 配信のダウンロード
この記事ではwindows用バイナリファイルを利用してstreamlinkをインストールした場合のコマンドを紹介します

他のインストール方法を利用した場合や別のOSを利用している場合は各自でstreamlinkの使用方法を調べて下さい

windowsキーとRキーを同時押しし
「ファイル名を指定して実行」
という画面を開きます
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3793870/9025ca7c-8851-ab65-b197-e41c7d90534e.png)
そこにcmdと入力しOKを押すことでコマンドプロンプトが開きます
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3793870/89c1d85d-17ad-b4d4-3026-6a1ea5a4cd69.png)

後はこのコマンドプロンプトに
「streamlink -o "c:/ファイルパスを入力/保存名.ts" "streamURLをここにコピー" "best"」

という風に入力した後エンターキーを押すとダウンロードが開始されます

:::note alert
###### 注意:配信が続いてる間常にダウンロードが続きます
途中で中断したくなった場合はctrl+cキーをコマンドプロンプトのウィンドウ内で押すことでその場で中断され、開始された時点から中断した時点までの配信ファイルが完成します

配信が終わった場合は恐らく勝手にダウンロードも終わると思いますが終わらなかった場合はctrl+cキーにより中断して下さい
:::

## 最後に
m3u8が拡張子の配信リンクなのでffmpegのinputに指定しても普通にダウンロードできると思いますが未検証です
Dockerを用いたReact環境の構築の備忘録

# 最初に
Dockerを用いてReact環境を作ったときの備忘録です。当方、初心者ですので厳密性などは欠きます。皆さんの助けになったらとてもうれしい気持ちです！

# 環境について
* windows
* Docker version 24.0.2
* remote-container（vscodeの拡張機能）

Macについては動作確認していません。

# ディレクトリ構成

## 最終的な構成
最初に、環境構築後のディレクトリ構成を下に示します。
```
my-react-app-test
└── Dockerfile
└── docker-compose.yml
└── app
    └── react-app
        ├── node_modules
        ├── public
        ├── src
        ├── .gitignore
        ├── package-lock.json
        ├── package.json
        └── README.md
```
## 最初の構成
```
my-react-app-test
└── Dockerfile
└── docker-compose.yml
└── app
```
最初の構成は上記のようになっています。

# Dockerfile
Dockerfileの記述は以下の通りです。
```
FROM node:16.14.2
WORKDIR /usr/src/app
```

* nodeのバージョンとして最初に定義しています。また、alpineをつけるとvscodeのdev containerでattachすることができなかったため、消しています。dev containerはalpineには使えないのか。。

* 次に、コンテナ内でどのディレクトリにおいて作業したいかをWORKDIRで決めてあげます。

# docker-compose.yml
docker-compose.ymlの記述は以下の通りです。

```
version: '3.9'
services:
  react-app:
    build:
      context: .
      dockerfile: Dockerfile
    volumes:
      - ./app:/usr/src/app
    ports:
      - "3000:3000"
    stdin_open: true 
    environment:
      - CHOKIDAR_USEPOLLING=true
    tty: true
```
ymlの記述について、environmentを上記のように設定することでホットリロードできるようにしています。しかし、バージョンによっては、package.jsonをいじる必要があるため、後で紹介します。

### docker-compose.ymlの詳細
* react-app
    * サービスの名前を決めてあげます。
* build
    * buildとしてDockerfileを用いるのでdockerfileとしています。また、同じディレクトリにいるため、直接記述して指定してあげます。また、contextについてはDockerデーモンへルートディレクトリを渡しており、今回のような場合は必要が無いと思うのですが、一応記述してあります。Dockerfileとdocker-compose.ymlが同じディレクトリではない場合にはcontext: . の記述が無いとエラーの原因になります。(未検証)
* volumes:
    * ローカルの./appとコンテナの/usr/src/appをマウントしてあげます。
* ports:
    * ローカルホストのポートを指定します。
* tty:
    * コンテナが持続するようにtty:trueとしておきます。

# 実際に走らせる
```
docker-compose run --rm react-app sh -c "npm install -g create-react-app && create-react-app react-app"
```
無事に終了したら、react-appフォルダがappの直下に追加されていると思います。

```
docker-compose up -d
```
でコンテナを動かします。一応バックグラウンドでも動くように-dを付けています。

# コンテナに入る
vscodeを開いて、remote-containerのattachの機能を使ってコンテナに入ります。コンテナへ入ることに成功したら、実際に/usr/src/app/react-appに入ります。
最後にnpm startをして問題がなければlocalhost3000へ飛ばされるので、reactのロゴがくるくる回っているのを確認すれば成功となります。

# ホットリロードについて
ホットリロードについては、package.jsonのscriptsを変更する必要があり、以下のように変更してください
```
 "start": "WATCHPACK_POLLING=true react-scripts start"
```
# 最後に
以上となります。参考になりましたら幸いです。

# 参考記事
https://zenn.dev/rihito/articles/96dfad8d4990f9

https://qiita.com/chora_8192/items/c5838a343a17ccb44d24
36日目 ECSについてまとめてみた社畜L

## 🔎はじめに
ついに僕の番が回ってきたね…  
今回はECSについてSAAの出題範囲内でまとめていこうと思う。

## 🔍ECSってなに？
DockerコンテナをAWS上で管理(運用、管理)するサービスのこと。
これだけでは全く分からないと思うので、詳しく説明していくよ。

## 🔎どう便利なの?
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3766505/3bfbb54c-f2e4-3ab9-9c1c-744913c27c20.png)

## 🔍さっきから言ってるコンテナってなに？
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3766505/101b05f2-b151-a8f7-0152-ae20536734e6.png)
上記のイメージのように実行環境をパッケージ化したもので、
コンテナでアプリの実行をするよ。

具体的に何がセット(パッケージ)になっていて、どうやって動いているのかというと…
&emsp;&emsp; ->Dockerイメージを読み取って実行する
&emsp;&emsp; ->[コード][ライブラリ][システムツール][スクリプト]などなど

## 🔎Dockerイメージってなに？
アプリケーションが実行されるために必要な環境やファイルのことで、
設定を含む静的なテンプレートを指すよ。
イメージとしてはコンテナでプログラムを実行するときの材料置き場かな。

※僕は最初勘違いしていましたが、
アプリケーションの相関関係や処理の流れを定義しているわけではないみたい。
&emsp;&emsp;->それを定義するのはコードや構成ファイル


## 👓真実はいつも１つ！（結論）
ECSをうまく活用していくことで要件にもよると思いますが、
EC2でアプリケーションを運用するよりも設定が簡単に行うことができ、
より柔軟性のあるアプリケーションを開発できるのではないでしょうか。(未経験)
主任・課長シフトがすぐに確認できるLINEBot＃入門編

# 今日は主任誰がいる？何時から？

私は、小売業で販売課長をしています。
チームメンバーは、業務の中で主任・課長からの承認や押印をもらうことが頻繁にあり、その度に「今日は主任誰がいるっけ？」「何時から出勤だっけ？」「課長は？」などの言葉が飛び交います。シフト表を見れば分かるけれど、調べるのに時間が掛かります。そこで、プログラミングもAIもよくわかっていなかった初心者マークの私が、習いたてのLINEBotで挑戦してみました。
また、プライベートでの困りごとである「睡眠時間の確保」入浴・就寝時間のお知らせにも挑戦し、まずは日常生活にデジタルを取り入れる楽しさを経験したいと思いました。

# 完成品
https://twitter.com/saakuya75/status/1791004221833384201?s=61&t=tK6QWfyS8524_YcArUZTeQ

# 使用ツール
・LINE Developers
・Make
・Google スプレッドシート

# Makeシナリオ
![スクリーンショット 2024-05-16 23.09.06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3786155/d22c9e7d-c8a4-c29f-c378-89fa9071ce37.png)

# 制作開始
## １.Googleスプレッドシートを作ろう
勤務計画をCSVデータでダウンロードし、Googleスプレッドシートに貼り付け加工します。
![スクリーンショット 2024-05-16 14.50.59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3786155/2948162f-fe8a-5631-538e-c4ee925ca00c.png)

## 2.Makeでシナリオを作ろう
いたってシンプルです。LINEでメッセージを受け取り→Googleスプレッドシートを読み取り→LINEで該当の日付のメッセージを返すイメージです。

![スクリーンショット 2024-05-16 15.19.46.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3786155/eb6dbff9-85b5-e9ba-b17a-8f96c8548fa3.png)
１.LINEモジュールはLINEDevelopersで作成したLINEアカウントと紐付け。
2.Googleモジュールはシート名を選択、フィルター設定、行数設定をします。

![スクリーンショット 2024-05-16 15.51.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3786155/95eea8a4-3450-640c-aec5-c0e0511dc2e5.png)

４.LINEモジュールに応答部分の設定をします。
５.最後に、LINEBotを永続化させる左下のSCHEDURINGを【ON】に設定すれば完成。

# 試作品
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3786155/e763a707-65d5-b42d-f1e2-d3b76cb714e2.png" width=50%>

まずは、応答確認ができました。一安心。
とてもシンプルなので、こちらに手を加えていきます。


# ステップアップに挑戦！入浴・就寝時間お知らせ機能をつけてみよう。
私は趣味が多く、「1日24時間じゃ足りない」「あれもしたい、これもしたい」というブルーハーツ状態です。加えて人員不足から仕事の拘束時間が増え、自分時間が減っています。帰宅後、ドラマも観たいし本も読みたいしSNSもチェックして〜なんてしていると気づけば深夜に。寝不足が続き、ソファや床で寝落ちすることも。「お風呂に入っておいで」「もうベッドに入ったら」なんて言ってくれるお母さん的な存在が欲しい...
そこで、日々の睡眠時間の目標を立て、入浴・就寝時間を加えました。

![スクリーンショット 2024-05-16 23.16.37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3786155/f3b12df9-a4e6-13b6-fab6-12b208ddd337.png)


私の尊敬する、田中みな実様の名言も添えて♡
みな実様は寝室にはスマホを持ち込まないそう。す、すごい、みな実様の壁は高い...

今回は仕事・プライベートで活用できるものを作成しましたが、睡眠の部分を「販促」や「連絡事項」にすると現場ですぐに活用できると思います。


# 感想
とにかく、初めて応答が返ってきた時の感動はとても大きかったです。「やったー」とバンザイし涙しました。作ってみたいものは色々あったのですが、自分の技術と時間では難しく今回は入門編ということでこちらを作成しました。タブの量が過去一になる程、たくさん調べながら成功と失敗を繰り返し完成しました。
パソコンでのスクショってどうやるの？Googleスプレッドシートって？MarkDown記法とは？と、わからないことだらけの中スタートしました。時間はすごく掛かりましたが、実際に自分で作成してみると理解が深まり、次は業務で活用できるコミュニケーションツールを作成してみたいと思います。



#### ＊リベンジしたいこと
①日付けに/を付けると返答せず、数字のみで対応。
②リマインド機能を付けたくて何度もチャレンジしたが時間切れに。
③次は他のチームの勤務計画で挑戦したいが、５０名以上と人数が多くデータ加工に時間がかかるが、もっと短時間でできる方法はないか模索中。

# 修正しました
①制作物の動画を冒頭に載せファーストインプレッションにおさめました。
②挿入画像のサイズが大きく見づらかったのでサイズを縮小しました。
③Qiitaのタグに#は不要と教えていただきました。


# 参考資料
https://qiita.com/kiku_2005/items/ac0f7762b6a26941c251

https://qiita.com/88Eqv/items/9ca66d28599b9712b9b9

https://qiita.com/tomowkrh/items/9c4a616bd1fd40e5e3b9

https://qiita.com/s053050g/items/ec57a6f0130a9c06c460



https://qiita.com/U-MA/items/996ae933ae94c5711883
UnityのProjectの起動画面が[Open Scene]で止まったときの対処法

## 何が起きたの？
昨日まで開けていたUnityプロジェクトが今朝突然開けなくなった。
何度か開き直しを試みるが、同じ箇所で止まってしまう。
![スクリーンショット 2024-05-16 170101.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/141541/77acddfa-173e-9497-1796-0624d6f56610.png)

調べても同じ現象が見当たらなかったので、簡易的だが備忘録として残しておく。

## 現象
他のプロジェクトは起動する。
Project起動中に｢Open Scene｣という箇所でプログレスバーが完全に停止して、何時間待っても動かない。


## 試したこと
- タスクキル→Projectを再度起動
- PCの再起動
- Libraryフォルダを丸ごと削除する
- 問題となっているシーンを削除する

最後試したシーンの削除で解消出来た。

## もう少し詳細
Project起動時のログもEditor.logに格納されている。
各OSでのEditor.logの格納場所は以下の通り。
| OS | パス |
|---|---|
|macOS|~/Library/Logs/Unity/Editor.log|
|Windows|C:\Users\username\AppData\Local\Unity\Editor\Editor.log|

内容を確認してみると、Opening Sceneのログを残して完全に停止している様子。
![スクリーンショット 2024-05-16 172304.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/141541/b0e05d87-c75b-d4b9-ed03-b9640fe5cdeb.png)
エラーも出ていないため、裏で何が起こっているかも把握できず…

開くことが出来ていないシーンを削除して再度プロジェクトを開くことで無事開くことが出来た。
Git管理していたので、削除差分をCheckoutするこで復帰も出来た。
詳細まで把握できず対策も出来ないため不完全燃焼だが、このような現象もあるらしいので同じ現象で困った場合に参考になれば幸いである。
gitで変更内容が別ブランチに同時反映された？！

# はじめに
最近gitでいろいろとやらかしている気がするんですが、今回はその1つを共有しておきたいと思います。

# 問題
リポジトリを編集した後に、自分が切ったすべてのブランチに内容が変更されてしまう

# 原因
<font color="red">**コミットしてなかったから**</font>
コミットせずにブランチを切り替えるとそうなるらしいです。

# 終わりに
ここまで短い記事は書いたことないかもです笑
【Unity】Meta XR SDKを入れたProjectを読み込むとエラーが発生する

# はじめに
Meta XR SDKを入れたProjectをclone後に読み込むとエラーが発生したので、エラーの解消方法を記録します。

```
An error occurred while resolving packages:
  One or more packages could not be added to the local file system:
    com.meta.xr.sdk.core: Cannot download the package. Your account does not grant permission to use the package. Please visit the Asset Store to acquire the package and add it to your account:
      Access to 'https://download.packages.unity.com/com.meta.xr.sdk.core/-/com.meta.xr.sdk.core-***.tgz' was denied
    com.meta.xr.sdk.interaction: Cannot download the package. Your account does not gr...

(For the full error message, see the editor log file located at [C:/Users/***/AppData/Local/Unity/Editor/Editor.log])


Click on Retry to relaunch Unity and reopen your project.

Click on Continue to launch Unity.  Some or all packages may not be imported which may cause compilation errors.
```

# エラー解消方法
* UnityEditorで利用しているアカウントでアセットストアにログインし、対象のアセットを購入（無料）する
* キャッシュの影響で即時パッケージをインストールできない様です、パッケージがインストールされない場合は以下の方法でキャッシュをリセットしてください。
    * UnityEditor上でアカウントのログアウト＆ログイン
    * Unity再起動
    * PC再起動
    * Libraryディレクトリの削除
    * 新規プロジェクトで対象のSDKをインポート
Google Merchant Centerで「ファイルが見つかりません」となるとき

- Google Merchant Centerでフィードの登録（商品登録）が上手くいかなかった時のトラブル事例の１つです
- 「フィード全体の問題」において「ファイルが見つかりません。」と表示されていたら、Google スプレッドシート の共有状態を確認しましょう、という話です


# 上手くいかなかった時の状態

- Google Merchant Center で商品フィードを登録していた時のこと
- 商品登録は、 `商品 > フィード > メインフィードを追加 > Google スプレッドシート` で追加した
- `商品 > フィード >  (追加したフィード) > 処理中` において、次の警告文が表示された

> フィードで登録した商品データが商品データ仕様を満たしていないため、商品は承認されませんでした。商品を顧客に表示するには、フィードを修正して更新してください。 すべての問題を確認するには、[診断] ページに移動します。

- また、同ページ（処理中）の「属性名」において「未使用（0）」「使用（0）」という状態になっていた
- 同ページ（処理中）の「フィード全体の問題」において「ファイルが見つかりません。」と表示された

- 「時間の問題か」と思い、24時間以上の様子を見たが改善されなかった
- Google スプレッドシート のフィード名が、[ヘルプ：商品データ仕様](https://support.google.com/merchants/answer/7052112)の内容と一致していなかったので、ヘルプ通りに変更してみたけど、ダメだった（例：「概要」を「商品説明」や「description」にしてみる）

![0516001.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/283603/37024cc9-977e-e217-a6a4-b6cd4e14dbeb.png)



# 回答：スプレッドシートを公開状態にしてください

- もう自力じゃダメだったので、Copilotへ聞いてみた
- 「全員に公開」となっていることを確認してください
- ......あっ！！！
- 作業しているアカウントが、公開を制限しているものだった事を思い出した
- 一般的なGoogleアカウント（無料アカウント）でフィードの登録を最初から試したところ、すんなり解決した
- Google スプレッドシート のフィード名は、デフォルトの状態で問題なかった（フィード名を変更する必要なし）

![0516002.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/283603/84143791-c079-a666-56f6-43715eb5e914.png)
Expressプロジェクトの始め方

# 概要
Expressアプリを`express-generator`を使用して作成する。
viewsは`ejs`

# 実装手順
## 前提条件
`npm`, `Node.js`, `express-generator`をインストールしていること。

## expressプロジェクトの作成
```shell
express --view=ejs HelloWorld
```
`express --view=ejs HelloWorld`でテンプレートエンジンにejsを指定して、`HelloWorld`プロジェクトを作成する。

プロジェクトディレクトリが作成されたら、そのディレクトリに移動して`npm install`を実行する。<br>
依存パッケージがインストールされる。

## 新たなルーティングの追加とviewsの追加
既存の`app.js`にルーターを定義してルーティングの追加をする。
```js app.js
var createError = require('http-errors');
var express = require('express');
var path = require('path');
var cookieParser = require('cookie-parser');
var logger = require('morgan');

var indexRouter = require('./routes/index');
var usersRouter = require('./routes/users');
var helloRouter = require('./routes/hello');  // 追加

var app = express();

// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'ejs');

app.use(logger('dev'));
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));

app.use('/', indexRouter);
app.use('/users', usersRouter);
app.use('/hello', helloRouter);  // 追加

// catch 404 and forward to error handler
app.use(function(req, res, next) {
  next(createError(404));
});

// error handler
app.use(function(err, req, res, next) {
  // set locals, only providing error in development
  res.locals.message = err.message;
  res.locals.error = req.app.get('env') === 'development' ? err : {};

  // render the error page
  res.status(err.status || 500);
  res.render('error');
});

module.exports = app;
```

つづいて、新規ファイル`hello.js`を作成する。
```js hello.js
var express = require('express')
var router = express.Router()

router.get('/', function(req, res, next) {
  res.render('hello', { title: 'hello, world.'})
})

module.exports = router
```

最後に静的ページを`views`ディレクトリに作成する。
```html hello.ejs
<!DOCTYPE html>
<html>
  <head>
    <title><%= title %></title>
  </head>
  <body>
    <h1><%= title %></h1>
  </body>
</html>
```

以上で`npm start`することで、ブラウザから`localhost:3000/hello`にアクセスするとHello,world.が表示される。

# 簡単な解説
`app.js`に追加した部分
```js app.js
// hello.jsをインポートしている。
// app.jsから呼び出せるようにしているイメージ
var helloRouter = require('./routes/hello');  // 追加

// "/hello"にアクセスされた際に、上記でインポートしたhelloRouterの処理を実行する。
app.use('/hello', helloRouter);  // 追加
```

作成した`hello.js`
```js hello.js
var express = require('express')
var router = express.Router()

// このファイルの処理が呼び出された際に、"/"にアクセスしてきた場合に実行される。
// hello.ejsをレンダ―する。
// その際に、titleに`hello, world`を格納して渡している。
router.get('/', function(req, res, next) {
  res.render('hello', { title: 'hello, world.'})
})

module.exports = router
```

最後に静的ファイル`hello.ejs`
```html hello.ejs
<!DOCTYPE html>
<html>
  <head>
    <!-- titleに格納された値をtitleとする。 -->
    <title><%= title %></title>
  </head>
  <body>
    <!-- titleに格納された値をh1タグ内に表示する。 -->
    <h1><%= title %></h1>
  </body>
</html>
```

# まとめ
なんとなく理解していたexpressプロジェクトの作成方法をまとめてみた。
ここから、typescriptの導入だったり、ログ出力、importの使用などを進めていきたい。

疑問点、ご指摘等ありましたらコメントお願いいたします。
Instagramの埋め込みを表示する方法

PCから埋め込みたい投稿にアクセスすることで、Instagramの埋め込みリンクを取得することができます（要ログイン）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3192305/21d69659-5d47-da91-7fd0-7780dcb4492f.png)

しかし、このコードを直接HTMLに貼っても以下のような表示が出て、表示されません。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3192305/59ec5d66-ebd5-682c-596c-1b89daa2f4b7.png)

埋め込みコードの最終行のscriptの読み込み先URLがよくなさそうです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3192305/7da55902-9574-8ea0-b0ff-de0fe7c82950.png)

```umekomi.html
<script async src="//www.instagram.com/embed.js"></script>
```
この部分のURLにhttps:// をつけると正常に表示されました。
```umekomi.html
<script async src="https://www.instagram.com/embed.js"></script>
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3192305/57c9b5db-b221-3fc4-999e-0e2c133142c6.png)

以上です。
Amazon S3の各バケットの使用量一覧取得シェルスクリプト

aws s3 ls でも使用量取得できるけど、オブジェクト数が多い場合にエコじゃないので違うやり方。
多分こんな感じ。
リージョンは必要に応じて追記してください。

```shell
#!/bin/sh

# 直近の値が分かれば良いので前日を指定
ymd=$(date '+%Y-%m-%d' --date '1 days ago')
start_time="${ymd}T00:00:00Z"
end_time="${ymd}T23:59:59Z"
period=86400

# 数値を人に優しくするよ
human_readable() {
  # 小数で渡ってくるので整数化
  num=$(echo $1 | awk '{printf("%d\n",$1)}')

  # 単位
  units=(B KB MB GB TB PB EB ZB YB)

  # 判定用の閾値
  thresholds=(1 1024 1048576 1073741824 1099571627776 1125899906884629 1152921504606846976 1180591620717411303424)

  # 処理
  i=1
  while [ $num -gt ${thresholds[$i]} ]; do
    i=$((i + 1))
  done
  i=$((i - 1))

  # 出力
  num=$(awk "BEGIN { print $num / ${thresholds[$i]} }")
  num_readable=$(printf "%.2f" "$num")
  echo "${num_readable}${units[$i]}"
}

# バケット名一覧取得
bucket_names=$(aws s3 ls | awk '{print $3}')

for bucket_name in ${bucket_names};
do
  # バケットごとの使用量取得
  bucket_size=$(aws cloudwatch get-metric-statistics \
  --namespace AWS/S3 \
  --metric-name BucketSizeBytes \
  --dimensions Name=BucketName,Value=${bucket_name} Name=StorageType,Value=StandardStorage \
  --statistics Sum \
  --start-time ${start_time} \
  --end-time ${end_time} \
  --period ${period} \
  --output text | awk '{printf $2}')
  bucket_size_readable=$(human_readable ${bucket_size})
  echo "s3://${bucket_name}/ size:${bucket_size_readable}"
done
```
CreateMLでマルチラベル分類をしようとしたら詰まった話

## はじめに
趣味の開発でcreateMLを用いて多ラベル分類の検証を簡単に行おうとしていましたが、データを読み込む過程でハマってしまい3時間ほど時間を溶かしてしまいました。ググっても答えがパッと見当たらなかったので、備忘として残しておきます。

CreateMLによる機械学習(画像認識)のやり方は[公式ドキュメント](https://developer.apple.com/documentation/createml/creating-an-image-classifier-model)を参照して下さい。


## 前提条件
[公式ドキュメント](https://developer.apple.com/documentation/CreateML/creating-a-multi-label-image-classifier)に準い、学習データのディレクトリ構成は以下とします。
```direct
train/
├── image1.jpg
├── image2.jpg
├── ...
└── annotations.json
```

## 問題
[公式ドキュメント](https://developer.apple.com/documentation/CreateML/creating-a-multi-label-image-classifier)においては、多ラベル分類のアノテーションファイルの形式が以下のように示されていましたが、
```json:annotations.json
[
    {
        "filename": "image1.jpg",
        "annotations": ["window_sill", "aloe", "pot"]
    },
    {
        "filename": "image2.jpg",
        "annotations": ["cactus", "pot", "person"]
    }
]
```
この形式でデータを読み込まそうとしても、以下のように`Data Analysis stopped`と表示され、データが正常に読み込まれませんでした。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/324069/4df368b9-0051-9bc6-29ab-8b55e8a68833.png)

## 対応方法
正しくは、以下のように`filename`を`image`に直すことで解決できました。
```json:annotations.json
[
    {
        "image": "image1.jpg",
        "annotations": ["window_sill", "aloe", "pot"]
    },
    {
        "image": "image2.jpg",
        "annotations": ["cactus", "pot", "person"]
    }
]
```
以上のように変更すると、正常にデータを読み込むことができました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/324069/63568717-ee09-1d92-d5d5-05eafea2a2e7.png)

## まとめ
深層学習のモデル作成はpytorchやtensorflowでやるのが現状スタンダードだとは思いますが、GUIを用いたモデル作成はお手軽で楽しいのでぜひ一度は試してみてください。その時にデータがなぜか読み込まれない等の問題が発生した際にこの記事が参考になれば幸いです。
【Docker×FastAPI×SQLAlchemy】APIサーバとスクレイピングの処理でコンテナを切り分けたかったときにしたこと

# 解決したいこと
スクレイピングアプリを実装していた。
スクレイピングの処理用のコンテナとapiサーバ用のコンテナで分けたかった。
SQLAlchemyを使っていたため、どちらの処理もmodels.pyを参照していた。

# 解決方法
DjangoとNginxを使って静的ファイルを配信する方法を調べている時に気付いたのだが、マウントして同期すればいいのではないかと考えた。

1. /backendフォルダみたいなフォルダを作成する
1. docker-compose.ymlにおいてbackendコンテナとapiコンテナを用意し、volume先としてどちらもホスト側の/backendフォルダを指定する
1. docker-compose.ymlのcommandには、backendコンテナではスクレイピングの処理を実行するスクリプト、apiコンテナではapiサーバを起動するスクリプトを書く
Arc for Windowsブラウザで日本語入力ができない不具合へのとりあえずの対処法

本記事では、先日リリースされたブラウザ「Arc for Windows」で日本語入力が機能しない場合の対応についてご紹介します。
根本的な解決法ではないので、一時的なバグ回避の小ネタとしてお試しください。

:::note info
 **【結論】** 
日本語入力がうまくいかないときは、

 - **最後に半角スペースを足す** 
 - **最後に全角スペースを打ってから消す** 

あたりで対処しましょう。
:::

※Arc for Windows v.1.1.2（2024年5月16日時点最新）にて確認しています。

---

## 前置き
かねてよりMac環境では話題になっていた新しいブラウザ「Arc」が、待望のWindows板を正式リリースしました。（現時点ではWindows11のみ対応）

https://arc.net/

GoogleChromeなどでおなじみ **Chromium** をベースとしており、これまで使っていたChromeやEdgeからブックマークや拡張機能をそのままインポートして移行することもできます。

ということで、私もさっそく使ってみました。

## 日本語入力できない問題

そして、さっそく致命的な問題がありました。

Arcでは新しいタブを開く際、 **コマンドパレット（Ctrl+T）** を使用してブックマークの選択やGoogle検索などをダイレクトに行うのが大きな特徴なわけですが...

![スクリーンショット 2024-05-16 130141.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3628125/3f0cdb7b-b16d-3773-8a95-7c0b8eea6f9d.png)

![スクリーンショット 2024-05-16 131047.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3628125/c2743d91-ed84-56f6-5db5-e088e40c0865.png)


ここで、 **日本語入力をした場合には検索がうまくいきません。** （サジェストが表示されない）

![スクリーンショット 日本語入力で検索できない](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3628125/baaf5d00-43ee-6f4c-6831-030c8ae124c9.png)

このままEnterを押すと、履歴上の見当違いなページが開いてしまいます。

ブラウザを使ううえでWeb検索はド真ん中の動作ですから、これは私たち日本語ユーザーにとって **致命的な欠陥** と言わざるを得ません。

ちなみに、同様にArcの主要機能であるタブのピン留め（Pinned）エリアにおいても、 **フォルダ名を日本語で入力すると更新できない** というバグがあるようでした。

## とりあえずの対処法

さすがにこれでは使い物にならないので色々模索していると、とりあえずのバグ回避の小ワザを発見しました。

### 1. 最後に半角スペースを足す
全角で日本語入力したあと、そのままEnterを押すのでは入力内容を認識してくれないのですが、最後に半角スペースを入れてあげるとうまくいくようです。
どうしてかはよくわかりません。

![arc-nihongo-fix1-ezgif.com-video-to-gif-converter.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3628125/312765c1-38c7-90e2-08e7-bc9e07df57e2.gif)

### 2. 最後に全角スペースを打ってから消す
半角/全角の切り替えがめんどくさい方は、全角のままスペースを入力し、それをBackSpaceで消す手順でも大丈夫そうです。
フォルダ名をリネームする際など、余計なスペースを入れたくない場合はこちらがいいかもしれませんね。

![arc-nihongo-fix2-ezgif.com-video-to-gif-converter.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3628125/fb8b9484-03c1-295d-1f9a-5667e7c7ad73.gif)

以上2パターン、入力するキー数は同じなのでお好みでどうぞ。

## まとめ

というわけで、日本語入力がうまくいかないときは、

 - **最後に半角スペースを足す** 
 - **最後に全角スペースを打ってから消す** 

あたりで対処しましょう、というお話でした。

今回の件について「もっとスマートな解決法があるぞ！」という方がいらっしゃいましたら、ぜひ教えてください。

そこまでしてArc使う意味ある？という気もしますが、でもやっぱり、タブをサイドバー形式で配置するUIやブックマーク管理の機能性、またスッキリしたデザインは非常に魅力的です。
コマンドパレットも日本語入力以外は便利で快適なんですよね。

Arc for Winsdowsはまだベータテストを明けたばかりということで、ほかにもバグと思われる細かい挙動の不具合が結構あちらこちらにあるように見えます。

今後のアップデートで少しずつ改善していくことを期待して、個人的にはもうしばらくArcブラウザに歩み寄って慣れていきたいかなと思っています。
Apache のアクセスログを CloudWatch Logs Insights で分析する

# やりたいこと

Apache のアクセスログを CloudWatch Logs Insights を使ってステータスコード毎に集計する。

# 前提

Apache のアクセスログは次の通り、CloudWatch ログに記録されているものとする。


```
127.0.0.1 - - [14/May/2024:12:57:09 +0000] "GET / HTTP/1.1" 200 5 "-" "curl/8.3.0"
```

Apache のアクセスログログを CloudWatch ログに吐き出す方法については本題ではないため、以下のページを参考にさせていただきました。

https://blog.serverworks.co.jp/cloud-watch-logs-apache-access-log-setting

# CloudWatch Logs Insights で集計する 

https://qiita.com/suuu/items/8387df88f134348f22c7#クエリ構文について

クエリ構文については以下のページを参考にさせてもらいました。

**結論**
結果としては以下のクエリとなりました。

```
parse '* - * [*] "* * *" * * * *' as host, identity, dateTimeString, httpVerb, url, protocol, statusCode, bytes,Referer,UserAgent
| stats count() as count_status by statusCode
| sort statusCode asc
```

![スクリーンショット 2024-05-16 14.48.06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/280929/c149b801-e5ab-ca7e-142e-9257a03720e5.png)

ここで 上からクエリの詳細を確認していきます。

**parse**

一時フィールドとしてデータを抜き出しています。
例えば、parse の 1行目だけを実行した結果は以下の通りです。

![スクリーンショット 2024-05-16 15.09.11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/280929/a5b0ef00-e033-b37d-3bb1-b66d5b472a88.png)

**stats**

statusCode 毎に count 関数を使って集計しています。

**sort**

statusCode を昇順にしています。
SQLでいう `ORDER BY` です。

# boto3

これではつまらないので boto3 で実装してみた。

```python
import boto3
import time

# クライアントの作成
logs_client = boto3.client('logs')

# クエリの設定
log_group_name = 'access_log'  # ロググループの名前を指定
query_string = '''
parse '* - * [*] "* * *" * * * *' as host, identity, dateTimeString, httpVerb, url, protocol, statusCode, bytes,Referer,UserAgent
| stats count() as count_status by statusCode
| sort statusCode asc
'''

# クエリの開始
response = logs_client.start_query(
    logGroupName=log_group_name,
    startTime=int((time.time() - 3600) * 1000),  # 過去1時間のログを対象とする場合
    endTime=int(time.time() * 1000),            # 現在時刻
    queryString=query_string,
    limit=1000
)

query_id = response['queryId']

# クエリの結果を取得
while True:
    response = logs_client.get_query_results(
        queryId=query_id
    )

    if response['status'] == 'Complete':
        break

    print('Waiting for query to complete...')
    time.sleep(1)  # 1秒待機してから再度チェック

# クエリ結果の出力
for result in response['results']:
    print(result)
```

結果は以下の通りです。

```
[{'field': 'statusCode', 'value': '200'}, {'field': 'count_status', 'value': '8'}]
[{'field': 'statusCode', 'value': '404'}, {'field': 'count_status', 'value': '1'}]
```
【UE5】PlayerStart のBADSIZEの消し方（備忘録）

# PlayerStart のBADSIZEの消し方
![bandicam 2024-05-16 15-00-57-289.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1940156/a0c7301a-2771-a77f-8b41-7f362f9e2458.jpeg)

単純にこの当たり判定が床にめり込んでいることでこの表示になっているっぽいです。
https://docs.unrealengine.com/4.27/ja/Basics/Actors/PlayerStart/

めり込みを解消するとBADSIZE消えます
![download.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1940156/c8d5793b-5f4c-8fde-9557-046926a4e2c1.gif)
マンハッタン距離・ユークリッド距離

## 本日覚えたこと　-マンハッタン距離・ユークリッド距離-
Pythonの練習のため、AtCoderやPaizaなどでちまちまとアルゴリズムの勉強中です。
で、問題にマンハッタン距離についての問題がありました。
というか、そもそも

**マンハッタン距離ってなんだったっけ？ユークリッドは聞いたことあるような……？**

用語がわからない超初心者の私。
ちょっと恥ずかしいと思いつつも人間だれしも最初は初心者！と開き直って調べてみました。

## 説明
点Xから点Yまでの距離のこと。
マンハッタンは直角に曲がりつつ移動した距離のこと。(ピンク）
ユークリッドは直線距離。（水色）
うむ。なるほど。なんか記憶の底から、うっすらと思い出が。中学生くらい？
ウン十年前過ぎて、もう忘却の彼方です。
ユークリッドはたしかギリシャ人。ではマンハッタンはアメリカ人？とか考えつつ。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3780076/018a4e6d-2602-b605-263a-3ea419e8489a.png)
x = [0,0]　y = [2,2]
としたら
マンハッタン距離　→　｜0 – 2｜+｜0 – 2｜ = 4 
ユークリッド距離　→　$\sqrt{2^2 + 2^2}$　=　$\sqrt{8}$
ということですな！

## コードにすることを考える
図にして、数式にしたらわかった……が。コードにするのはどうやるのじゃ？
- リストの中身を絶対値にしたい　→　abs関数というのがいけそう
- 2乗はわかる　→　**2ですな！
- ルートの書き方　→　math.sqrt　というのがあるらしい。
書いてみた
~~~python
import math

x = [0, 0]
y = [2, 2]
a = abs(x[0] - y[0])
b = abs(x[1] - y[1])

# マンハッタン
print(a+b)

# ユークリッド
print(math.sqrt(a**2 + b**2))
~~~

いや、普通に大量にデータあったらめんどくせ！ってなるやん　↓　からの
なんか**numpy**なるものがよさげ。リストのまま渡せる？のかな？
~~~python
import numpy as np

x = [0, 0]
y = [2, 2]

manhattan = np.sum(np.abs(x - y))
euclidean = np.linalg.norm(x - y)

print(manhattan)
print(euclidean)
~~~
動かん……
<font color="Red">TypeError: unsupported operand type(s) for -: 'list' and 'list'</font>
なんのことでしょう？

調べた結果、numpy用の配列に入れないとダメだったことが判明。
~~~python
x = np.array(x)
t = np.array(y)
~~~

## わかったこと
<font color="Red">**ライブラリってすげえ**</font>


ついでに、ユークリッドさんの本名（？）が気になって調べてみた。
**Εὐκλείδης**
ギリシャ語でGoogle翻訳から音声出してみたけど、エウクレイデス　とかには全然聞こえない。「エフキーリーヴィス」（フは下唇を噛んでる感じの）って聞こえるような。外国の人に聞いたら誰やねんってなるヤツですね。

#### 参考URL

https://kentei.ai/blog/archives/606

https://ja.wikipedia.org/wiki/%E3%82%A8%E3%82%A6%E3%82%AF%E3%83%AC%E3%82%A4%E3%83%87%E3%82%B9
RDS AuroraMySQL の VolumeBytesUsed の削減

データベースには2GBくらいしかデータが入っていないのに VolumeBytesUsed が130GBもあったため、調査＆解消したので、メモを残します

## 結論
```
OPTIMIZE TABLE <テーブル名>
```
上記コマンドを実行し、VolumeBytesUsedが削減された

## なぜ VolumeBytesUsed に記録されているデータ容量より多く表示されていたか
VolumeBytesUsed には、記録されているデータ容量以外に、フラグメンテーションによる開放されていないストレージ容量を含んでいる

## データの開放余地のあるデータ容量を確認する方法
データベース名：information_schema
テーブル名：tables
の data_free の項目に未開放の容量が記録されている
以下のコマンドで確認可能
```
SELECT 
    table_schema AS `Database`,
    table_name AS `Table`,
    ROUND(data_free / 1024 / 1024 / 1024, 2) AS `Data_Free_GB`,
    ROUND((data_length + index_length) / 1024 / 1024 / 1024, 2) AS `Data_Used_GB`
FROM 
    information_schema.tables
WHERE
    table_schema NOT IN ('mysql', 'information_schema', 'performance_schema', 'sys')
ORDER BY 
    data_free DESC
```

## OPTIMIZE TABLE <テーブル名> に関して
data_free が 130GB もあったので時間がかかるかと思ったが、1秒もかからなかった
このコマンドは、テーブルのロックが入るようで、実行は慎重に行う必要がある
ペインドリブンではじめるFigmaプラグイン開発

デザイナーがFigmaプラグインをつくってみた！という内容です。
選択したフレーム群を、命名規則のもと自動的にリネームする機能を開発しました。

https://www.figma.com/community/plugin/1270021574725531926/name-layers

## なぜFigmaプラグイン？

自分でやってみて、デザイナーがJavaScriptに入門するならFigmaプラグイン開発はおすすめなのではと思いました。
- 自身が一番のユーザーであり、確かなペインがある
- ゴールを単一機能の実現に絞れる
- UIで触っているものをコードからも触るので、既知である

## 動機

JSフレームワークを理解したく、そのためにJavaScriptを学びたい。だけど入門書を読むと、概念理解が追いつかず途中で詰まってしまう。つまり書かないと進めない、でも書けない、困った…。
という状況からなかなか抜けられませんでした。

でもある時なにげなく[Figma Plugin APIの公式ドキュメント](https://www.figma.com/plugin-docs/)を眺めたら、部分的に分かるところがありました。小さな可能性の発見！つまみ読みしてきた入門書も役に立っているのです。
ChatGPTを傍らに、具体的に書いてみようと思い立ちました。

## ゴール設定

取り扱うペインを以下にしました。

**「Auto layoutのためにレイヤー名を管理するのは面倒だ :-( 」**
- レイアウト都合で変動するフレーム名は儚い存在
- 繰り返し打ち込む同じ綴り
- 一度名付けはじめると、整っていないと気持ちわるい

いにしえのPhotoshop時代を思い出す作業が苦痛でした。機能名はFigmaのコンポーネントとして定義するのでよく。それ以外の「header, main, sub, container, item, row, col, label...」をなんとかできないか。

セマンティックな名前は内容を踏まえる必要があるけど、レイアウトならレイヤー構成やAuto layoutの設定からパターン化できそうです。

## レイアウトパターンの定義

[レイアウトプリミティブ](https://every-layout.dev/)やTailwind CSSを念頭に置きつつ、次のようなパターンとしました。

- wrapper：画面デザインの外枠
- container：最大幅がありセンタリングされたフレーム
- grid：3つ以上の同幅アイテムをもつフレーム
- cell：gridの子フレーム
- center：単一アイテムをセンタリングするフレーム
- row：横並びのAuto layout
- col：rowの子フレーム
- wrap：折り返しのAuto layout
- stack：縦積みのAuto layout

## 処理の流れ

1. `figma.currentPage.selection` で選択ノードから、`FrameNode` を取り出す。選択ノードに子がある場合は `findAllWithCriteria()` でサブツリー内からも取り出す
1. ユーザーが命名（命名規則で定めた名前以外）した `FrameNode` は対象から外す
1. 対象ノードを順に条件と照らし合わせて、名前を上書きする

いたってシンプルなコードとなりました。

https://github.com/minoshintaro/name-layers

## 開発してみて

JavaScriptを分からないなりにも、実現したい処理を切り分けてChatGPTに問い掛ければ、なんとかなるものだと思いました。自分がやりたいことを具体的なコードで示してくれるので分かりやすいし、とにかく書いてみる、ができるようになりました。

ちなみにプラグインを公開すると、毎週Figmaからコミュニティレポートが届きます。「Getting a lot of love」という見出しとともに、ユーザーが何人増えたよ、などを教えてくれます。自分と同じFigmaユーザーが、世界のどこかで使ってくれているのだと思うと、とてもうれしい！

コードを書くのって楽しいですね。
Google Apps Scriptによるスプレッドシート連携の使い分け

今更ですが気になったので調べてみました。

Google Apps Scriptを使用して特定のスプレッドシートからデータを取得する場合、以下の2つの方法があります。それぞれの使い分けについて説明します。

1. **独立したGoogle Apps Scriptプロジェクトとして作成**
2. **特定のスプレッドシートにバインドされたGoogle Apps Scriptとして作成**

### 1. 独立したGoogle Apps Scriptプロジェクトとして作成

#### メリット
- 複数のスプレッドシートに対して共通のスクリプトを使用できる
- スプレッドシートに依存せず、他のGoogleサービスとも連携しやすい

#### デメリット
- 特定のスプレッドシートにバインドされていないため、各スプレッドシートへのアクセス権限を明示的に設定する必要がある
- 設定やデプロイが少し複雑になることがある


#### 手順
1. **Google Apps Scriptエディタにアクセス**: [Google Apps Script](https://script.google.com)からアクセスし、新しいプロジェクトを作成します
2. **スクリプトの作成**: コードをエディタに貼り付けます
3. **デプロイ**: 「デプロイ」 -> 「新しいデプロイ」 -> 「ウェブアプリ」を選択し、必要なアクセス権限を設定してデプロイします

### 2. 特定のスプレッドシートにバインドされたGoogle Apps Scriptとして作成

#### メリット
- スプレッドシートに直接バインドされるため、アクセス権限の設定が簡単
- スプレッドシートに関連する操作がスムーズに行える

#### デメリット
- そのスプレッドシートにしか使用できない
- スプレッドシートの依存度が高くなる

#### 手順
1. **スプレッドシートの作成**: Google Sheetsで新しいスプレッドシートを作成します
2. **スクリプトエディタの開き方**: スプレッドシートを開いた状態で「拡張機能」 -> 「Apps Script」を選択します
3. **スクリプトの作成**: コードをエディタに貼り付けます

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/782507/a9c7dc8e-42a0-df86-9442-0715884d6196.png)


#### コード例
```javascript
function doGet(e) {
  const requiredParams = ['sheetName'];

  // パラメータの検証
  for (const param of requiredParams) {
    if (!e.parameter[param]) {
      return ContentService.createTextOutput(`必要なパラメータが不足しています: ${param}`)
        .setMimeType(ContentService.MimeType.TEXT);
    }
  }

  const sheetName = e.parameter.sheetName;

  try {
    const spreadsheet = SpreadsheetApp.getActiveSpreadsheet();
    const sheet = spreadsheet.getSheetByName(sheetName);

    if (!sheet) {
      throw new Error('指定されたシートが見つかりません');
    }

    const data = sheet.getDataRange().getValues();
    return ContentService.createTextOutput(JSON.stringify(data))
      .setMimeType(ContentService.MimeType.JSON);
  } catch (error) {
    return ContentService.createTextOutput(`エラーが発生しました: ${error.message}`)
      .setMimeType(ContentService.MimeType.TEXT);
  }
}
```
このコードは、特定のスプレッドシートにバインドされたスクリプト用で調整されています。`spreadsheetId`パラメータが不要で、`SpreadsheetApp.getActiveSpreadsheet()`を使用して現在のスプレッドシートにアクセスします。

### 使い分けのイメージ
- **複数のスプレッドシートに対して共通のスクリプトを使用したい場合**: 独立したGoogle Apps Scriptプロジェクトとして作成し、スプレッドシートIDをクエリパラメータとして渡します
- **特定のスプレッドシートにのみ使用する場合**: 特定のスプレッドシートにバインドされたGoogle Apps Scriptとして作成します。これにより、簡単にアクセス権限を設定し、スプレッドシートの操作がシンプルになります

### デプロイと実行
どちらの方法でも、スクリプトを作成した後にデプロイする必要があります。デプロイ時には適切な権限を設定し、ウェブアプリとして公開します。これにより、指定したURLを使用してスクリプトを実行し、スプレッドシートからデータを取得することができます。
VBA3

Function ReadCSV(ByVal filePath As String) As Variant
    Dim fso As Object
    Dim ts As Object
    Dim content As String
    Dim lines() As String
    Dim lineCount As Long
    Dim i As Long
    
    ' Create FileSystemObject
    Set fso = CreateObject("Scripting.FileSystemObject")
    ' Open the file with Shift-JIS encoding
    Set ts = fso.OpenTextFile(filePath, 1, False, -1)
    
    ' Count the number of lines in the file
    lineCount = 0
    Do While Not ts.AtEndOfStream
        ts.ReadLine
        lineCount = lineCount + 1
    Loop
    
    ' Close and reopen the file to reset the position
    ts.Close
    Set ts = fso.OpenTextFile(filePath, 1, False, -1)
    
    ' Read the file content line by line
    ReDim lines(1 To lineCount)
    For i = 1 To lineCount
        lines(i) = ts.ReadLine
    Next i
    
    ' Close the file
    ts.Close
    
    ReadCSV = lines
End Function
Databricks にて json 形式の文字型の列から値を抽出する SQL の備忘録

## 概要

Databricks にて json 形式の文字型の列から値を抽出する SQL の備忘として残します。


## 検証コードと実行結果

### json 形式の文字型の列をもつ一時ビューを作成

```sql
%sql
CREATE OR REPLACE TEMPORARY VIEW tmp_json_string AS 
SELECT
1 AS id,
'{
  "item_01":"abc",
  "Item_02":"123",
  "dict_01": {
      "item_in_dict_01":"efg",
      "item_in_dict_02":"hij",
      "item_in_dict_03":123
  },
  "list_01": [
    "list_01",
    "list_02"
  ],
  "dict_in_list_01": [
    {"dict_01" : "abc"},
    {"dict_02" : "123"}
  ]
}' as json_string_col
;
SELECT * FROM tmp_json_string;
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24031/ebf397df-16f2-ab3d-6574-673956f58abd.png)


###  json 形式の文字型の列から値を抽出する SQL を実行

```sql
%sql
SELECT
  id,
  -- 最上位レベル列を取得
  json_string_col :item_01,
  json_string_col :['Item_02'],
  json_string_col :`Item_02`,
  -- 入れ子になったフィールドを抽出す
  json_string_col :dict_01 :item_in_dict_01,
  -- 配列から値を抽出
  json_string_col :list_01 [0],
  json_string_col :dict_in_list_01 [0] ['dict_01']
FROM
  tmp_json_string;
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24031/28bd8478-a6ba-86f9-d7be-0a3043ae353f.png)
ポータルサイトにおいて、重複判定ページを削減してクロールバジェットを節約する施策

## パラメ付きの重複判定ページのURLを寄せる施策を実施しました

今回テクニカルSEOの施策を実施したサイトはこちら
https://tas-reno.com/

### Googleサーチコンソールにおける重複判定

googleサーチコンソールにおいて、重複ページ（同じコンテンツで別URL）はなるべく減らした方が良いです。
大規模サイトの場合、その分クロール割り当てを消化してしまうので、ソフト404と並んで対策しておきたいところです。

▼Googleが提唱しているクロール割り当ての意識が必要なサイト定義
大規模（重複のないページが 100 万以上）で、コンテンツが中程度に（1 週間に 1 回）更新されるサイト
中規模以上（重複のないページが 1 万以上）で、コンテンツがかなり頻繁に（毎日）更新されるサイト
Search Console で URL の大部分が検出- インデックス未登録に分類されるサイト

引用　
https://developers.google.com/search/docs/crawling-indexing/large-site-managing-crawl-budget?hl=ja#manage_inventory


### 今回重複判定をもらっていたURL

サイト上の一部検索結果において、パラメ付きの同一コンテンツで別のURLが複数発生してしまっていました。
すべて1URL1コンテンツに寄せる必要があります。
URLを寄せる際に、考慮したい観点としては、
* URLを極力短くできるか
* 開発が実装しやすいか
* パンくずなど他のサイト上のURLの変更漏れはないか

あたりです。
今回は開発が実装しやすい形式のURLに寄せることとしました。

## 結果

結果としては、重複判定のURLを減らすことができ、クロールバジェットの節約に成功しました。
明確に順位が向上したなどの結果は目に見えてはないですが、クロールの制御はテクニカルSEOの土台であるため、対策しておくに越したことはありません。
肌感ですが、割り当ての量にも寄るとは思うのですが、重複判定を一度くらっているからかクロールされきるまで1か月程度はかかった印象です。
クロール効率もあまりよくなさそうなので、極力発生しないようなサイトにしておきたいですね。
画面を開くたびに、ログイン認証におけるトークンの有効期限確認は、フロントエンドとバックエンドのどちらでやるべきか

# フロントエンドでの確認
## 利点
・ユーザー体験が向上する
　→即時にフィードバックを提供できるため
・サーバーの負荷が軽減される
　→サーバーとの通信が不要になるため

## 欠点
・セキュリティリスクが高い
　→トークンの有効期限情報がクライアント側に存在するため、改ざんのリスクがある
 
・正確性に欠ける可能性がある
　→クライアントの時計が不正確な場合など

# バックエンドとの通信での確認
## 利点
・セキュリティが強化される
　→トークンの有効期限情報はサーバー側で管理され、改ざんのリスクが低い
・トークンの正確な状態を常に把握できる
　→サーバー側で一元管理されるため
 
## 欠点
・サーバーの負荷が増加する
　→クライアントごとに頻繁に通信が発生するため
・レスポンス時間が長くなる可能性がある
　→通信に時間がかかるため

# ChatGPTの見解
バックエンドとの通信で確認する方法が一般的に推奨されます。 
理由としては、「セキュリティ強化」！

具体的な実装方法としては以下のようなアプローチがあります：
## ①APIリクエスト時にトークンを検証
・クライアントからの各リクエストにトークンを添付し、バックエンドでその都度トークンを検証します。
・トークンが無効（例：期限切れ、改ざんなど）の場合、バックエンドは適切なエラーレスポンスを返します。

## ②定期的なトークン検証
・クライアント側で一定の時間ごとにバックエンドへトークンの有効性を確認するリクエストを送信します。
・トークンが有効であれば新しいトークンを発行する（リフレッシュトークンを使用する方法も含む）。

# セキュリティ強化のための追加対策
・HTTPSを使用して通信内容を暗号化する。
・リフレッシュトークンを使用し、アクセストークンの有効期限を短く設定する。
・CORS設定を適切に行い、不正なアクセスを防ぐ。
・CSRFトークンを使用し、クロスサイトリクエストフォージェリ攻撃を防ぐ。
Databricks に to_json 関数を利用した際に NULL のカラムを保持する方法


## 概要

Databricks では to_json 関数を利用する際には NULL のカラムを保持する方法を共有します。to_json 関数を実行する際には`ignoreNullFields`オプション（デフォルト値が`true`）の設定により NULL のカラムは喪失するため、NULL のカラムを保持したい場合には、`ignoreNullFields`オプションを`false`に設定する必要があります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24031/38e4c7bc-a97e-01f8-cf42-25faa9525585.png)

引用元：[JSON Files - Spark 3.5.1 Documentation (apache.org)](https://spark.apache.org/docs/latest/sql-data-sources-json.html)

`ignoreNullFields`オプションは、Spark Conf の`spark.sql.jsonGenerator.ignoreNullFields`の値に依存し、`spark.sql.jsonGenerator.ignoreNullFields`のデフォルトが`true`であるため、`ignoreNullFields`オプションのデフォルト値が`true`となります。

```python
spark.conf.get("spark.sql.jsonGenerator.ignoreNullFields")
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24031/112281ff-26a4-f12b-123c-262d55cfa698.png)

引用元：[Configuration - Spark 3.5.1 Documentation (apache.org)](https://spark.apache.org/docs/latest/configuration.html)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24031/36500898-dd49-8e44-ca57-86ba8aecf58b.png)

Spark Dataframe 操作にて json 形式で書きこむ場合にも同様の事象が発生するため、下記のように Spark Conf を設定することで NULL のカラムを保持できます。

```python
spark.conf.set("spark.sql.jsonGenerator.ignoreNullFields", "false")
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24031/47292a76-fe56-1ddd-3d1d-963e9c11fc7d.png)

## 検証コードと実行結果

### 一時テーブルを作成

```sql
%sql
CREATE OR REPLACE TEMPORARY VIEW tmp_struct_tbl
AS
SELECT
  from_json(
      '{
        "int_col": 0,
        "str_col": "abc",
        "null_col": null
      }',
      'int_col int,
      str_col STRING,
      null_col STRING'
    )
   as struct_col
;
SELECT * FROM tmp_struct_tbl;
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24031/9c7e7c69-cb0f-8b9a-dcb5-7d749cf734ab.png)

### デフォルトの状態で`null_col`カラムが喪失することを確認

```sql
%sql
SELECT
  to_json(
    struct_col
  ) as json_str_col
FROM
  tmp_struct_tbl
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24031/1ebccbac-810e-869b-fb70-b9c729e33563.png)

### `ignoreNullFields`オプションを`false`に設定して`null_col`カラムが保持されているを確認


```sql
%sql
SELECT
  to_json(
    struct_col,
    map('ignoreNullFields', 'false')
  ) as json_str_col
FROM
  tmp_struct_tbl
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24031/88ad9276-144d-e74b-6e7f-95b8898845a3.png)
継続渡しスタイル（CPS）を理解する：フィボナッチ数列の実装を通じて

# はじめに
Continuation-Passing Style (CPS)は、関数型プログラミングや非同期プログラミングにおいて重要な概念です。CPSを理解することで、複雑な計算や非同期処理の制御が容易になります。この記事では、CPSの基本概念から具体的な例、そしてCPSを活用するメリットまで説明します。

# CPSとは何か
CPS（継続渡しスタイル）は、関数の戻り値を直接返すのではなく、「継続」と呼ばれる別の関数に渡すスタイルです。継続は、関数が計算を完了した後に何をすべきかを定義します。これにより、関数の実行が完了した後の処理を明示的に制御できます。

# 実装例
### 通常の再帰的実装

```js
// 通常の関数呼び出しでは、計算の結果が直接戻り値として返されます。
function add(a, b) {
  return a + b;
}

const result = add(2, 3);
console.log(result); // 5
```

### CPSによる実装

```js
// CPSでは、計算結果は継続に渡されます。
function addCPS(a, b, cont) {
  cont(a + b);
}

addCPS(2, 3, result => console.log(result)); // 5
```

## 基本的なCPSの例
CPSの基本的な例として、加算と乗算の関数を見ていきます。

### 加算のCPS
```js
function addCPS(a, b, cont) {
  cont(a + b);
}

addCPS(2, 3, result => console.log(result)); // 5
```
### 乗算のCPS
```js
function multiplyCPS(a, b, cont) {
  cont(a * b);
}

multiplyCPS(2, 3, result => console.log(result)); // 6
```
これらの関数では、計算結果を継続（cont）に渡すことで処理を進めています。

# フィボナッチ数列のCPSによる実装
CPSの概念を使ってフィボナッチ数列を計算する関数を実装してみます。

### 通常の再帰的実装
```js
function fib(n) {
  if (n === 0) return 0;
  if (n === 1) return 1;
  return fib(n - 1) + fib(n - 2);
}

console.log(fib(10)); // 55
```
### CPSによる実装
```ts
type NS = (n: number) => number;
type CPS = (n: number) => (k: NS | CPS) => number;

// fibCPS に n を渡し、最終的に結果を受け取るために恒等関数 x => x を渡します。
const fib: NS = n => 
  fibCPS(n)(x => x);

// n が 0 なら ret(0) を返し、1 なら ret(1) を返します。
// それ以外の場合、fibCPS(n - 1) の結果を a とし、さらに fibCPS(n - 2) の結果を b として、
// ret(a + b) を呼び出します。
const fibCPS: CPS = n => {
  return n === 0
    ? ret(0)
    : n === 1
    ? ret(1)
    : fibCPS(n - 1)
        (a => fibCPS(n - 2)
           (b => ret(a + b))
        );
}

// ret は、与えられた値 x を継続 k に渡します。これにより、計算が次のステップに進みます。
const ret: CPS = x => k => 
  k(x);

// 使用例：
// fib(40) を呼び出すと、fibCPS(40)(x => x) が実行され、フィボナッチ数列の第40項が計算されます。
// fibCPS は再帰的に呼び出され、最終的な結果が ret 関数によって継続に渡されます。
console.log(fib(40)); // 102334155
```
この実装では、計算結果が次の継続に渡されることで、計算の流れが継続的に進行します。

# CPSの利点
### 非同期処理の容易な実装
CPSは非同期処理の実装において特に有用です。非同期処理の結果を次の継続に渡すことで、コールバック地獄（callback hell）を避け、コードをより直感的に書くことができます。

### コントロールフローの明示的な管理
CPSでは、関数の実行が完了した後の処理を継続関数として渡すため、コントロールフローを明示的に管理できます。これにより、複雑な処理やエラーハンドリングが容易になります。

### 再帰の最適化
CPSは再帰の最適化にも役立ちます。再帰的な関数呼び出しを継続として表現することで、スタックオーバーフローのリスクを軽減し、効率的な再帰処理が可能になります。

# まとめ
CPS（継続渡しスタイル）は、関数の戻り値を直接返すのではなく、継続関数に渡すスタイルです。これにより、非同期処理や複雑なコントロールフローを容易に管理できます。非同期プログラミングや高階関数の使用が一般的な関数型プログラミングにおいて特に有用です。
SAP Cloud Identity ServicesでAccess Deniedエラーが出たときの対処法

# 作業背景

SAP Cloud ALMへ初期の管理ユーザで新規ユーザを作成しました。
そこで、SAP Cloud Identity ServicesにアクセスするとAccess Deniedエラー発生。
SAP CISのURLは末尾がadminの管理画面URLです。

今回はその対処法です。


# エラー画面

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2821335/b83f25ec-0349-643f-8da8-2f57ae9f15a3.png)

# SAP Cloud Identity Servicesにアクセス
## Administratorからユーザ追加
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2821335/ab286d9a-26b4-68f1-c083-644cf6ea1d15.png)

# 全てにチェック。メールを入力
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2821335/ccc8151a-cbab-f34b-298a-99edfd29f06e.png)

## 存在するユーザとのポップアップ
既にidentifierが存在するので名前の入力は不要でした。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2821335/7edd9900-50c4-ba5a-1ef8-8b460f1665e5.png)

## saveボタン押下後作成完了
これで管理画面にもアクセスできました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2821335/4aa01d84-0c74-1f75-6456-ea67515408c8.png)
Machine unlearningで扱われていること

# はじめに
みなさまお元気でしょうか。うっふん。
最近めっきり記事を書いていないので、ちょっと今日読んだ記事についてかく、くらいの軽い記事を書きたいと思います。

machine learningは色々研究されていますが、2013年頃からmachine unlearningも研究されているようですね。
不勉強であまり知らなかったので、今回は[こちらの記事](https://ai.stanford.edu/~kzliu/blog/unlearning?utm_source=substack&utm_medium=email)をざっくり読み解いて、周辺情報を調べて、最後に感想を述べようと思います。

# Unlearningの必要性
覚えたものを忘れるmachine unlearningの必要性は、秘密情報や危険な情報、嘘などを学習から取り除くためです。

# Unlearningの評価
基本的には、unlearningしたモデルが、忘れたいものをそもそも学習していないモデルとどれだけ近いかを測ります。
NeurIPS 2023 Machine Unlearning Challengeｃでは[こちら](https://www.kaggle.com/competitions/neurips-2023-machine-unlearning/)に記述ありますが、ダウンロードできず、詳細なメトリックは不明でした。

# NeurIPS 2023 Machine Unlearning Challenge
上記詳細記事にはありますが、面白かったのは、Googleから提案された[NeurIPS 2023 Machine Unlearning Challenge](https://unlearning-challenge.github.io/)というunlearningのコンペがあり、以下のような手法が提案され、精度が高かったのは、「addition of noise, weight re-initialization, KL regularization, and fine-tuning on the retain set」だったとのこと。
1. Gradient ascent on the forget set;
1. Gradient descent on the retain set (and hope that catastrophic forgetting takes care of unlearning);
1. Gradient descent on the forget set, but with uniformly random labels (to “confuse” the model);
1. Minimize KL divergence on outputs between unlearned model and original model on the retain set (to regularize unlearned model performance on unrelated data);
1. Add some noise to the weights;
1. Re-initialize weights that had similar gradients on the retain set and forget sets, and finetune these weights on the retain set;
1. Prune weights by L1-norm and fine-tune on the retain set;
1. Reset first/last 𝑘 layers and fine-tune on the retain set; and
1. Heuristic/arbitrary combinations of the above.

ちなみに優勝したのは、[上記4と8を組み合わせたもの](https://www.kaggle.com/competitions/neurips-2023-machine-unlearning/discussion/458721)。すなわち、(1)忘れたいサンプルを覚えておくべきサンプルと見分けがつかないようにする忘れるステージと(2)覚えておくべきデータでファインチューニングする、という手法。



# 最後に
大事なことは、目的で、実は今回の目的のためには、忘れることが必要ではなく、言ってはいけないことや嘘や間違いだ、として学習すべきかもしれないことです。

しかしそうすると、何もわかっていないように見えるLLMが、実は重要情報を抜き出すためにとぼけているだけ、ということもあり、ますますAIというものが恐ろしい知能をもつ脅威が見えてきますね。