OmniAICreator/Qiita-1.07M huggingface dataset:
Oracle Cloud Infrastructure Architect Associate 勉強メモ（オブジェクトストレージ)

# オブジェクト・ストレージ
OCIで提供されるストレージは以下のものがある。
- LocalNVMe
- ブロック・ボリューム
- ファイル・ストレージ
- オブジェクト・ストレージ
- アーカイブ・ストレージ

### オブジェクト・ストレージ
- インターネット規模の高性能ストレージプラットフォーム。
- 信頼性と費用効果の高いデータ耐久性を提供。
- 非構造化データ（分析データや画像、動画など）に最適。
- データは**オブジェクト**として管理される。
- リージョナルなサービス。**特定のインスタンスに関連付くものではない**。
- 3つの異なるストレージ層を提供。
- VCN内リソースからサービスゲートウェイを使用しプライベートにアクセス可能。
- 高度な機能（リージョン間のコピー、認証のリクエスト、ライフサイクルルール、大きいファイルのマルチアップロードなどを提供。）
- 保持ルールの提供。
#### 使用例
- コンテンツ・リポジトリ
画像や動画、一般的ファイルなど。長期に安価で保存する。一般的な使い方。
- 非構造化・半構造化データ
DBに登録する前のデータなど（構造化データはリレーショナルDBに登録することが多い）
- ビッグ・データ、Spark、Hadoop、データ分析
データの分析用のデータ。
- アーカイブ、バックアップ
頻繁には使わないが、長期保存したい場合。

#### 特徴
- 強固な一貫性と耐久性
データの整合性を監視。一つのリージョンの複数の場所にコピーを保存し整合性を確認。
- コストパフォーマンスの良さ
用途に合わせてストレージ層があり、使用量に応じて課金が発生。
- パフォーマンス
転送が高速など
- 使いやすさ
コンソール経由やAPI、SDKなど利用してアクセス可能。
- カスタム・メタデータ
オブジェクトに対してキーバリューのペアを付与可能。
- セキュリティー
データは暗号化して保持。

#### リソース
- オブジェクト
各オブジェクトはオブジェクト自体とメタ・データで構成。
- バケット
各オブジェクトはバケットに格納。（オブジェクトを入れる入れ物）
バケット名はリージョンのテナント内で一意である必要がある。
- 名前空間
バケットを識別する一意な名前。
バケットはフラットなものだが、名前空間を利用することで疑似的な階層構造にすることができる。

#### オブジェクトストレージの階層
- Standard（標準）
高速・即時・頻繁なアクセス用。
データの最新コピーなど。
瞬時に検索することも可能。
ダウングレード不可。
- Infrequent（頻度の低いアクセス）
標準よりコストが低い
最小保存期間31日（最低でも31日以内に削除したり更新したりしても、最低でも31日分の料金はかかる）
- Archive（アーカイブ）
めったにアクセス・更新されないデータ。
最小保存期間90日
オブジェクトのダウンロード前に標準ストレージにリストア（書き換え）が必要。
リストアに１時間必要。
ダウンロードはデフォルトでリストアしてから２４時間可能
アップグレード不可。
# 自動階層化
アクセス頻度がわからない場合やアクセス頻度が変化する場合に向いている。
更新頻度が最低保存要件を超えると下のアクセス層に移動（最低保存要件より速いと上に）。
自動階層化により、ストレージが変更された後に最低保存要件を満たさなかった場合に料金は発生しない。
オブジェクトライフサイクル管理（バケットにルールを付ける（n日後にストレージ層を移動、削除など））とは併用不可。
# アクセスと認証の管理
コンソールやAPIなどからアクセスすると認証が手間である。簡単にアクセスする仕組み。
- 認証済みリクエスト
固有のURLを発行しアクセス。
URLには有効期限を設定（いつでも削除することも可能）
- パブリック・バケット
バケットをパブリックとして作成。
パブリックに変更しても認証済みリクエストに影響なし。
# レプリケーション
別リージョンにコピーを作成する。リージョン障害からの保護。
送り先のリージョンにバケットを作成しておく必要あり。
オブジェクトごとに設定（一括では不可）
アーカイブストレージでは利用不可。
# バージョニング
オブジェクトストレージではバージョニング（バージョン管理）が可能。
バケットレベルで定義可能。
ストレージコストが増えるのでコストは増加する。
いつでも有効・一時停止が可能。
### 他の機能との連携
- 暗号化される。
- ライフサイクルマネージメント利用可能。
- 選択したバージョンのコピーが可能。
- レプリケーションではバージョンはコピーされない。
- **保持ルールはバージョニング使用時に利用できない。**
# 保持ルール
バケットに対して保持ルールを適用するとデータを不変に（読み取りのみ）にすることができる。（期限付きまたは無期限）
保持ルールのロック機能（管理者であっても保持ルールを一定期間削除できなくなる）
バケットの再暗号化、コピーには影響なし。
保持ルールがある場合、ライフサイクル管理から削除されなくなる。
レプリケーションでは保持ルールはコピー不可。
保持ルールが適用されている場合はバージョニングが動作しない。
# ロギング
OCIのロギング機能がロギングを行う。
オブジェクトストレージからread/weiteイベントをロギングサービスに送信する。（フォーマットはオープンソースのFluentd形式）
OCIのロギング・アナリティクスと連携可能。
バケットごとにロギングを有効化できる。
# オブジェクトのコピー
オブジェクトを同じまたは異なるリージョンの別のバケットにコピー。
非同期操作。
アーカイブ・ストレージからは直接コピーできないので一度取り出しが必要。
送り先のバケットは作成しておく必要あり。（コピー時に指定する）
# マルチパートアップロード
大きいファイルの転送を普通に行うのでは時間がかかる。→ 分割して並行でアップロードすることで高速化。
（インターネットのパケット通信と似ている？）
転送できるオブジェクトの最大サイズは10Tib(約10TB)。100Tib超えた場合マルチパートアップロードを推奨。
オブジェクトパートサイズは10MiB~50MiB。分割数は最大10,000パート。
コンソールからもできるが、定期的に行う場合にはAPIの使用またはCLIから利用可能。
SRE初心者がDatadogでSLOを設定してみた

SLI/SLOやDatadogについて書いていきますが、細かいことには言及していきません。
SRE初心者がなんか設定したんだな〜程度に見てください。


## レイテンシーのSLI/SLOの理想と現実について
まずは計算方法の理想と現実の違いについて

理想的なリクエスト成功率のSLIは
**SLI = レイテンシーが〇〇秒以下のレスポンス数 / 全レスポンス数**

実際のSLIは
**SLI = 一定期間で平均レイテンシーの99パーセンタイルが2秒未満であった割合**


また、理想のSLOは
**30日間で2秒未満のレスポンスが99%**

実際のSLOは
**30日間で1時間での平均レイテンシーの99パーセンタイルが2秒未満であった期間が99%**


理想と現実が違ったものになった理由はDatadogで表現可能かどうかでした。
DatadogのSLOではMetricsを用いて設定する方法と、Monitorsを用いて設定する方法があります。
そして、Metricsを用いて設定する場合は、分母と分子が必須となります。

![スクリーンショット 2023-07-18 2.45.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/312923/547becd9-f97b-1d14-9549-4690af94e386.png)


今回Datadogに設定するにあたり、「〇〇秒以下のレスポンス数」を取得することができないため分子が設定できませんでした。
また、取得可能なものとして「レイテンシーの〇〇パーセンタイル」がありましたが、この情報では分母が設定できませんでした。


よって、DatadogのSLO設定時にはMonitorsを用い、Monitors内では「一定時間での平均レイテンシーの99パーセンタイルが2秒未満」であることを設定しました。

![スクリーンショット 2023-07-18 2.47.03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/312923/4d3db30d-84f4-7b58-4ce9-04f7ffc7d719.png)


実際数字を見てみると理想と現実では求めている数字の意味が違っていることがわかると思います。
しかし、現実問題として設定できることとできないことがあるため完璧を求めすぎることをやめました。
メンバーとの会話の中でも実際に運用していく中でSLOの数値を正しくしていくことで数値の妥当性を保とうという結論になりました。


