OmniAICreator/Qiita-1.07M huggingface dataset:
VisualStudioのLiveShareを使ったDraw.ioのリアルタイム共同編集

最近は開発プロジェクトをリモートワーク(テレワーク)だけで実施することが当たり前になってきており、「アジャイル」に作業をするために、ZoomやTeamsのホワイトボード、ExcelやGoogle Sheetsの共同編集、Miroのような共同編集に特化したサービス等を使用して複数人でリアルタイムに一つの成果物を作成・編集して、オフライン開発と同等かそれ以上に生産性を向上させているような開発プロジェクトも出てきているかと思います。

同様にソースファイルもVSCode拡張機能の「LiveShare」を使うことで、複数人で同時編集したりレビューを実施できますが、これにVScode拡張機能版として提供されている「Draw.io」を組み合わせることでUMLのドローイングもリアルタイム共同編集が実現できることを最近知ったので、セットアップ方法や注意点を残しておこうと思います。

リアルタイム共同編集は一昔前は簡単にはできなかったことなので、なんとなく「先端開発感」を感じれると思います。
何かとChatGPTが話題になっていますが、このような環境が徐々に整備されてくると、自分が作成した成果物をChatGPTがリアルタイムにアドバイスしてくれるような時代もそう遠くはないように思えますね。

