OmniAICreator/Qiita-1.07M huggingface dataset:
GCP PCDE合格記(2024/2/13投稿)

# はじめに
この度GCP認定のGoogle Cloud Certified - Professional Cloud Database Engineerを受験してきましたので、勉強した内容と受験した感想を書いておきます。

# 前提
* Google CloudはSkill Boostなどで少し触った程度
* AZ-900/AZ-104/AZ-700/AZ-305/AZ-204/DP-900/AZ-500/DP-203は取得済み
* AWS認定は全て取っています(詳細は[こちら](https://qiita.com/handy-dd18/items/d21d914bf1c475d777f2))
    * [SAP on AWS認定](https://qiita.com/handy-dd18/items/18e8a856906f97bbb964)も取ってます
* AWSの実務経験あり(一部Azureも)
* Google Cloud認定は8つ目になります。

# 学習内容
受験した2024年2月12日時点では、Professional Cloud Database Engineerは英語試験のみが提供されています。
そのため、普段DeepL頼りで英語を自力で読む機会があまりない私からすると日本語試験より合格ハードルが高めだったので、いつもより重点的に試験対策をしました。
そのため、今回は以下の順番で勉強を進めました。

* ①試験対策記事をいくつか読んで、必要そうな学習箇所を確認
* ②公式ドキュメントを読みつつscrapboxにメモしながら学習
* ③[公式模擬問題](https://cloud.google.com/learn/certification/cloud-database-engineer?hl=ja)を解いて、間違えたところを深掘り
* ④練習問題([Udemy](https://www.udemy.com/share/10apFo3@gezXrE6ItFs6RVrRSTJwgTDd-CeGAbltoFvNeQgLersckxoHDpT-KN0-E6FUgm7B/)を解いて、英語試験に慣れる

## 試験対策記事を読む+公式ドキュメントで学習する
今回は毎度お世話になっているG-genさんの解説記事やQiitaの受験記事などを参考に出題範囲内のサービスや機能、べスプラについてScrapboxにメモしながら学習しました。

https://blog.g-gen.co.jp/entry/professional-cloud-database-engineer

https://qiita.com/lvep/items/434bdd3f3b9c1cf00217

こんな感じでメモしていました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/440403/bced32df-0b3b-552d-6d12-6242f39a8057.png)

G-genさんの記事が特に必要な要素を網羅的にまとめられていたので、それを元に公式ドキュメントで深掘りしつつ、Qiita記事に記載されてる観点も追加で深掘りしました。

Google CloudのDB移行周りはよくわかっていなかったので、そのあたりを事前に学習できていたのは良かったです。

## 公式模擬問題
その後は過去のGoogle Cloud試験と同様に公式の[模擬問題](https://cloud.google.com/learn/certification/cloud-database-engineer?hl=ja)を解きました。

今回は英語試験なので模擬試験も最初は英語で受けましたが、そもそも「知識が足りない」＋「英語が読めない」だと解くこと自体がままならなかったので、日本語訳して解く→復習する→英語で解く→復習する、という形にして、必要な知識と英語の学習を行いました。

## 練習問題
模擬問題のあとはUdemyで公開されている[練習問題](https://www.udemy.com/share/10apFo3@rwfmUKhglzAWUaKLeH9WuGYHQ4XI7CAg0_R1F5fCdczoy6v9gX5ncINZmU9cC3G8/)を購入して勉強しました。

50問×3セットあるうちの2セットしか解いてませんが、割と類似問題多かったので、これはやっておいて良かったです。
こちらでも日本語訳して解いた後に英語で解き直す方法をとったので、英語に慣れるのにも役立ちました。

# 受験した感想
内容というよりは英語に苦しめられました笑
内容的には公式模擬問題やUdemyの練習問題とさほど変わらないように感じました。(寧ろ少し簡単？)

英語問題の解き方については[過去に受けた英語試験](https://qiita.com/handy-dd18/items/cd9410fc2c02a28b4c1d)の時の経験を参考に、以下の方法で解きました。

* 問題文の最後を見て何を問われているか確認する
* 問題文を読んだ後、選択肢のサービス名で除外できるものを探す
* 読めない単語は読み飛ばして、文章内のサービス名の位置を確認して、前後の分から読める単語の範囲で推察する

読めない単語はかなり多かったですが、模擬問題などで頻出した単語だけは覚えていたので、なんとか意味が理解できて解けた問題が多かったと思います。

# 受験結果
無事合格でした。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/440403/7e64c1ce-eb97-a65f-d913-53526edea5a5.png)


# おわりに
残るGoogle Cloud試験は英語試験のMachine Learningだけ...と思ってたのですが、Cloud Digital LeaderとProfessional Google Workspace Administratorも残っていたので、次のGoogle Cloud試験はそのどれかを受けると思います。

この記事がどなたかの参考になれば幸いです。
macosのFlutterプロジェクトでFirebase初期化時の問題と解決策

macOS向けのFlutterアプリで`flutterfire configure`コマンドを実行した後、`[cloud_firestore/unavailable] The service is currently unavailable.`というエラーに遭遇しました。

## 問題の原因

`flutterfire configure`コマンドによって、macOS向けのアプリには`GoogleService-Info.plist`ファイルとfirebase_options.dartが生成されます。
この自動生成された`GoogleService-Info.plist`が予期せぬエラーの原因となることがあります。

## 解決策

この問題を解決するには、以下の手順を実行します。

1. **`GoogleService-Info.plist`の削除**

    `macos/Runner`ディレクトリから`GoogleService-Info.plist`ファイルを削除します。


2. **`firebase_options.dart`を使用したFirebaseの初期化**

    Firebaseを初期化する際には、`firebase_options.dart`から`DefaultFirebaseOptions.currentPlatform`を引数に渡して初期化します。これにより、各プラットフォーム向けの正しいFirebase設定が使用されます。

    ```dart
    import 'package:firebase_core/firebase_core.dart';
    import 'firebase_options.dart';

    void main() async {
      WidgetsFlutterBinding.ensureInitialized();
      await Firebase.initializeApp(
        options: DefaultFirebaseOptions.currentPlatform,
      );
      runApp(MyApp());
    }
    ```
Ubuntu Desktop 22.04.3 LTS で Flutter on Desktop

Ubuntu Desktop 22.04.3 LTSでFlutter on Desktopを使ってデスクトップアプリを作っていきたいと思います。

:::note warn
本記事はUbuntu Desktop 22.04.3 LTS（以下Ubuntu22）において、すでにVisual Studio Codeやsudoの設定が済んでいる方が対象となります。私はDebianを利用していますが、記事の説明のために今回はUbuntuを用意しました。
:::

## Flutterのインストール
https://docs.flutter.dev/get-started/install/linux


### 公式のコマンドにてFlutterのインストール
``` :bash
sudo snap install flutter --classic
```
![u01.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3698535/39854342-1173-4109-7f36-1cb3786705a7.png)
マニュアルインストールの説明もありますが、snap経由でインストールをするとPathの設定などを自動で行ってくれるので今回は公式のコマンドに従って作業を行いました。


### flutter doctorを実行
``` :bash
$ flutter doctor
```
![u02.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3698535/ab60b702-fa77-194f-2ef3-c667a1170bb9.png)
VS Codeの項目を見ると謎のエラーで怒られています。


### Unable to determine VS Code versionエラーに対応
https://github.com/flutter/flutter/issues/139027
``` :bash
flutter channel master && flutter upgrade
```
![u04.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3698535/7ae3f2bf-5e94-443c-80db-34e1a3c904cb.png)
上記のスレッドを参考にchannelをmasterに切り替えます。


## flutter doctorを再実行
``` :bash
$ flutter doctor
```
![u05.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3698535/2647d275-10c8-e8d0-c74e-4837fbd95fe4.png)
今回はDesktop BuildをやりたいのでAndroid Buildに必要なAndroid Studioの設定は行いません。


## Desktop Buildの確認

![u07.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3698535/1dfeb0aa-f0d3-2090-7fe2-8700aabfc6ba.png)

とくにエラーも出ずにあっさりとデスクトップアプリとして起動できました。Windows11未対応PCを来るべき日に備えてDebian/Ubuntuに完全移行できるように、またLinuxに無いものは自分で作れるように環境を移行していこうと思います。
【ChatGPT有＋DALL-E3】が目的物を知っているか確認。


　どうも、カーブミラーです。

　今回は、ChatGPTとDALL-E3が、目的物を知っているか確認してから、描画依頼します。

:::note info
本記事は、ChatGPT（有料版）
＋DALL-E3で行なっております。
画像はありません。あしからず。
:::

　ChatGPTとDALL-E3は、
　　別々の生成AIであることは
　　　これまでも書いてきましたね。

　それでも
　　知識ベースは
　　　近しい状態かも
　　　　しれません。

　ともかく、
　　目的物を知っているか
　　　をChatGPTさんに
　　　　尋ねます。

　今回は、
　　“編みぐるみ”と
　　　“ねんどろいど”を
　　　　尋ねます。

　“編みぐるみ”は
　　ご存知の方も
　　　多いでしょう。

　編み物で
　　ぬいぐるみを
　　　作製するものです。

　“ねんどろいど”は
　　フィギュアの一種です。

　二頭身の
　　人形で、
　　　とてもカワイイです。

　では
　　やり取りをどうぞ。
***
***user***
編みぐるみをご存知ですか？

***ChatGPT***
はい、編みぐるみについて知っています。編みぐるみは、編み針やかぎ針編みの技術を用いて作られる、布や糸から作られたぬいぐるみの一種です。日本語で「編み」と「ぐるみ（ぬいぐるみの略）」を組み合わせた言葉で、小さな動物やキャラクター、物の形をした愛らしい玩具です。色々な材料や色の糸が使用され、細かい装飾やパーツが加えられることもあります。趣味として楽しむ人も多く、手作りの温かみと個性が魅力的なアイテムとされています。
***
　合ってますね。

***
***user***
ねんどろいどをご存知ですか？

***ChatGPT***
はい、ねんどろいどを知っています。ねんどろいどは、日本のグッドスマイルカンパニーによって製造されている、可動式の小さなフィギュアです。特徴的な大きな頭部と小さな体が特徴で、アニメ、マンガ、ゲーム、映画などの様々なキャラクターが製品化されています。交換可能な表情パーツや小道具が付属していることが多く、キャラクターを様々なポーズで飾ることができます。
***
　念のため、
　　グッドスマイルカンパニーを
　　　調べてみました。合ってますw

　このあと、
　　簡単な指示をして
　　　描画ができました。
***
　とりあえず、
　　描画された“ねんどろいど”の
　　　プロンプトを出力させました。
***
***user***
英語プロンプト出力。和訳。SEED値出力。

***ChatGPT***
英語のプロンプトは次のとおりです：

"An adorable chibi-style figurine of a girl character, inspired by the Nendoroid design. This character should have large, expressive eyes, a cute, small mouth, and a simplistic yet detailed outfit that reflects a magical or fantasy theme. The figurine is posed in a cheerful stance, with one hand waving and the other holding a magical accessory, like a wand or a small creature. The background should be a soft, blurred gradient to emphasize the figurine's details and vibrant colors."

和訳はこちらです：

「ねんどろいどデザインにインスパイアされた、愛らしいちびスタイルの少女キャラクターフィギュア。このキャラクターは、大きく表情豊かな目と、かわいらしい小さな口、そしてマジカルやファンタジーテーマを反映したシンプルながら詳細な衣装を持っているべきです。フィギュアは元気な構えでポーズをとり、一方の手で手を振り、もう一方の手には魔法のアクセサリー、例えば杖や小さな生き物を持っています。背景はフィギュアのディテールと鮮やかな色を強調するために、柔らかいぼかしのグラデーションであるべきです。」
***
　ここからすると
　　“ねんどろいど”は
　　　ChatGPTさんも
　　　　DALL-E3さんも
　　　　　形状を知っている
　　　　　　とわかります。

　“編みぐるみ”も
　　同じでした。

　目的物を知っているかを
　　確認してから、指示すれば
　　　あとは細かい点を指示するだけ。
***
　知らない場合も
　　あります。

　そうした場合、
　　似た存在をもとに
　　　細かく指示します。

　似たものがないと
　　難しいかも、ですけどねw

　みなさんの
　　作品制作の糧に
　　　なれば、幸いです。

　今回は、これまで。
みかん仕分け

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


うーん、これで、一部はうまくいったんですが
２つのテストケースでだめでした。

```py
N,M = map(int,input().split())
for _ in range(M):
    w = int(input())
    if 0 < w < N:
        print(N)
        continue
    if w % N >= round(N/2,0):
        print((w//N+1) * N)
    else:
        print((w//N) * N)
```

```py
#１つ目入力
13 4
244
686
344
685

#出力（間違い）
247
689
351
689

#２つ目入力
1 2
665
429

#出力(間違い）
666
430
```

２つ目の入力は１の倍数なんですよね。。。。
四捨五入したらどうなるのか？
のは
１時間経ってしまったので強制ギブで。
ansが最初-100000となっているのが説明を読んでも分からず。

```py
N,M = map(int,input().split())

for _ in range(M):
    x = int(input())
    #とんでもなく最低値を低くしておく
    ans = -100000

    for w in range(1, 1201):
        #Nの倍数の箱でなければスキップ
        if w % N != 0:
            continue
        #多分余りをどこにするかという話？
        if abs(x - w) <= abs(x - ans):
            ans = w

    print(ans)

```

```
みかんの重さが最大で 1000 程度なので、みかんを入れる箱の候補は 1 ~ 1200 の箱です。
( N が最大 100 より、1100 の箱とかも候補になるので、余分に調べることにする )
各みかんごとにどの箱に入れるのが良いかを計算することができます。
みかん 1 つにつき、最大 1000 回程度の計算が行われるので、M(≦10) 個のみかんそれぞれに計算を行っても 10000 回程度の計算しか行われないため、制限時間に余裕をもって間に合います。
重さが x のみかんを入れる箱の求め方を考えます。
箱の候補は 1 ~ 1200 なので、変数 : w が 1~1200 の範囲で for 文を回します。
みかんを入れる箱には N の倍数が書かれているので、w が N の倍数かどうかを判定する必要があります。
w が N の倍数かどうかは、以下のように判定することができます。
w % N == 0 : (w を N で割ったあまりが 0 かどうか)
候補の箱の中で、箱に書かれた数が x に最も近い箱(複数ある場合は大きい方)を探す必要があります。
以下の変数を定義して for 文を回すと良いでしょう。
ans := これまでにみた候補の箱に書かれた番号のうち、x に最も近いもの
```

えーと。。。全然文章が理解できないです。
とくに「みかんを入れる箱の候補は 1 ~ 1200 の箱です。」
( N が最大 100 より、1100 の箱とかも候補になるので、余分に調べることにする )
のところ。

```
・ 1 ≦ N ≦ 100
・ 1 ≦ M ≦ 10
・ 1 ≦ w_i ≦ 1,000 (1 ≦ i ≦ M)
```

ってことなので、
本当はNが最大100*Mが最大10でそれらを掛けると1000。
ただし、NがMAX100なので、
たとえば、1001~1049までは1000になるが、1050以上だと実は1100の可能性もある。
そのためみかんのいれる箱は1100なのだが、念の為余分に1200まで増やすということらしい。

ここで、みかんを入れる箱は1200個とするということはわかった。
で、それらをループで回しつつ、Nの倍数にならない場合はスキップ、

```
つまりNの倍数になる箱のときだけ、候補の箱の中で、
箱に書かれた数が x に最も近い箱(複数ある場合は大きい方)を探すことになります。
```
ということで、

1つ目のケースで
#１つ目入力
10 3
24
35
3

Nが10ですね。xは24。ｗは最初は10なので、

```
w: 10
abs(x - w): 14
abs(x - ans): 100024
ans: 10
w: 20
abs(x - w): 4
abs(x - ans): 14
ans: 20
w: 30
abs(x - w): 6
abs(x - ans): 4
w: 40
abs(x - w): 16
abs(x - ans): 4
w: 50
abs(x - w): 26
abs(x - ans): 4
w: 60
abs(x - w): 36
abs(x - ans): 4
w: 70
abs(x - w): 46
abs(x - ans): 4


```
と、x−wが一番小さくなる数値を探していたわけですね。
そしてそれをansにするということをやっていたわけです。

というわけで見直します

```py
N,M = map(int,input().split())

for _ in range(M):
    x = int(input())
    #とんでもなく最低値を低くしておく
    ans = -100000

    for w in range(1, 1201):
        #Nの倍数の箱でなければスキップ
        if w % N != 0:
            continue
        #絶対値で差が限りなく小さくなる数値を探してAnsにする
        if abs(x - w) <= abs(x - ans):
            ans = w

    print(ans)

```
とこういう形になりました。

コメントも頂いていました。
そうですね、丸めるのがなかなか難しいんです。。。
それを、商（//)で解決されていました。。なるほど。
たとえば
24＋（10//2)=29 これを10で割ってかけ直すと20
35＋（10//2)＝40　これを10で割ってかけ直すと40
３はそのまま10ですね。
なるほど。。。。


```py
N,M = map(int,input().split())
for _ in range(M):
    w = int(input())
    # Nよりwが下だったら問答無用でNに寄せる
    if w < N:
        print(N)
    else:
    #それ以外は、
        print((w + N // 2) // N * N)

```

いやあ難しかったです。。。
けど、ロジックを考えるのっておもしろいですね！
PythonによるDatabricksノートブックのHTML形式でのエキスポート

メニューからはできますが、ノートブックから実行できたらと思ったのでトライします。

REST APIがあるのでこちらを使います。

[Export a workspace object](https://docs.databricks.com/api/workspace/workspace/export)


```py
# URLの取得
databricksURL = "https://" + spark.conf.get("spark.databricks.workspaceUrl")

# トークンの取得
myToken = dbutils.notebook.entry_point.getDbutils().notebook().getContext().apiToken().getOrElse(None)
```

REST APIを呼び出します。ここで重要なのは`direct_download`です。デフォルトはfalseなので指定は不要なのですが明示的に記述しています。これがfalseの場合、base64でエンコードされた文字列が返却されます。

```py
import requests
import json
import base64
 
header = {'Authorization': 'Bearer {}'.format(myToken)}
endpoint = '/api/2.0/workspace/export'
payload = """{
"path": "/Workspace/Users/takaaki.yayoi@databricks.com/20240213_notebook_html_export/export notebook as html",
"format": "HTML",
"direct_download": "false"
}
"""
 
# REST APIの呼び出し
resp = requests.get(
  databricksURL + endpoint,
  data=payload.encode("utf-8"),
  headers=header
)
```

レスポンスはJSON形式なのでパースします。

```
'{"content":"PCFET0NUWVBFIGh0bWw+CjxodG1sPgo8aGVhZD4KICA8bWV0YSBuYW1lPSJkYXRhYnJpY2tzLWh0bWwtdmVyc2lvbiIgY29udGVudD0iMSI+Cjx0aXRsZT5leHBvcnQgbm90ZWJvb2sgYXMgaHRtbCAtIERhdGFicmlj
```

```py
# JSONのパース
d = json.loads(resp.text)
d['content']

# HTMLへの書き込み
with open("/Workspace/Users/takaaki.yayoi@databricks.com/20240213_notebook_html_export/output.html", "w") as fh:
    fh.write(base64.b64decode(d['content']).decode())
```

HTMLとして保存されています。
![Screenshot 2024-02-13 at 10.55.11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/1d59bdd5-5697-e7b0-aae7-37b1089ffa65.png)

エキスポートして開くときちんとHTMLになっています。
![Screenshot 2024-02-13 at 10.55.50.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/6a3e5c67-8a59-5874-395c-dc3bb60183ab.png)


### はじめてのDatabricks

[はじめてのDatabricks](https://qiita.com/taka_yayoi/items/8dc72d083edb879a5e5d)

### Databricks無料トライアル

[Databricks無料トライアル](https://databricks.com/jp/try-databricks)
DuplicatiとStorjを使用してPCのフルバックアップを行う方法

# はじめに
皆さんこんにちは。
突然ですが、PCの定期バックアップは行っていますか？

クラウド全盛の時代であるため、定期バックアップの必要性はあまり感じていないかもしれません。
しかし、ある日突然PCがぶっ壊れることもあります。そんなときフルバックアップを取っていると、すぐさまPC環境を復元することができ便利です。

フルバックアップを取ろうとするとある程度の容量が必要になるため、既存のGoogle DriveやOneDriveでは容量が足りませんし、
SSDでRAIDを組んで自宅NASを作るのは面倒で初期投資もかかります。

そこで今回は私が行っているお手軽UbuntuPCフルバックアップ方法を紹介します。
# Duplicatiとは
https://www.duplicati.com

Linuxで動くFreeのバックアップソフトウェアを探して、Duplicatiにたどり着きました。

Duplicatiは、Windows、macOS、Linuxを含む複数のプラットフォームに対応した無料で使えるオープンソースのバックアップソフトウェアであり、FTP、SSH、Google Drive、Amazon S3など多様なストレージバックエンドをサポートしています。
# Storjとは
https://www.storj.io

言わずとしれた分散型クラウドストレージサービスです。
IPFSとBlockchainの組み合わせにより非常に安価かつ可用性が高く、Amazon S3やGoogle Cloud Storageの代替として使用する企業もいます。

同様のサービスにFilecoinがありますが、個人利用に関してはUIの良さから私はStorjを使用しています。
25GBまで無料で使用できるのでとりあえずアカウント作っておくのもオススメです。
# PCのフルバックアップを設定する
StorjのDocsに従って設定を行います。

https://docs.storj.io/dcs/third-party-tools/duplicati

### 1. Duplicatiをインストールする
[公式サイト](https://www.duplicati.com/download)からDuplicatiをインストールし、`http://localhost:8200/`にアクセスします。
### 2. 新規バックアップを作成する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2605179/2864a95f-916b-265d-2fcf-14c8f2d6892f.png)
### 3. 暗号化方式をオフにする
Storjの方でAES-256で暗号化されるため問題ありません。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2605179/874ef26d-5dc0-9e8d-342c-1849182444bc.png)
### 4. バックアップ先を設定する
画像のように項目を選択し、[Storj Docs](https://docs.storj.io/learn/tutorials/quickstart-uplink-cli/generate-access-grants-and-tokens/generate-a-token)を参考に作成したAccess Grantや、Bucket、Folderを指定します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2605179/172bfcaa-1785-8219-571a-eb1fd711c44f.png)
### 5. 通信テスト
Storjとの通信ができるかをチェックします。
### 6. バックアップ対象を設定する
特定のpathのみといった指定が可能です。例えばUbuntuだと基本home配下だけバックアップを取れば良かったりします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2605179/f2454c1a-e526-c223-94a2-2dc44649d251.png)
隠しファイルやnode_moduleといった大規模ファイルはアップロードしないといった除外設定もできるので便利です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2605179/3a67fe5b-166c-5833-4af6-3c7070752cd6.png)

### 7. バックアップスケジュールを設定する
時間と曜日を指定できます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2605179/fff3187f-0b65-2e82-2378-92e369d3e91d.png)
### 8. バックアップ設定を指定する
アップロード時のサイズ指定や、バックアップ履歴をどこまで残すかといった設定が行えます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2605179/56a6b3c6-cfad-c7f7-131f-91e9a0ff26e3.png)

### 9. 完了！
お疲れ様でした。
# さいごに
PCのバックアップは取っておいて損はありません。本当に。
この記事がとりあえずフルバックアップ取りたいと思っている人の一助になれば幸いです。
エラー対応 "dyld[94108]: Library not loaded: @rpath/Electron Framework.framework/Electron Framework"

# はじめに

Electron+Next.jsでデスクトップを開発しています。
ElectronのバージョンとNext.jsのバージョンをあげたときにエラーが発生しました。
macOSも同時期にsonomaにアップデートしました。

# 問題

MacOSでElectronを開発モードで起動した時だけ以下のエラーが発生しました。
本番ビルドすると正常に動作していました。

- バージョン
  - macOS 14.3
  - electron 27.1.2

> dyld[94108]: Library not loaded: @rpath/Electron Framework.framework/Electron Framework
>   Referenced from: <XXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX> /folder/node_modules/electron/dist/Electron.app/Contents/MacOS/Electron
>   Reason: tried: '/folder/node_modules/electron/dist/Electron.app/Contents/Frameworks/Electron Framework.framework/Electron Framework' (no such file), '/folder/node_modules/electron/dist/Electron.app/Contents/Frameworks/Electron Framework.framework/Electron Framework' (no such file), '/Library/Frameworks/Electron Framework.framework/Electron Framework' (no such file), '/System/Library/Frameworks/Electron Framework.framework/Electron Framework' (no such file, not in dyld cache)
> /folder/node_modules/electron/dist/Electron.app/Contents/MacOS/Electron exited with signal SIGABRT
>  ELIFECYCLE  Command failed with exit code 1.

# 解決方法

問題はmacOSでElectronをビルドした時に、シンボリックリンクが正常に貼られていないことが原因でした。
自分のアプリのソースコードにある `node_modules/electron` の `dist` ファイルを削除して、 `npm run postinstall` を実行すると正常に動作します。

```sh
cd app_root/node_modules/electron
rm -r dist
npm run postinstall
cd ../..
pnpm dev # 自分のアプリのdev起動方法で！
```

これで問題なく動きました。
バグが修正されるまでは、スクリプトを作るなりで対応する必要がありそうです。

https://github.com/castlabs/electron-releases/issues/144#issuecomment-1413801564

# おわりに

すぐにバージョン上げた時のエラー処理には意外と時間かかってしまうので、タイミングを考える必要がありますね..

# 参考

- https://github.com/castlabs/electron-releases/issues/144
- https://github.com/electron-userland/electron-builder/issues/7743
新卒エンジニアがProgateを二ヶ月受講した感想

## 前書き
こんにちは。りょりょです。
本日は、11月ごろから始めたProgateを受講し終えたので、その感想をつらつらと書いていきたいと思います。
これから、Progateを受講しようとしている方、大昔に受講した大先輩などに共感していただきたい内容となっております。

## 自己紹介
・新卒アプリケーションエンジニア（Ruby,Rails）
・未経験（大学では遺伝子の研究）

## やったこと
・JavaScript,Sass,SQL,Git,CommandLine各1周
・RubyOnRails,Ruby,HTML&CSS各4周

## 受講のきっかけ
私はもともと業務でRailsを使っている手前、Railsチュートリアルを使って自主学習をしようと思っていました。しかし、教育係の先輩からまだ少し早いんじゃないかというストップをかけられていたわけです。（入社2ヶ月目くらいの話です。）
そうして月日が流れ、基本情報の勉強・資格の取得などをしているうちに気づいたら11月。冬真っ盛りとなっていました。（私の住んでいる場所は、豪雪地帯なので初めての雪に、ドキドキしていました。まぁそんな気持ちも、スタッドレスタイヤですっ飛んでいきましたが、10万円…）
そんなこんなで、入社後半年くらいの11月からProgateをスタートさせることにしました。

## 受講の感想
結論から言うと、大満足！めちゃくちゃよかったと思います。
何がよかったかというと、基礎力が大幅に固まったような気がするというのが一番大きいです。
いろんな方のレビュー記事を見ていると、
・Progateは簡単すぎて、ITエンジニアには意味がない
・こんなのでは業務では通用しない
などの意見が散見されました。
しかし、全然そんなことありませんでした。確かに、Progateには要件定義・設計・環境構築・デプロイなどの一部の工程が無視されているため、Progateを勉強したら無双できるかといわれるとまったくそんなことはないと思います。
それでも、なんとなく研修をこなして、何となく実務に慣れてきてしまった基礎力皆無の雑魚雑魚エンジニアの私にとって、コードをたくさん書いて、大量のインプットをするというのは本当に基礎力を向上してくれたという実感がありました。

## これから
これからは、Railsチュートリアルを制覇したいと思っています。実はもうそれなりに取り組んでいますが、Progateや日々の業務のおかげか、本当に簡単にRailsチュートリアルをこなしています。本当は、3周位する予定でしたが、1周で十分そうです。
今後は、応用情報を取得するか、ガンガン開発していってアウトプットをしまくるか迷っている途中です。また進捗がありましたら、この場で報告させていただきます。

## あとがき
ここまで読んでくださった方、長々とお付き合いいただきありがとうございました。
学生時代の私なら、自主的にお金を払って勉強するということは、信じられなかったと思います。最近では、趣味だったスマブラやソシャゲよりも優先して、勉強しているという変わりようです。それもこれも、QiitaやZennでモチベーション・ポエム記事を書いてくださる先輩方のおかげです。いつもありがとうございます。<(..)>
地方に就職した新卒エンジニアの振り返りと目標

# 初めに
初めまして、地方でエンジニアとして採用されてもうすぐ一年がたとうとしている、りょりょです。

新卒で現在の会社に就職して、何となくSEという仕事がどんな仕事かというのが、見えてきたような気がします。会社での研修もそこそこに、簡単な仕事なら与えていただけるようになり、ちょっとずつ会社に慣れてくるくらいのフェーズだと思います。

会社員としてエンジニアとして働く中で、特に不平や不満はないですが、いい意味でも悪い意味でも一生このままというのは、私の人生に多少の閉塞感を与えてくれます。

そこで、人生を楽しくするためにも、エンジニアとして成長するためにも、Zennにて目標を書くことで自分に言い聞かせる作戦です。（きれいごとを書いていますが本当はフリーランスか起業をしてお金持ちになるというのが目標です）


# これまでとこれから
ひとまず、この一年間で何をして何ができるようになったのかを書いていきます。

###### ITパスポート・基本情報技術者の取得
資格の取得ですね。私はIT未経験だったので、基本的な業界の知識を広く浅く知ることができました。しかし、資格取得は勉強に対するコスパがあんまりよくないような気がするので（高度資格などは例外だとは思いますが）、応用情報は取らなくていいかなといった感じでいます。

#### Progate
これに関しては現在取組中です。広く浅くといった内容なので、初学者にも優しくかつ値段も良心的なので非常に良いサービスだと実感しています。しかし、設計やデプロイ、細かい業務範囲などまではカバーされていないので、あくまで前提知識みたいな感じでとらえています。このサービスのおかげで、新卒一年目としては適切なレベルの学習ができたと感じています。


そして、これから二年目に向けての目標は

#### Railsチュートリアルの完走
これはもともと目標にしていました。会社では主にRailsを用いて業務を行っている関係上、早くに勉強したかったのですが、先輩にまだ早いといわれたのでまずはProgateで基礎固めをしてから臨むという方向で学習を進めていました。これにより、現在の知識をさらに深めていければいいかなと思っています。

#### ポートフォリオ作成
これは、勉強をしている方なら言わずもがなの話かもしれませんが、学習において最も知識や経験が身につくのはアウトプットを行っている時です。一年目に、インプットばっかりの学習をしてしまっていたので、二年目からはガンガンアウトプットをして知識や技術を身に着けていきたいと考えています。

以上が今年の振り返りと来年度以降の目標です。
正直なところ、同期や年の近い同僚がいないので、学習進度やモチベーションを保つのが難しいと感じました。その代わりとして、ZennやQiitaで目標高く活動されている皆様とともに頑張りたいと思っています。

以上です。初めてで長くなって読みにくい文章だったと思います。ここまで読んでくださった方にはお詫びと感謝を申し上げます。
【Ruby,Rails】クラスメソッドとインスタンスメソッドの違い

どうもこんにちは。

今回は、初心に帰ってクラスメソッドとインスタンスメソッドについてまとめます。

# まずは実行される時の形から覚える

## クラスメソッド

クラスメソッドは以下のような形で実行されます。

```ruby:Railsコンソール
# newメソッド
pry(main)> Sample.new
# createメソッド
pry(main)> Sample.create(name: 'サンプルA')
# findメソッド
pry(main)> Sample.find(1)
# allメソッド
pry(main)> Sample.all
```

## インスタンスメソッド

インスタンスメソッドは以下のような形で実行されます。

```ruby:Railsコンソール
# インスタンスを作成してから...
pry(main)> sample = Sample.new
# saveメソッド
pry(main)> sample.save
# updateメソッド
pry(main)> sample.update(name: 'サンプルB')
```

## 違いは...

これらの違いは、メソッドを実行するのが「**モデル(クラス)に対して**」なのか「**インスタンスに対して**」なのかです。

# 定義する時の違い

## クラスメソッド

### その１ メソッド名の前にselfを明示的に記述して定義する

```ruby
class Sample
    def self.sample_method
        # 何かしらの処理
    end
end
```

`self`はメソッドを定義する対象を指します。定義した箇所での`self`は`Sample`なので、`Sample`クラスに対してメソッドを定義したことになります。そのため、`self`を`Sample`に置き換えて定義しても問題ないです。

### その2 特異クラスの中に定義する

```ruby
class Sample
    class << self
        def sample_method
            # 何かしらの処理
        end
    end
end
```

特異クラスの説明をすると長いので省略しますが、特異クラスの中に定義してもクラスメソッドとして使用することができます。`class << self; end`の間では、複数のメソッドを定義することができます。

## インスタンスメソッド

```ruby
class Sample
    def sample_method
        # 何かしらの処理
    end
end
```

インスタンスメソッドの場合に何も考えずに、メソッドを定義すればOKです。
【備忘】シングルサインオン（SSO）認証について

### シングルサインオン（SSO）認証とは？
シングルサインオン（SSO）認証は、ユーザーが1つの認証情報（ユーザー名とパスワード、または他の認証手段）を使用して複数の関連するシステムやアプリケーションへアクセスできるようにする仕組み。
これにより、ユーザーは複数のアカウントを持つ必要がなくなり、便利かつ効率的にオンラインサービスを利用で可能。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1303394/a9a9b367-bf7c-4f8c-d81f-01bf51e0cb08.png)


### シングルサインオン（SSO）の仕組み
SSOの仕組みは、次のような流れで動作する。

・**認証サーバーへのログイン**
ユーザーは認証が必要なサービスにアクセスしようとすると、まずSSOプロバイダー（認証サーバー）のログインページにリダイレクトされる。

・**認証情報の入力**
ユーザーは自身の認証情報（ユーザー名とパスワードなど）を入力し、認証サーバーにログインする。

・**トークンの発行**
認証サーバーはユーザーが正当なものであることを確認し、有効なセッショントークンを発行。

・**サービスへのアクセス**
サービスプロバイダーは、ユーザーが持つトークンを検証し、そのトークンに基づいてユーザーの認証状態を確認する。もし有効であれば、ユーザーはログインせずにサービスを利用可能。

### シングルサインオン（SSO）のメリット・デメリット
#### メリット
**利便性**
ユーザーは1つの認証情報で複数のサービスにアクセスできるため、ログイン情報の記憶や管理が簡素化される。

**セキュリティ強化**
SSOはセキュリティポリシーやマルチファクタ認証などの高度なセキュリティ機能を組み込むことができ、セキュリティの強化に寄与が可能。

**管理の簡素化**
システム管理者はユーザーのアクセス権やパスワードリセットなどを1か所で管理できるため、管理作業が簡素化される。

#### デメリット:
**単一障害点のリスク**
SSOプロバイダーがダウンした場合、ユーザーは全てのサービスにアクセスできなくなる可能性がある。

**セキュリティリスク**
SSOプロバイダーが侵害されると、ハッカーは複数のサービスにアクセスできる可能性がある。

### まとめ
シングルサインオン（SSO）認証は、ユーザーの利便性とセキュリティを両立させることで、オンラインサービスの利用体験を向上させると同時に、セキュリティリスクを最小限に抑えることができ、企業や組織がSSOを導入することで、効率性とセキュリティを高めることが可能となる。
.net8がもたらすComplex Formバインディング

.net8 RC2がリリースされ、APIに対してComplex Formバインディング機能を導入しました。アップロードファイルタグは、Complex Formの一例です。以下は、単一ファイルアップロードの例です。
.csファイルは以下の通りです：

```csharp
using Microsoft.AspNetCore.Mvc;
var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();
app.UseStaticFiles();
app.MapPost("/upload", ([FromForm] DocumentUpload document) => {
    return Results.Ok();
}).DisableAntiforgery();
app.Run();

public class DocumentUpload {
    public string Name { get; set; };
    public string? Description { get; set; }
    public IFormFile? Document { get; set; }
}
```

htmlファイルは以下の通りです：

```html
<!DOCTYPE html><html>
<head> 
    <title>文件上传表单</title>
</head>
<body>
    <h2>上传文件</h2>
    <form action="/upload" method="post" enctype="multipart/form-data"> 
    <label for="name">名称：</label><input type="text" name="name" />
    <br><br>
    <label for="description">描述：</label>
    <textarea row="3" name="description"></textarea>
    <br><br>
    <label for="file">文件：</label>
    <input type="file" name="Document" id="file" accept=".jpg, .png, .pdf">        
    <br><br>
    <input type="submit" name="submit" value="上传">
    </form>
</body>
</html>
```

実行結果：
![alt画像](https://mmbiz.qpic.cn/sz_mmbiz_png/4CAA63nvHRBx61hmQo347zApH0JLD9kQmh7SLCQ0fAiblPkYjXj1VwP4ovsHEFKztFfibPniaVKIffzpnnObR8PSw/640?wx_fmt=png)
局部変数の確認：
![alt画像](https://mmbiz.qpic.cn/sz_mmbiz_png/4CAA63nvHRBx61hmQo347zApH0JLD9kQuZ5qBeFXQPQ6rpfQ8kWTyOJlfkibzQyK8u8xo9RfqiamrAcO2pQtjeGw/640?wx_fmt=png)
複数の画像をアップロードしたい場合は、エンティティクラスのファイルリテラルタイプをIFormFileCollectionに変更すればよいです。
csコードは以下の通りです：

```csharp
public class DocumentUpload {
    public string Name { get; set; }
    public string? Description { get; set; }
    public IFormFileCollection? Documents { get; set; }
}
```

実行結果は以下の通りです：
![alt画像](https://mmbiz.qpic.cn/sz_mmbiz_png/4CAA63nvHRBx61hmQo347zApH0JLD9kQeckOSnY3QwPRPdSgSXScbGBHIO7II5bDoNy6Sbx3Dg40PribgkgOd7Q/640?wx_fmt=png)
局部変数の確認：
![alt画像](https://mmbiz.qpic.cn/sz_mmbiz_png/4CAA63nvHRBx61hmQo347zApH0JLD9kQdBeDYqOgIbU4vhCBHyUThia7oPlMd2ROWpq6iaiaia5ZSmN69wz7pIkqxw/640?wx_fmt=png)
小さな機能ですが、開発体験に大きな影響を与え、簡素化され、直感的で使いやすいです。

(Translated by GPT)
元のリンク：https://mp.weixin.qq.com/s?__biz=MzA3NDM1MzIyMQ==&mid=2247487181&idx=1&sn=f119574194e33bb2c509b9870a58bea4&chksm=9f0051e7a877d8f108763f9c95d640cae1e9a64310321cc28f79951ee17b2c24dd7b910d3434&token=2050451386&lang=zh_CN#rd
【ChatGPT】「あなたは〇〇です」パターン集

ChatGPTに役割を与える

# 記事作成
- あなたはプロのWebライターです。
- あなたは高度なSEOテクニックを駆使し、読者を引きつけるウェブコンテンツを提供するプロです。
- あなたは情報をわかりやすく伝える能力に長け、オンライン読者を魅了するウェブライターです。
- あなたは緻密なリサーチとクリエイティブな文体を組み合わせ、効果的なウェブコンテンツを生み出すプロフェッショナルです。
- あなたはブランドの声を的確に表現し、オンラインコンテンツで読者の心を捉える優れたウェブライターです。
- あなたは、ターゲットオーディエンスのニーズを的確に把握し、戦略的なコンテンツを提供する経験豊富なウェブライターです。

# Twitter テキスト作成
- あなたはXでフォロー数が多く人気があるアカウントを運用するための実績豊富なエキスパートです。
- あなたはXでフォロワー数を増やし、コンテンツを最適化するノウハウに長けたプロフェッショナルです。
- あなたはXでフォロー数を増やす秘訣を知り尽くし、コミュニケーション戦略を熟知したスペシャリストです。
- あなたはXでのフォロワー獲得に成功し、コンテンツの魅力を最大限に引き出す技術を持つ専門家です。
- あなたはXでのアカウント運用においてリーダーシップを発揮し、フォロワーの関心を維持するノウハウを持つプロです。
- あなたはXで大規模なフォロワーを持ち、熱心なコミュニティを築くアカウント運用者です。
- あなたはXにおいてフォロー数が爆発的に増え、コンテンツが拡散されるアカウントの管理者です。
- あなたはXで圧倒的な人気を誇り、コンテンツを通じて影響力を持つアカウントを運用しています。
- あなたはXでトップクラスのフォロワー数を誇り、独自のブランドを構築するアカウントのオーナーです。
- あなたはXで高い知名度と信頼を獲得し、コンテンツを通じて多くの人々にインスピレーションを与えるアカウントを運営しています。
【C#の細かいポイント】nullを適切に扱う方法

皆さんはきっとこんな例外に遭遇したことがありますよね：未将对象引用到实例（System.NullReferenceException：“Object reference not set to an instance of an object.”）。そう、これは全てのC#プログラマーにとって馴染み深い例外でしょう。でも、ベテランであっても完全に防ぐことはできません。
まず、値型は直接nullにはできません。型の後に「？」を加えることで、可null値型に拡張します：
```csharp
int i1 = default; 
Console.WriteLine(i1); 
int? i2 = null; 
Console.WriteLine(i2 ?? 0);
Console.WriteLine(i2.HasValue ? i2.Value : 0);
```

参照型は本来nullにできますが、ここでは少し問題があります。nullを防ぐためには、すべてのサードパーティの呼び出し箇所で、返り値が参照型の場合は空判定を加える必要がありますが、これはかなりの作業量になります。そこで、参照型を定義する際に型の後ろに「？」を加えることで、結果がnullを含むかどうかを区別し、この方式を使って空判定を行うと、かなり楽になります。
```csharp
string? s1 = string.Empty; 
Console.WriteLine(s1.Length); 
string? s2 = default; 
Console.WriteLine((s2 ?? string.Empty).Length);
```

```csharp
Console.WriteLine(string.Empty == "");//true
Console.WriteLine(string.Equals(string.Empty, ""));//true
Console.WriteLine(string.Empty == null);//false
Console.WriteLine(string.Equals(string.Empty, null));//false
```

以下は自作の型Orderです：
```csharp
public record Order(int Id, string Name, string? Description = null);
```

単一エンティティをクエリする場合、nullが許容される場合はOrder?として定義し、呼び出し箇所では空判定が必要です。戻り値がOrderの場合、戻り値がnullでないことを保証する必要があります。
```csharp
Order? GetOrder1()
{ 
    return default(Order); 
    //return null;
} 
Order GetOrder2()
{ 
    return new Order(default, string.Empty, default);
}
```

コレクションの場合、nullでないコレクションを返すには、次のような形式で空でないコレクションを返します。このコレクションはnullではなく、要素数は0です。
```csharp
IEnumerable<Order> GetOrders1()
{
    return Enumerable.Empty<Order>();
} 
IList<Order> GetOrders2()
{
    return new List<Order>();
} 
Order[] GetOrders3(){ 
    // return new Order[0]; 
    return Array.Empty<Order>();
}
```
(Translated by GPT)
元のリンク：https://mp.weixin.qq.com/s?__biz=MzA3NDM1MzIyMQ==&mid=2247487196&idx=1&sn=7e571eada81fbc8fe69aa91caf62e30b&chksm=9f0051f6a877d8e09806a7fac093fcbe9fa5193c61f279bbe788a19b8b737f60508c69065a90&token=2050451386&lang=zh_CN#rd
主キーの型について適しているもの　まとめ

ふと気になったやつ

||UUID|連番ID|
|---|----|---|
|必要ビット数|128ビット|BIGINT 型64 ビット<br> INT 型 32 ビット|
|衝突|理論上起こり得る|サイズ制限により可能性あり|
|分散システム|分散システムでうまく機能する|値の重複を避けるために調整コンポーネントが必要です|
|サポート|NoSQL と分散データベースによって適切にサポートされています|NoSQL および分散データベース内での使用は推奨されません。|
|規則性|あるにはあるが複雑なため、予測しにくいし覚えるのが難しい|数字の連番であるため、予測しやすいし覚えやすい|


INSERTとかSELECTとかの挙動
UUID型は、適切なキャッシュ戦略がないので純粋にテーブル全体に対するキャッシュ率の勝負になる。

ということらしい
UUIDv6,v7,v8はこれらの問題解決したものになる。ってさ

いろいろ問題解決した定義 postgres
URLとかに使えるUUIDの定義の仕方だってお
```sql
CREATE TABLE XXX(
    id SERIAL,
    uuid UUID NOT NULL,
    PRIMARY KEY (id)
    UNIQUE (uuid)
)
```
Japan AWS Jr. Champion活動記録 Vol.9

## はじめに
1月は、Jr. Champions有志による自主勉強会とAI/ML Workshopが開催されました。今回はその2つについて書いていきます。これからも活動に関して、定期的にアウトプットしていきます！

↓ 前回の記事はこちら ↓

https://qiita.com/am_i-12/items/ed6759b089a14fcee931

## Japan AWS Jr. Champion Partner Programとは
> [「Japan AWS Jr. Champion Partner Program」](https://aws.amazon.com/jp/blogs/psa/2023-aws-jr-champions/)とは、AWS Partner Network (APN) 参加企業に所属し、現在社会人歴 1 ～ 3 年目で AWS を積極的に学び、アクションを起こし、周囲に影響を与えている APN 若手エンジニアを選出しコミュニティを形成する、日本独自の表彰プログラムです。本プログラムでは、AWS に関して実践してきた技術的な挑戦や、コミュニティのリードなど自ら起点となって周囲に影響を与えているか、アウトプットを通じて周囲へ貢献しているか、という観点が評価の対象になります。2023 Japan AWS Jr. Champions に選出された方は、一定の技術力があり、社内の AWS コミュニティをリードでき、今後は Japan AWS Top Engineers そして Japan AWS Ambassadors になることが期待される皆様です。

2023年は[82名が選出](https://aws.amazon.com/jp/blogs/psa/2023-japan-aws-jr-champions/)されており、1年間Japan AWS Jr. Championsとして活動しています。

AWS Summit Tokyoの表彰時に撮影した集合写真
![img_7571_720.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2851817/b6c165ed-6033-741d-c32c-2338b9be42fe.jpeg)

## Jr. Champions勉強会
### 「CloudWatchでAPM」

:::note info
**APMとは**
APMとは、アプリケーションパフォーマンスモニタリングの略である。情報システムの稼動状態を利用者側の視点から監視し、問題点の把握や原因究明などを素早く行うこと。特に、専用のソフトウェア（APMツール）を用いてこれを自動的あるいは効率的に実施すること。
参考：[IT用語辞典e-words APM](https://e-words.jp/w/APM.html)
:::

**感想**
Re:invent 2023で発表された[Amazon CloudWatch Application Signals (プレビュー版)](https://aws.amazon.com/jp/about-aws/whats-new/2023/11/amazon-cloudwatch-applications-signals-observe-preview/)を中心に、APMについて発表してくださいました。発表者の方は、以下の通り、Amazon CloudWatch Application Signalsについて解説したQiita記事も出されていて、それも併せて拝見させていただきました。

新しいCloudWatch Application Signalsだけでなく、XrayやADOT等で行われてきたAWSのAPMの歴史も含めて紹介してくださっていて、とても興味深かったです。

https://qiita.com/AoTo0330/items/4d3cf0f6126f1a2a76c5

## AI/ML Workshop
1月のMeetUpは、AWSのパートナーソリューションアーキテクトの方と、パートナーセールスソリューションアーキテクトの方による、AI/機械学習に関する講義とハンズオンを中心に行われました。

### 講義
- 生成AIとは
- AWSにおける生成AIとは
    - Amazon Q
    - Amazon Bedrock
    - Amazon CodeWhisperer
- 生成AIのAWSトレーニングコース紹介

### ハンズオン
- CloudFormationでKendraのIndexを構築
- SageMaker Notebookインスタンスを起動
- 実際に会話してみる

**感想** 
実際に触ってみたいと思っていながら、なかなか触れていなかったKendraやSageMakerを使えてとても楽しかったです。実際に会話する場面では、「関西弁にして」や「英語にして」等で返答のスタイルを変える指示を行いました。講師の方によれば、各地の方言では関西弁が一番適切に出るようで、博多弁や青森弁などの方言ではまだ回答がうまく作られないそうです。講義内で実際に試してみたところ、確かにどの方言で指示しても関西弁ほどの完成度にはなっておらず、AIとの会話の未成熟な部分を実感することができました。

Skill Builderや社内JAMイベントでもAI・機械学習の設問を取り入れておりますが、個人でも勉強を続け、業務に活かせるものがないか、模索したいと思います！

以上です。ありがとうございました。
新卒からCKS合格までの自分のKubernetesラーニングパスをまとめる

# はじめに

私事ですが、最近CKSに合格しました。これで実技を伴うKubernetesの認定資格をすべて取りました。
そこで、今まで自分が学んだことを目に見える形にしたいと思い、ラーニングパスを書くことにしました。
これからKubernetesを学ぶ人の参考になれば幸いです。

※CKS（Certified Kubernetes Security Specialist）はKubernetesのセキュリティに関する認定資格です。

https://training.linuxfoundation.org/ja/certification/certified-kubernetes-security-specialist-cks-jp/

※実技を伴うKubernetes認定試験とはコマンドラインから問題を回答する試験のことです。現在、CKAD、CKA、CKSの３種類があります。Kubernetes認定試験には他にもKCNAがありますが、選択式の試験になります。

https://lpi.or.jp/k8s/

# 自身のKubernetesラーニングパス

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1474054/e0bf58ed-32aa-8608-da5e-1fc9202c7cbb.png)

勉強は、Kubernetesについてと、他サービスについてを並行して学んでいました。CKSの試験範囲ではありませんが、業務ではマネージドサービスを使うため、基盤にとらわれず勉強したかったためです。

CKS合格後、さらにKubernetesを極めるのであれば、CRDやマネージドサービスを学んでいく必要があると思っています。

※書き方は以下を参考にさせていただきました。

https://qiita.com/KurokawaKouhei/items/4e9aa3b526f3f233bf85

# 認定試験の範囲と対応

CKA、CKAD、CKSの範囲がラーニングパスとどのように対応するかいかに示します。
ただし、それぞれの資格は完全な上位下位の関係にあるわけではなく、役割が異なっているため、出題されるサービスは同じでも、求められる理解度が異なる場合があります。
私が学んだことベースで描いたものですので、参考程度にしていただけますと幸いです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1474054/b31aaa9d-0312-362c-ee04-d41c7f9955dc.png)

# 勉強にかかったお金

最後にCKS合格までにかかった書籍代や受験費を簡単にまとめます。
起きたイベントに対してかかった合計費用の遷移をグラフにします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1474054/2b155aee-2405-adfc-f7ac-d301ed17ea1f.png)

合計で20万近くかかっていますね。。。
その分、得たものも大きかったと思っています。

以下、買ったもの例です。
https://www.udemy.com/course/certified-kubernetes-administrator-with-practice-tests/
https://www.amazon.co.jp/基礎から学ぶコンテナセキュリティ――Dockerを通して理解するコンテナの攻撃例と対策-Software-Design-plusシリーズ-森田/dp/429713635X

# おわりに

自分の学んできたことを図にすると、「たくさんやってきたんだなー」と実感できてよいと思います。
これからも勉強します。
指定のディレクトリを開いた状態で VS Code を起動する

VS Code を普通に起動すると前回終了時の状態で開く。
特定のディレクトリを開いた状態で起動させたい場合、ショートカットのプロパティに開きたいパスを追記すればよい。

# ショートカットの設定

普通に VS Code のショートカットを作成し、プロパティの「リンク先」に開きたいディレクトリを追記するだけ。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/801825/bcdffe83-cd7e-bdbf-0797-07d76bbdaef0.png)

ショートカット名はディレクトリ名やプロジェクト名等自分が分かりやすいものに変えておく。

### Windows 上のディレクトリを指定する場合

Code.exe の後ろにパスを追記する。
余談：shift を押しながらディレクトリ (ファイル) を右クリックすると「パスをコピー」があるので、これを利用すると楽

リンク先(T): `"C:\～略～\Code.exe" "C:\Users\username\Documents\sample"`

### WSL (Ubuntu) 上のディレクトリを指定する場合

`--remote wsl+[ディストリビューション名]` を記載したうえでパスを追記する。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/801825/5ff75cd2-97b0-d21d-55f2-e1db59acade3.png)
Ubuntu 上の /hoge/username/sample を指定する場合は以下のようになる。
リンク先(T): `"C:\～略～\Code.exe" --remote wsl+Ubuntu /home/username/sample`
BCM-ARMをブートしてみた

NetBSD-10のBCM5301Xのコードをいじってブートしてみました。

https://dmesgd.nycbug.org/index.cgi?do=view&id=7501

NetBSD/armのARMv7はBCM5301X以外はFDTになっていてGENERICなカーネルです。

おそらくNetBSD-7くらいからメンテナンスされてなくて、修正したところは以下のようなところです。

* なぜかメモリの物理アドレスが違っていて、変更しました

* ~~0x80000000からメモリがあるような設定になっていましたが、実機で見ると0x00000000と0x88000000からあります。BCMな各種DTSを見ても0x80000000なアドレスはありません。~~ 0x80000000からメモリがありそれが0x00000000から見えるようになっているようです。これはブートローダーなどの便宜のためではないかと思われます。

* devmapの書き方が変わったので変更しました

* 明らかなバグも修正しました

今確認できてる問題点は以下になります。

* ネットワークやUSB2が機能しない

* USB3のコードがない

* 0x00000000からの128Mしかメモリが使えていない。0x88000000からのメモリが使えない

* DMAのtagのコードに物理アドレスが指定されている

* DIAGNOSTICを設定してカーネルを作るとccaでpanicする

* Timerがおかしい

* マルチプロセッサーのコードがない（おそらくDual-Coreと思われます）

まだいろいろいじらないとだめそうです。参考にできそうな情報は、

* Linux方面のGPLなコード

* DTSファイル

* FreeBSDのBHDNのコード

猛牛さんのGPLアーカイブはぐちゃぐちゃなので、githubで探すのが良いです。

GPLアーカイブでBCM固有の処理は以下にあります。

arch/arm/mach-brcm-hnd/*
arch/arm/plat-brcm/*
arch/arm/plat-brcm/include/*

src/shared/*

BroadcomはMIPS SOCの初期のころはSiBaという仕様だったのを、後期にBCMAという仕様に変更しました。BCMAは移行のために複雑になっています。BCM5301XはこのBCMAを踏襲しています。

なんとQiitaに[BCM5301Xを使っている人](https://qiita.com/hnw/items/14cf95651b344ce9f6e2)がいました。NetBSDではsysctlのmachdep.fpu_idでfpuの有り無しが分かります。

NetBSDのBroadcomサポートはBCM2系より先にBCM53系が実装されたようです。

FreeBSDにはBCM53のコードはありません。

このポートはU-Bootを使ったターゲットだったようで、BCM5301Xとしては特殊なものだったのかもしれません。

~~Broadcomはデーターシートを一切公開していないので、おそらくGPLなコードを解析して作られたのではないかと思われます。~~

ソースのCopyrightが2012で入っていて、チップのリリースも同時期なので、なにかの製品化に向けて開発して、データーシートも手元にあったのかもしれません。

githubにこんな定義がありました。BCM4707とBCM53010は同じものみたいです。BroadcomはMIPS SOCの頃からなぜか二つの呼び名がありました。

```
#define	BCMA_CHIP_ID_BCM4707		53010
#define	BCMA_CHIP_ID_BCM47094		53030
#define	BCMA_CHIP_ID_BCM53018		53018
```

メモリマップ

```
 * 0x0000_0000..0x07ff_ffff      128MB  DDR2/3 DRAM Memory Region (dual map)
 * 0x0800_0000..0x0fff_ffff      128MB  PCIe 0 Address Match Region
 * 0x1800_0000..0x180f_ffff        1MB  Core Register Region
 * 0x1810_0000..0x181f_ffff        1MB  IDM Register Region
 * 0x1900_0000..0x190f_ffff        1MB  ARMcore (CORTEX-A9) Register Region
 * 0x1c00_0000..0x1dff_ffff        1MB  NAND Flash Region
 * 0x1e00_0000..0x1dff_ffff        1MB  Serial Flash Region
 * 0x4000_0000..0x47ff_ffff      128MB  PCIe 1 Address Match Region
 * 0x4800_0000..0x4fff_ffff      128MB  PCIe 2 Address Match Region
 * 0x8000_0000..0xbfff_ffff     1024MB  DDR2/3 DRAM Memory Region
 * 0xfffd_0000..0xfffe_ffff      128KB  Internal Boot ROM Region
 * 0xffff_0000..0xffff_043f     1088B   Internal SKU ROM Region
 * 0xffff_1000..0xffff_1fff        4KB  Enumeration ROM Register Region
```
Formオブジェクト

# はじめに
プログラミング初心者です。現在Ruby on Railsにてアプリ作成中終盤。
間違っている箇所がありましたら、コメントお願いします。

# Formオブジェクトについて
今回Formオブジェクトという新しい概念を学びました。
このFormオブジェクトの目的は、<b>1つのフォームから送られてきた情報を複数のテーブルに保存することです。
### 手順
#### 1.Formオブジェクト用のモデルを作成します。
保存したいテーブルがorder（注文情報）とaddress（注文者の情報）だったら、order_address.rbというファイルを自主作成します。
#### 2.そのファイルにform_withで使用する機能とバリデーションを作成します。
```
include ActiveModel::Model
attr_accessor :hoge, :hogehoge,:hogehogehoge ~~~~

↓以下バリデーションの記述
```
#### 3.データをテーブルに保存する処理
```
↑バリデーションの記述

ef save
    order = Order.create(hoge: hoge, hoge_id: hoge_id, hoge_id: hoge_id)
    Address.create(hoge: hoge, hoge_id: hoge_id ~~~~)
  end
```

#### あとは
コントローラーはorders_controller.rbで大丈夫です。
しかし、コントローラー内にはしっかり@order_addressのインスタンスを作成します。

ざっくり以上です。

### 本日のエラー
本日のエラーとして次の二つの壁にぶち当たりました。
・フォームを入力して保存しようとすると、NoMethodErrorが出てしまった。
・上記が解決すると、次はActiveHashのprefecture_idが保存されない

<b>NoMethodErrorの原因

エラーによるとActiveHashのprefecture_id（都道府県）が存在しないよ〜というものでした。原因はなんとも単純、
```
attr_accessor :post_code, :prefecture_id, :city, : ~~~
```
この部分のprefecture_idの"id"が抜けていただけでした、、、、。
次、切り替えていこう、、、。

<b>Activehashが保存されない

またまたActiveHashのprefecture_idのエラーです。
ビュー画面を見ても空欄ですよ〜というエラーメッセージが出るばかりなので、コンソールを見てみました。
すると、prefecture_idが正しいのですが、なぜかコンソール上はprefectured_idになっていました。（prefecturedって笑）
原因のindex.html.erbのフォーム内を修正して解決です⭐️
Certificate-Based Authentication 証明書ベースの認証を使用した組織へのログイン


+ [IPアドレスでの公開アクセス設定の他に、サイトへアクセス可能な端末を指定するような制限・制御が必要ではないか?](https://trailhead.salesforce.com/trailblazer-community/feed/0D54V00007XIa9T)

ページ単位でのアクセス制御はできないない
ディープラーニングによる二値分類タスク：閾値の操作とPyTorchの基本

# はじめに
二値分類問題は、データが二つのクラスのいずれかに属するかを判断するタスクです。メールがスパムか否か、画像に猫が含まれるかどうかなど、多くのアプリケーションで見られます。この記事では、PyTorchを用いた二値分類モデルの構築と、予測における閾値の適切な設定方法に焦点を当てます。

# PyTorchとは？
PyTorchは、FacebookのAIリサーチチームによって開発されたオープンソースの機械学習ライブラリで、その柔軟性とパワフルな機能により、研究者や開発者から広く支持されています。PyTorchは、動的な計算グラフを提供し、複雑なアーキテクチャの構築とデバッグを容易にします。

# データの準備と前処理
モデルの訓練に先立ち、データの準備と前処理が必要です。データをモデルに供給する前に、特徴量のスケーリングや正規化を行うことで、訓練プロセスを安定させ、収束を早めることができます。以下は、データの読み込み、標準化、および訓練セットと検証セットへの分割を行う基本的な手順です。
```
import pandas as pd
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler

train_df = pd.read_csv('path/to/train_data.csv')
X = train_df.drop('target_column', axis=1).values
y = train_df['target_column'].values

# データの標準化
scaler = StandardScaler()
X_scaled = scaler.fit_transform(X)

X_train, X_val, y_train, y_val = train_test_split(X_scaled, y, test_size=0.2, random_state=42)
```
# モデルの構築
PyTorchを用いて、二値分類のためのシンプルなニューラルネットワークを構築します。ここでは、複数の全結合層を持つ基本的なアーキテクチャを使用します。
```
import torch
import torch.nn as nn
import torch.optim as optim

class BinaryClassifier(nn.Module):
    def __init__(self, num_features):
        super(BinaryClassifier, self).__init__()
        self.fc1 = nn.Linear(num_features, 128)
        self.fc2 = nn.Linear(128, 64)
        self.fc3 = nn.Linear(64, 1)
        self.relu = nn.ReLU()
    
    def forward(self, x):
        x = self.relu(self.fc1(x))
        x = self.relu(self.fc2(x))
        return torch.sigmoid(self.fc3(x))

model = BinaryClassifier(X_train.shape[1])
```
## 訓練プロセス
モデルの訓練には、適切な損失関数と最適化アルゴリズムの選択が重要です。二値分類では、二項交差エントロピー損失が一般的に使用されます。
```
criterion = nn.BCELoss()
optimizer = optim.Adam(model.parameters(), lr=0.001)
```
# 閾値の最適化
モデルが予測する値（通常は確率）をクラスラベルに変換するためには閾値が必要です。多くのケースで0.5が使用されますが、これは必ずしも最適な選択ではありません。特に、データセットが不均衡な場合や、偽陽性と偽陰性のコストが異なる場合には、閾値を調整することでモデルの性能を向上させることができます。

検証データセットを使用してモデルの性能を評価し、F1スコアなどの指標を用いて閾値を決定します。
```
threshold = 0.2  # 閾値を0.2に設定
y_val_pred = []
with torch.no_grad():
    for inputs, labels in val_loader:
        outputs = model(inputs).squeeze()
        predicted = (outputs >= threshold).float()
        y_val_pred.extend(predicted.numpy())

mean_f1 = f1_score(y_val, np.array(y_val_pred), average='macro')
print(f'Mean F1 Score: {mean_f1}')
```
# テストデータでの予測とサブミッション
最後に、選択した閾値を使用してテストデータセットで予測を行い、結果をサブミッションファイルとして保存します。
```
predictions = []
with torch.no_grad():
    for inputs in test_loader:
        outputs = model(inputs).squeeze()
        predictions.extend((outputs >= threshold).float().numpy())

sample_submission[1] = np.where(np.array(predictions) >= threshold, 1, 0)
sample_submission.to_csv('/content/drive/MyDrive/fin_tech/submission_nn_.csv', header=None)
print('Submission file has been created.')
```
# 最後に
閾値の適切な設定は、二値分類タスクにおけるモデルの性能を大きく左右します。PyTorchを使用したモデルの構築と訓練プロセスを通じて、異なる閾値でのモデルの挙動を評価し、タスクの要件に最適な閾値を見つけることが重要です。
ClosedOpportunityTriggerのトレイルヘッド




+ [We tried to insert Opportunity records as part of the challenge check, but the insert failed. Error: thException: OPP_INSERT | System.DmlException: Insert failed. First exception on row 0; first error: CANNOT_INSERT_UPDATE_ACTIVATE_ENTITY, ClosedOpportunityTrigger: execution of AfterInsert caused by: System.DmlException: Insert failed. First exception on row 0 with id 00TWU0000002p852AA; first error: INVALID_FIELD_FOR_INSERT_UPDATE, cannot specify Id in an insert call: [Id] Trigger.ClosedOpportunityTrigger: line 13, column 1: []](https://trailhead.salesforce.com/trailblazer-community/feed/0D54V00007XGrNi)

+ [Challenge is not completed.(Bulk Apex triggers)](https://trailhead.salesforce.com/trailblazer-community/feed/0D54V00007X7ESh)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/7064749f-dcb9-d01a-b8c4-23dcf42ee214.png)
cscの作法 その452

# 概要
cscの作法、調べてみた。
DxLibDotNet.dll、使ってみた。
練習問題やってみた。

# 練習問題
ブロック崩しを作れ。

# 写真

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/59588e14-7d17-8d2d-2ba5-72a8d84244dd.png)


# サンプルコード

```
using System;
using DxLibDLL;

class Test {
	[STAThread]
	static void Main() {
		int X,
			Y;
		int i = 300;
		int bx = 150;
		int by = 150;
		int dx = 2;
		int dy = 2;
		int[] cx = new int[50];
		int[] cy = new int[50];
		int[] cz = new int[50];
		int j;
		int k;
		int s;
		for (k = 0; k < 5; k++)
		{
			for (j = 0; j < 10; j++)
			{
				cx[k * 10 + j] = 21 + 60 * j;
				cy[k * 10 + j] = 21 + 20 * k;
				cz[k * 10 + j] = 1;
			}
		}
		uint red = DX.GetColor(255, 0, 0);
		DX.ChangeWindowMode(DX.TRUE);
		DX.SetGraphMode(640, 480, 32);
		if (DX.DxLib_Init() == -1)
			return;
		s = DX.LoadSoundMem("coin07.mp3");
		while (DX.ProcessMessage() == 0 && DX.CheckHitKey(DX.KEY_INPUT_ESCAPE) == 0)
		{
			DX.ClearDrawScreen();
			if ((DX.GetMouseInput() & DX.MOUSE_INPUT_LEFT) != 0)
			{
				DX.GetMousePoint(out X, out Y);
				Console.WriteLine(X);
			}
			if (DX.CheckHitKey(DX.KEY_INPUT_RIGHT) == 1)
			{
				i = i + 3;
			}
			if (DX.CheckHitKey(DX.KEY_INPUT_LEFT) == 1)
			{
				i = i - 3;
			}
			bx = bx + dx;
			by = by + dy;
			if (bx > 590)
			{
				dx = -dx;
			}
			if (bx < 50)
			{
				dx = -dx;
			}
			if (by > 480)
			{
				break;
			}
			if (by < 50)
			{
				dy = -dy;
			}
			if (bx > i && bx < i + 100 && by > 430)
			{
				dy = -dy;
			}
			for (k = 0; k < 5; k++)
			{
				for (j = 0; j < 10; j++)
				{
					if (cz[k * 10 + j] == 1)
					{
						if (bx > cx[k * 10 + j] && bx < cx[k * 10 + j] + 58 && by < cy[k * 10 + j] + 48)
						{
							cz[k * 10 + j] = 0;
							dy = -dy;
							DX.PlaySoundMem(s, DX.DX_PLAYTYPE_BACK);
						}
					}
				}
			}
			for (k = 0; k < 5; k++)
			{
				for (j = 0; j < 10; j++)
				{
					if (cz[k * 10 + j] == 1)
					{
						DX.DrawBox(cx[k * 10 + j], cy[k * 10 + j], cx[k * 10 + j] + 58, cy[k * 10 + j] + 18, DX.GetColor(255, 255, 0), DX.TRUE);
					}
				}
			}
			DX.DrawBox(0, 0, 640, 20, DX.GetColor(0, 0, 255), DX.TRUE);
			DX.DrawBox(620, 0, 640, 480, DX.GetColor(0, 0, 255), DX.TRUE);
			DX.DrawBox(0, 0, 20, 480, DX.GetColor(0, 0, 255), DX.TRUE);
			DX.DrawBox(i, 460, i + 100, 460 + 20, DX.GetColor(255, 255, 255), DX.TRUE);
			DX.DrawCircle(bx, by, 30, DX.GetColor(0, 255, 0), DX.TRUE);
			DX.ScreenFlip();
		}
		DX.SetFontSize(64);
		DX.DrawString(250, 240, "GAME OVER", DX.GetColor(255, 255, 255));
		DX.ScreenFlip();
		DX.WaitTimer(2000);
		DX.DxLib_End();
	}
}





```

以上。
AppSheet APIを用いたデータの取得方法


# AppSheet APIを用いたセンサーデータの取得方法

## はじめに
この記事では、AppSheetのAPIを利用して特定のセンサーデータを取得する方法を解説します。
Pythonを使い、AppSheetのAPIに対してリクエストを送信し、応答を受け取る実際のコードを見ていきましょう。

#### 関連リンク
* AppSheet公式ドキュメント
    * [AppSheet API Guide](https://help.appsheet.com/en/articles/1979979-appsheet-api-guide)


## AppSheet APIの基本

AppSheetはクラウドベースのアプリケーションプラットフォームであり、カスタムアプリの作成を容易にします。
このプラットフォームは、外部アプリケーションとの連携をサポートするAPIも提供しています。

### 必要な情報
- `APPSHEET_APP_ID`: AppSheetアプリケーションのID
- `APPSHEET_APP_ACCESS_KEY`: AppSheetアプリケーションのアクセスキー
- `GOOGLE_DRIVE_SENSOR_FOLDER_ID`: Google Drive内のセンサーデータフォルダのID
- `SENSOR_TABLE_NAME`: データを取得するセンサーテーブルの名前

### APIリクエストの例
以下のコードは、AppSheet APIを使って特定のMACアドレスを持つセンサーのデータを取得する方法を示しています。

```python
import json
import requests

# 重要な情報はマスクされています
APPSHEET_APP_ID = "********-****-****-****-************"
APPSHEET_APP_ACCESS_KEY = "********-****-****-****-************"
SENSOR_TABLE_NAME = 'sensors'
SENSOR_API_URL = f'https://api.appsheet.com/api/v2/apps/{APPSHEET_APP_ID}/tables/{SENSOR_TABLE_NAME}/Action'

HEADERS = {
    'ApplicationAccessKey': APPSHEET_APP_ACCESS_KEY,
    'Content-Type': "application/json"
}

mac_address = "D8-3A-DD-43-D3-3A"
data = {
    "Action": "Find",
    "Properties": {
        "Locale": "en-US",
        "Selector": f"Filter(sensors, [MACアドレス] = '{mac_address}')"
    },
    "Rows": []
}

response = requests.post(SENSOR_API_URL, headers=HEADERS, json=data)
if response.status_code == 200:
    rows = response.json()
    # 応答の処理
    if len(rows) == 1:
        print(rows)
        print(rows[0].get('Row ID'))
    else:
        print("No rows")
else:
    print(f"API call failed: {response.json()}")
```

このコードでは、AppSheetの`Find`アクションを使用して、指定されたMACアドレスに一致するセンサーデータを検索しています。

## まとめ
この記事では、AppSheet APIを使用してセンサーデータを取得する方法について説明しました。実際のアプリケーション開発やデータ分析にこの方法を応用することができます。


## 参考
* [Lambda(Python)でGoogle Driveへファイルアップロード #Python - Qiita](https://qiita.com/w2or3w/items/b66a4a8e45e6001a9c46)
* [LambdaからGoogleDrive内のファイルを読む #AWS - Qiita](https://qiita.com/afukuma/items/f0d8f0d9d97d9e43ed98)

---
### 会社紹介

**株式会社 Mosaica**  
最先端テクノロジーで社会課題を解決し、持続可能な未来を創造する IT カンパニー。
AI ソリューション、クラウド統合、DX 推進、経営コンサルティングなど包括的なサービスでビジネス変革を支援しています。  

詳しくは [公式サイト](https://mosaica.co.jp/) までお気軽にご相談ください。
公式サイト： https://mosaica.co.jp/
【JavaScript】コールバック関数とは

# コールバック関数とは
JavaScriptのコールバック関数は、他の関数の引数として渡され、ある特定のイベントや非同期操作が完了した後に実行される関数です。コールバック関数は、非同期性やイベント駆動のプログラミングで広く使用されます。主な目的は、非同期処理が完了した後に行いたい処理を指定することです。

コールバック関数は、通常、以下のようなシナリオで使用されます。

1\. **非同期処理の完了後の処理** : ファイルの読み込み、HTTPリクエストの送信、データベースクエリの実行などの非同期操作が完了した後に、特定の処理を実行するためにコールバック関数が使用されます。

2\. **イベントハンドリング** : ユーザーのアクションに対応するためにイベントリスナーとしてコールバック関数を登録することがあります。たとえば、ボタンのクリックやマウスの移動などのイベントに対する処理を指定します。

3\. **エラーハンドリング** : 非同期処理中にエラーが発生した場合に、エラーを処理するためのコールバック関数を指定することがあります。

以下は、非同期処理の例として、コールバック関数を使用するJavaScriptのコードの例です。
```js
function fetchData(callback) {
  // データの取得（非同期）
  setTimeout(function() {
    const data = { name: 'John', age: 30 };
    callback(data);
  }, 1000);
}

function processData(data) {
  console.log('Data:', data);
}

fetchData(processData);
```
この例では、`fetchData`関数が非同期でデータを取得し、取得が完了した後に`processData`関数が呼び出されるように指定されています。`processData`関数はコールバック関数として`fetchData`関数に渡され、データが取得された後に実行されます。
【jQuery】OR演算子とは

# OR演算子とは
OR演算子 `||` は、複数の条件式を組み合わせるために使用されます。この演算子は、左側の条件が真であれば、それ以上評価せずに真を返します。左側の条件が偽の場合は、右側の条件を評価し、その結果を返します。

# 使用方法
jQueryと組み合わせてOR演算子を使用する例を示します。
```js
if (jQuery('input[type="text"]').val() === '' || jQuery('input[type="password"]').val() === '') {
    alert('ユーザー名またはパスワードが入力されていません');
}
```
この例では、`input[type="text"]`と`input[type="password"]`のいずれかが空である場合にアラートが表示されます。OR演算子 `||` を使用して、複数の条件を組み合わせています。左側の条件が偽（つまり、入力フィールドが空でない）の場合、右側の条件が評価されることはありません。
【JavaScript】asyncとは

# asyncとは
`async`キーワードは、非同期関数を定義するための修飾子です。非同期関数は、非同期的に処理を実行し、処理が完了するまでプログラムの他の部分の実行をブロックしない特殊な関数です。

`async`キーワードを使用すると、関数の宣言時にその関数が非同期であることを明示できます。非同期関数は、`await`キーワードを使って非同期的に処理を待機することができます。

# 使用方法
以下は、`async`キーワードを使用した非同期関数の例です。
```js
async function fetchData() {
  const response = await fetch('https://api.example.com/data');
  const data = await response.json();
  return data;
}

fetchData()
  .then(data => {
    console.log('Data fetched:', data);
  })
  .catch(error => {
    console.error('Error fetching data:', error);
  });
```
この例では、`fetchData`関数が非同期関数であり、`await fetch()`を使ってAPIからデータを取得しています。`await`キーワードは、非同期操作が完了するまで処理を一時停止し、その後に処理を再開します。そのため、`fetchData`関数が非同期であるため、その呼び出し元である.`then`メソッドによって返されるPromiseを待つことができます。

# まとめ
`async`キーワードを使用することで、非同期的な処理をより簡潔に記述し、理解しやすくすることができます。
B2C Commerce のガイド付き検索リダイレクト機能


+ [検索リダイレクト](https://help.salesforce.com/s/articleView?id=cc.b2c_managing_search_redirects.htm&type=5)

+ [「Select Language」を「Japanese (Japan)」に設定するたびに（添付のスクリーンショットで黄色で強調表示されています）、それが「Default」設定にリセットされます。](https://trailhead.salesforce.com/trailblazer-community/feed/0D54V00007XIUWp)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/8e38c98f-df9b-8e82-2388-724b48ad0d56.png)
【jQuery】readyとは

# readyとは
`ready`関数は、ドキュメントが完全に読み込まれ、DOMが操作可能な状態になった時点で指定したコードを実行するための方法です。これは、ページがロードされた後にJavaScriptコードを実行する際に非常に便利です。

# 使用方法
ready()関数は、以下のように使用します。
```js
$(document).ready(function() {
  // ここにjQueryコードを記述する
});
```
または、略記した形式として以下のように書くこともできます。
```js
$(function() {
  // ここにjQueryコードを記述する
});
```
この関数は、ドキュメントが完全に読み込まれ、DOMが操作可能な状態になったときに実行されるコールバック関数を受け取ります。これにより、ページのロードが完了する前にjQueryコードが実行されるのを防ぎ、安全な方法でDOM要素にアクセスすることができます。

例えば、ページが読み込まれた後に特定の要素に対してイベントリスナーを追加したり、DOMの構造を変更したりする必要がある場合に、`ready`関数を使用すると便利です。