また、他社でも同様の設定方法をしているためDatadogを利用したレイテンシーのSLIの設定としてはベターなのではないかと考えています。参考として[ZOZOさんの記事](https://techblog.zozo.com/entry/wear-slo-operation#:~:text=%22metric%22%0A%7D-,%E3%83%AC%E3%82%A4%E3%83%86%E3%83%B3%E3%82%B7,-99th%20percentile%2C%2050th)を載せさせていただきます。



以上がレイテンシーのSLI/SLOの現実についてでした。
補足で、「なぜパーセンタイルを用いないでパーセンテージを用いているの？」については[こちら](https://cloud.google.com/blog/ja/products/gcp/building-good-slos-cre-life-lessons/#:~:text=%E3%82%92%E8%BF%94%E3%81%97%E3%81%BE%E3%81%99%E3%80%82-,%E3%83%91%E3%83%BC%E3%82%BB%E3%83%B3%E3%83%86%E3%83%BC%E3%82%B8%E3%81%AE%E7%90%86%E7%94%B1,-%E3%81%93%E3%81%93%E3%81%A7%E3%81%AF%E3%80%81%E3%83%AC%E3%82%A4)の記事を持って説明に返させていただきます。
さらに、パーセンタイル（百分位数）とパーセンテージ（百分率）の違いにてついては[こちら](https://kenkou888.com/category13/percent_tile.html)がわかりやすいです。



## DatadogのMetricsについて
ここからは何か理論的な話というよりも、これ便利だったという話になります。
まずは、SLOsやMonitorsの設定の際にMetricsを選択して、必要に応じてクエリを書いていくと思います。

その中でSLOsやMonitorsの設定画面で各Metricsの比較やAWS側の内容との比較をするのは困難だと思います。
そんな時はMetorics Explorerを利用すると良いです。

![スクリーンショット 2023-07-18 3.16.00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/312923/254be5b7-fb5e-ba77-f87a-12f9a064c018.png)


便利なこととしては、複数のクエリを比較することができるのとSLOsやMonitorsの編集を行わないため変に保存してしまう危険性も少ないことです。

さらに、Metorics Summaryを利用すると使用可能なMetrics NameやTag Key, Tag Valuesを検索すことができます。
これにより、自分のプロダクトでは何が利用可能なのか、何でクエリを絞り込むことができるのか判断が可能となります。

![スクリーンショット 2023-07-18 3.19.06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/312923/963b5e35-36da-86c1-15df-10df57c3a196.png)



## 最後に
SLI/SLOを複数設定する中で課題とする箇所は数多くありました。しかし、今回はライトに記事を書きたかったのでボリュームや難易度を落としています。
アウトプットとしては全然書き足りていないですが、また気がむいた時にかければなとおもいます。

あくまで初心者なので内容に不備がございましたらコメントでこっそり教えて下さい。
Base64バイナリで受け取ったファイルをStreamで画像として保存する

### Base64バイナリで受け取ったファイルをStreamで画像として保存する
[BASP21](http://www.hi-ho.ne.jp/babaq/basp21.html)を使用してます．

先頭でページの文字コードをUTF-8にしておきます，
```vb
<%@ CodePage=65001 %> 
```

BASP21でバイナリを読み込む．
```vb
Set bobj = Server.CreateObject("basp21")
byteArray = Request.BinaryRead(Request.TotalBytes)
' 画像送信時にフォームのnameに「image」と名前を付けて送信しておく
sarray = bobj.FormBinary(byteArray,"image")
```

読み込んだバイナリをStreamでWindows-1252(utf-8のWin版かな？）文字列に変換し，変数「str」に保存．
「image,base64の画像本体」となっているのでカンマでSplitしてbaseに保存．
このとき，```<%@ CodePage=65001 %> ```でASPファイルを明示的に文字コードをUTF-8の宣言しておかないと文字化けしてうまくいかなかったです．
```vb
dim stream : set stream = server.CreateObject("ADODB.stream")
stream.type = 1 'TypeBinary
stream.mode = 3 ' read write
stream.Open
stream.write(sarray)
stream.Position = 0
stream.Type = 2 ' TypeText
stream.Charset = "Windows-1252"
str = stream.ReadText ' binary to string
stream.close
set stream = nothing

base = Split(str,",") 
```

base(1)の本体部分をDOMDocumentのBase64Dataを使ってBase64デコードする．

```vb
' string Base64 decode
Set objXML = Server.CreateObject("MSXml2.DOMDocument")
Set objDocElem = objXML.createElement("Base64Data")
objDocElem.DataType = "bin.base64"
objDocElem.text = base(1) 'the base64-encoded string
imgdata = objDocElem.NodeTypedValue
```

imgdataに画像バイナリが格納されているのでStreanでpng画像としてサーバに保存します．
```vb
' 画像ファイルを保存
FileName = "D:\folder\picture.png"

set stream = server.CreateObject("ADODB.stream")
stream.type = 1 'TypeBinary
stream.mode = 3 ' read write
stream.Open
stream.write(imgdata)
stream.SaveToFile FileNa
```

今回はJPG・PNG問わずPNGで保存するような仕様にしました．送信時にJavaScriptでCanvasに一度描画して画像サイズを縮小しているため，バイナリに拡張子の情報自体がないのだと思います．
入力ファイルに拡張子が存在する場合，Streamでの画像保存時に元の拡張子を考慮する必要があるかもしれません．
optparseの使い方

rubyにおけるoptparse の使い方について記載します。

コマンドライン上からオプション -a, -b を渡すには下記のように記載します。
```ruby:sample.rb
require 'optparse'
opt = OptionParser.new

opt.on('-a') {|v| p v }
opt.on('-b') {|v| p v }

opt.parse!(ARGV)
p ARGV
```

実行結果は下記のようになり、コマンドライン上から渡したfoo、bar、bazがARGVに配列として格納されていることが分かります。
```
ruby sample.rb -a foo bar -b baz
# => true
     true
     ["foo", "bar", "baz"]
```

OptionParserのparse!メソッドによってARGVの解析を行います。
parse!ではARGVからオプション名自体が取り除かれますが-aや-bも含めたい場合は!を使用せずにparseメソッドを使います。

# 参考
https://docs.ruby-lang.org/ja/latest/library/optparse.html
LangChainを使ってChatGPTのFunction Callingを超簡単にやってみる

# はじめに

LangchainはLLMを利用したアプリケーションを開発するためのフレームワークです。BingAIの要約は以下。

>LangChainは、言語モデルを利用したアプリケーションを開発するためのフレームワークです。1言語モデルをAPI経由で呼び出すだけでなく、他のデータソースと連携したり、環境とやりとりしたりできるような、より強力で差別化されたアプリケーションが可能になると考えています。
>
>LangChainフレームワークは、次の2つの価値提案を提供します。
>
>コンポーネント: LangChainは、言語モデルを扱うために必要なコンポーネントのモジュール化された抽象化を提供します。また、これらの抽象化の実装も集めています。これらのコンポーネントは、LangChainフレームワークの他の部分を使っているかどうかに関係なく、使いやすく設計されています。
>
>ユースケース特化型チェーン: チェーンとは、特定のユースケースを最適に達成するために、これらのコンポーネントを特定の方法で組み合わせることを意味します。これらは、特定のユースケースに簡単に取り組めるようにするための高レベルなインターフェイスとして考えられます。また、これらのチェーンはカスタマイズ可能に設計されています。
>
>したがって、以下のドキュメントでは、これら2つの価値提案に分けて説明します。このドキュメントでは、コンポーネントとユースケースを高レベルで言語に依存しない形で説明します。言語に依存した方法でこれらのコンポーネントやユースケースに取り組む方法については、ページ上部にリンクされている言語別セクションをご覧ください。

多数のAgent機能が提供されていてニーズがハマればすごく簡単にLLMを利用したアプリが開発できるのがウリです。

今回はLangChainでOpenAI API のFunction Callingを利用してみます。

# やってみた

コードと結果は以下。[こちら](https://book.st-hakky.com/docs/agents-of-langchain/#tool-%E3%82%AF%E3%83%A9%E3%82%B9%E3%82%92%E4%BD%BF%E7%94%A8%E3%81%99%E3%82%8B%E6%96%B9%E6%B3%95)を参考にWeb検索と計算を行う機能を追加しました。

```function_calling.py
import os
from langchain import LLMMathChain, OpenAI, SerpAPIWrapper
from langchain.agents import initialize_agent, Tool
from langchain.agents import AgentType
from langchain.chat_models import ChatOpenAI

# set api key
os.environ["OPENAI_API_KEY"] = "[YOUR OPENAI API KEY]"
os.environ["SERPAPI_API_KEY"] = "[YOUR SERPAPI API KEY]"

llm = ChatOpenAI(temperature=0, model="gpt-4")
search = SerpAPIWrapper()
llm_math_chain = LLMMathChain.from_llm(llm=llm, verbose=True)
tools = [
    Tool(
        name="search",
        func=search.run,
        description="Googleで検索して結果を返します"
    ),
    Tool(
        name="Calculator",
        func=llm_math_chain.run,
        description="数理計算の結果を返します",
    )
]

agent =  initialize_agent(tools, llm, AgentType.OPENAI_FUNCTIONS, verbose=True)

# run 
result = agent.run("SpaceX社の創業者の誕生日を検索してその年齢を算出してください。本日は2023年7月8日です。")
print(result)
```

実行結果

```shell
$ python function-calling.py

> Entering new  chain...

Invoking: `search` with `SpaceX founder's birthday`

Elon Reeve Musk (/ˈiːlɒn/ EE-lon; born June 28, 1971) is a business magnate and investor. He is the founder, CEO and chief engineer of SpaceX; ...
Invoking: `Calculator` with `2023 - 1971`

> Entering new  chain...
2023 - 1971``text
2023 - 1971
``
...numexpr.evaluate("2023 - 1971")...

Answer: 52
> Finished chain.
Answer: 52SpaceXの創業者であるElon Muskの誕生日は1971年6月28日です。したがって、2023年7月8日現在で彼の年齢は52歳です。

> Finished chain.
SpaceXの創業者であるElon Muskの誕生日は1971年6月28日です。したがって、2023年7月8日現在で彼の年齢は52歳です。
```

当たった。 ログを見ると`search`と`Calculator`が呼ばれているのがわかります。`AgentType.OPENAI_FUNCTIONS`でFunction Callingを利用するエージェントになります。

# おわりに

まだ詳しくドキュメントを読んでないけどかなりスッキリと実装できそうな印象でいい感じです。
Next.jsでvideoを使う方法、Mp4を入れたいあなたへ

<h2>最近の画像作成ソフトは凄いと言わざるを得ない</h2>

筆者は可愛い女の子と無縁な生活を送っているため、かわいい女の子が喋ってくれるだけで嬉しくなる。しかもかわいい女の子がガチャ要素ででるとか、もう神アプリか。

そんなわけでStableDiffusionで生成した動画（MP4）をブログにアップしたい!!


調べてみると画像ストレージのCloudinalyを使ったmp4の再生方法はいくつかあったが、ローカル環境に取り入れる記述があまりなかったので、備忘録としてとっておく。

<h2>Next.jsで動画いれるのはさほど難しくない</h2>
難しくないといっても、生のHTMLに記載するより一手間かかる。

まずはいつも通り
```php:
yarn create react-app

//もしくは
npm create react-app
```

作成したフォルダ内で

```php:
yarn add next-videos -E
```

next.config.jsに下記項目を追加する

```php:next.config.js
const withVideos = require('next-videos')
module.exports = withVideos()
```


今回はpage.tsxと同じ階層にvideo.mp4（のせたい動画）をアップロードして
page.textのreturn文にmp4などの動画を差し込む文言を追加。

※本来はPublicに収納する方が好ましい


```php:page.text
export default function Home() {
  return (
        //省略

        <div>
          <video src={require('./video.mp4')} controls  playsinline/>
        </div>

        //省略
 )
}
```

.mp4のあとのcontrolsは必須。playsinlineもiphoneやandroidで再生するためには必須なので記載しよう。

muted（ミュートや）loop(ループ再生）などを好みで付け足してもいい


<h2>最後に</h2>
写真に声をあてて、しゃべらせたいあなた。最近の技術の躍進はすばらしいので是非一度体験してほしい。

![video.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2860275/91522791-d511-3261-9ae4-711f6735a01b.gif)
Vue.jsを触ってみる

# 動機
お仕事でVue.jsを少し触りましたが、よくわからない状態なので改めて勉強してみました。
私のフロント側の技術レベルとしては、
* 生のHTML、CSS、JavaScriptを読んで改造することがギリギリできる。
* LaravelのbladeファイルやJavaのJSPファイルは作れる。
です。

記事に間違いがありましたら優しく教えてください😇

# Vue.jsとは
有名なJavaScriptのフレームワーク。
SPAの実装などフロント側の開発で用いられる。
https://ja.vuejs.org/

# 使用方法
## 環境
Windows10のPCで作業します。
Vscodeを使ってプロジェクトを編集していきます。

## インストール
公式のインストール手順を参照して実行します。
https://ja.vuejs.org/guide/quick-start.html#creating-a-vue-application

node.jsの最新版をインストールします。
特にカスタマイズしませんでした。

Powershellでは`$ npm -v` が動くのに、VscodeのPowershellでnpmコマンドが見つからない問題が発生しましたが、PC再起動で解決しました。

下記コマンドを実行します。
`$ npm init vue@latest`

選択肢はすべてNOにしました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/691111/ee2b5637-ba1e-8c33-0918-a2675aae9def.png)

Vscodeの拡張機能から「Vue Language Features (Volar)」をインストールします。名前がよく似た拡張機能が多いため注意してください。

下記2つのコマンドを実行する。
`$ cd <your-project-name>`
`$ npm install`

下記コマンドを実行するとlocalhostで環境が実行される。
`$ npm run dev`

必要な場合は、下記コマンドでビルドすることができます。
`$ npm run build`

## チュートリアル
公式のチュートリアルで基本を学びました。
(レンダリング、ウォッチャー、コンポーネント、イベントなど)
https://ja.vuejs.org/tutorial/#step-1
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/691111/d143e6e3-2597-b04a-2454-1dc959c45fe2.png)

JavaScriptをある程度知っていないと読解できない部分があるため、少し苦労しました。

## Vue router
## Vue routerとは
Vue.jsにルーティング機能を持たせる。
指定したURLとVueのコンポーネントを紐付けることで、画面をリロードせずに画面描画を切り替えられます。
これでSPAが実装できます。

## Vue routerのインストール

https://router.vuejs.org/installation.html
`npm install vue-router@4`でインストールする。

router.jsの新規作成やmain.jsなどを作成していく。

```main.js
import './assets/main.css'

import { createApp } from 'vue'
import App from '@/App.vue'
import router from '@/router'


const app = createApp(App)
app.use(router)
app.mount('#app')
```

routesの中のpathは好きなように設定します。
home.vueとresume.vueは適当なページを用意しておけばOK。
```router.js
import { createRouter, createWebHistory } from 'vue-router'
import home from '@/page/home.vue'
import resume from '@/page/resume.vue'


const routes = [
  { path: '/', name: 'home', component: home },
  { path: '/home', name: 'home', component: home },
  { path: '/resume', name: 'resume', component: resume },
]

const router = createRouter({
  history: createWebHistory(),
  routes,
})

export default router
```

```App.vue
<template>
  <p>ブログサイト</p>
  <router-view />
</template>
```

この状態で`$ npm run dev`を実行すると、
* http://localhost では「ブログサイト」という文字とhome.vueの内容が表示されます。
* http://localhost/resume では「ブログサイト」という文字とresume.vueの内容が表示されます。

つまりこんな状態で動作しています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/691111/7a0d7090-f7d3-14f3-e291-0e7a32315f28.png)

URLによって`<router-view />`(=コンポーネント)が切り替わる仕組みになりました。
これで簡単ですがSPAの実装ができました。

# 最後
Laravelのbladeファイルとは仕組みが異なるため、コンポーネントや画面遷移を理解するのにとても時間がかかりました。
JavaScriptがわかる人はすごいですね。。
ここまでわかればフルスタックエンジニアと呼称していいのか？🤔
DelphiでWindowsストアアプリの試用版を作ってみた

# TWindowsStoreで試用残り時間が変な件

今更ながらWindowsStoreアプリを制作。忘れない様にメモしておくことにする。  

他の方の投稿を参考にストアに公開することはできたのだが、試用期間の残り日数を表示すると、なんと10675199日となってしまう。  
embacarderoの[サンプルプログラム](https://docwiki.embarcadero.com/RADStudio/Sydney/en/Using_the_WindowsStore_Component)通りなのに・・・  

こんなのとっくに誰もが通過した内容だろうと、ググってみると[ハマっている方](https://www.delphipraxis.net/201236-twindowsstore.html)を発見。  
だけども解決したか不明・・・  全然情報無いのですがだれもやってないの？  

~~~
LRemainingTrialDays := WindowsStore1.AppLicense.TrialTimeRemaining.Days;
~~~

色々やってみると、[Microsoftのサンプルプログラム](https://github.com/Microsoft/Windows-universal-samples/blob/main/Samples/Store/cs/Scenario1_TrialMode.xaml.cs#L89)通り、下記の様にすることでまともな日数が取得できました。  
ついでに、ExpirationDateは世界標準時の様で、Nowと比較するとおかしいことになるので、９時間進めて比較や表示を行いました。  
~~~
ExpirationDateJ := WindowsStore1.AppLicense.ExpirationDate;
ExpirationDateJ := IncHour(ExpirationDateJ, 9);
LRemainingTrialDays := Round(DaySpan(Now, ExpirationDateJ));
~~~

ストアに公開しない（ローカル）で、試用版のテストを行う方法もわかったが、これもすぐに忘れそうな内容なので後でメモすることにします。
CP4D監査レコードをLogDNAにエクスポートする際、TLSを使用してLogDNAに接続する場合のLogDNA TLS証明書の取得方法

Cloud Pak for Dataの監査レコードをLogDNAにエクスポートするにあたり、TLSを使用してLogDNAに接続することができます。（TLSなしで接続することも可能ですが、TLSを使用した接続が推奨されます。）

LogDNA への Cloud Pak for Data 監査レコードのエクスポート
https://www.ibm.com/docs/ja/cloud-paks/cp-data/4.6.x?topic=solution-exporting-audit-records-logdna
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2763758/ab182168-540f-412d-b9ea-30d8fa9050cf.png)
TLSを使用してLogDNAに接続するためには、CP4Dのzen-audit-config構成マップにてLogDNA TLS証明書の内容を記載する必要があるため、事前にLogDNAのTLS証明書を取得します。
尚、構成マップにはpem形式での記載が必要となりますが、ダウンロードされる証明書はcert形式のため、これをpem形式に変換します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2763758/9e432747-8a0c-a966-db64-ec7979bdf619.png)
本記事では、LogDNA TLS証明書の取得方法および証明書のpme形式への変換方法について紹介します。（本記事では、IBM CloudにてデプロイしたIBM Log Analysis with LogDNAから証明書を取得しています。）

1. IBM Log Analysis with LogDNAのコンソールにて、「？」アイコン（Install Instructions）をクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2763758/47143e6f-9d89-4f9d-125c-49c4315263a0.png)

2. 表示された画面の、左側ペインにて、「Via Syslog」の下の「syslog-ng」をクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2763758/74cbb40d-c952-f574-d788-bfbcd87f4e2f.png)

3. 「Download Root CA Certificate」をクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2763758/909388bd-301d-dc26-319d-b1eaf061fec8.png)

4. 「id-root-ca.crt」ファイルがローカルにダウンロードされる
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2763758/6c97522e-f83d-79dc-edbe-dac99b9c9829.png)

5. LogDNA TLS 証明書をpem形式に変換（以下の例では、Linuxサーバーに「ld-root-ca.crt」ファイルを転送してpemへの変換を実施）
```
# ls -ltr
total 12
-rw-r--r--. 1 root root 9909 Apr 25 10:46 ld-root-ca.crt
# openssl x509 -in ld-root-ca.crt -out logdna.pem -outform PEM
# ls -ltr
total 16
-rw-r--r--. 1 root root 9909 Apr 25 10:46 ld-root-ca.crt
-rw-r--r--. 1 root root 2094 Apr 25 16:26 logdna.pem
```

これで、LogDNA TLS証明書をpem形式に変換できましたので、「logdna.pem」ファイルの内容を、構成マップの「ca.pem」のエントリーに記載します。
S3にデプロイしたReactアプリで、ページ遷移後にリロードすると404エラーになる

# 事象
Reactで作成したWebアプリをAWS S3にデプロイしたところ、TOPページ以外のページでリロードした際に、404 Not Foundになりました。
```
404 Not Found
・ Code: NoSuchKey
・ Message: The specified key does not exist.
・ Key: ******
・ RequestId: ****************
・ HostId: ****************
```
ルーティングには`react-router-dom`の`BrowserRouter`を使用しています。

# 原因
今回Reactで作成したWebアプリはSingle Page Application（SPA）です。
React Routerはクライアントサイドでのルーティングを提供するもので、URLに応じて新たにUIをレンダリングすることで、別ページへ遷移したかのように見せかけます。
S3上にはindex.html以外のページは存在しないため、リロードすると、S3がそのURLの先に置かれたファイルを探してしまい、404エラーが発生します。
`BrowserRouter`の代わりに`HashRouter`を使うことでも解決できるようですが、URLに`#`が入るのは綺麗ではありません。

# 解決策

### 方法１：エラードキュメントにindex.htmlを登録する

`S3 > 該当のバケット > プロパティ > 静的ウェブサイトホスティング`の`編集`を選択します。
![website-hosting.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3513849/ef98f1c4-4c50-b5a2-2e8f-ffee83bb277a.jpeg)
エラードキュメントに`index.html`と入力して`変更の保存`をクリックします。
![error-document.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3513849/6b0eca93-a19f-a2db-8ee8-fd8273e3b658.png)

この設定によって、エラーが発生した場合にindex.htmlが返されるようになります。

`BrouserRouter`はブラウザのアドレスバーに現在位置を保存し、ブラウザの履歴スタックを利用して遷移を実現しています。
index.htmlが返されても、アドレスバーに入力されているURLは変わらないため、リロード直前に表示されていたUIがレンダリングされます。

この方法は手軽な上、見かけ上は問題なく動作します。しかし、デベロッパーツールのコンソールを見てみると、依然としてリロード時に404エラーが発生しています。
![console.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3513849/405594b8-c247-293d-8cbb-6dbf5ec1d89e.png)

そこで、次の方法も試してみました。

### 方法２：CloudFrontのカスタムエラーレスポンスを使用する
まず、CloudFrontのディストリビューションを作成します。
オリジンドメインには該当のS3バケットを指定してください。入力ボックスを選択すると、S3バケットの候補が表示されるので、該当のバケットを選択の後、`Webサイトのエンドポイントを使用`をクリックします。
![cloudfront-origin-domain.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3513849/f3334192-ded0-ca08-edff-b3d7fe88b65f.png)

デフォルトルートオブジェクトには`index.html`を入力します。
![default-route-object.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3513849/2f4e9ffe-0fb4-7818-e717-5cd9715f0b90.png)

他の項目は適宜設定してください。
`ディストリビューションの作成`をクリックします。デプロイが終了するまでしばらく時間がかかります。

続いて、`該当のディストリビューション > エラーページ > カスタムエラーレスポンスを作成`と進みます。以下の図のように、404エラーに対してレスポンスコード200と`/index.html`を返すように設定します。
![custom-error-responce.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3513849/83ee8bd3-36d5-ecb9-5c27-7dd0b061c916.png)

こうすることで、方法１のようにリロード時に404エラーが発生することがなくなります。

一方で、次のような問題点があるようです。
- エラーレスポンスを書き換えるため、ブラウザ側でエラーハンドリングを実装しようとすると機能しなくなる
- SPAと従来のウェブアプリケーションのハイブリッド構成の場合、意図しないレスポンスになることがある

どの方法にも一長一短がありますね。


# 参考

https://reactrouter.com/en/main

https://stackoverflow.com/questions/51218979/react-router-doesnt-work-in-aws-s3-bucket

https://qiita.com/ekzemplaro/items/d88e7516dfe5d748db53

https://sb-blog.link/archives/281
Oracle Analytics Cloud：表ビジュアライゼーションで連番（順位）を付ける

# はじめに
Oracle Analytics Cloud（**OAC**）の表ビジュアライゼーションを作成したときに、連番をつけたくなることがあります。
計算式で連番をつけられるかどうか試してみます。

# 今回使用するデータ
Jリーグの公式サイトで公開されている、2022年の明治安田生命J1リーグの順位表をExcel化しました。

https://www.jleague.jp/standings/2022/

順位は、ワザとデータ化しませんでした。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2342206/a27e86c5-8a32-1dbc-b6c0-a514cbd5e6b2.png)

# データセットの作成
OACにログインし、作成したExcelファイルをアップロードしデータセットとします。
ExcelファイルをOACのブラウザ画面にドラッグ＆ドロップし、内容を確認したら「ビジュアル化」をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2342206/b90318f6-5dde-dcde-4b39-b60276d36602.png)

# ワークブックに表を追加
一番上の項目である「クラブ名」をクリックして選択します。
シフトキーを押しながら、一番下の項目「得失点」をクリックして、全部の項目を選択します。
右クリックして、「ビジュアライゼーションの選択」をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2342206/77e0a995-c19d-3203-af84-7ee5214832fe.png)
「表」をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2342206/55097081-5693-9d75-89c4-950b359e4fd7.png)

# 連番を表示するための計算を追加
「マイ計算」を右クリックし「計算の追加」をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2342206/f5dcaa6b-8aef-106a-98e6-ea16a3202aff.png)
「名前」を「順位」とし、次の式を入力してから「保存」をクリックします。
```
rsum(1)
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2342206/0b115ffa-c903-190e-ec67-aac89a9c0dbb.png)
作成した計算を「クラブ名」の上に表示します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2342206/e7132c8b-2ba0-8edf-b9e9-8147c85399c8.png)
「勝点」をクリックして、勝点の多い順に並べ替えをします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2342206/0be66053-fade-46c5-aab9-bd9c367c72a5.png)
完成です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2342206/4dcadb2c-65e7-14a9-decc-2c1b6f23b84f.png)

# もう一つの方法
便宜上、計算式には「順位」という名前をつけましたが、実際には1番上の行から連番されるだけなので、順位を示すためには適切な並び順を指定する必要があります。
例えば、勝点を昇順に並べ替えるとこんな感じになります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2342206/8a0fbb96-cd4f-e8f6-29b4-45858333943e.png)
そこで、別の方法を試してみます。
「表」から「順位」を削除して、代わりに「勝点」をドラッグ＆ドロップします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2342206/faa5c74b-9a4e-1a1f-d032-6d650efc0902.png)
追加した「勝点」をクリックして、「集計(デフォルト)」から「ランク」を選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2342206/3b354d13-4f28-77cf-c227-0a6e9816888e.png)
プロパティで、「RANK 勝点」のヘッダー表示をカスタムにして「順位」と入力します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2342206/0de03fff-288c-7947-9f77-13f3ac54c710.png)
今度は、勝点で昇順ソートしても勝点に基づいた正しい順位が維持されました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2342206/fa3644da-9c4a-fe80-58c1-e7d2cc222a8f.png)

::: note
計算式で「rank(勝点)」という式を入力することで、「勝点」メジャーの集計方法を「ランク」に変更するのと同じ結果を得られます。
:::
NFTについて（基本概念と特徴）

# NFTの定義とは何か
NFT（Non-Fungible Token）は、非交換可能なトークンです。通常の通貨や仮想通貨とは異なり、一つ一つが独自の特徴や識別子を持ち、他のトークンとは交換することができません。これにより、デジタルアセットの一意性を確保し、所有権を証明することができます。

*例えば、*
デジタルアートでいうと、あるアーティストがオンラインでデジタルアートを作成し、それをNFTとして発行します。このNFTは、そのアート作品の一意性と所有権の証明となります。他の人が同じデジタルアートのコピーを作成しても、それらは同じNFTではなく、別々のアセットとして扱われます。


# NFTの性質
NFTは、デジタルアセットに対して以下のような特別な性質をもちます。

**1. ユニーク性と一意性**
 同じデジタルアセットのコピーが作成されても、それぞれのNFTは独自の特徴や識別子を持っています。これにより、デジタルアセットの一意性を確保し、偽造や複製を防ぐことができます。

**2. 所有権の証明**
NFTはブロックチェーン上で所有権情報が記録されるため、デジタルアセットの所有権を証明することができます。例えば、あるアーティストがデジタルアートをNFTとして発行すると、そのNFTの所有者は、そのアート作品の正当な所有者であることが明確になります。

**3. トレースの可能性**
NFTのブロックチェーン上の取引履歴は永久的に記録されます。したがって、デジタルアセットが所有者から所有者へ移転する際の取引履歴を追跡することができます。これにより、デジタルアセットの起源や転売の経緯を透明にすることができます。
また、NFTは転売時に、作者への報酬が入る仕組みを設計できます。取引額の数％が作者に還元されるため、クリエイターの長期的な利益につながります。

*例えば、*
NFTで発行されたバーチャルな絵の作品でいうと、あるクリエイターがデジタル上で絵を制作し、NFTとして発行します。このNFTには、その作品の詳細な情報や所有者の履歴がブロックチェーン上に格納されます。これにより、この作品の所有者は正確に特定され、作品の転売が行われた場合にも取引履歴が追跡され、制作者のクリエイターは転売が行われた際にも利益が入る仕組みを作ることができます。

# NFTが持つ主な特徴や利点
NFTは、以下の特徴や利点を持っています。

**1. 所有権の透明性と証明性**
NFTはブロックチェーン上で所有権情報が公開され、透明になります。デジタルアセットの所有者は、ブロックチェーン上の情報を通じて簡単に確認できます。これにより、オンラインのアート市場やデジタルコレクションにおいて、所有権の証明と信頼性の向上が図られます。

**2. 取引履歴の追跡可能性**
NFTの取引履歴はブロックチェーン上で永久的に保存されます。したがって、過去の取引や転売価格などを透明に追跡することができます。これは、オンラインのアート市場やコレクター間の取引において、信頼性や透明性を高める効果があります。

**3. プログラム可能性による付加価値の創造**
NFTはスマートコントラクトと組み合わせることで、様々な付加価値を提供できます。スマートコントラクトによって、アーティストにロイヤリティを自動的に支払ったり、転売時の手数料を設定したりすることができます。これにより、クリエイターやアーティストがより公平な報酬を受け取ることが可能となります。

# まとめ
今回は、基本的な特徴などについて記事にしましたが、今後もNFTについて発信していきたいと思っています。
最後まで読んでいただきありがとうございました。
EXCEEDED_MAX_SIZE_REQUEST



+ [Deploy Apex class to Org fails with Max Size Request exceeded](https://trailhead.salesforce.com/trailblazer-community/feed/0D54V0000794lmD)


Following these suggestions, you should be able to overcome the "EXCEEDED_MAX_SIZE_REQUEST" error and successfully deploy your Apex class to your Salesforce org.

1. Reduce the size of the deployment: Check if there are any unnecessary files or large files that can be removed or optimized. Remove any debug logs, temporary files, or unused resources that are not required for the deployment.

2. Split the deployment: If your deployment includes multiple files or resources, you can split them into smaller chunks and deploy them separately. This can help ensure that the size of each deployment is within the allowed limit.

3. Use the Salesforce CLI with the Metadata API: Instead of using the Salesforce CLI with the default SOAP API, you can try using the Salesforce CLI with the Metadata API. The Metadata API has a larger maximum size limit for requests (approximately 400 MB) compared to the SOAP API.

4. Make sure to replace path/to/metadata with the actual path to your metadata directory and yourOrgAlias with your Salesforce org alias.

(sfdx force:mdapi:deploy -d path/to/metadata -u yourOrgAlias)


今回は、以下は違うかも
+ [Configuring the Data Loader. ](https://help.salesforce.com/s/articleView?id=000384730&type=1)
EventBridgeからLambda起動

# はじめに
2年目に突入したエンジニアでございます。

今回はAWSを少し触れることがあったので忘れないためにここに備忘録として記載しておきます。


# 今回の内容：EventBridgeからLambdaを起動する。

[1. Lambda関数の用意](#1-Lambda関数の用意)
[2. EventBridgeルールの作成](#2-sEventBridgeルールの作成)
[3. 結果の確認](#3-結果の確認)

## 1. Lambda関数の用意

まずは今回実行するLambda関数を用意します。

https://qiita.com/Hamoto/items/bd486937de142a589f8f

上記の記事を参考にしましたが、今回EventBridgeからLambdaを起動するだけの構成を予定しているため、
メッセージを返すのではなくS3にファイル出力するようなコードにしてみました。

### コードの修正

```python:lambda_function.py
import boto3

def lambda_handler(event, context):
    # S3へのアクセスに使用するクライアントを作成
    s3_client = boto3.client('s3')

    # アップロードするファイルのパラメータを指定
    bucket_name = 'your-bucket-name'  # アップロード先のバケット名
    file_name = 'example.txt'  # アップロードするファイル名
    file_content = 'This is an example file.'  # アップロードするファイルの内容

    # ファイルをS3にアップロード
    s3_client.put_object(
        Body=file_content,
        Bucket=bucket_name,
        Key=file_name
    )

    return {
        'statusCode': 200,
        'body': 'File uploaded successfully!'
    }

```

![スクリーンショット 2023-07-18 063251.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2660549/51c3550b-d0d8-f433-fcf4-72fdab1b549f.png)

### 実行ロールへの権限追加

デフォルトで作成されるLmabdaの実行ロールではS3へのファイル作成ができなかったため、
下記のポリシーを実行ロールに追加して対応しました。

![スクリーンショット 2023-07-18 070334.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2660549/577a1730-57c0-1f94-7dd8-e062e5053be2.png)


```json
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "s3:PutObject"
      ],
      "Resource": "arn:aws:s3:::your-bucket-name/*"
    }
  ]
}
```

## 2. Event Bridgeルールの作成

今回はcron式によるスケジュール起動を行いたいため、
EventBridgeスケジューラからスケジュールの作成を押下します。
- ルール名とスケジュールのパターンを設定
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2660549/8cd9c3e1-1087-493c-a586-216ab24c1111.png)


- ターゲットリソースの選択
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2660549/827e2907-78ff-f030-3d8b-d84127a55a0e.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2660549/05526c13-586c-279d-f289-560145385edd.png)

その他はデフォルトのまま、作成を完了します。
そうすると、毎時15分にLmabda関数を起動するスケジューラの完成です！

https://docs.aws.amazon.com/ja_jp/AmazonCloudWatch/latest/events/ScheduledEvents.html

## 3. 結果の確認
（作業状況の問題で下記の結果は毎時45分に起動するようにスケジュールを修正した状態の結果です。）
- S3への出力確認
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2660549/a08d94e7-b5df-8740-d31b-2f7beb3e4edf.png)

- ログでの確認
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2660549/aa5588a5-3170-4c1c-f49a-e645112a6cb8.png)


# おわりに

最後まで読んでいただきありがとうございます。

今回はよくあるLambda-EventBridgeの構成についてまとめました。
少しでも参考になると幸いです。

ありがとうございました。

# 参考

https://docs.aws.amazon.com/ja_jp/AmazonCloudWatch/latest/events/ScheduledEvents.html

https://qiita.com/Hamoto/items/bd486937de142a589f8f
ChatGPTの新機能「Code interpreter」についての記事まとめ

Code interpreterを活用する上で読むべき記事をまとめました

# Code interpreterで出来ること

Code interpreterで出来ることを色々と試している記事

「Code interpreterってどんなことできるの？」と思っている人はまず読むのがおすすめ

https://zenn.dev/yuhei_fujita/articles/try-chat-gpt-code-interpreter

https://zenn.dev/karaage0703/articles/5df61d446684f9

https://note.com/kajiken0630/n/ndd8307e12039

# Code interpreterを使うためのTiPs

Code interpreterを使うためのTiPsがまとまった記事

https://qiita.com/ot12/items/39ff4264e0f13209ba62#%E6%97%A5%E6%9C%AC%E8%AA%9E%E3%83%95%E3%82%A9%E3%83%B3%E3%83%88%E3%81%AE%E4%BD%BF%E3%81%84%E6%96%B9

# Code interpreterの仕組み

Code interpreterの仕組みを解説している記事

https://www.bioerrorlog.work/entry/code-interpreter-chatgpt

# Code interpreterで使えるファイル

Code interpreterでどんなファイルが扱えて、それぞれのファイルでどんなことができそうかをまとめている記事

https://note.com/it_navi/n/n8ddee31d6cf2

# 売上分析

Code interpreterでアパレル店舗の売上分析ができるかを実験した記事

https://generativeinfo365.com/?p=1031

# 画像処理

「Code Interpreter」を使って画像処理がどんなことができるかを紹介している記事

https://bocek.co.jp/media/exercise/chatgpt/7092/

# コーディング能力

Code Interpreterはデータ分析で注目されがちだけど、コードリーディング能力も優秀だから色々使えて便利だよっていう記事

https://laiso.hatenablog.com/entry/2023/07/16/123214

# データ分析コンペ

Code interpreterだけを使ってデータ分析コンペに出たらどれくらいの成績が出るのかを実験した記事

https://generativeinfo365.com/?p=968


# 外部データへのアクセス

外部データへのアクセスができないのか確認した記事

https://acro-engineer.hatenablog.com/entry/2023/07/12/120000

# webアプリの作成

「Code interpreter」を使って、webアプリを作った経緯が書かれている記事

一行もコードを書かずにwebアプリが作成できているのがすごい

https://note.com/bbz662bbz/n/n7c9b620cd8f0

# 長期記憶を持たせる方法

Code interpreterでこれまでの会話の議事録を残させることにより、長期記憶を持たせる方法を解説している記事

https://murasan-net.com/index.php/2023/07/12/chatgpt-code-interpreter-longtoken/


# 地図を書く方法

「Code interpreter」を使って地図を書く方法が紹介されている記事

地域別の売上などのデータと組み合わせることで、視覚的に分かりやすい可視化ができそう

https://note.com/currypurin/n/nc27e5879d29e

https://note.com/currypurin/n/n19ac549195e6

https://note.com/it_navi/n/nd92d7b47a075

# 日本語フォントを使用する方法

「Code Interpreter」を使用して日本語でグラフを作成すると文字化けするのを回避する方法を解説した記事

https://blog.kinto-technologies.com/posts/2023-07-11-ChatGPT-GPT4-Code-Interpreter-%E6%97%A5%E6%9C%AC%E8%AA%9E%E3%83%95%E3%82%A9%E3%83%B3%E3%83%88%E5%AF%BE%E5%BF%9C/


# 日本語OCRの方法

普通にやるとできない日本語OCRを頑張ってできるように実現した方法が解説された記事

https://note.com/it_navi/n/n68a4a1159189
NASに商機到来　NASは、ブッチギリで広帯域

# 2023/07/18 商機到来 NAS
商機到来シリーズの投稿です。

## 商機発見

    **NASは、簡単にすぐディスク交換できます。データ移動しているとみなすとブッチギリで広帯域です。**

## どんなディスク移動させるか？
- メモリの多いNASへ
- コピー先へ、ネット越しより速いことあり
- 性能のよいNAS(GPUつき)へ
- 2Bayから4bay
Railsデプロイ時のエラー:error Command "webpack" not found.

ElasticBeanstalkでRailsをデプロイ時に遭遇したエラーについて記載します。
誰かのお役に立てれば幸いです。

## 環境
- Elastic Beanstalk Ruby 3.6.7@Ruby 3.0 running on 64bit Amazon Linux 2
- Rails 7.0.4.3
- bundler_version: 2.2.33
- rake_version: 13.0.6

## エラー内容

>[INFO] Running command /bin/su webapp -c bundle exec /opt/elasticbeanstalk/config/private/checkforraketask.rb assets:precompile
[INFO] Found assets:precompile task in Rakefile
[INFO] Running command /bin/su webapp -c bundle exec rake assets:precompile
[INFO] Compiling...
Compilation failed:
yarn run v1.22.19
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.
error Command "webpack" not found.

## 原因
Rails6までは`bundle exec rake assets:precompile` の実行時に自動で `bundle exec rake yarn:install` が実行されていましたが、 Rails7 からは実行されなくなったためでした。
これはRails7からWebpackerが標準サポートから外されたためです。そのため今回のエラーはRails6以前からRails7にアップグレードすると発生します。

## 対応
webpackerがインストールされるようにします。
手順としては`lib/tasks/yarn.rake`を作成して下記の内容を記載します。
```shell
Rake::Task["assets:precompile"].enhance [ "yarn:install" ]
```
ただ、サポートが切れているのでプロジェクトによっては他に移行した方が良いかと思います。

## 参考

この記事は下記を参考にさせていただきました。ありがとうございました。
- https://tech.basicinc.jp/articles/230
Windows上でPysparkを用いたデータ処理④　～余談編：マジックコマンドについて～

# はじめに
2年目に突入したエンジニアでございます。

今回は突然Sparkを用いてデータ処理を行うことになり、
周りがMacPCやVirtualBoxでのLinux環境を使用する中、
なんとかWindowsメインで何とかならないかと試行錯誤した過程の第四弾です。

前回まででようやくSparkアプリケーションを起動してデータを読み込むところまで確認しました。

https://qiita.com/ys_kmr/items/160d8453e8a43dc98adf

https://qiita.com/ys_kmr/items/10147791a0e187dc3cc4

https://qiita.com/ys_kmr/private/7bb2d314ba74a1fd4324

# 今回の目的：JupyterNotebook上で便利なマジックコマンドについて知りたい

今回はSparkの処理等から外れて、
JupyterNotebookで使える便利なコマンドであるマジックコマンドについて紹介します。

[1. マジックコマンドとは](#1-マジックコマンドとは)
[2 ラインマジックコマンド](#2-ラインマジックコマンド)
[3. セルマジックコマンド](#3-セルマジックコマンド)

## 1. マジックコマンドとは

マジックコマンドはJupyterNotebookなどで利用できる特別なコマンドで、
Pythonコードの実行とは異なる特別な機能を提供します。

マジックコマンドには以下の2つのタイプがあります。

-  [ラインマジックコマンド](#2-ラインマジックコマンド)
コマンドが単一の行で実行されます。行の先頭に `%` を付けて使用します。
例えば、`%timeit` はコードの実行時間を計測するラインマジックコマンドです。

- [セルマジックコマンド](#3-セルマジックコマンド)
コマンドが複数行のコードセル全体に適用されます。行の先頭に `%%` を付けて使用します。
例えば、`%%timeit` は複数行のコードの実行時間を計測するセルマジックコマンドです。

マジックコマンドはシステムコマンドの実行、プロファイリング、
環境変数の設定など、さまざまな機能を提供しています。

https://ipython.readthedocs.io/en/stable/interactive/magics.html

## 2. ラインマジックコマンド

|コマンド|説明|
|---|---|
|`%quickref`||マジックコマンドの一覧を表示|
|`%run`|外部のPythonスクリプトの実行|
|`%timeit`|コードの実行時間の計測|
|`%load`|スクリプトファイルの内容の読み込み|
|`%whos`|変数の一覧を表示|
|`%pip list`|ライブラリの一覧を表示|
|`!pip install ライブラリ名`|ライブラリをインストール|
|`%config`|各種オプションを設定する|
|`%_info`||

## 3. セルマジックコマンド

|コマンド|説明|
|---|---|
|`%%bash`|Bashコマンドの実行|
|`%%html`|セル内でHTMLコンテンツの表示|
|`%%writefile`|ファイルへのコンテンツの書き込み|
|`%%time`|セルのじっくお時間を計測|
|`%%capture`|セルの出力を一時的にキャプチャする|


# おわりに

今回は短かったですが、最後まで読んでいただきありがとうございます。

今回はJupyterNotebookを使用する上で便利なマジックコマンドについて紹介しました。
このほかにも大量に用意されており、sparkmagicなど追加することもできるので調べてみてください。
少しでも参考になると幸いです。

ありがとうございました。

# 参考

https://ipython.readthedocs.io/en/stable/interactive/magics.html

https://qiita.com/azumabashi/items/a8c8b1433e2e8eba39bc

https://qiita.com/mgsk_2/items/437656b8ce42c03e41a6

https://qiita.com/naka-j/items/4a5db6304be65c13b796
2023/7/18主にITとかセキュリティの記事

SOHOルータで隠れるマルウェア「AVrecon」発見、近年最大規模の知られざる脅威(7/16)
https://news.mynavi.jp/techplus/article/20230716-2728561/

3カ月活動が停滞していたCl0pが復活、今もっとも恐ろしいランサムウェア(7/16)
https://news.mynavi.jp/techplus/article/20230716-2727708/

生成AI、茨城県内大学が指針　活用前提、制限も(7/16)
https://ibarakinews.jp/news/newsdetail.php?f_jun=16894274182762

マネックスクリプトバンク、暗号資産に関する独自の格付評価モデルを考案(7/17)
https://www.jiji.com/jc/article?k=000000020.000045035&g=prt

マイナンバー混乱　河野氏の責任も調査せよ(7/16)
https://www.sankei.com/article/20230716-HCQC6DPBOBNKPHJDGY3XJSWVJI/

週刊仮想通貨ニュース｜リップル裁判の判決に注目集まる、6月の米CPI発表など(7/16)
https://coinpost.jp/?p=472766

みずほ銀行を偽るフィッシング確認、注意を(7/15)
https://news.infoseek.co.jp/article/mynavi_2633531/?tpgnr=it

サイバー攻撃の大半は人為的ミスが原因(7/16)
https://news.yahoo.co.jp/articles/32dfd6f4e9cf49c7d9471304b03741832bd44e1f?source=rss

「台湾有事シミュレーション」から見えた“日本のジレンマ”とは(7/16)
https://news.yahoo.co.jp/articles/547b8a1ea352044d1afa7b861b116790bfebde5e
【Uipath】PiP（ピクチャ イン ピクチャ）の認証エラーの解消（Microsoft アカウント利用者向け）

ずっとピクチャ イン ピクチャが認証エラーになって使えずだったのですが、解消しました。
同じハマり方をしている人がいらっしゃるかと思い記事にしました。

（例）ピクチャインピクチャの実行方法
---
　studioの画面上部のタブからデバッグにあるピクチャインピクチャをクリックします。
　　![p2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/264141/b2d34c0c-6da0-3a71-9458-d9647d829a6e.png)

　そうすると認証時のダイアログが出ます。正しい認証情報を入力してもエラーになります。
　　![p1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/264141/4af6c8aa-da2f-0ca3-71d9-1c20e95a099c.png)

　仕方がないので、解消に向けて色々調べてみました。
---
https://docs.uipath.com/ja/robot/standalone/2021.10/user-guide/picture-in-picture

　公式ドキュメントを見てみますが、今回の事象に関するヒントは見つかりません。

[【UiPath】ピクチャインピクチャについて（前編）](https://qiita.com/miya_gis/items/a306e887a024f9d69db6)
　PiPの仕組みに関する記事を拝読させていただきました。
　なるほど、RDPの拡張機能を利用しているのですね！

[Remote Desktopで"お使いの資格情報は機能しませんでした"と表示される場合の対処法](https://qiita.com/Shion1305/items/45fb2d099db39febc1a0)
　Microsoftアカウントの資格情報の保存方法に関する記事を見つけました。
　なんとWindowsバグだったとは。。

ということで、通常PINでサインインしているところ、パスワード認証でサインインし直しました。:sunny:
これで正常に認証でき、ピクチャインピクチャが利用できるようになりました。
同じ事象でお困りであれば、お試しください。
![p3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/264141/35de74ea-cd6f-b9a9-a3bc-ee42302b0a18.png)

以上です。ご精読いただき、ありがとうございました。

参考
---
 こちらの記事を参考にさせていただきました。有難うございました。
　・[【UiPath】ピクチャインピクチャについて（前編）](https://qiita.com/miya_gis/items/a306e887a024f9d69db6)
　・[Remote Desktopで"お使いの資格情報は機能しませんでした"と表示される場合の対処法](https://qiita.com/Shion1305/items/45fb2d099db39febc1a0)
【Unity】SwirlShader

## 概要
渦を巻いて小さくなっていくエフェクトです。
![Swirl.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3112894/f7ce568e-5bf1-df31-7b3b-7d2e972582b2.gif)

## 実装
HLSL
```
// 渦巻きShader
Shader "Custom/Swirl"
{
    Properties
    {
        _MainTex ("Texture", 2D) = "white" {}
        _Progress ("Progress", Range(0, 1)) = 1.0
        _Power ("Power", Range(1.0, 3)) = 3
        _MinSpeed ("Min Speed", float) = 10
        _MaxSpeed ("Max Speed", float) = 90
    }
    SubShader
    {
        Tags {
            "RenderType"="Transparent"
            "Queue"="Transparent"
            "IgnoreProjector"="True"
            "RenderPipeline"="UniversalPipeline"
        }
        LOD 100

        Pass
        {
            Name "ForwardLit"
            Tags { "LightMode"="UniversalForward" }

            Cull Off
            Lighting Off
            ZWrite Off
            Blend SrcAlpha OneMinusSrcAlpha

            HLSLPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            // make fog work
            #pragma multi_compile_fog

            #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"

            struct Attributes
            {
                float4 positionOS : POSITION;
                float2 uv : TEXCOORD0;
            };

            struct Varyings
            {
                float2 uv : TEXCOORD0;
                float4 positionHCS : SV_POSITION;
            };

            sampler2D _MainTex;
            half _Progress;
            half _Power;
            half _MinSpeed;
            half _MaxSpeed;

            CBUFFER_START(UnityPerMaterial)
            float4 _MainTex_ST;
            CBUFFER_END

            Varyings vert (Attributes v)
            {
                Varyings o;
                o.positionHCS = TransformObjectToHClip(v.positionOS.xyz);
                o.uv = TRANSFORM_TEX(v.uv, _MainTex);
                return o;
            }

            half4 frag (Varyings i) : SV_Target
            {
                float2 uv = i.uv;

                uv *= 2.0;
                uv -= float2(1, 1);

                half len = length(uv);
                half rSpeed = lerp(_MaxSpeed, _MinSpeed, len);

                half sinX = sin((1 - _Progress) * rSpeed);
                half cosX = cos((1 - _Progress) * rSpeed);

                float2 trs = mul(uv, float2x2(float2(cosX, sinX), float2(-sinX, cosX)));
                trs /= pow(_Progress, _Power);

                trs += float2(1, 1);
                trs /= 2.0;
                if (trs.x > 1 || trs.x < 0 || trs.y > 1 || trs.y < 0)
                {
                    discard;
                }
                return tex2D(_MainTex, trs);
            }
            ENDHLSL
        }
    }
}
```

## あとがき
参考リンク
https://godotshaders.com/shader/swirl-sink/
Google Cloud Functionsでログイン後の画面からデータのダウンロード

# 前書き
業務で管理画面からデータを収集するコードを作成していて、最初はselenium+AppleScriptでmacbookをスリープしない設定にして自動化していました。
しかし、こうすると動かしているmacbookは指定の時間には必ずネットワークに接続していないといけません。
どこかに遊びに行く時などにも一応持って行くmacbookで実装してしまったため、前にバッチ処理で使ったことのあったGoogle Cloud Functions(GCF)に移植できないかと思って、色々と試していました。

## 問題1:Google Cloud Functionsでseleniumを動かす例が少ない
seleniumは、Pythonを含め様々なツールで使えるようになっているウェブサイトのテスト自動化ツールです。
その自動化部分をスクレイピング用のツールとして使われることが度々あります。
そんなseleniumですが、GCFのようなサーバーレス環境で使われる例はあまりありません。
あったとしても、2020年が最終更新のserverless-chromeを使ったものなどです。

## 問題2:javascriptによるファイルのダウンロードがうまくできない。
なんやかんやserverless-chromeを用いて実装して、実際にデプロイしたところ、目的のボタンを押してもファイルがダウンロードがされませんでした。

GCFは/tmp下以外読み込み専用になっているのが問題なのかと思い、tmpをダウンロード先に指定してもうまく行きませんでした。
serverless-chromeが問題なのか、対象のサイトが問題なのかああでもない、こうでもないと色々と無駄な時間を過ごしました。

## 解決策
やる気の失せた自分は、chatGPTにseleniumの代替案を聞いたところ、puppeteerというヘッドレスchromeを操作できるnode.jsのライブラリがあるということを知り、pythonにもそのラッパーのpyppeteerが存在することを知りました。

node.jsで動くなら、pythonでも動くやろという精神で実装したところ、実際にうまくいきました。
```python:data_download_puppeter.py
import asyncio
from pyppeteer import launch
async def main(dl_path):
    browser = await launch()
    page = await browser.newPage()
    cdp = await page.target.createCDPSession()
    await cdp.send(
        "Page.setDownloadBehavior",
        {"behavior": "allow", "downloadPath": dl_path},
    )
    ##以降に、ページへのアクセスからデータをダウンロードするところまでの自動化手順を記述する
    ...