(astah*Proにもこの機能が実装されるといいのになあ、、、）

# 準備

## 1. VScodeをインストール

VSCode未インストールの場合は以下からVisualStudioCodeをダウンロードしてインストール
https://code.visualstudio.com/download
※起動後の「テーマ」選択はお好みのテーマを選択

## 2. プラグインをインストール

画面左側のメニューアイコンの「拡張機能」からプラグインをインストール
* Japanese Language Pack for Visual Studio Code
※初回起動後に日本語の言語パックをインストールするか聞いてくるためインストール済みの場合あり
* Drawio Integration
* Live Share

# LiveShare実行方法

## 1. Draw.ioの動作確認

### フォルダ(Workspace)選択
[ファイル]⇒[フォルダを開く]で任意のフォルダを選択する。
※フォルダ(Workspace)を作成しないとLiveShareで閲覧できないので注意

### dioファイル作成
VScode内の「エクスプローラ」の作成したフォルダ内にで拡張子がdioとなる任意のファイルを作成しクリックして開く
Draw.ioの編集画面が表示されることを確認する。
※「ダークモード」だと使いにくいため画面右下の「Theme: XXXXX」を「Theme: Kennedy」へ変更することをおすすめします

## 2. Live Shareの設定

### Githubアカウント作成

Live ShareではGitHubのアカウントまたはMicrosoftアカウントを使用するため、アカウントを持っていない場合は以下からアカウントを作成する
https://github.co.jp/

### Live Shareの設定手順

[ホスト]
* 画面左側のメニューアイコンの「Live Share」の「SESSION DETAILS」から「Share」を選択すると認証が発生するので「Github」でログインする。
* ログログイン後に[SESSION DETAIL]の横にある「Copy Colaboration Link」アイコンや「More Info」などからリンクをコピーしてメンバーへ共有

[ゲスト]
* 画面左側のメニューアイコンの「Live Share」から「SESSION DETAILS」から「Join」を選択し共有されたリンクを入力すると認証が発生するので「Github」でログインする
* [VISUAL STUDIO LIVESHRE(WORKSPACE)]からホスト側で作成したdioファイルが閲覧でき、クリックしてDraw.ioの画面が表示されて閲覧・編集できれば設定完了
 
2人以上で動作確認できない場合は、VSCodeを2つ起動して各々「ホスト」「ゲスト」に見立てて接続確認する

# おまけ

残念ながら私が自社で使用しているPCは、インストールされているセキュリティソフトの制約から「LiveShare」が接続できない状況です。もし、そのような環境の場合、「ホスト」側はVScodeのデスクトップ版を使用し、「ゲスト」側は[VScodeのオンライン版](https://vscode.dev) を使用することで使える(拡張機能のインストールが必要)場合があるので、一度お試しください。
※どうやらVScodeのオンライン版はLiveShareの「ホスト」になれないようです

追記:2024/6/6
インターネット経由で接続する場合セキュリティソフト等の影響でうまく接続できない場合があるようです。
その場合、VSCodeにて[ファイル] > [ユーザー設定] > [設定](setting.jsonの設定)で「liveshare.connectionMode」を「auto(初期値)」から「relay」変更することがで接続できる場合があるようですのでお試しください。
(恐らくゲスト側のみの設定で問題ないと思われますがホスト型とゲスト側双方での設定をお試しください)

参考サイト:Live Share の接続要件
https://learn.microsoft.com/ja-jp/visualstudio/liveshare/reference/connectivity#changing-the-connection-mode
paizaラーニング（Bランク）

はじめまして、kaitanです。
今回はちょくちょく勉強のために解いているpaizaラーニングの練習問題について、理解が出来なかったところを復習用にまとめておくなど。
# Bランクアップメニュー
＜問題＞
行数 H , 列数 W の盤面があり、各マスには文字が 1 つだけ書かれています。盤面と y , x 座標 が与えられるので、盤面の与えられた座標の文字が "." の場合は "#" に、"#" の場合は "." に書き換えた後の盤面を出力してください。

なお、マスの座標系は左上端のマスの座標を ( y , x ) = ( 0 , 0 ) とし、
下方向が y 座標の正の向き、右方向が x 座標の正の向きとします。

```
H W
S_0
...
S_(H-1)
y x
```

* 1 行目には盤面の行数を表す整数 H , 盤面の列数を表す整数 W が与えられます。
* 続く H 行には、盤面の i 行目の文字をまとめた文字列 S_i が与えられ、 S_i の j 文字目は、盤面の i 行目の j 列目に書かれている文字を表します。(0 ≦ i < H, 0 ≦ j < W)
* 続く 1 行 には、 文字を書き換えるマスの y , x 座標が与えられます。


＜正解＞
```Python
H, W = map(int, input().split())
```

まずは行数、列数のH、Wを受け取る。map関数すごい便利そうなので使い方を覚えておきたい。

```Python
S = [list(input()) for _ in range(H)]
```

次に座標系を「リストのかたちで」受け取っている。ここの考え方は合っていた。
何度繰り返すかは行数分だけ入力があるのでrange(H)となっている。

```Python
y,x = map(int, input().split())
```

. を # に、#を.に変更する座標が与えられる。これはmap関数を使っておけばよい。

```Python
if S[y][x] == ".":
    S[y][x] = "#"
else:
    S[y][x] = "."
```

y座標とx座標の順番に気を付けつつ、"."なら"#"へ、"#"なら"."へ変更する。
リストのため、スライスで上書きができるのが便利。ここがこの問題のキモだったような感じがした。

```Python
for i in S:
    print("".join(i))
```

自分的に大きな発見だったのがここ。いつもリストからstrへの変換で悩んでいたがjoin関数で連結できるのが便利。
1項目の""は区切り（今回は不要）、2項目はfor構文でSの各列を拾ってそのつどjoinして連結させている。
（改行は自動ではいるっぽい。）
【VSCode】html.erbファイルでエメットを使用する方法

## はじめに
VSCodeを再インストールしたとき、erbファイルでエメットを使う設定方法を忘れてしまっていたので、書き残します。

+ VSCod 1.76.2
## 設定方法
まずVSCodeの設定を開きます
![スクリーンショット 2023-03-22 12.48.17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3071346/40f20eec-64cb-b027-692d-a204dbcf2e10.png)
開いたら、検索バーに「emmet」もしくは「emmet include」と入力し、「emmet: Include Languages」の項目追加をクリックする。 
![スクリーンショット 2023-03-22 12.50.10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3071346/7e2f7826-ff9f-ef76-0b26-cb92eaeeb706.png)
項目に「erb」、値に「html」を追加したら、OKをクリックします。
![スクリーンショット 2023-03-22 12.50.28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3071346/13291a36-18fc-3456-f72b-81499b5c2374.png)
これでerbファイルでもエメットが利用できるようになります！

## エメットが効かない場合
エメットが反映されない場合、次のことを試してみてください。
### Emmet: Trigger Explanation On Tabにチェックを入れる
設定で「emmet trigger」と検索し、チェックを入れる
![スクリーンショット 2023-03-22 13.20.42.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3071346/b4eecb82-6c0e-9570-e1eb-75c6a3190951.png)

### Emmet: Trigger Expanded Addreviationをalwaysにする
設定で「emmet trigger expanded」と検索し、「always」に設定する。
![スクリーンショット 2023-03-22 13.22.25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3071346/4d85b881-a6b1-69bd-22f1-e17abe691b30.png)
PS5ってどうなってんの？【スペック・GDDR・SSD編】

# PS5を手に入れた！！！
2020年11月12日に発売されて以降入手困難だったPS5を先日とうとう入手することができました。なかなか入手することができず購買意欲は枯れ果てていたのですが、ある日何気なくAmazonでPS5を検索してみると、
「あれ？Primeのマークがついてるなぁ」
「FREE deliveery Tomorrow！！？？？買えるやん！」
ということで即買い。最近進めていたPS4版Wo longをPS5へ移行してプレイしてからPS5の虜になっています。これでも組込みエンジニアの端くれなのでPS5の中身がどうなっているのか調べてみよう！というのがこの記事の導入である。
仕事じゃないので体系的に内容をまとめるつもりはなく、気になったところを深掘りしたり寄り道したりしながら色々調べていこうと思います。

# 公式 PS5分解映像
調べてみるとYoutubeに公式の[PS5の分解映像](https://www.youtube.com/watch?v=iLKvWhcA_KU)が公開されていました。
<iframe width="1280" height="720" src="https://www.youtube.com/embed/iLKvWhcA_KU" title="PlayStation®5 分解映像" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen></iframe>

#### 言及されていたスペックなど

|  |PS5スペック|PS4スペック(比較用)|
|---|---|---|
|CPU  |x86-64-AMD Ryzen "Zen2" (8コア16スレッド、MAX3.5GHz)|x86-64-AMD "Jaguar" (8コア)|
|GPU  |AMD Radeon RDNA 2-based graphics engine (Max2.23GHz, 10.3TFLOPS)|AMD Radeon based graphics engine (1.84TFLOPS)|
|メモリ  |GDDR6 16GB (帯域幅Max448GB/s)|GDDR5 8GB|
|ストレージ|SSD 825GB (カスタムSSDコントローラで転送速度5.5GB/s)|HDD (500GB/1TB)|

# GDDRとは？
Graphics DDRと言って、要は高速大容量の処理が必要なグラフィクス系に特化したDDRで転送帯域がめちゃくちゃでかいとのこと。その分信号のタイミング制約などが非常に厳しくGPUのそばに近接して設置する必要があるらしい。メインメモリに使用されるDDRとは設計思想から違って、DDRはどちらかと言うと小さなデータを高速にランダムアクセスするのに優れているのに対して、GDDRは大量のデータをとにかく高速にアクセスするのに特化しているらしい。なのでPS5においてもこのグラフィクス用のGDDRに加えて、512MBのDDR4がシステム(OS)用に実装されている模様。
こうなるとシステム的な繋がりやフローが気になり始める…

## ストレージ小さくない？
と思ったそこの方。私もでした。確かPS4でも1TB選択できたはずだよね、と。実はPS5では圧縮機能があって、ローカルに保存するアプリケーションは圧縮されてSSDに保存されているらしい。参照記事によるとSubnauticaというゲームはPS4では14GBの容量を食っていたが、PS5のSSD上では5GBしかなかったとのこと。ソニー的にはコストとか何かしらの制約を考えてサイズを抑えるために圧縮してるんだろうか。~~自分の環境のWo longで確認しようと思ったがPS4を取り出すのが死ぬほど面倒くさい…~~

## 次回
多分続くと思います。気になったところのメモ。
- ブロックダイアグラム
- システムフロー（一般的なゲームの話）
- オープンワールドゲーについて

# 参考文献
この記事は以下の情報を参考にして執筆しています。
- [DDR SDRAMとGDDRの違いは？用途や実装形態、動作の違いをまとめてみた](https://www.videotech.tokyo/2021/10/ddr-vs-gddr.html)
- [DDRメモリとGDDRメモリの違いは何ですか？](https://cloudo3.com/ja/hardware/ddr%E3%83%A1%E3%83%A2%E3%83%AA%E3%81%A8gddr%E3%83%A1%E3%83%A2%E3%83%AA%E3%81%AE%E9%81%95%E3%81%84%E3%81%AF%E4%BD%95%E3%81%A6%E3%82%99%E3%81%99%E3%81%8B%EF%BC%9F/33301838)
- [Sony PlayStation 5 SoC die pictured up close](https://videocardz.com/newz/sony-playstation-5-soc-die-pictured-up-close)
- [The PlayStation 5's compression tech can drastically reduce game file sizes](https://www.techspot.com/news/89769-playstation-5-compression-tech-can-drastically-reduce-game.html)
ChatGPTを相手に想定問答を行う

# はじめに
Twitterで想定問答をやってるツイートを見かけたのでさっそくやってみた。
感想としては、自分の考えを整理できて、それをアウトプットに反映できるところがいい。

# 質問文例

```
以下のシチュエーションで、私がプレゼンをやります。
あなたはこのプレゼンの仮想質問者として、発表者に対して毎回質問を投げかけてください。

# プレゼンのタイトル
スクリプト活用による変更作業の再現性向上

# プレゼンのテーマ
普段はlinuxコマンドの手動実行で変更作業を行っている作業者が
スクリプト活用により業務改善に成功したインフラエンジニアに対して何でも質問できる

# 質問方法
プレゼンに対して、チャットで、１問ずつ、質問する。
発表者は、質問に対して、専門的知見を持って回答する。

# 終了方法
発表者から「今日はここまで！」という説明があったら終了

では、始めます。早速質問をしてください。
```

# 実際の様子
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/416263/f3bcb9d0-aa4b-e693-dfef-10f63a74f0bd.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/416263/3ebbb3dc-4195-ae39-5764-52a299fdf78c.png)
【一般】続、HTML Post時にユーザートークンを使用してみる

以前に投稿した記事 [【一般】HTML Post時にユーザートークンを使用してみる ](https://qiita.com/Miki_Yokohata/items/514b8bdbbb5ae09e4e11)に関連する追加記事です。

以前の投稿記事では、生成したユーザートークンを直接 拡張表現式に記入しました。
しかし、トークンをシステムプロパティに設定することで、一種の定数のように使用でき、変更が発生した場合でもクエリを開く必要がなくなり、メンテナンスが容易になります。

ここではそれについて説明します。

## システム プロパティの定義 ##
システムプロパティは、独自のコードで値を定義できる Sharperlight 機能の 1 つであり、コードを指定することで他の Sharperlight オブジェクトから参照できます。
ここでは、ユーザートークンをシステムプロパティとして定義し、クエリの拡張表現式で参照するようにします。

[Sharperlight](https://www.sharperlight.com/)アプリケーションメニューから**システムのプロパティ**を選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2530698/ff4d3fcf-5d5d-6835-2f59-7bb59236c02c.png)
[システムのプロパティ] ウィンドウが開いたら、[新規] ボタンをクリックして、新しいシステム プロパティの作成を開始します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2530698/ab28adc6-c43f-7f6c-6e02-ce42ac6326bc.png)
**ユニークコード**を入力し、**値**を設定します。 この場合、ユーザー トークンを値フィールドに入力します。 「保存」ボタンをクリックして保存します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2530698/90f16f88-4886-5a1f-519c-d9489864063f.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2530698/300440c1-925c-2526-30cf-4071c3027237.png)
## システム プロパティの使用 ##
以前の投稿[【一般】HTML Post時にユーザートークンを使用してみる ](https://qiita.com/Miki_Yokohata/items/514b8bdbbb5ae09e4e11)で使用した公開レポートを開きます。
クエリ定義を開き、定義してある拡張表現を開きます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2530698/8695eb62-6457-ac2f-005c-a4d179bd2d46.png)
この部分をシステムプロパティを参照する関数に置き換えます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2530698/2d9ad931-99b3-1692-5427-bafd6eb9d1ee.png)
「検索」テキスト フィールドに **system pro** と入力します。
関数 `Get a System Property by name SystemPropertyGet(code, defaultValue)`をダブルクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2530698/91a5b75d-d5a7-e667-4463-fa63bbda5c28.png)
テンプレートが拡張式関数の構文テキストフィールドに表示されます。
トークンのシステム プロパティのコードを設定します。 デフォルト値として、**システムプロパティに'AdminToken' を設定してください**というメッセージを設定しました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2530698/f76c1ad7-6d4f-2e65-91cd-9bad3cac2de7.png)
これで完了、実行時に実際のトークンに置き換えられます。
ユーザー トークンが変更された場合でも、このクエリを更新する必要はなく、変更はシステムプロパティを更新することによって処理されます。
Python3のインスタンス変数

***Python3***のインスタンス変数についてのプログラムを実装しました。


```Python
# 新規作成 2023/3/22
# インスタンス変数

class MenuItem:
    def info(self,name,price):
        # 「 ○○: ¥□□ 」となるように出力してください
        self.name = name
        self.price = price
        print(self.name + ": ¥" + str(self.price))


menu_item1 = MenuItem()
menu_item1.info("サンドイッチ",300)

menu_item2 = MenuItem()
menu_item2.info("おにぎり",150)
```
【JavaScript】JavaScriptまとめ②(条件分岐）

# 概要
JavaScriptの理解を深めるため、
[<img width="200" alt="51vlB3JskRL.jpg" src="https://m.media-amazon.com/images/I/41vZUGXaYML._SX350_BO1,204,203,200_.jpg">](https://www.amazon.co.jp/%E3%82%B9%E3%83%A9%E3%82%B9%E3%83%A9%E3%82%8F%E3%81%8B%E3%82%8BJavaScript-%E6%96%B0%E7%89%88-%E6%A1%9C%E5%BA%AD-%E6%B4%8B%E4%B9%8B/dp/4798173266/ref=sr_1_15?crid=341O9294X80Z7&keywords=javascript&qid=1679238835&sprefix=javas%2Caps%2C185&sr=8-15)
で学習した内容を記載していく。

本記事では、条件分岐について記載する。

## if文
#### if文の書き方
```
if (条件式) {
    条件式がtrueの場合の処理;
} else {
    条件式がfalseの場合の処理;
 }
```
{}で囲まれた部分をブロック文と呼ぶ。1つ目のブロック文には、条件式がtrueの場合の処理を書き、elseの後ろの２つ目のブロック文には、条件式がfalseの場合の処理を書く。

#### if文の具体例
「金額が5000円以上の場合は`送料無料`、そうでない場合は`送料800円`とコンソールに表示する」プログラムの場合。
```if_example.js
const price = 3000;

if (price >= 5000) {
    console.log('送料無料');
} else {
    console.log('送料800円');
}
```

#### else ifによって分岐を増やす
複数の条件による分岐がある場合は`else if`を使うことでプログラムを作ることができる。
```
if (条件式１) {
    条件式１が真値となる場合の処理;
} else if (条件式2) {
    条件式２が真値となう場合の処理;
} ・・・

 // 同様に何個でも条件式を追加することができる 
} else {
    どの条件式も真値にならない場合の処理;
} 
```
「重量による配送料」は、`else if`を使って以下のように書くことができる。
```else_if.js
const weight = 300;

if (weight < 250) {
    console.log('配送料２００円');
} else if (weight < 500) {
    console.log('配送料４００円');
} else if (weight < 1000) {
    console.log('配送料６００円');
} else {
    console.log('取り扱いできません');
}
``` 

#### 論理積（&&）と論理和（||）
２つの条件両方を満たすような条件を`AND条件`という。一方どちらか１つを満たせばよい条件を`OR条件`という。
このAND条件とOR条件を作るための、`&&`と`||`という演算子が用意されている。&&を`論理積演算子`、||を`論理和演算子`という。
```
条件式A && 条件式B
// AとBの両方がtrueなら、true。そうでなければfalse

条件式A || 条件式B
// AとBのどちらか１つがtrueなら、true。両方falseならfalse
```
これで、以下のようなコードも`&&`と`||`を使うことで簡潔に書くことができる。

・年齢が２０歳以上、かつ２９歳以下なら「２０代」と表示するプログラム。
・年齢が１０歳以下、または６０歳以上なら「ジュニアまたはシニア」と表示するプログラム
```and_or.js
const age1 = 25;
if (age1 >= 20 && age <= 29) {
    console.log('２０代');
}

const age2 = 65;
if (age <= 10 ||  age >= 60) {
    console.log('ジュニアまたはシニア');
}
```

## 三項演算子
シンプルなif文は、`三項演算子`を使って簡潔なコードに書き換えることができる。条件式が真値の場合は、？の後ろの値を返し、偽値の場合は：の後ろの値を返す。
```
(条件式) ?　真値のときに返す値 :　偽値の時に返す値;
```
例えば、次のようなif文を使ったコードがあったとする。
```
const size = 20;
let result;
if (size >= 30) {
    result = '粗大ゴミ';
} else {
    result = '不燃ごみ';
}
```
これを三項演算子を使って書くと次のようになる。
```
const size = 20;
const result = (size >= 30) ? '粗大ゴミ'　: '不燃ごみ';
```

## switch文
switch文はある変数がどのような値なのかによって処理を分岐させることができる。
#### switch文の書き方
```
switch (変数) {
case 値１:
    変数が値１となるときの処理;
    break;
case 値2:
    変数が値2となるときの処理;
    break;
case 値3:
    変数が値3となるときの処理;
    break;
default:
    その他の処理;
}
```
もし、どの`case`にも一致しない場合は、`default`以降の処理を実行する。

順位によって、処理を分岐させる例は以下のように書くことができる。
```switch.js
const ranking = 2;

switch (ranking) {
case 1:
    console.log('金メダル');
    break;
case 2:
    console.log('銀メダル');
    break;
case ３:
    console.log('銅メダル');
    break;
default:
    console.log('メダルなし'); 
}
```
【npm】npm installでEAGAINエラーが出たときの対処法

`npm install`を実行したところ以下のエラーが発生。（ファイルパスなどは一部省略）

```
npm ERR! code EAGAIN
npm ERR! syscall spawn sh
npm ERR! path ...
npm ERR! errno -35
npm ERR! spawn sh EAGAIN
npm ERR! command sh -c node ...

npm ERR! A complete log of this run can be found in:
npm ERR!     ....
```

よく分からなかったので色々ググっていたら、以下の記事を発見。
https://itpfdoc.hitachi.co.jp/manuals/3020/30203K2843/AJSM0023.HTM

`EAGAIN`というのが、プロセスの過多や一時的なメモリ不足が原因で発生するシステムコールエラーのようです。

そこでプロセスの過多や一時的なメモリ不足の解消方法をググりました。
https://www.4900.co.jp/smarticle/6986/

こちらを参考に起動中のアプリをいくつか終了させたあと、再度`npm install`コマンドを実行したところ、エラー解消できました！
FileMaker Pro19でODBCデータソース一覧が出ない

FileMaker Pro19にバージョンアップした際にスクリプトからODBCデータソース一覧が出ない。

FileMakerの無償サポートが1年間あるので、サポートに連絡。
管理→セキュリティ→Adminユーザ選択→詳細設定→完全アクセス選択→編集からODBC/JDBCによるアクセスにチェックを入れるよう指示されるが改善しない。
サポートからは後ほどメールでODBC設定方法のURLが送られてきたが、いずれも問題なさそう。

試しにFileMaker Pro14にダウングレードしてみたら、ODBC一覧が出た。
いろいろ調べていたら、FileMaker Pro19からは、64bitしかインストールできなくなったようだ。ODBCドライバを64bitにしてみたら、FileMaker Pro19でODBC一覧がでてきて解決した。
IBM i駆け出し日記：Power VSをACSに接続する -ACSダウンロード編-

# ACSからPowerVS環境のIBM iへ接続できるようにする
ACS(IBM i Access Client Solutions)からPowerVS上のLPARを操作できるようにします。
ACSを用いるとわざわざIBM Cloudコンソールを開かずともiの操作ができます。
まず本記事ではACSのインストール方法について記載していきます。
インストールしたバージョンは1.1.9.1です。


※[ACS](https://www.i-cafe.info/column/serials/dekiruibmi_no6)とは
IBM iへアクセスする機能を提供してくれるアプリケーションのこと。5250コンソールに接続できたり、NW管理ができたり、OSSパッケージ管理ができたり、さらにはNavigator for iというGUIでiのシステム操作ができるサービスが開けたりなどなど様々な開発や保守に便利な機能がついています。

## インストール準備
ACSはJavaで開発されたソフトのため、JRE(Javaの実行環境)の導入が必要です。
またバージョンはWindowsでは**Java8以降**、Mac OSは**Java11以降**が前提です。
今回はOracle Javaを使います。ここからインストールできます。
https://www.oracle.com/jp/java/technologies/downloads/#jdk17-ma

MacはJDKがいいとの記載ありです。

:::note warn
Technote for Mac:
When installing Java on Mac, select a JDK instead of a JRE. The JRE for Mac installs Java for only the browser. It does not install Java for other applications. Installing the JDK makes Java available to other applications such as IBM i Access Client Solutions.
:::

Macユーザーはインストールに少々注意が必要です。
参考：https://qiita.com/6onoda/items/b57d43af315e0f3c65c6#mac-%E3%83%A6%E3%83%BC%E3%82%B6%E3%83%BC%E3%81%AF%E5%B0%8E%E5%85%A5%E3%81%AB%E6%B3%A8%E6%84%8F

javaがインストールできたらターミナルで**java --version**コマンドを入力します。こんな感じで出てきたらOKです。
```
sakurakoga@sknoMacBook-Air ~ % java --version
openjdk 11.0.18 2023-01-17
IBM Semeru Runtime Open Edition 11.0.18.0 (build 11.0.18+10)
Eclipse OpenJ9 VM 11.0.18.0 (build openj9-0.36.1, JRE 11 Mac OS X aarch64-64-Bit 20230213_260 (JIT enabled, AOT enabled)
OpenJ9   - 05926xxx
OMR      - f491bxxx
JCL      - 4e06xxxxx based on jdk-11.0.18+10)
```



## ACSインストール
以下にIBMidでサインインします。
http://ibm.biz/IBMi_ACS
IBMidが無い場合は、「IBMidの作成」をクリックしてIBMidを作成してください。

IBMidでサインインすると英語の記載でライセンス等の説明があります。
![スクリーンショット 2023-03-22 11.49.45.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3212743/17df4a55-83a0-c288-b4b5-73af19d3afd1.png)
内容をご一読頂き、宜しければ 「 I agree *」　にチェックを入れて、「I confirm」 を押してクリックして次へ進んでください。


画面が遷移してダウンロード用のZIPファイルの選択画面になります。


必須は一番上のモジュール **IBM i Access Client Solutions (1.1.9.1)** です(青く選択されているやつ)。
![スクリーンショット 2023-03-22 11.55.19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3212743/e10e3370-332c-c9a4-3e45-b6fa65e4f89e.png)
これをローカルの任意のフォルダーに保管しZIP解凍すれば最低限のセットアップは完了です。

中にacsbundle.jar というファイルがあり、これを起動するとACSメニュー画面が表示されます。
![スクリーンショット 2023-03-22 12.36.14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3212743/1ca7486b-3d4b-523c-7331-0553f95a177c.png)

![スクリーンショット 2023-03-22 12.38.00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3212743/9d6af767-0b27-ea1a-c5d8-ee9227afaec5.png)

アプリケーションインストールのために、任意のOS(私はMac)のapplicationタブを開いてinstall_acsを押します。
![png 2023-09-29 at 14.28.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3212743/dce55f25-b2d6-d502-95dc-b743f5ea47c4.png)


以上でダウンロードは終了です。
以降セットアップの記事に続きます。
【CSS】アイコンはSVG＋mask-imageが良さげ【IE非対応】

これまでサイト制作でアイコンを使う時は

| 方法 | メリット | デメリット |
|-----------|------------|------------|
| pngで背景画像　| 簡単 | 拡大縮小に弱い、色変えできない |
| SVGで背景画像　|拡大縮小に強い|色変えできない|
| アイコンフォント| すでにあるものを取り入れるなら簡単<br>色変えできる、拡大縮小に強い|カスタムの手間がかかる|
|SVGをそのまま埋め込む|色変えできる、拡大縮小に強い|HTMLのSVGのコードが多い|
| left       | right       | center       |
| aligned    | aligned     | aligned      |

ということで、どれも一長一短だな・・・と思ってたんですが、どこかで見かけたmask-imageが一番よさそうだったのでメモ

## SVG＋mask-imageの使い方
::afterに指定する前提です

```css
button::after {
	content: "";
	position: absolute;
	top: 50%;
	right: 30px;
	transform: translateY(-50%);
	width: 26px;
	height: 4px;
	mask-image: url('画像パス');
	mask-size: 100% auto;
	mask-repeat: no-repeat;
	mask-position: center;
	background: blue;
}
```

## SVG＋mask-imageのメリット・デメリット
### メリット
色変えできる
→backgroundを変えればOK
もちろんtransitionもできる

拡大縮小に強い
→SVGなので！
mask-sizeは指定した方が良さそう
ないと崩れるブラウザがある

SVGは背景画像のようにして使うので、HTMLにSVGのコードを書かなくて良い
→base64でもいいんですが、そこまでじゃない時はSVGの画像パスを書くのが良さそう

## 参考にしたサイト
https://zenn.dev/kagan/articles/cf3332462262f1
https://manamiw.com/svg-icon-color/
クソみたいに面倒なソースコードの変換をChatGPTにやらせる

# はじめに

プログラムを書いてると、
**仕様変更で、単純な書き換えを大量にやらなきゃいけない…** とか、
**既存のクラスにすごい似たクラスを作る必要がある…（けど継承とかコピペでは作れない…）** とかが時々ある。

例えばこんな感じのクラス。

```cs
public string? Capital { get; set; }
public string? Employees { get; set; }
public string? Bank { get; set; }
public string? Url { get; set; }
public string? Address { get; set; }
public string? BusinessPartner { get; set; }
public string? Memo { get; set; }
```

これ↑を…こんな感じ↓にしないといけないとか。あるよね？
（この例はC#だけど、C#じゃなくてもいいです。）

```cs
public string? Capital { get => Company.Capital; set => Company.Capital = value; }
public string? Employees { get => Company.Employees; set => Company.Employees = value; }
public string? Bank { get => Company.Bank; set => Company.Bank = value; }
public string? Url { get => Company.Url; set => Company.Url = value; }
public string? Address { get => Company.Address; set => Company.Address = value; }
public string? BusinessPartner { get => Company.BusinessPartner; set => Company.BusinessPartner = value; }
public string? Memo { get => Company.Memo; set => Company.Memo = value; }
```

このくらいなら手作業してもいいかもだけど、実際には10倍くらいの量がある巨大なクラスが対象だと、一気にやる気が消滅する。
**自分はもっと生産的なことをしたい。**

# ChatGPTにやらせる

私はAPIにやらせてるけど、普通のChatGPTでもbingでもできる。
長いプロンプトをごちゃごちゃ書く必要はない。
コツは、どれが変換前後の例なのかをわかりやすく示すこと。

例えばこんな感じ。

```
ユーザが入力するテキストを変換してください。

#ユーザの入力例
public string? Name { get; set; }

#変換例
public string? Name { get => Company.Name; set => Company.Name = value; }
```

あとは、複数個一気に投げても、**複数個一気に変換してくれる。**
もし変換がおかしい場合は、例を増やせばOK。
例も、複数行一気に書いていい。

# まとめ

ChatGPTを使って、文字列の簡単な変換が一気にできることを示しました。

ChatGPTで生産性を上げる方法をいろいろ考えてます。
いろいろな職業がAIにとってかわられるその日まで、AIを使い倒してやるのです。
SalesforceでのiPad、iPhone関連

[まとめページに戻る](https://qiita.com/Keiji_otsubo/items/60afc2a8d211b6f7d89f)
[まとめA～M](https://qiita.com/Keiji_otsubo/items/f3ddedee6793bf1576f8)


+ [lightningでのリストメールで添付ファイルが開けない(iphoneの問題か？)](https://qiita.com/Keiji_otsubo/items/9e64d19e98d7cd929783)
+ [lightning-inputでtype='date'/'time'/'datetime'とした場合、タブレットでタッチした際にキーボードが表示されてしまう。](https://trailhead.salesforce.com/ja/trailblazer-community/feed/0D54S00000OqTn1)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/6d6b9582-469e-7f47-2205-a3f24ae1ace0.png)

本件ですが、HTMLの<input type="date">等を使用することで解決しました。


# ログインできない

+ [Not able to login to Salesforce on iPad](https://trailhead.salesforce.com/trailblazer-community/feed/0D5KX00000MZOa0)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/590b7f08-f87e-4787-ae3d-ca6684ba936f.png)


:::note
Please check this article. 

https://wpexperts.io/blog/fix-safari-cant-establish-a-secure-connection-to-the-server-error/
 
https://trailhead.salesforce.com/trailblazer-community/feed/0D54V00007T4BeNSAV
:::
Go言語で説明する「ポリモーフィズム」について

### はじめに

ポリモーフィズムとは、メッセージが複数の形式で表示される能力です。ポリモーフィズムは、オブジェクト指向プログラミングの重要な特徴の1つとされ、実行時またはコンパイル時に達成することができます。`Golang`は軽量オブジェクト指向言語であり、インターフェースを通じてのみポリモーフィズムをサポートしています。

Go言語では、主にインターフェースを使用してポリモーフィズムが実現されます。インタフェースに定義された関数を実装する型は、インタフェースとして定義された型になります。これがGoでポリモーフィズムを実現可能にするプロパティです

### 説明

ポリモーフィズムを実現するために、Goではインタフェースが使用されます。以下は、ポリモーフィズムの例です。

```go
package main

import "fmt"

type Animal interface {
    Speak() string
}

type Dog struct {}

func (d Dog) Speak() string {
    return "Woof!"
}

type Cat struct {}

func (c Cat) Speak() string {
    return "Meow"
}

type Cow struct {}

func (c Cow) Speak() string {
    return "Moo"
}

func main() {
    animals := []Animal{Dog{}, Cat{}, Cow{}}
    for _, animal := range animals {
        fmt.Println(animal.Speak())
    }
}
```

この例では、Animalインタフェースが定義されており、Speak()メソッドを持っています。Dog、Cat、およびCow構造体はすべて、このメソッドを実装しています。そのため、これらの構造体はすべてAnimal型として扱うことができます。

最後に、forループ内で各動物のSpeakメソッドが呼び出されます。これにより、「Woof!」、「Meow」、「Moo」という異なる出力が得られます。

https://golangdocs.com/polymorphism-in-golang

https://www.geeksforgeeks.org/polymorphism-in-golang/
EC2（Amazon Linux 2）へdocker composeをインストール


## 状況

EC2インスタンス（Amazon Linux 2）上で「docker-compose」を使っていたが
2023年6月でサポート終了とのことで「docker compose」を使えるようにしたい。

すでに入っていないか確認したところ、以下のように表示されてしまった。

```
$ docker compose version
docker: 'compose' is not a docker command.
See 'docker --help'
```

## 環境

OS：Amazon Linux 2
（AMI名：amzn2-ami-kernel-5.10-hvm-2.0.20230119.1-x86_64-gp2）

```
$ docker version
Client:
 Version:           20.10.17
```

## やったこと

### [手段1] docker公式のインストール方法を試す

https://docs.docker.com/compose/install/linux/#install-using-the-repository

こちらに従って普通にインストールしようとしたところ、次のエラーに遭遇しました。

```
$ sudo yum install docker-compose-plugin
読み込んだプラグイン:extras_suggestions, langpacks, priorities, update-motd
amzn2-core                                                                                                                                   | 3.7 kB  00:00:00     
224 packages excluded due to repository priority protections
パッケージ docker-compose-plugin は利用できません。
エラー: 何もしません

### 別のEC2インスタンスでも...
$ sudo yum install docker-compose-plugin
Loaded plugins: extras_suggestions, langpacks, priorities, update-motd
No package docker-compose-plugin available.
Error: Nothing to do
```

### [手段2] Githubにある説明を見ながらインストール

https://github.com/docker/compose#linux

こちらに従ってみます。

1. ドキュメント指定の場所（今回は`/usr/local/lib/docker/cli-plugins`）を用意し
1. [release](https://github.com/docker/compose/releases)から該当のファイルをダウンロードする
1. ファイル名は `docker-compose` にする
1. ダウンロードしたファイルを`chmod +x`で実行可能な状態にする
1. 使えるか確認する

#### 1. 必要なディレクトリを用意

```
$ sudo mkdir -p /usr/local/lib/docker/cli-plugins
$ cd /usr/local/lib/docker/cli-plugins
```

#### 2. docker composeの実行ファイルをダウンロード

[release](https://github.com/docker/compose/releases)ページから、自分がほしいファイルを探してURLをコピーし、`curl`で取得しました。

![スクリーンショット 2023-03-20 17.41.57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2174570/fcfad327-9fbd-6522-b235-7474f59af5f7.png)

```
$ curl -OL https://github.com/docker/compose/releases/download/v2.16.0/docker-compose-linux-x86_64
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
  0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0
100 45.4M  100 45.4M    0     0  25.0M      0  0:00:01  0:00:01 --:--:-- 40.2M
```

 `curl`コマンドのオプションはこちらを参考にしました

https://weblabo.oscasierra.net/linux-file-download/


#### 3 & 4. リネーム、実行権限付与

```
$ mv docker-compose-linux-x86_64 docker-compose
$ chmod +x docker-compose 
```

#### 5. コマンドを打てるか確認

EC2へのsshを一度し直す必要がありました。

```
$ docker compose version
docker: 'compose' is not a docker command.
See 'docker --help'
```

↓ SSH接続し直すと...

```
$ docker compose version
Docker Compose version v2.16.0
```

バージョンが確認でき、インストール成功です。
星評価(raty)の平均値を表示する

参考
https://qiita.com/busitora2/items/5b59d1ea9e90c1b016b4

# 前提
・Userモデル
・Movieモデル
・Commentモデル

MovieモデルとUserモデルは多対多の関係です。（commentが中間テーブル）

自分の場合は星評価はすでに機能として付けていたので、平均値を表示するところからです。

commentsテーブルのデータ型はこんな感じです。
```2023***create_comments.rb
class CreateComments < ActiveRecord::Migration[6.0]
  def change
    create_table :comments do |t|
      t.text :content
      t.references :user, foreign_key: true, null: false
      t.references :movie, foreign_key: true, null: false
      t.integer :likes_count, default: 0
      t.float :raty, default: 1.0, null: false

      t.timestamps
    end
  end
end
```

```movies_controller.rb
def show
    @movie = Movie.find(params[:id])
    @comment = Comment.new
    @comments = @movie.comments
    @user = User.find_by(id: @comment.user_id) 
  end
```

```comments_controller.rb
class CommentsController < ApplicationController
  before_action :logged_in_user, only: [:create, :destroy]
  before_action :correct_user,   only: :destroy

  def create
    @comment = current_user.comments.new(comment_params) 
    if @comment.save
      flash[:success] = 'レビューを投稿しました。'
      redirect_to movie_path(@comment.movie_id)
    end
  end

  def destroy
    @comment.destroy
    flash[:success] = 'レビューを削除しました。'
    redirect_back(fallback_location: root_path)
  end

  private
    def correct_user
      @comment = current_user.comments.find_by(id: params[:id])
      redirect_back fallback_location: root_path if @comment.nil?
    end
    
    def comment_params
      params.require(:comment).permit(:movie_id, :user_id, :content, :raty) 
    end
end
```
表示したいviewに書いていきます。
```movies/show.html
<% if !@current_user_comment.nil? %>
    <h5>あなたのコメント・感想：</h5>
    <p><%= @current_user_comment.content %></p>
    <%= link_to "削除", @current_user_comment, method: :delete, data: { confirm: "本当に削除しますか？" } %>
<% else %>
    <%= form_for @comment do |f| %>
    <div class="field" id="star">
      <%= f.label :raty, "星評価：" %>
      <%= f.hidden_field :raty, id: :comment_star %>
    <script>
        $('#star').raty({
          starOff: "<%= asset_path('star-off.png') %>",
          starOn: "<%= asset_path('star-on.png') %>",
          starHalf: '<%= asset_path('star-half.png') %>',
          scoreName: 'comment[raty]',  <!-- ratyカラムへの保存 -->
          half: true,  <!-- 星半分の入力 -->
    });
    </script>
    </div>
      <%= f.hidden_field :movie_id, value: @movie.id %>
      <%= f.text_field :content, class: "text-field" %>
  
      <%= f.submit '投稿', class: "submit-btn" %>
    <% end %>
        <% end %>
//↑コメントと星評価の投稿

//↓星評価の平均値
      <div id="star-rate<%= @movie.id %>">
        <p>コメント<%= @movie.comments.count %>件</p>
      </div>   
    <script>
      $('#star-rate<%= @movie.id%>').raty({
        size      : 36,
        starOff   : '<%= asset_path('star-off.png') %>',
        starOn    : '<%= asset_path('star-on.png') %>',
        starHalf: '<%= asset_path('star-half.png') %>',
        half: true,
        readOnly: true, 
        score: <%= @movie.comments.average(:raty).to_f.round(1) %>,
        //↑ 平均点を算出し、round関数で切り上げる
      });
    </script>

    （省略）
```
Windowsユーザーが初めてのMacで戸惑ったこと（基本操作）

>随時追記予定です（23/3/22）
環境はMacBookPro, OSはv13.2.2, M2チップ

## コピペ等
|Windows|Mac|
|:--:|:--:|
|Cntrol + C|Command + C|
|Cntrol + V|Command + V|
|Cntrol + Z|Command + Z|
|Cntrol + T|Command + T|
|Cntrol + W|Command + W|

## スクリーンショット
 - 画面全体のスクリーンショット：Shift + Command + 3
 - 画面選択してスクリーンショット：Shift + Comand + 4
 -  スクリーンショットの画像をコピペしたい場合は、 **Control** ボタンも同時に押す
　（Shift + Command + 3or4 + Control）

❓ スクリーンショットはどこに格納されるか
　デスクトップに保存される（デスクトップの表示方法は[こちら](#デスクトップの表示)）
　Controleを押しながらスクショした場合は、デスクトップに保存されない
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/441429/e69862b5-0148-c11c-60d5-d79ff6a15048.png" width="500">

## ファイルを捨てる
 - ゴミ箱にドラッグ＆ドロップ
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/441429/2ca7e013-dccc-c0e0-f0b6-da197c0a7567.png" width="500">

## ブラウザ/アプリの全画面化
 - Command + Control + F
全画面化するのもやめるのも同じコマンド

（全画面前）
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/441429/2a2be80b-c293-58de-bbd7-3e3821fd7451.png" width="500">

（全画面後）
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/441429/3525ab37-f873-2187-f24f-856a05c56273.png" width="500">


## デスクトップの表示
>Windowsでは Windows ＋ D

 - Fn + F11
ホットコーナーの割当で、画面の四隅へのカーソルドラッグで自動的に表示させるようにしたほうが便利かも

## ターミナルの起動
>ターミナルとは、Windowsのコマンドプロンプトみたいなもの
 - Command + Spaceを押下し、
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/441429/0c58f4c7-ef14-53c3-9508-629e4cd6e809.png" width="500">

 - terと検索
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/441429/e955b328-d6a1-45e2-1d96-4c4bfe5383a7.png" width="500">

 - 開く
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/441429/cf762925-e516-5b14-31f5-0bac3cb5a469.png" width="500">


## システム設定の開き方
>システム設定とは、Windowsのコントロールパネルみたいなもの
 - Doc（画面下に出てくる、Windowsのタスクバーみたいなもの）の中にシステム設定があるのでクリック
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/441429/b84626eb-2df0-c637-2025-774aab5ad4e3.png" width="500">


## PC情報の調べ方（PC名など）
 - システム設定を開く
 - 一般タブをクリック
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/441429/585060d4-8ed1-bbcc-92b6-24c05e89bbfd.png" width="500">



## ダウンロードフォルダを開く
 - Docにマウスオーバー、Finderをクリック
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/441429/d8488fc8-8481-6e48-5476-031a20d8e867.png" width="500">

 - ダウンロードをクリック
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/441429/6efaa67e-c379-e692-4b48-fe24f1bc9fdf.png" width="500">


※Finderなんぞや？　ディレクトリ構造はどうなってるの？　については、こちらの記事がわかりやすかったです
https://macblog.site/finder-tree-structure/


## アプリの通知設定
アプリケーション（Slack, Googleカレンダー等）で通知を設定しても、Mac本体側でも許可しないと、通知がされません。（Slackの設定がおかしいのかと思って1時間くらい格闘しましたが、本体設定でした…）
 - システム設定 > 通知 > 各アプリ　で「通知を許可」をアクティブにする
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/441429/f4c6e7cd-0b1f-ab62-9167-7ba72312dce1.png" width="500">


## Web画像の保存
>Windowsだと、画像の上で右クリック
 - Control + 右クリック
単に右クリックだと、画像のリンク先に飛ぶor画像の拡大表示　などの挙動になります
【AmazonLinux2023】GA(一般提供開始)~AL2との違い~

■AmazonLinux2023
2023年3月15日GA
●リリースノート
https://docs.aws.amazon.com/ja_jp/linux/al2023/release-notes/relnotes-20230315.html
●詳細
https://aws.amazon.com/jp/blogs/aws/amazon-linux-2023-a-cloud-optimized-linux-distribution-with-long-term-support/
・2023年～５年間サポート
5 年間の長期サポートが付属します。最初の 2 年間の期間の後、各メジャー バージョンは 3 年間のメンテナンス期間
※メジャー リリースは 3 か月ごとに更新
※メジャーバージョンは２年毎にリリース（2025年にAmazonLinux2025がリリース予定）

■AL2との違い
https://docs.aws.amazon.com/ja_jp/linux/al2023/ug/compare-with-al2.html
・パッケージ管理コマンド
yum⇒dnf 
パッケージマネージャー AL2023 のデフォルトのソフトウェア パッケージ管理ツールは DNF です。 DNF は、Amazon Linux 2 のパッケージ管理ツールである YUM の後継です。 
※アップデートチェックコマンド
dnf check-release-update

・SELinux
デフォルトでは、AL2023 の Security Enhanced Linux (SELinux) が有効になっており、許容モードに設定されています。 
permissive モードでは、許可の拒否はログに記録されますが、強制はされません。 
SELinux は Amazon Linux カーネルのセキュリティ機能であり、Amazon Linux 2 では無効になっていました。

・OpenSSL 3
デフォルトでAL2023 は、Secure Sockets Layer (SSL v2/v3) および Transport Layer Security (TLS v1) ネットワーク プロトコルを使用します。
AL2ではOpenSSL 1.0.2であった

・IMDSv2（EC2セキュリティ強化）
インスタンス メタデータ オプション
https://dev.classmethod.jp/articles/use-ec2-imdsv2/
脆弱性があるウェブサーバーを作成時、メタデータ取得にPUTメソッドでTokenを発給しなければいけなくなりセキュリティが強化された

■特徴
・リポジトリバージョンのロック
すべての AL2023 Amazon マシン イメージ (AMI) はデフォルトで特定のリポジトリ バージョンにロックされます。

・XFSファイルシステム
AMI ルート ファイルシステム AL2023 AMI と Amazon Linux 2 は両方とも、ルート ファイルシステムで XFS ファイルシステムを使用します

・Extra Packages for Enterprise Linux (EPEL)
RHEL・CentOS互換のためのパッケージ
※AL2同様サポート対象外

・cloud-init
cloud-initはマシンの初期設定を自動で行うためのツール
cloud-init がパッケージ リポジトリを管理します。
EC2ユーザデータを利用してcloud-initを操作することも可能
https://docs.aws.amazon.com/ja_jp/AWSEC2/latest/UserGuide/user-data.html
https://qiita.com/juno_rmks/items/47080117a52e846dcb37
AL2023 では、利用できないリモート リソースによって致命的なエラーが発生し、cloud-init の実行が失敗します。この Amazon Linux 2 からの動作の変更により、より安全な「フェイル クローズ」のデフォルト動作が提供されます


■インスタンスメタデータ
EC2自身でコマンド押下
ec2-metadata --help
curl http://169.254.169.254/latest/meta-data/
[JavaScript/TypeScript]base64形式の画像データをFile型に変換したい


## はじめに
APIにリクエストする際、base64形式で来るデータをデコードする必要があり、調べていましたがいまいちしっくり来る情報がなく、先人様たちの記事を参考にbase64形式の画像データをFile型にデコードする方法を模索しました。
Node.js環境では`Buffer`を使用するのがベターらしかったので`Buffer`を用いて変換します。
## base64形式をFile形式に変換する
画像データをbase64で受けとります。
まずはbase64形式のヘッダー部分の`base64:`を取り除きます。
```typescript
const fileData =base64Data.replace(/^data:\w+\/\w+;base64,/, '')
```
次にヘッダーを取り除きbase64のコードのみとなったデータを`Buffer.from`を用いてBuffer型に変換します。
調べた限り、Buffer型への変換は現在`Buffer.from`で実行するのが推奨されていそうです。

``` typescript
const decodedFile = Buffer.from(fileData, 'base64')
```
これでBuffer型となった画像ファイルを用意できました。

これにて必要な情報が全て揃ったため、`new File()`でFile型に変換します。
``` typescript
const file = new File([decodedFile], `fileName.jpg`, { type: 'image/jpeg' })
```

これにてFile型へのデコードが完了しました。

全てのコードをまとめるとこうなります。

``` typescript
const fileData =base64Data.replace(/^data:\w+\/\w+;base64,/, '')
const decodedFile = Buffer.from(fileData, 'base64')
const file = new File([decodedFile], 'fileName.jpg', { type: contentType })
```

## まとめ
`Buffer.from`を用いて変換している記事が少なく、File型への変換をしている記事も少なかったためまとめました。
今回の記事はこちらの記事を参考に作成させていただきました。
https://dev.classmethod.jp/articles/node-js-base64-encoded-image-to-s3/
WPF VirtualizingPanel で仮想化する

VirtualizingPanelでの仮想化について学習したことをまとめおく

整理：VirtualizingPanelについて
子要素が大量にある ItemsControl などのパネルに対して、仮想化されたスクロールアイテムを提供することができます。VirtualizingPanel を使用することで、UI パフォーマンスを向上させ、大量のアイテムを持つコントロールをより効率的に扱うことができます。

仮想化可能な子要素は、同じ型である必要があり、サイズを一定に保ち、再利用が可能である.
また、仮想化が有効になるためには、VirtualizingPanel の ScrollViewer.ScrollUnit プロパティが Item に設定されている必要がある

VirtualizingStackPanelを使って仮想化を有効化した簡単な実装例

    <Grid>
        <ListBox Name="listBox" 
                 VirtualizingStackPanel.IsVirtualizing="True"
                 VirtualizingStackPanel.VirtualizationMode="Recycling">
            <ListBox.ItemsPanel>
                <ItemsPanelTemplate>
                    <VirtualizingStackPanel />
                </ItemsPanelTemplate>
            </ListBox.ItemsPanel>
        </ListBox>
    </Grid>

**仮想化がOFFになる条件**
①ListBoxなどのビューがグルーピングされている。
②ListBoxなどのCanContentScrollプロパティがfalseである。
　　※falseの場合、ピクセル単位でスクロールする（論理スクロール）。Trueの場合、ユニット（アイテム）単位でスクロールする（物理スクロール）
Android13のNFC操作でTagLostExceptionが出ない

Android13になってタグが離れた場合にTagLostExceptionではなくSecurityExceptionが発生するようになっていた。

## 謎のエラー
NFCの操作で**SecurityException**が起きていることがCrashlyticsで検知された。見たことがないパターンだったので調査。

## TagLostException
Android12まではNFCでタグ（カード等）の操作をする際に端末等からタグが捕捉されていない場合は**TagLostException**が発生していた。

かざされたカードが動いて範囲からずれた場合にも発生する。
私のアプリではこれを検知してかざし直しの要求をしていた。

## SecurityException
Android13からタグ操作を行う際に必ず呼ばれる[getTagService](https://android.googlesource.com/platform/frameworks/base/+/refs/heads/android13-release/core/java/android/nfc/Tag.java#376)で[チェック](https://android.googlesource.com/platform/packages/apps/Nfc/+/refs/heads/android13-release/src/com/android/nfc/NfcService.java#2084)が行われるようになっている。
タグが捕捉されていない場合は**SecurityException**が投げられる。

## 対応
**TagLostException**をキャッチしていたところで**SecurityException**もキャッチするように修正する必要がある。

TagLostExceptionもDeprecatedにならずに残っている。どんな理由があったのだろうか。

## 追記
この変更ですが、脆弱性対応でした。
https://nvd.nist.gov/vuln/detail/CVE-2022-20199
https://source.android.com/security/bulletin/pixel/2022-12-01
２台のMacを公開鍵暗号方式でssh接続した

AWSのEC2をMacのターミナルから操作したいと思い、練習としてmac同士をssh接続してみた。

####  まず２台のMacの役割の割り振りを決める。
私は家族に借りたMacをサーバ、自分のMacをクライアントと定めた。

#### まず、接続先のMacにリモートログインを許可する必要がある。
「システム環境設定」を開き、「共有」をクリックし、左側のサイドバーで「リモートログイン」を選択する。
そこで、リモートログインを許可するユーザーアカウントを選択する。

#### 公開鍵と秘密鍵の生成
接続元のMacで公開鍵と秘密鍵を生成する。
次のコマンドを使用して、鍵を生成する。
```zsh
ssh-keygen -t rsa
```
このコマンドを実行すると、鍵の生成場所を尋ねられる。
デフォルトの場所（/Users/ユーザ名/.ssh）にした。

もし、.sshフォルダがなければ作る。検索したら簡単に作れるので省略する。

#### 公開鍵の転送
次に、接続先のMacに公開鍵を転送する必要がある。
次のコマンドを使用して、公開鍵を転送する。
```zsh
ssh-copy-id <接続先のユーザ名>@<接続先のIPアドレス>
```
このコマンドを実行すると、接続先のMacにログインするためのパスワードが求められる。
接続先のMacのログインパスワードを入力する。

接続先のユーザ名は、接続先のMacのターミナルウィンドウで'whoami'と入力すれば確認できる。
接続先のIPアドレスは、接続先のMacの「システム環境設定」→「ネットワーク」→「詳細」→「TCP/IP」に載っているIPv4アドレスを入力する。


#### SSH接続
公開鍵が転送されたら、接続先のMacにSSH接続できる。
```zsh
ssh <接続先のユーザ名>@<接続先のIPアドレス>
```
このコマンドを実行すると、公開鍵を使用して接続先のMacに自動的にログインされる。


#### SSH接続を終了
以下のコマンドを実行する
```zsh
exit
```
Rails7でActionController::ParametersをMarshal.dumpしようとすると TypeError (can't dump IO) となる

Railsのバージョンを6.1から7.0に上げた時に```Marshal.dump(params)```みたいなコードが```TypeError (can't dump IO)```というエラーが出て一部使えなくなっていました。

paramsの中身はActionController::Parametersによるparamsです。

# 原因
一体なぜなのかよくわからなかったのですが、調べてみるとこんな結果が。以下一部引用させてもらいます
> paramsハッシュに「logging_context」ハッシュを追加し、その中に「:request」オブジェクトがあり、Marshalはそれを捨てたくないのです。

https://discuss.rubyonrails.org/t/change-6be9c498bccd8dbc-eval-error-cant-dump-io/82079


logging_contextはActionController::Parametersのinitialize時に代入される変数の一つのようです。以下引用
```actionpack/lib/action_controller/metal/strong_parameters.rb
def initialize(parameters = {}, logging_context = {})
  
  # 〜〜〜〜〜〜〜〜〜〜〜<中略>〜〜〜〜〜〜〜〜〜〜〜〜〜〜

  @parameters = parameters.with_indifferent_access
  @logging_context = logging_context <= これ
  @permitted = self.class.permit_all_parameters
end
```
https://github.com/rails/rails/blob/main/actionpack/lib/action_controller/metal/strong_parameters.rb

# logging_contextの中身を見てみる
デバッグ機能で見れるらしいという噂もありますが、方法がよくわからないのでモンキーパッチを当てて確認します。
def initializeの中身はコピペしただけのものを用意します。
```lib/monkey_patches/strong_parameters.rb
module ActionController
  class Parameters
    def initialize(parameters = {}, logging_context = {})
      parameters.each_key do |key|
        unless key.is_a?(String) || key.is_a?(Symbol)
          raise InvalidParameterKey, "all keys must be Strings or Symbols, got: #{key.class}"
        end
      end

      @parameters = parameters.with_indifferent_access
      @logging_context = logging_context
      @permitted = self.class.permit_all_parameters
      pp @logging_context # 見るだけなのでこれで
    end
  end
end
```

結果はこんな感じ
```terminal
{:controller=>"HomesController",
 :action=>"index",
 :request=>#<ActionDispatch::Request GET "http://localhost:3000/homes" for ::1>,
 :params=>{"controller"=>"homes", "action"=>"index"}}
```
全てのlogging_contextがこんな感じかはわからないのですが、とりあえず自分の環境ではこのような結果になりました。
つまり、この
```:request=>#<ActionDispatch::Request GET "http://localhost:3000/homes" for ::1>```
の部分をrails的にはdumpしたくないということでしょうか。

例えば普通に画面から送られてきているparamsをdumpしようとすると失敗します。

```tekitous_controller.rb
paramsの中身
<ActionController::Parameters {"age"=>"25"} permitted: false>

dumpしてみる
Marshal.dump(params)

結果 エラーになる
TypeError (can't dump IO)
```
logging_contextから:requestを除けばdumpができるようになるのですが、流石にそれはダメそうです。


# 対策
### 対策その1 permitするとdumpできるようになる
普通にこれが手堅いような気がします
```tekitous_controller.rb
Marshal.dump(params.permit(age: 25))
```

### 対策その2 hashに変えてしまう
私の場合はparamsだと不都合が出る場合があったのでhashに変換することでdumpできるようになりました。
parameters以外の情報が必要ないという場合はこれでもいいかもしれません。

```tekitous_controller.rb
Marshal.dump(params.to_unsafe_h)
```

### 対策その３ 新しくActionController::Parametersを作る
要素の同じActionController::Parametersであっても、その場で生成したActionController::Parametersにはrequest情報がないためdumpが可能です。
ただあまり使い所はないかもしれません。
```tekitous_controller.rb
その場でActionController::Parametersを生成
Marshal.dump(ActionController::Parameters.new(params.to_unsafe_h))

結果 dumpが成功する
"\x04\bo:!ActionController::Parameters\b:\x10@parametersC:-ActiveSupport::HashWithIndifferentAccess{\x06I\"\bage\x06:\x06EFi\x1E:\x15@logging_context{\x00:\x0F@permittedF"
```
dockerコマンド

開発環境構築
docker-compose build

Dockerコンテナを立ち上げる
docker-compose up

2つまとめて
docker-compose up --build

Dockerコンテナを停止
docker-compose stop

Dockerコンテナに接続
docker-compose exec web bash

起動中のDockerコンテナを確認
docker-compose ps
CHATGPTに翻弄されすぎた個人の備忘録（ハンドライティング編）

今回の記事はCHATGPTを使わずに書いています。
あくまで個人の考えなので、内容についてはご容赦ください。

# Microsoftの戦略
　Bingを使い始めて、OPEN-AIへのアクセスは減りました。Bingが最新のCHATGPT4だと言うので、最近はチャットオンリーで使っています。いろいろ会話をして、何となくChatgptを検索サイトとして、上手いことスクリプトを加工しているのが見えます。
　Microsoftのパターンは、たいてい回答結果にリンクが付与されていて、そこへの検索ルートを確保しつつ、今までのブラウザを通じた広告モデルに導くという戦略が見え見えでした。
　もちろんMicrosoft内でも、ＡＩコンプライアンスに関する組織があり、それなりに社会的な責任を考える部署だったらしいですが、そこも解散されたような話をチラ見しました。
　特に企業系はOFFICE365で汚染されており、先ずは既存のビジネス顧客をターゲットとして、いち早くアーリーアダプターとして押さえておきたかったというのが見え見えです。

# 世間の反応
　Youtubeを見ても、エンジニア界隈はかなりザワついています。何となくなのですが、江戸時代に海外からやってきた黒船が、まさに上陸する前のザワつきに似ています。企業は情報漏洩リスクを懸念して、まずは慎重な姿勢でCHATGPTを静観しているという状況です。
　こんな中、やはり私は個人的な業務と趣味にいち早くCHATGPTを駆使して、ようやく一周して冷静になったかなと言う感じです。（しかしながら、この2か月間で経験したことは、やはり人類が新たな段階にシフトしたなと言わざるえません）

# 私の取り組み
　Chatgptと出会った時に、まず着手したのは自分の運営しているFacebookコミュニティのレスポンス作成でした。これは【絵文字と文章で】という指示をすると、丁度いい感じのコメントをしてくれるので重宝しました。（ここで言う丁度いい感じというのが、微妙な意味を指していて、要するに、世間の反応に即して、丁度いい感じという表現をせざる得ないことを発見しました）
　つまり、今はＡＩを使っていることを悟られないように、あくまで人間がやっている前提で、不自然にならないような効率化・・・コメント作成者は、かわいい絵文字をプチプチと入れて、丁寧な気持ちで返信しているんだよと・・・手間暇かけている。じつは、ここが後の説明でも大事になってくるのですが、これからは人間が、いかに手間暇をかけたかということが、大事な時代になってくるんだと思います。

# AIの使い方
　最終的にどうしたかと言うと、コメントのトップには【AI】という肩書を入れて、今度はダイレクトにCHATGPTをコピペすることにしました。人間と言うのは、不思議なものですが、ロボットが回答としたということを書くと、どんな文章でも、すんなり受け止めてくれるようです。
　これからの時代ですが、AIを使った記事やソースには、必ずＡＩで作成したことを明示しなければいけない時代が来ると思います。例えばＴＶや雑誌、新聞には、広告を意図したものである場合、すべて広告ですという告知があるように、AIで作成しているものは、AIが作成したことを示す義務があるように思います。（仮にAIを裏で使っている場合も、最終的には世の中に出す際には、どこかで人間が責任を取るか、もしくは受け止める側が精査する必要がある）
　これは言うなれば、やはり人類がAIと向かい合う上で、法整備やコンプライアンス、そういった周辺のことを並行して進めなくてはいけない。そうでない今の過渡期は、まさに大戦国時代のように思います。

# 個人タスク
　さてさて、大きなことを書きましたが、あくまで私は立場の低い民間人なので、それらのことはお偉いさんに任せるとして、私は個人の利益のみを追求して使っていこうと思います。

プログラミング　⇒　これからはQiitaやTeratailに聞くことは無くなりそうです。Copilotもサブスク契約しましたが、すべて解約。Bing一本で十分です（AIには金をかけない!。これが我がポリシーです）

音楽作成　⇒　山活動のＰＲ用に、テーマソングを作りました。作曲はCREEVOさんに頼っていますが、いずれ何処かで別なWEBサービスも登場することでしょう。日本語という言葉のメリットがあるので、外国との差別化は出来ていますし、日本でしか成り立たないビジネスは残っていくものだと思います。

画像作成　⇒　最近はMidjourney、BlueWillowなど沢山のサイトが、タケノコのように出てきました。AI論文に出たものが、1年ほどするとサービスが登場する。そういった流れだと思いますが・・・stablediffusionのソースを触ると、キーワードのバリアがないため、とてつもない有害な画像が生じます。これはある意味、未成年禁止など、法的に取り締まらなくてはならないように思います。

動画作成　⇒　上記のような画像処理でコマ送りで処理するサイトはあります。人間が撮影したような映像を作ってくれるものはありませんが。個人的には学生時代に行ったアメリカ旅行のDV動画があり、これをいつの時代に復元してくれるものが出てくれることを願います。

# 最後に
　２か月ほどですが、本当にAIに翻弄されました。しかしながら、目の前にある、自分用のために使うアプリケーションは、やはり自分が作った方が良さそうです。半年後～１年後にどんな世界が訪れるのかは知りませんが、人としてやるべきことは、人が地道にやっていく・・・。
　流されざること岩のごとしと言いますが、いまが人類の試練の時かもしれません。

# 参考
https://www.unite.ai/best-ai-music-generators/
WPF 依存関係プロパティのオーバーヘッド

依存関係プロパティのオーバーヘッドとなる事項を調べた範囲でまとめた

整理：そもそもオーバーヘッドと何か
オーバーヘッドはある処理を行うために必要以上に必要な処理やデータを取り込んだり行うこと
例えばデータベースに対するクエリを実行する際に、必要以上のデータを読み込んでしまい、データ転送のコストが増加すること。また、プログラムで無駄な計算を行うことで、処理速度が低下すること等

依存関係プロパティに潜むオーバーヘッドとなる事項はこんなところ
**登録**
大量の依存関係プロパティを定義した場合、その登録プロセスがオーバーヘッドを引き起こすことがある

chatGPTさんは
依存関係プロパティが登録されると、CLR プロパティの基盤となるフィールドや、メソッド、イベントなどが内部的に作成されます。また、依存関係プロパティのインスタンスごとに、内部的に使用するメモリが必要になるため、多数の依存関係プロパティを定義する場合には、その数だけメモリ消費量が増加し、パフォーマンスに悪影響を与える可能性があります。
→多数の依存関係プロパティを定義する場合には、そのオーバーヘッドを軽減するために、プロパティの共有や継承、プロパティの分類やグループ化などの設計上の工夫が必要になります。また、不要な依存関係プロパティは定義せず、必要最小限のプロパティを定義することも大切

アドバイスまでしてくれた

**初期値**
依存関係プロパティの初期値が複雑である場合、その初期化処理がオーバーヘッドを引き起こす可能性があります。例えば、複数のプロパティを参照して初期値を計算する場合や、大量の初期化処理を行う場合などが該当します。

**メタデータのオーバーライド**
依存関係プロパティのメタデータをオーバーライドする場合、そのオーバーライドが多数存在する場合にオーバーヘッドが発生する可能性があります。例えば、多数の依存関係プロパティで同様のメタデータのオーバーライドを行う場合や、複数の派生クラスで同様のメタデータのオーバーライドを行う場合などが該当します。

**大量のデータのバインディング**
依存関係プロパティのメタデータをオーバーライドする場合、そのオーバーライドが多数存在する場合にオーバーヘッドが発生する可能性があります。例えば、多数の依存関係プロパティで同様のメタデータのオーバーライドを行う場合や、複数の派生クラスで同様のメタデータのオーバーライドを行う場合などが該当します。
ディレクトリ内のMarkdownファイルを全てHTMLに変換するシェルスクリプトを作る


- 指定されたディレクトリ内のMarkdownファイルをHTMLに変換するためのスクリプトを作る。

- 変換されたHTMLファイルは、元のMarkdownファイルと同じディレクトリに保存される。

- 変換後のHTMLファイルがすでに存在していて、元のMarkdownファイルよりも新しい場合は変換しないようにしている。

以下のコードをsh拡張子のファイルで保存する。
```zsh
#シェルの宣言
#!/bin/bash　

#パラメータとして渡されたディレクトリを変数directoryに格納
directory=$1

#ディレクトリが指定されていない場合、スクリプトの使用方法を出力して、スクリプトを終了
if [ -z "$directory" ]
then
    echo "Usage: convert_md_to_html.sh [directory]"
    exit 1
fi

#forループを使用して、ディレクトリ内のMarkdownファイルを１つずつ処理
for file in "$directory"/*.md; do
    html_file="${file%.md}.html" #変換後のHTMLファイル名を作成

    #変換後のHTMLファイルがすでに存在、かつ元のMarkdownファイルよりも新しい場合は、処理をスキップ
    if [ -e "$html_file" ] && [ $(date -r "$html_file" +%s) -ge $(date -r "$file" +%s) ]; then
        echo "Skipping $file - $html_file already exists and is newer than $file"
    else
        pandoc -s "$file" -o "$html_file"    #MarkdownファイルをHTMLに変換
        echo "Converted $file to $html_file" #処理されたファイル名を表示
    fi
done
```


## このシェルスクリプトの使い方
私はmdフォルダを作り、Markdown形式のファイルをそこに保存している。
上のシェルスクリプトもchange.shという名前でMarkdownフォルダ内に保存する。
Macのターミナルで、mdフォルダに移動して以下のコマンドを実行。
```zsh
sh change.sh .
```
これで、mdフォルダ内のMarkdownファイルを変換できる。
Salesforce認定アソシエイト試験の公式練習問題解説してみた-10

こんにちは

Salesforce認定アソシエイト試験の公式練習問題があるのはご存じでしょうか。
Trailheadにフラッシュカードとして何度も解ける練習問題がございます。

今回は
認定資格試験の準備: Salesforce 認定アソシエイト＞
データモデルについて学ぶ

の問題2問目を解説します


https://trailhead.salesforce.com/ja/content/learn/modules/cert-prep-salesforce-certified-associate/study-up-on-the-data-model

今回の内容は動画でも公開しています

https://www.youtube.com/watch?v=8o0XkeoKb5s

<iframe width="560" height="315" src="https://www.youtube.com/embed/8o0XkeoKb5s" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen></iframe>



本日の問題はこちらです

![数式.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531631/276cdd52-c4af-d340-3560-850e4bbcaa63.png)


正解はCの数式です

まず商談に数式項目を作成します
数式：
CloseDate - TODAY()


この数式をレポートで表示させることにより、商談完了までの日数の表示が可能です

詳細はこちらのTrailheadもご確認ください

https://trailhead.salesforce.com/ja/content/learn/modules/point_click_business_logic/formula_fields

## 他の認定アソシエイトの勉強方法について

他の勉強方法についてはこちらをご確認ください

https://qiita.com/Takaa/items/d35c9955fe8eb889d76b