if __name__ == "__main__":
    asyncio.get_event_loop().run_until_complete(main())
```
また、asyncを利用しているため、subprocessで上記のプログラムを呼び出すことでGCFで実際に動かすことができます。
```python:main.py
import subprocess
def main_process(event={}, context={}) 
    result = subprocess.run(
        ["python", "data_download_puppeter.py"], capture_output=True, text=True
    )
    print(result.stdout)
    ##以降でダウンロードしたファイルを処理する。
```

## 最後に
よくよく調べると、ヘッドレスが最近のChromeだと組み込まれてるっぽいので、もしかしたらこんなことをやらずにseleniumで実装できるのかも？


## 参考
[pyppeteerの使い方](https://rinoguchi.net/2020/08/pyppeteer-manual.html)
軽量・セキュアな .dockerignore の書き方


# .dockerignore の悩み

こいつ、 `.gitignore` を同じ仕様に見えて微妙に若干違ったりするので、 `.gitignore` からコピペで生成したりすると良きせぬファイルが混じってセキュリティの低下や転送時間増加を招くことがある。

# 解決策

すべてを無視する設定を1行目に入れ、 `!` 始まりで選択的にディレクトリやファイルを指定することでdocker build時に最小限のファイル転送で済むようになる。

```bash
# すべてを無視する
**
# ただし、以下は許可する
!prisma/**
!src/**
!test/**
!.tool-versions
!nest-cli.json
!package.json
!pnpm-lock.yaml
!tsconfig*
```

唯一、後に転送が必要になる親ディレクトリを足した際に `.dockerignore` の更新を忘れる可能性があるという欠点があるが、今のところこれが `.dockerignore` 設定のベストプラクティスだと思う。
powershellではchmodが使えない


## ■はじめに
```
The authenticity of host 'ec2-XX-XXX-XXX-XXX.ap-northeast-1.compute.amazonaws.com (XX.XXX.XXX.XXX)' can't be established.
ECDSA key fingerprint is SHA256:5vDb7b5ozqxJ0FbDv9Qao4LYSd5a+Do5p6Ay6/ZNyV0.
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Warning: Permanently added 'ec2-XX-XXX-XXX-XXX.ap-northeast-1.compute.amazonaws.com,XX.XXX.XXX.XXX' (ECDSA) to the list of known hosts.
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@         WARNING: UNPROTECTED PRIVATE KEY FILE!          @
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
Permissions for 'web-site.pem' are too open.
It is required that your private key files are NOT accessible by others.
This private key will be ignored.
Load key "web-site.pem": bad permissions
ec2-user@ec2-XX-XXX-XXX-XXX.ap-northeast-1.compute.amazonaws.com: Permission denied (publickey,gssapi-keyex,gssapi-with-mic).
```

aws上のec2に自分のPCからキーファイルを使用して接続しようとすると上記のエラーに見舞われました。
接続時の注意点というか手順の画面に「chmod 400のコマンドでアクセス制限を行ってから使うように」みたいな注意書きが書いてありますが、chmodコマンドはwindows(powershell)では使えません。

# ■代わりにicaclsコマンドを使用する


```
# $pathに対象のキーファイルのパスを設定
$path = ".\aws-ec2-key.pem"
# 対象ファイルの既存の権限をリセットする
icacls.exe $path /reset
# 操作ユーザに読み取り権限（chmod 400）を付与
icacls.exe $path /GRANT:R "$($env:USERNAME):(R)"

# 読み取り権限権限の削除（※ここまで実行すると権限が消える）
icacls.exe $path /inheritance:r
```

# ■参考文献
https://gist.github.com/jaskiratr/cfacb332bfdff2f63f535db7efb6df93
LOG1

　エンジニアの仕事について 私は詳しくないのですが
情報が平等に与えられているインターネットの世界で
アナログの紙に文章を書くだけだと もう通用しないんじゃないかと思ったので
ディスクやらカセットやらにしてソフトウェアとして売るとか
時代に合わせた発想が 試されていると思いました
　システムそのものを作るのには まだ書籍になって世の中に出回っていない専門知識がいるのかなとか 考えています
読書メモ：ソフトウェアアーキテクチャの基礎

# はじめに
https://www.oreilly.co.jp/books/9784873119823/

を読みました。
タイトルと話題になっていることに惹かれて時々期間を空けながら読み進めたので、
自分のための整理とメモを残します。

# 感想
身にならない感想ですが、「率直に難しかった」というところが一番です。
本の中身としては、
- ソフトウェアアーキテクチャとはなんぞやの解説（何を考えないといけないか）
- ソフトウェアアーキテクチャのパターンの紹介、解説
- ソフトウェアアーキテクトとして活動するために必要なこと

みたいな章立てでした。
初めは真ん中に対する知識が欲しかったのですが、自分が体験・理解しているパターン以外の話は
なかなか頭に入らず、最初と最後の点がむしろ汎用的で色々と頭に残りました。

本を読んで、例えば「あなたにとってアーキテクチャとは？」と聞かれたら、
今の自分はこう答えると思います。
「非機能要件に対するトレードオフを考え、リードすること」

この本を読んで、自分の中には、
- アーキテクチャとは非機能要件を考えることである（もしくは一部がそうである）
- アーキテクチャは正解がない、トレードオフである（正解はないが、不正解を踏み抜かないことが必要）
- アーキテクトはソフトウェア開発をリードする立場である

という考えが纏まりました。
MongoDB のデータベース作成からデータ挿入まで(Docker)


MongDBをdockerで触ったときのメモです。
初心者向けで、DB構築からデータ挿入をとりあえず出来るくらいです。

```docker-compose.yaml
version: '3'
services:
  mongo:
    image: mongo
    ports:
      - 27017:27017
    volumes:
      - ./db/data:/data/db
      - ./docker-entrypoint-initdb.d:/docker-entrypoint-initdb.d:ro
    environment:
      MONGO_INITDB_ROOT_USERNAME: "root"
      MONGO_INITDB_ROOT_PASSWORD: "password"
    command: ["mongod", "--bind_ip",0.0.0.0]
    container_name: "mongo"
```

[MONGO_INITDB_ROOT_USERNAME]と[MONGO_INITDB_ROOT_PASSWORD]を環境変数として、指定しておくと、adminデータベースに管理者ユーザとパスワードを自動的に作成してくれます。
commandは「mongod --bind_ip 0.0.0.0」を実行をすることを示しています。これを実行すると、mongodbサーバのすべてのインタフェースから接続を受け付けるようになります。


```
      - ./docker-entrypoint-initdb.d:/docker-entrypoint-initdb.d:ro
```
上記部分は、docker-entrypoint-initdb.d内のスクリプトを実行するための設定です。mongodbが作成された後に、実行されます。このdocker-entrypoint-initdb.dの中には以下のjavascriptを保存しておきます。

```init-mongo.js
db = db.getSiblingDB('admin');
db.auth('root','password');
db = db.getSiblingDB('TestDB');
db.createCollection('TestCollection');
```

上記javascriptはadminデータベースに接続し、db.auth()で認証をします。rootユーザとして認証出来ているので、その他のデータベースへの操作も可能となります。
認証出来たら、db.getSiblingDB('TestDB');で任意のデータベース(今回はTestDBという名前のデータベース)に切り替え、createCollectionでコレクションを作成します。
コレクションを作成したら、コレクションに対し、データを挿入していきます。

データの挿入はpymongoを使用して、pythonから実行する方法もありますが、今回はコンソールから実行してみます。
```
mongosh --eval "db.TestCollection.insert({name:"testName"})" --username "root" --password "password"
```
成功すると、以下の様に返ってきます。
```
{
  acknowledged: true,
  insertedId: ObjectId("XXXXXXXXXXXXXXXXXXXXX")
}
```
### 補足？
今回は管理者ユーザを使用していますが、ユーザ作成とロール作成が必要ですね。。。
とりあえず、触るだけの状態

## 参考URL
https://www.mongodb.com/
【ShellScript】複数の配列を繰り返し処理する方法


## 方法

次のように記述することで複数の配列を同時に繰り返し処理できます。  

```sample.sh
alphabet=(a b c d e)
kana=(あ い う え お)
for ((i=0; i<"${#alphabet[@]}"; i++)); do
  echo "${alphabet[i]}${kana[i]}"
done

```

```terminal
$ bash sample.sh
aあ
bい
cう
dえ
eお

```
共同開発　ルーティング　nemespace

自分のメモ用程度に作成してます。
### :shamrock:namespaseを使用して顧客と管理者のルーティング作成

:star:**管理者用**
```routes.rb
      devise_for :admin, skip: [:registrations, :passwords], controllers: {
      sessions: "admin/sessions"
    }
      namespace :admin do
        get '/' => 'homes#top'
        resources :items, except: [:destroy]
        resources :genres, only: [:index, :create, :edit, :update]
        resources :customers, only: [:index, :show, :edit, :update]
        resources :orders, only: [:show, :update]
        resources :order_details, only: [:update]
      end
```
:snowflake:**namespace :admin do**を指定することで管理者と顧客に分けてcontrollerやviewsを作成できる。
URLにadminが含まれる。
パス：/admin/items
コントローラー：Admin::itemsController
のようになる。
:star:**顧客用**
```routes.rb
      devise_for :customers, skip: [:passwords], controllers: {
      registrations: "public/registrations",
      sessions: 'public/sessions'
    }
   
    scope module: :public do
    root :to =>"homes#top" 
    get '/about' => 'homes#about'
    resources :items, only: [:index, :show]
    resources :customers, only: [:show, :edit, :update] do
      collection do
        get 'check_out'
        patch 'withdraw'
      end
    end
     resources :cart_items, only: [:index, :update, :destroy] do
      collection do
        delete 'all_destroy'
      end
    end
     resources :orders, only: [:new, :create, :index, :show] do
      collection do
        get 'confirm'
        get 'complete'
      end
    end
     resources :addresses, except: [:new, :show]
  end
end
```
:snowflake:**scope module: :public**という記述は、Railsのルーティングで、「この範囲のルーティングはpublicフォルダ内のコントローラを使う」と指示するためのものです。これにより、コントローラの配置場所とコードの整理がしやすくなります。ただし、この設定は**namespace :admin do**のようにURLに/publicが含まれるわけではありません。

:snowflake:**collection do**はRailsのルーティングにおいて、特定のリソース全体に対して動作するカスタムアクションを定義するためのブロックです。具体的には、特定のIDを必要としないアクションを追加するのに使います。例えば、check_outやwithdrawのようなアクションです。
______
```routes.rb
#管理者側ルーティング
      devise_for :admin, skip: [:registrations, :passwords], controllers: {
      sessions: "admin/sessions"
    }
#顧客側ルーティング
      devise_for :customers, skip: [:passwords], controllers: {
      registrations: "public/registrations",
      sessions: 'public/sessions'
    }
```
:snowflake:ここではdevise_forメソッドを使用して、adminとcustomersという2つの異なるユーザーグループ（管理者と顧客）に対する認証機能を作成しています。devise_forはDeviseというRailsの認証システムを利用するためのメソッドです。

:snowflake:**skip: [:registrations, :passwords]** の部分では、特定の認証関連のルート（パスワード変更や登録など）をスキップ（除外）しています。例えば、skip: [:registrations, :passwords]を指定すると、新規登録やパスワード変更のルートは作成されません。

**管理者用**：管理者がログイン・ログアウトできる機能を提供します。新規登録やパスワードの変更はスキップします。
**顧客用**：顧客が新規登録、ログイン、ログアウトを行う機能を提供します。パスワードの変更はスキップします。
_________

**参考**

https://zenn.dev/goldsaya/articles/db16acaad100b3


https://pikawaka.com/rails/destroy_all