OmniAICreator/Qiita-1.07M huggingface dataset:
Inspect で Windows UI の中身を覗いてみる。

# これは何？
Visual Studio 備え付けのツール Inspect とは何か、何ができるのかの備忘録です。

# Inspect とは

[Accessibility tools - Inspect](https://learn.microsoft.com/en-US/windows/win32/winauto/inspect-objects) に記載がある通り、Windows のUI 検査ツールです。
UI 要素のプロパティ情報を採取、確認が簡単に可能です。
エラーダイアログなどを選択すれば、どのプロセス (プログラム) 由来で出されているものかもわかります。

日本語ページは
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/48302/c936655b-9889-0512-8ae6-261043f0ee10.png)
とアレなので紹介しません。

(ドキュメントの切り替えには是非 [データ全損ニキ](https://twitter.com/HomesickTic) の Chromium 拡張機能 [JA/EN Url Trigger](https://chromewebstore.google.com/detail/jaen-url-toggler/cojobaphcadfijmiiopiklfpompmljgm) をお使いください。)

## インストールパス
・C:\Program Files (x86)\Windows Kits\\{ver}\bin\\{Build ver}\x86

私は C:\Program Files (x86)\Windows Kits\10\bin\10.0.22621.0\x86 にありました。


# サンプル : タスクトレイの時刻の中身を見てみる
何ができるかの簡易シナリオとして、タスクバーの時計がどういうものなのか眺めてみます。

## 起動
inspect.exe を叩きます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/48302/5db26894-6880-e61c-2041-b49a85107cf0.png)

## 選択箇所が黄色枠で囲まれるようにする
"Show Highlight Rectangle (赤枠)" をクリックします。
これにより、選択中のオブジェクトが黄色枠で囲まれるようになります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/48302/0bc46c1a-f880-df52-f203-3262b91ea7db.png)

## カーソルから確認したいオブジェクトを選択する
"Select Cursor (赤枠)" をクリックし、その後確認したいオブジェクトを選択します。
今回はタスクトレイの時刻。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/48302/c3680ed2-ce3f-5ea0-dd5b-1e4d25727c0c.png)

確認対象が黄色枠で囲まれます。
同時に Inspect 側で対象オブジェクトのツリーが展開、オブジェクトが選択状態になります。
プロパティも表示されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/48302/4ffd7b69-eef4-8064-a594-3172b90ad736.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/48302/b12c7a4b-8dd6-8223-d87a-c62dbcf2633c.png)

※ なお、この後、**"Watch Cursor" を再度オフに**してください。
(オフにしないまま Inspector 以外をクリックすると、その都度そっちにターゲットが移ります)

## 結果確認
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/48302/e2b4e3ca-82fc-1630-f314-0c32cdd5d1da.png)

このタイミングの "時計" のプロセス ID が 2876 だとか Framework は XAML だとかそもそもボタンだったりといろいろ情報が確認できます。
OS コンポーネントなのでこれ以上は調べられませんが、これが内製アプリだったりすると
いろいろわかりそうですね。

## おまけ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/48302/28fd1e6e-5e3c-36d5-831e-c603d00073b5.png)

タスクトレイ (タスク バー) のプロセス ID と同じということは、
全部一元管理されているんですね。
初心者JavaScriptのメモ帳（hasOwnProperty()メソッド）

## hasOwnProperty()メソッド
hasOwnProperty()メソッドは、JavaScriptのオブジェクトにおいて、指定されたプロパティがそのオブジェクト自体に存在するかどうかを判定するためのメソッドです。

具体的には、与えられたプロパティがオブジェクト自体に直接定義されている場合にはtrueを返し、プロトタイプチェーンから継承されたプロパティや、その他の方法で追加されたプロパティに対してはfalseを返します。

```diff_javascript
const person = {
    name: 'John',
    age: 30
};

console.log(person.hasOwnProperty('name')); // true
console.log(person.hasOwnProperty('gender')); // false

```
この例では、personオブジェクトにはnameプロパティが直接定義されているので、hasOwnProperty('name')はtrueを返します。しかし、genderプロパティはオブジェクト自体には存在しないため、hasOwnProperty('gender')はfalseを返します。

hasOwnProperty()メソッドを使用することで、オブジェクトのプロパティが直接定義されているかどうかを確認することができ、不必要なプロトタイプチェーンの参照を防ぐことができます。
初心者が意識するセキュリティ



## はじめに
初心者が意識するセキュリティに関しての備忘録です。
初心者です😅
間違えてる部分が多々あると思います。
もし見つけた場合、ツッコミいただけると助かります🙇
<br>
## 🦁<INS>**結論**</INS>🦁
GitHubを覚えたら「環境変数」「.env」「git ignore」を適切に使えるといい。
 GitHubでは公開をするのが基本になるため「APIキー」「アカウント情報」「データ」などの情報を漏らさないために最低限のセキュリティが必要。

## 環境変数
基本どこからでもアクセスできる。
.envファイルで定義しておくことで、管理がしやすく、コード上には漏洩してはいけない情報を書かなくていい。

```py
import os
from dotenv import load_dotenv

load_dotenv()

login_id = os.getenv('LOGIN_ID')
```  


## .envファイル
ローカル環境で環境変数を管理するためのプレーンテキストファイルテンプレート。アプリケーションの実行環境に応じて読み込まれる変数を定義し、開発者間での環境設定の共有や、機密情報をソースコードから分離して管理するのに役立つ。

```shell:.env
# APIの設定
API_KEY='your_api_key_here'
API_SECRET='your_api_secret_here'
```  

## .gitignoreファイル
ファイルに指定したものは、GitHubでコミットしても公開されない。
.envファイル、写真や動画などのデータ、ログファイル、公開の必要のないテストファイル、データが蓄積されたcsvファイルなど、プロジェクトのリポジトリに含めることにより、不要なファイルのコミットを防ぎ、機密情報の誤公開を避けることができる。

```conf:.gitignore
# 特定のファイルを無視
.env

# ディレクトリ全体を無視
build/

# ログファイルと一時ファイル
*.log
*.tmp
*.temp

# 特定のパターンにマッチするファイルを無視
*.jpeg
*.mp4

# testと付くファイル全て無視
*test*
```


:::note info
押さえておくべき点
* 「環境変数」「.env」「git ignore」はプロジェクトを始めた際に用意する。
:::  
***

:::note alert
注意点
* .envファイルと.gitignoreは、ファインダーなどで通常は見えない→隠しファイルとして扱われ、特殊コマンドで可視化できる。
:::  

***

## まとめ😺
私はこれを知らずにGitHubにプッシュした結果、Googleなどから通知が来て驚いた経験があります💦
セキュリティの観点、操作性の観点などからもより良いやり方を時間があれば見つけていきたいなと思います。
***
.NET WebAPIのレスポンスで日付型を変える場合

WebAPIのレスポンスでDateTimeを返す時に、ミリ秒を３桁で出力する

[json内の日付フォーマットがそのままではSystem.Text.Jsonで解釈されないときのConverter](https://qiita.com/hatobeam75/items/c4d7a2d2dc8df697030d)を参考に

DateTimeJsonConverterを作成し、
```C#(DateTimeJsonConverter.cs)
public class DateTimeJsonConverter : JsonConverter<DateTime>
{
    public override DateTime Read(
        ref Utf8JsonReader reader,
        Type typeToConvert,
        JsonSerializerOptions options)
    {
        if (reader.GetString() is not { } str) return DateTime.MinValue;
        if (DateTime.TryParse(str, out var dateTime)) return dateTime;
        throw new JsonException("DateTime Parseエラー");
    }

    /// <summary>
    /// 日時をシリアライズするときにミリ秒は000で出力する
    /// </summary>
    /// <param name="writer"></param>
    /// <param name="dateTimeValue"></param>
    /// <param name="options"></param>
    public override void Write(
        Utf8JsonWriter writer,
        DateTime dateTimeValue,
        JsonSerializerOptions options) =>
        writer.WriteStringValue(dateTimeValue.ToString(
            "yyyy-MM-ddTHH:mm:ss.fff", CultureInfo.InvariantCulture));
}

```
:::note info
[jun maeda](https://qiita.com/juner)さんにコメント頂きReadを編集しました


```diff_c
- if (reader.GetString()! == null) return DateTime.MinValue;
- try
- {
-    var dateTime = DateTime.Parse(reader.GetString()!);
-    return dateTime;
- }catch
- {
-    throw new JsonException("DateTIme Parseエラー");
- }

+ if (reader.GetString() is not { } str) return DateTime.MinValue;
+ if (DateTime.TryParse(str, out var dateTime)) return dateTime;
+    throw new JsonException("DateTime Parseエラー");
```
:::

```C#
public class Hoge
{
  [JsonConverter(typeof(DateTimeJsonConverter))]
  public DateTime created_at { get; set; }
}
```


Hogeに適応してみたところ

```C#
var obj = JsonSerializer.Deserialize<Hoge>(json);
```
とやったところミリ秒が3桁で出力されることが確認できました。

ですが、WebAPIの戻り値で確認したところ、DateTimeJsonConverterが適応されずミリ秒の３桁が出力されません。
そこで

```C#(Program.cs)
builder.Services.AddControllers().AddJsonOptions(options =>
            options.JsonSerializerOptions.Converters.Add(new DateTimeJsonConverter()));

```
でDateTimeJsonConverterを登録したところWebAPIでも適用されました。
Macのターミナルソフトで文字選択だけでコピーする方法

MACのターミナルで文字を選択しただけでコピーする方法

Teratermは文字を選択しただけでクリップボードにコピーしてくれて便利ですよね。MACのデフォルトのターミナルソフトではそうならず残念。

iTerm2というターミナルソフトをインストールすると文字選択だけでコピーしてくれます。よかった。

設定は、
`iTerm2メニュー -> Settings -> General -> Selection -> Copy to pastebord on selection`にあります。
DockerDeskTop for WindowsをUbuntuで使用する

<h3>1.DockerDeskTop for Windowsのインストール</h3>
<a href="https://docs.docker.com/desktop/install/windows-install/">公式</a>を参照


<h3>2. DockerDeskTop の設定の確認</h3>
DockerDeskTopを起動
→ Settingsを開く
→ Generalを開く
→ 「Use the WSL 2 based engine」にチェックが入っていることを確認
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3706432/052473a0-3716-0850-057e-dc5bd04a615b.png">


<h3>3. Ubuntuにてコンテナを起動</h3>

```
docker run hello-world
```
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3706432/6235059e-2127-d54e-d7a6-845298583bd2.png">
Email composer

[メール関係の設定のまとめに戻る](https://qiita.com/Keiji_otsubo/items/160369c1c4c7dca02ea9)


+ [Pardot Emailのまとめ](https://qiita.com/Keiji_otsubo/items/c21122dcbaf7dea7ff96)

# アドレスが違う

+ [Wrong email address appearing for user](https://trailhead.salesforce.com/trailblazer-community/feed/0D54V00007eqnBK)

:::note
Found my own answer. In case anyone else runs into the issue, in the user's personal settings, under "My Email Settings" it was set with the wrong email address there.

自分なりの答えを見つけました。他の誰かがこの問題に遭遇した場合に備えて、ユーザーの個人設定の「自分のメール設定」で、間違ったメール アドレスが設定されていました。
:::


# 差し込み印刷の扱い

+ [「中括弧が差し込み項目として扱われる」 - 新しい Lightning エディタで解決しますか?](https://trailhead.salesforce.com/trailblazer-community/feed/0D54V00007X669G)

:::note
この問題は、現在の製品リリースでは修正されています。電子メールの返信および転送の引用されたコンテンツの中かっこの間にスペースが追加され、差し込みフィールドのパターンの一致とその後のエラーが防止されます。
2024/03/27
:::


# メールコンポーザー

+ [How do I get the textbox back on the email action?](https://trailhead.salesforce.com/trailblazer-community/feed/0D54V00007HNaQa)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/333461e1-1ac7-689b-5239-80238791e1af.png)

:::note
Please check this article. 

Email body section does not load in the Email composer
https://help.salesforce.com/s/articleView?id=000384148&type=1
:::


# できないこと

+ [新しいメールコンポーザーの印刷オプション](https://trailhead.salesforce.com/trailblazer-community/feed/0D54V00007X9t3iSAB)

:::note
これは、少なくとも近い将来にはサポートできない可能性が高くなります。その理由は、印刷アクションがサードパーティ コンポーネントであるコンポーザーの一部であるためです。これを差し込みフィールド エンジンに接続するには、かなりの作業が必要になります。このフィードバックをチームと共有します。
:::

# 未解決

+ [改行ができない？　New email composer + Place user signatures before email threads](https://trailhead.salesforce.com/trailblazer-community/feed/0D54V00007YwC3TSAV)

+ [この署名の動作を新旧の電子メール コンポーザーでテストしました。基本的にはどちらも同じですが、新しい作成者の署名と前の電子メールの内容の間に空行が追加されています。空行の構成方法に関して、古い電子メール コンポーザと新しい電子メール コンポーザにはいくつかの違いがあります。これに関連する既知のバグがあるため、バグの修正に取り組むにつれて動作が再び変更される可能性があります。](https://trailhead.salesforce.com/trailblazer-community/feed/0D54V00007YwC3T)

:::note
参考資料をありがとう！電子メールの署名の上に数行の空白行が存在するのは予期された動作です。署名の上に複数の空白行がある例は見たことがありませんが、これが署名自体の HTML に起因するものではありません。もちろん、そうでないと思われる場合は、署名 HTML と問題を再現する手順を含むサポートにケースを提出することは誰でも歓迎されます。
:::
外部ログイン情報のプリンシパル認証エラー

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




+ [外部ログイン情報のプリンシパル認証エラー対応について](https://trailhead.salesforce.com/trailblazer-community/feed/0D54V00007ZAfiy)


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/572495b5-591e-c1ad-8afa-fcd76d76762a.png)

:::note
接続アプリケーションにて
OAuthポリシー：管理者が承認したユーザーは事前承認済み
プロファイル：該当プロファイル(今回はシステム管理者)
を設定したところ外部ログイン情報プリンシパルの認証が通りました。
Developer Editionでは何故このような設定をせずとも認証が通ったのかは分かりませんがsandbox環境でLWCアプリを動かすことが出来ました。
:::
【ChatGPT有＋DALL-E3】で出力された画像を解釈するのは、結局人間。


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

　今回は、“出力された画像を解釈するのは、結局人間”とタイトルを付けましたが、どう思いますか？

:::note info
本記事は、ChatGPT（有料版）
＋DALL-E3に留まらず、生成し
た画像についてです。あしからず。
:::

　今日（2024/02/23）は
　　天皇誕生日、祝日🇯🇵。

　また一段と寒いですね。

　東京は冷たい雨です。
　　雪がチラついた、という
　　　ポストもありました。
***
　さて、
　　昨日は
　　　猫の日でした。

　X-Twitterでも
　　猫の画像が
　　　たくさんアップ
　　　　されていました。

　かくいう私も
　　ちょっとアップ量を
　　　増やして参戦いたしました。

　そんな中、
　　相手とのやり取りに
　　　画像をポンポンと出したのです。

　楽しかった、と
　　いうのが感想ですね。
***
　ただし、
　　ChatGPTさんとDALL-E3さんの
　　　コンビは、こちらの指示に
　　　　素直に従ってくれません。

　でも
　　だからと言って、
　　　その画像が使えない
　　　　わけでもありませんでした。

　今回は、
　　そこに焦点を当て、
　　　私が思ったことを
　　　　書きます。
***
　一枚の絵・画像を
　　作る際の労力は、
　　　AIにより、確実に減りました。

　その分、
　　それまで
　　　描いてこなかった人々が
　　　　次々と、生成AIで
　　　　　参入してきています。

　それ自体は
　　歓迎しています。
　　　私もそんな人間のひとりですし。

　しかし、
　　簡単に（時間も労力もかけず）
　　　それなりの作品が
　　　　描けてしまうので
　　　　　あまり、良くない感じも
　　　　　　受けています。

　もちろん、
　　自分も
　　　そこに入っている気は
　　　　しています。(=^・^=)

　彼らに
　　何が足りないのか？

　私は、
　　美術に関しては門外漢。
　　　よくわからないのが
　　　　実情です。

　それでも
　　わかるものは、あります。

　作品には
　　その人が
　　　何を重視しているのか、
　　　　が現れます。

　よく見るのが
　　理想の異性。
　　　さらに言えば、
　　　　身体を求めている。

　これは別に、
　　おかしなことではありません。
　　　むしろ、正常だと言えます。
　　　　人間は、動物ですからね。

　でも
　　ふつうの人は
　　　それで満足なはずです。

　“自分の彼氏彼女だよ”と
　　ポストする程度です。
　　　一般人が撮る写真と
　　　　同じです。

　絵師は
　　そこで止まりません。
　　　さらなる高みを目指します。

　気になるところを
　　とことんまで、
　　　ブラッシュアップする。

　表情・ポーズ、背景、照明、その他。

　衣装や靴や装飾品も
　　そこに含まれます。
***
　ここで、ふつうの人は
　　つまずきます。
　　　それぞれの要素を
　　　　言葉にしなければ
　　　　　生成AIには伝わりません。

　文章も画像も
　　その点は、変わりません。

　同じなんです。

　詳細な情報を
　　入れていけば、
　　　生成されるのは、
　　　　理想に近付くはずです。

　その情報を
　　生成AIがどう受け取るか
　　　という点が、使っていないと
　　　　わかりません。

　やはり、
　　生成AIを語るには
　　　使っていないとダメですね。
***
　それはともかく、
　　つまずいたら
　　　学習が必要です。

　己の知っている言葉が
　　それほどないときに言うのに
　　　“語彙力がない”と、
　　　　自虐的にポストする方も
　　　　　いらっしゃいます。

　言葉は、学習すれば
　　いいではないですか。

　それよりも
　　自覚しておいて欲しいのは、
　　　“画像評価力がない”ことです。

　画像を評価する、
　　それがほかの人の作品でも
　　　自分の作品でも、です。

　X-Twitterで見ていると、
　　アップされる画像は
　　　ひとそれぞれです。

　緻密で美しいものから
　　稚拙な素人作品までが
　　　あります。

　そんな中で
　　人に自分の作品を
　　　認められたいならば、
　　　　自分の作品を
　　　　　ブラッシュアップして
　　　　　　いきましょう！

　方向性は
　　ひとそれぞれです。
　　　美術的なもの
　　　　物語性のあるもの
　　　　　お笑い系。

　どれでもいいけれど、
　　自分に“芯”を持って、
　　　やりましょう。

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

　今回は、ここまで。
ROS2講座19 RvizPlugin概要

# 環境

この記事は以下の環境で動いています。

| 項目 |	値 |
|:--|:--|
| CPU | Core i5-8250U |
| Ubuntu | 22.04 |
| ROS2 | Humble |

# 概要
Rvizは元々強力な可視化ツールですが、pluginを使うことで機能を拡張できます。ここではどのようなpluginを使うと何が出来るのかの概要を説明します。

# pluginの種類

pluginには3つの種類があります。

![plugins_basic.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/254442/7b8d837f-4d34-5afd-7bfe-716645ed084f.png)

* Display(rviz_common::Display, rviz_common::RosTopicDisplay)
    * 中央の3D Viewでの描画を行うものです。多くは上図中の矢印のように3次元空間上の位置に紐づく情報を表示します。
    * 3D Viewの中の「Test String」の文字のようにオーバーレイで文字などを表示することもできます。
    * この部分はOgreという描画ライブラリを用いています。これのAPIを使ってpluginを開発します。
    * RosTopicDisplayはこれに色々な便利機能を付けた基本クラスで、左のDisplay部分の「Color」の欄のような実行時に選択できるオプションや設定の保存ロードが簡単に出来るようになっています。
    * ただしこのような3D表示のpluginを作りたい場合、開発時間を考えるとvisualization markerを出力するROSノードを作る方が圧倒的に早いです。
* Panel(rviz_common::Panel)
    * 画面左下の「StringPanel」のように、UIを表示することが出来ます。
    * Qtで実装されていて、このAPIを用いて開発を行います。
    * メニューバーの「Panel」から表示の設定が出来ます。
* Tool(rviz_common::Tool)
    * 画面上部のツールバーから機能の発動が出来ます。
    * 3D view上でクリックしたりドラッグした結果からアクションを行うことが出来ます。
    * メニューバー右の「+」ボタンから新しいツールをセットすることが出来ます。
* View Controller
    * ここでは解説しませんが、3D viewの視点を変更することが出来ます。

# 参照
* [開発ガイド](https://github.com/ros2/rviz/blob/rolling/docs/plugin_development.md)
* [pluginlib](https://docs.ros.org/en/foxy/Tutorials/Beginner-Client-Libraries/Pluginlib.html)

# 目次ページへのリンク
[ROS2講座の目次へのリンク](https://qiita.com/srs/items/5f0d765343ca78f524ed)
【React Router v6】elementを使用してネストした画面遷移を実装する

# はじめに
現在ReactとTypeScriptを学習中です。
**Udemyの講座で画面遷移の実装方法を学んでいたのですが、React Router v5を使っていたため、今回はReact Router v6を使った実装を行いました。**
# 処理の流れ

**ログインページとホームページのルーティング**を設定しました。
今回は**ホームページからさらに、ユーザー管理画面と設定画面に遷移する処理**を実装しています。
```tsx:Router.tsx
import { FC, memo } from "react";
import { Route, Routes } from "react-router-dom";
import { Login } from "../components/pages/Login";
import { HomeRoutes } from "./HomeRoutes";

export const Router: FC = memo(() => {
    
    return (
        <Routes>
            <Route path="/" element={<Login />} />

            <Route path="/home">
                {HomeRoutes.map((route) => (
                    <Route
                        key={route.path}
                        path={route.path}
                        element={route.children} />
                ))}
            </Route>

        </Routes>
    )

})
```

**ホームページ→ユーザー管理画面（user_management）と設定画面（setting）の**ルーティングを設定しました。
```tsx:HomeRoutes.tsx
import { Home } from "../components/pages/Home";
import { Setting } from "../components/pages/Setting";
import { UserManagement } from "../components/pages/UserManagement";

// /コンポーネント配下のルーティング設定

export const HomeRoutes = [
    {
        path: "",
        exact: true,
        children: <Home />

    }, {
        path: "user_management",
        exact: false,
        children: <UserManagement />
    }, {
        path: "setting",
        exact: false,
        children: <Setting />
    }
]
```



# 注意点
今回はv5で実装されていた内容をv6で再度実装しなおしたのですが、
その際に二点ほど気を付けるポイントがあります。

・**Routeを使用する前にRoutesを忘れずに使う（Switchはv6では不要）**

公式ドキュメントでも「レンダリング処理はRoutesとRouteをセットで使ってね」といった旨の記載があります。

https://reactrouter.com/en/main/components/routes

ネストした画面遷移の実装もこのルールに従って行います。
```tsx
<Routes>
            <Route path="/" element={<Login />} />

            <Route path="/home">
                {HomeRoutes.map((route) => (
                    <Route
                        key={route.path}
                        path={route.path}
                        element={route.children} />
                ))}
            </Route>

        </Routes>
```

**・親ルートのパスは``path: "/"``ではなく``path: ""``でオッケー**
最初に/がはいるのは自明なので、わざわざ記載しなくて良いみたいです。

**修正前**
```tsx
export const HomeRoutes = [
    {
        path: "/",
        exact: true,
        children: <Home />

    }, {
        path: "/user_management",
        exact: false,
        children: <UserManagement />
    }, {
        path: "/setting",
        exact: false,
        children: <Setting />
    }
]
```
**修正後**
```tsx
export const HomeRoutes = [
    {
        path: "",
        exact: true,
        children: <Home />

    }, {
        path: "user_management",
        exact: false,
        children: <UserManagement />
    }, {
        path: "setting",
        exact: false,
        children: <Setting />
    }
]
```
# おわりに
まとめてみるとシンプルですが、v5→v6の移行に伴う変更点がいくつかあったため、実装にかなり苦戦しました。公式ドキュメントに詳しく情報が載っているので、積極的に活用したいです。

# 参考
https://reactrouter.com/en/main/route/route

https://qiita.com/shunii/items/b56fa9ede8ed3fa83442

https://zenn.dev/tomohide0102/articles/c4cae8a667ab80
Cloud Functionsでステージング環境作成〜Xcodeでターゲットを分けるまで

# はじめに
Firebaseでステージング環境を作成し、　Xcodeでターゲットを分ける作業をしたので、
手順をまとめてみました。

#### 前提条件
- Firebase上にStaging環境を既に作っている
- Firebase CLIを既にインストールしている

#### 環境
- Xcode15
- Firebase CLI 13.0.2

# Cloud Functionsをステージングにデプロイする。
#### 
どのプロジェクトか選択する
```
firebase use --add
Which project do you want to add? (Use arrow keys)
> sampleProject
```

エイリアス名をつける
```
What alias do you want to use for this project?
staging
```

これで環境ができるのでステージングを選択
```
firebase use staging
ow using alias staging (プロジェクト名)
```

デプロイ
```
firebase deploy --only functions
```

ローカルでエミュレート
```
firebase emulators:start
```

#### GoogleServiceInfo.plistの取り込み
下記のフォルダ構成でGoogleServiceInfo.plistを取り込みます。
![スクリーンショット 2024-02-23 12.17.36.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/314423/0b79f1b8-1b34-1f60-13ab-66d757b48077.png)

　該当するTargetだけにチェックを入れる
![スクリーンショット 2024-02-23 12.20.21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/314423/46b617a0-0763-d186-dc76-9e3b2227511b.png)

AppdelegateでFirebaseApp初期化
```
import FirebaseCore
...
FirebaseApp.configure()
```


↓Firebaseはここまでで問題ないので以下はその他の目的でTargetを分けたい人向け
# Xcodeでターゲットを分ける
#### ターゲット複製
ターゲットを複製してターゲット名をStaging SampleTarget変更
![スクリーンショット 2024-02-15 19.32.27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/314423/8336a9af-262b-abf0-fad0-83ebe549e39b.png)

#### 不要なinfo.plist削除
今回は同じinfo.plistを使いたい為複製で出来た不要なSampleTarget copy-info.plistを削除
![スクリーンショット 2024-02-16 12.49.54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/314423/3f8a279d-d641-e0e3-f502-281a0750cf40.png)

同じinfo.plistを読むようにステージングターゲットのGeneral->Packaging->info.plist FileをSampleTarget/Info.plistに変更
![スクリーンショット 2024-02-23 10.11.24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/314423/c2a75079-1d65-c3b6-df7c-5536da208ca9.png)

#### スキームの設定変更
manage SchemesをクリックしてSampleTarget-Stagingにターゲットと一緒に名前を合わせる
![スクリーンショット 2024-02-23 10.55.26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/314423/7b37312e-bb95-e6b0-225a-cdeee5dff06f.png)


##### Preprocessor Macrosの設定
今回GoogleInfo.plistはファイル名同じなので必要ありませんが、その他で必要であればPreprocessor Macrosの設定をします。
Preprocessor Macrosの設定でStagingからRELEASEを削除してステージングを追加
![スクリーンショット 2024-02-23 10.40.27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/314423/e4937289-f6f0-05a7-96f2-556ec50fc9e9.png)

#### Preprocessor Macrosの確認
下記のコードで確認
```
class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
#if STAGING
    print("STAGINGです")
#else
    print("それ以外です")
#endif
    }
}
```

![スクリーンショット 2024-02-23 11.10.43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/314423/4b87eeb7-4c04-efa1-d76a-c376e8668776.png)


**終わり！!**

参考：
https://zenn.dev/oimo_revolution/articles/17ab026cbef464
PHP Fatal error:  Uncaught TypeError: fclose(): Argument #1 ($stream) must be of type resource, bool given in

``` PHP
修正前
$fp = fopen('test.txt', 'w');
fclose($fp);
```
PHP Fatal error:  Uncaught TypeError: fclose(): Argument #1 ($stream) must be of type resource, bool given in ........................

``` PHP
修正後
$fp = fopen('test.txt', 'w');
if ($fp) {
    fclose($fp);
}
```
ファイルが正常に開かれたか確認する:
fclose()を試みる前に、ファイルが正常に開かれたことを確認してください。ファイルのオープンに失敗すると、fopen()がfalseを返す可能性があり、それが問題の原因となります。
Flutter(Dart)からGeminiを簡単に呼べるようになったので試してみる

## 動機

Dart3.3のアップデート記事をどこかで見たから。

## 本題

Googleの発表したAI Bard改めGemini を利用するためのパッケージ[google_generative_ai](https://pub.dev/packages/google_generative_ai) を触ってみる。

## サンプルを動かしてみる

### GeminiでAPIキー取得する

1. [Google AI Studio](https://ai.google.dev/tutorials/ai-studio_quickstart?hl=ja)を有効にする

    法人アカウントの場合、早期アクセスアプリの有効化が必要。

    Core Data Access Permissionsの許可が必要。

2. APIキーをCreateする

余談だが、[Gemini](https://gemini.google.com/?hl=ja)(本家)に聞いても教えてくれる。

### Flutterでアプリを起動する

```bash
% git clone git@github.com:google/generative-ai-dart.git
% cd samples/flutter_app
% fvm flutter run -d 1625B704-06DE-46E3-B905-2294D4E16509 --dart-define=API_KEY=[Google AI Studioで取得したAPIキー]
```

### 質問をしてみる

![Simulator Screenshot - iPhone 15 - 2024-02-18 at 02.45.12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/648545/7517e095-8767-f52b-2964-14f38ba43191.png)

日本語も通じる。AIらしい回答が返ってくる。

## コードをみる

samples/flutter_app/lib/main.dart

```dart
class _ChatWidgetState extends State<ChatWidget> {
  late final GenerativeModel _model;
  ...
  @override
  void initState() {
    super.initState();
    _model = GenerativeModel(
      model: 'gemini-pro',
      apiKey: _apiKey,
    );
    _chat = _model.startChat();
  }
```

_modelインスタンス生成のところ。`_models.startChat()`で会話をスタートしている。

```dart
  Future<void> _sendChatMessage(String message) async {
    setState(() {
      _loading = true;
    });

    try {
      var response = await _chat.sendMessage(
        Content.text(message),
      );
      var text = response.text;
```

チャット送信するメソッド。`_chat.sendMessage`の中で会話履歴`_chat.history`に追加されることでListViewが再描画される。

`Content.text(message)`はユーザー入力のメッセージということ。

`sendMessageStream`もあるので用途によってはこちら。

## 画像を送る

サンプルにそのような機能はない。自分で書く。

### 画像を送れそうなコードがある

```dart
  static Content data(String mimeType, Uint8List bytes) =>
      Content('user', [DataPart(mimeType, bytes)]);
```

画像を送ることもできそう。

# 参考

[What’s new in Flutter 3.19. Revolutionizing App Development with… | by Kevin Chisholm | Flutter | Feb, 2024 | Medium](https://medium.com/flutter/whats-new-in-flutter-3-19-58b1aae242d2)

[New in Dart 3.3: Extension Types, JavaScript Interop, and More | by Kevin Moore | Dart | Feb, 2024 | Medium](https://medium.com/dartlang/dart-3-3-325bf2bf6c13)

[クイックスタート: Dart アプリまたは Flutter アプリで Gemini API を使ってみる  |  Google AI for Developers](https://ai.google.dev/tutorials/dart_quickstart?hl=ja)
FlutterアプリをiOSエミュレーターで起動する

## 動機

起動手順だけメモ的に書いておく。

（同じ記事は星の数ほどある。）

## 本題

``` bash
# Flutterプロジェクトを作成する
% fvm flutter create flutter-playground --verbose
```

```bash
# iOSエミュレーターを起動する
# 今回はiPhone 15(iOS 17.0)を選択
% open -a Simulator

# Flutterの認識しているエミュレーターを探す
% fvm flutter devices
Found 3 connected devices:
  iPhone 15 (mobile) • 1625B704-06DE-46E3-B905-2294D4E16509 • ios            • com.apple.CoreSimulator.SimRuntime.iOS-17-0 (simulator)
  macOS (desktop)    • macos                                • darwin-arm64   • macOS 13.5 22G74 darwin-arm64
  Chrome (web)       • chrome                               • web-javascript • Google Chrome 121.0.6167.184

Checking for wireless devices...

No wireless devices were found.

Run "flutter emulators" to list and start any available device emulators.

If you expected another device to be detected, please run "flutter doctor" to diagnose potential issues. You may also try increasing the time to wait for connected devices with the "--device-timeout" flag. Visit https://flutter.dev/setup/ for troubleshooting tips.

# アプリ起動
% cd flutter-playground
% fvm flutter run -d 1625B704-06DE-46E3-B905-2294D4E16509
```

![01_simulator.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/648545/cd7f5abe-94c6-af9d-1a49-63a6b20de5ec.png)

## 最後に

エミュレータが起動できないときはXCodeとiOSのダウンロードから。

Androidエミュレータから起動したかったらまずはAndroid Studio落としてみると良。
読めば少し分かった気になれるLookMLの構成要素（後編）

## はじめに
こんにちは、カスヤです。
Lookerを触り始めることになったので、LookMLについて、そしてその反映結果について、公式の説明を基にしつつ、自身の解釈も加えて残しておこうと思います。前半ではLookMLオブジェクトの構成要素に焦点を当て、後半ではこれらの要素がビジュアライゼーションにどのように反映されるかについて詳しく解説します。

[前編はこちら（LookMLとは）](https://qiita.com/pull_request/private/20caca89a467d1af46cf)
## ビジュアライゼーション
定義したデータモデルはLookerトップ画面＞Exploreで参照できる。

### Exploreでデータを探索する
LookMLで定義したオブジェクトが表示されている。
![explore2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3632589/4fbb12f6-abc3-ab73-de95-869a85d35edf.jpeg)

商品名と売上（合計）を選択して、製品別の売り上げを出してみる。
![visual.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3632589/33fb72ed-c53a-fbb4-8ef5-20f0f5e732ba.jpeg)

売上（合計）が大きい製品のみにフィルタを適用し、金額の降順にしてみる。
![visual2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3632589/2a6863c4-c650-ab87-b4f3-ffa94beff29d.jpeg)

円グラフに切り替えてみる。
![visual3.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3632589/7986a9bd-582f-7e2b-5268-ee5c54f7b1c0.jpeg)

DWH周りの開発を担当することが多いので、BIでのビジュアライズのセンスが本当に皆無なのだが、このように一応はLookMLで定義したデータを参照することができた。

## 余談
ちなみにGoogle開発はGoogle Cloud含めてハイフン（-）を登録は出来るのだけど、後続開発で後々エラーを引き起こすことが多い（経験談）。Google製品の開発はぜひアンスコ（_）を利用しようね、と周りには勧めている。今回はエラーを引き起こしてみたくて内部のコードに一部ハイフンを含めてみたが、Exploreを表示するタイミングでエラーになった。エラー原因がよく分からなくてでも動かない、みたいな際の勘所としてお使いください。![explore_error.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3632589/56527d14-01ae-d7eb-eecf-136aa4730137.jpeg)


それではまた。
S3のバケットごとダウンロードするよ（※ちょとした失敗事例あり）

どもども、ogimanです。
2月なのに気温が20度近くいったり、と思ったら次の週には10度以下になったりで体調が・・・
気圧のせいか毎朝全然おきれません〜おじさんにはツラミ:ghost:

今日はAWSのS3バケットをまるっとダウンロード（アップロード）する方法を記載します。

コマンドに限らず技術全般で新しいインプットをすると、古い情報が玉突きのように記憶からなくなっていく！
コマンド覚えていられない症候群（記憶力がないだけｗ）に罹患しているのでメモっときます。

ご存知の方は時間が勿体ないのでここで離脱しましょうｗ

## ゴール
- S3のバケットごとをダウンロードする
- ローカルのデータをS3にフォルダごとアップロードする

## 要件
以下の2つの要件がありましたとさ
- 複数のサービスが扱っているのですが、1つのサービスがクローズとなったため、S3のバックアップしておきたい
- と思ったら、その後にバックアップした一部のデータを他のAWSアカウントのサービスへ移植したい


## 実行例

**S3のバケットごとをダウンロードする**

```bash
# ディレクトリ作成（※1）
# mkdir "ローカルにディレクトリを作成"
mkdir backup.hoge

# バケット→ローカルへのダウンロード
# aws --profile "プロファイル名" s3 sync s3://"バケット名" "ローカルにディレクトリを作成"
# credentialの指定は忘れずに！defaultで設定している場合は指定不要(※2)
aws --profile ogiman s3 sync s3://backup.hoge ~/Downloads/backup.hoge
```
※1 バケット名もしくは任意のディレクトリを作成しましょう。さもないと、バケット配下のコンテンツがダウンロードされます。詳細は実行結果を参照ください
※2 https://docs.aws.amazon.com/ja_jp/cli/latest/userguide/cli-configure-files.html#cli-configure-files-format-profile



**S3のバケットごとをアップロードする**

```bash

# バケット→ローカルへのアップロード
# aws --profile "プロファイル名" s3 sync ~/Downloads/"ローカルにディレクトリを作成"　s3://"バケット名"
aws --profile ogiman s3 sync ~/Downloads/backup.hoge　s3://backup.hoge
```


## ダウンロードの失敗事例

```
[ogiman:~/Downloads] $ aws --profile ogiman s3 sync s3://backup.hoge ~/Downloads
download: s3://backup.hoge/wordpress/hoge
download: s3://backup.hoge/app/hoge
[ogiman:~/Downloads] $
[ogiman:~/Downloads] $ ls -l  ~/Downloads　  (1)
drwxr-xr-x@ 4 ogiman  staff      128  2 22 10:48 app
drwxr-xr-x@ 3 ogiman  staff       96  2 22 10:48 wordpress
[ogiman:~/Downloads] $ mkdir backup.hoge (2)
[ogiman:~/Downloads] $ mv app backup.hoge　　(3)
[ogiman:~/Downloads] $ mv wordpress backup.hoge
[ogiman:~/Downloads] $
[ogiman:~/Downloads] $ ls -l backup.hoge
drwxr-xr-x@ 4 ogiman  staff  128  2 22 10:48 app
drwxr-xr-x@ 3 ogiman  staff   96  2 22 10:48 wordpress
```

1. 指定したバケット「backup.hoge」がディレクトリとして出来る想定だったが、バケット配下のコンテンツのみが入っている
1. せこせこと後からディレクトリを作成する・・・虚しい:sweat:
1. コンテンツを移動する・・・虚しい:grimacing:

つまり、cp(コピー)ではなく、あくまでも同期（sync）なのでディレクトリができなかったのでしょう。


## 補足

以下でもバケットのダウンロードできます。
`--recursive` オプション付与するのが面倒だったので`sync`を試しました　⇐怠惰なエンジニアです。

```
aws --profile ogiman s3 cp s3://"バケット名" "ローカルにディレクトリを作成" --recursive
```


## 参考（感謝）
- https://docs.aws.amazon.com/cli/latest/reference/
- https://docs.aws.amazon.com/ja_jp/cli/v1/userguide/cli-services-s3-commands.html#using-s3-commands-managing-objects-sync


## 最後に
普段aws-cliを触ってますが、色々とAWSのリソースを操作できて便利ですね！
大量にコマンドあるので覚えるのは無理ゲーなので、[公式ドキュメント](https://docs.aws.amazon.com/cli/latest/reference/)見ながら、試してます。
皆さんもぜひお試しあれ〜

この記事が少しでも参考になったら、 :heart: お願いします！
励みになります♪

ではでは、良い一日を〜
シェルのバックグラウンド実行って後だしできるって知ってました？

# この前までの私のちょっと時間のかかるバッチ実行の日常
「よっしゃー、今日はバッチ処理やるで！」と気合い入れて、タタタタッターン（bash xxxx.sh + Enter）。
おっと、またやらかしたわ。コマンドの末尾に`&`つけんの忘れたら、プロセスがフォアグラウンドで動いてまうねん。
これやと、ターミナルがこのタスクに独り占めされてまうわ。
この状況をどうにかするには、`Ctrl+C`でプロセスを止めてからやり直すか、それとも別のターミナルウィンドウを開くしかないねん。めっちゃ面倒くさいなあ。
# 今後の私のちょっと時間のかかるバッチ実行の日常
「さて、本日はバッチ処理の実施日でございますね」と心に留めました。
タッタタタッターン。
あら、不覚にも再び`&`を添え忘れてしまい、結果としてフォアグラウンドでの実行を余儀なくされました。
しかし、ご心配なく。
まずは、`Ctrl+Z`を駆使してプロセスを一時停止いたします。
続いて、下記のコマンドを使用し、プロセスをバックグラウンドで再開いたします。
```zsh:バックグラウンドで実行再開コマンド
bg
```
# 解説
長々と述べましたが、要は
**フォアグラウンドで実行 → 一時停止 → バックグラウンドで再開**
の手順を踏んだだけです。
## 複数のタスクを一時停止した場合はどうなるのでしょうか？
### ケース1：引数なしでバックグラウンド再開
`bg`コマンドを引数なしで実行すると、最も最近に一時停止したタスクが再開されます。
一時停止したタスクはスタックされるようになります。
```zsh:実行例
$ sleep 10 # sleepコマンドで10秒待機
^Z # Ctrl+Zで一時停止
zsh: suspended  sleep 10
$ sleep 11
^Z
zsh: suspended  sleep 11
$ bg # 引数なしでバックグラウンド再開
[2]  - continued  sleep 11
$ bg
[1]  - continued  sleep 10
```
### ケース2：引数でジョブを指定してバックグラウンド再開
引数でジョブ番号を指定することで、特定のタスクを明示的に再開できます。
```zsh:実行例
$ sleep 10
^Z
zsh: suspended  sleep 10
$ sleep 11
^Z
zsh: suspended  sleep 11
$ jobs # ジョブ番号を確認
[1]  - suspended  sleep 10
[2]  + suspended  sleep 11
$ bg %1 # ジョブ1を再開
[1]  - continued  sleep 10
$ bg %2 # ジョブ2を再開
[2]  + continued  sleep 11
```
# 今回の件の教訓
今回のケースは既に知っている人も多いかもしれませんが、私はこれまでなぜか遠回りの方法をとっていました。作業の中には、同様に非効率的な方法で行っていることが他にもあるかもしれません。ですから、面倒だと思っている作業に対しても、違和感を持ち、改善方法を積極的に調べるようにしようと思います。
デフォルトコンストラクタ

# コンストラクタとは
インスタンスの生成時に初期化を行うメソッドです。
クラス名と同じメソッド名にする事でコンストラクタとして扱われます。
voidを含めた戻り値の型を使用する事が出来ません。

# デフォルトコンストラクタ
クラス内にコンストラクタが1つも実装されていない場合に追加されるコンストラクタです。
内容は引数無し、処理内容無しとなります。

# 何故デフォルトコンストラクタが必要なのか？
例えば、インスタンス化の時には実行する処理がないクラスを作成する場合、わざわざ空のコンストラクタを定義しなくてもJavaがデフォルトコンストラクタを作成してくれるので手間を省くことが出来ます。

# 参考記事
https://qiita.com/kanfutrooper/items/5f9ecac1e6211c6feffc#:~:text=%E3%83%87%E3%83%95%E3%82%A9%E3%83%AB%E3%83%88%E3%82%B3%E3%83%B3%E3%82%B9%E3%83%88%E3%83%A9%E3%82%AF%E3%82%BF%201%20%E3%82%B3%E3%83%B3%E3%82%B9%E3%83%88%E3%83%A9%E3%82%AF%E3%82%BF%E3%81%AF%E3%80%81%E3%82%A4%E3%83%B3%E3%82%B9%E3%82%BF%E3%83%B3%E3%82%B9%E5%8C%96%E3%81%AE%E9%9A%9B%E3%81%AF%E5%BF%85%E3%81%9A%E5%AE%9F%E8%A1%8C%E3%81%95%E3%82%8C%E3%82%8B%E3%80%82,%E3%82%82%E3%81%97%E3%82%82%E3%82%B3%E3%83%B3%E3%82%B9%E3%83%88%E3%83%A9%E3%82%AF%E3%82%BF%E3%81%8C%E3%82%BD%E3%83%BC%E3%82%B9%E3%82%B3%E3%83%BC%E3%83%89%E5%86%85%E3%81%A7%E5%AE%9F%E8%A1%8C%E3%81%95%E3%82%8C%E3%81%A6%E3%81%84%E3%81%AA%E3%81%84%E5%A0%B4%E5%90%88%E3%80%81%E8%A3%8F%E3%81%A7%E5%BC%95%E6%95%B0%E7%84%A1%E3%81%97%2F%E5%87%A6%E7%90%86%E7%84%A1%E3%81%97%E3%81%AE%E3%82%B3%E3%83%B3%E3%82%B9%E3%83%88%E3%83%A9%E3%82%AF%E3%82%BF%E3%81%8C%E8%A3%9C%E3%82%8F%E3%82%8C%E3%81%A6%E5%AE%9F%E8%A1%8C%E3%81%95%E3%82%8C%E3%80%81%E3%81%93%E3%82%8C%E3%82%92%E3%80%8E%E3%83%87%E3%83%95%E3%82%A9%E3%83%AB%E3%83%88%E3%82%B3%E3%83%B3%E3%82%B9%E3%83%88%E3%83%A9%E3%82%AF%E3%82%BF%E3%80%8F%E3%81%A8%E8%A8%80%E3%81%86%E3%80%82%202%20%E3%83%87%E3%83%95%E3%82%A9%E3%83%AB%E3%83%88%E3%82%B3%E3%83%B3%E3%82%B9%E3%83%88%E3%83%A9%E3%82%AF%E3%82%BF%E3%81%98%E3%82%83%E3%82%BD%E3%83%BC%E3%82%B9%E3%82%B3%E3%83%BC%E3%83%89%E5%86%85%E3%81%AB%EF%BC%91%E3%81%A4%E3%81%A7%E3%82%82%E3%82%B3%E3%83%B3%E3%82%B9%E3%83%88%E3%83%A9%E3%82%AF%E3%82%BF%E3%81%8C%E5%AE%9A%E7%BE%A9%E3%81%95%E3%82%8C%E3%81%A6%E3%81%84%E3%81%9F%E5%A0%B4%E5%90%88%E3%80%81%E8%A3%9C%E3%82%8F%E3%82%8C%E3%81%AA%E3%81%84%E3%80%82
AWS RDS PostgreSQL 15にAWS Glueから接続するための条件

# 概要
首題のとおり。

ここにたどり着く人はどはまりしてどうしようもなくなって泣きながらたどり着いてるだろうから細かい説明は省き、正解と決め台詞だけ書きます。

現在の時刻は `2024-02-23 11:24 JST` で後々こっそり修正が入るかもしれません特に前提の２

# 説明
1. password_encriptionがmd5の状態で作成されたUSER(ROLE)であること
1. Glue, ConnectionsのDriverをS3から読み込む部分はバグってるかなんなのかわからんけど有効ではないため後述のコードでカバーする
1. (未確認だけど要素として記載) accepted_password_auth_method が md5+scram であること、少なくともscramの単体ではないこと

## 1の解説
たとえばPostgreSQL 1３ 以前のRDSからバージョンアップしてきた古参の USER はパスワードが md5 で保存されているためにGlueから利用できる。

PostgreSQL 15以降はpassword_encryption が `scram-sha-256` (おそらくデフォルト値がこれ)であるためその状態で作成されたユーザはGlueから接続するとfailする。

対策としてGlueからアクセスしたいユーザがある場合は psql などで password_encryption を md5に設定したうえで CREATE ROLE すること。

```
pgsql15db=> show password_encryption ;
 password_encryption 
---------------------
scram-sha-256
(1 row)

pgsql15db=> set password_encryption = 'md5';
SET
pgsql15db=> show password_encryption ;
 password_encryption 
---------------------
md5
(1 row)

CREATE ROLE ...;
```

## ２に対する対策のコード

AWSのバグかなにかではないかと…。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/570665/9acef176-4587-748d-e88c-ec2f70fe9025.png)

タチガワルイことに何事もなかったかのようにデフォルトで用意してあるクソ古いjarを噛ませてくるから**問題の解析をややこしくしている**。

Connection設定のUIにて異なるバージョンのpostgres jdbc driver のjarファイルを噛ませているがstack traceが行数含めて全く変わらなくて、なにか別なjarを参照しているのでは？という疑惑を持つ。

試しに手元でpgsqlのドライバをビルドして配置しても変わらなかったのでしこたまデバッグメッセージを仕込む。

ある段階でpythonのコードにjarの配置箇所を記述することでやっと別なjarを利用できることに気づく。

customJdbcDriverS3Path と customJdbcDriverClassName.

```
PostgreSQL_node1 = glueContext.create_dynamic_frame.from_options(
    connection_type="postgresql",
    connection_options={
        "useConnectionProperties": "true",
        "connectionName": "Postgresql connection",
        "dbtable": "tbl_xxxxx_xxxxx",
        "customJdbcDriverS3Path": "s3://****test-bucket/postgresql-42.7.0-SNAPSHOT.jar",
        "customJdbcDriverClassName": "org.postgresql.Driver",
    },
    transformation_ctx="PostgreSQL_node1",
)

```

これによって以後デバッグが効くようになり、問題の解析につながった。

## 3の説明
バージョンアップしたインスタンスであり、最初から md5+scram であったため検証はしていなくて試せていないけれど、絶対関係あるのでパラメータをチェックしてほしい。

https://docs.aws.amazon.com/ja_jp/AmazonRDS/latest/UserGuide/Appendix.PostgreSQL.CommonDBATasks.Roles.html

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/570665/09cfb6dd-7285-3ebd-421e-a9b2f58cd242.png)

# 決め台詞
お前の前にいるのは、２０年以上生きたJava使いだ。

# ありがとう
https://qiita.com/tmiki/items/e416cde07910e0d208a3
プロを目指す人のためのRuby入門［改訂2版］を読んで

プロを目指す人のためのRuby入門［改訂2版］を読んでの感想

## 良かったところ

### 説明が丁寧
まず、本書のイントロダクションにも書いてあったのですが、まったくプログラムを書いたことのない完全なプログミング初心者には少し難易度が高い印象でした。
ですが、サンプルコードがたくさん書かれているのでわかりやすかったです。

### 基礎から応用まで
中級者〜上級者用ではあるのですが、基礎を理解できる章からそれを使った応用の章までと網羅されていました。

### 例題とリファクタリング作業
章ごとに例題があり、動いた後にどのようにリファクタリングできるかを説明してあります。シンプルでわかりやすい構文での書き方を学べます。

## 学んだこと

プログラマの三代美徳は「怠惰・短気・傲慢」

### 基本構文について
* メソッドの戻り値の指定にreturnは使わない。returnはメソッドを途中で脱出する際に使われることが多く最後に評価された式がメソッドの戻り値になる。
* エイリアスメソッドが多くある。
* メソッド定義も式になっている。メソッド名をシンボルとして返す。

### テストを自動化する
* Minitestというテストを自動化するためにはテスト用のフレームワークを利用する

### 正規表現
* パターンを指定して文字列を効率よく検索・置換するためのミニ言語
* 構文や特殊な文字を組み合わせると複雑な条件を持つ検索パターンを簡潔に定義することができる

### class
* オブジェクトの設計図となるもの。
* クラスは属性とメソッドを持ち、そのクラスを基にして複数のインスタンス（オブジェクト）を生成することができきる。

### module
* クラスに似ているが、インスタンスの生成や継承ができない。
* クラス外で定義したmoduleはincludeするとクラス内で呼び出せるようになる。
```ruby
module Book
  def book?
    true
  end
end

class Pen
  include Book
end

Pen = pen.new
p pen.book?
#=> true
```


## 難しかったこと
* Rubyのコードは言語としての事前知識が必要だなと感じました。
  * 例題はありますが、言語の特性を活かした書き方を自分で理解して構文に慣れる必要があります。
* 一周では記載の内容を一度では十分に理解できなかったので、再度復習することが大事に感じました。
Java学習 SpringBootを使ってみる

# 新規プロジェクトを作成
### 手順
1. 専用サイトで、プロジェクトファイルを作成する
2. プロジェクトファイルをダウンロードする
3. ダウンロードしたファイルをIntelliJで読み込む

Rails では、ターミナルで `rails new` を実行したが、Spring Bootの場合は方法が異なる。

[Spring Initializr へのリンク](https://start.spring.io/)

## ファイル作成

|項目名        | 入力内容
|---          |---
|Project      | Gradle Groovy
|Language     | Java
|Spring Boot  | 2.7.8
|Group        | 任意のもの
|Artifact     | firstapp (任意のもの)
|Name         | FirstApp (任意のもの)
|Description  | ​First project for Spring Boot (任意のもの)
|Package name | (任意のもの)
|Packaging    | Jar
|Java         | 17

Spring Bootの最新バージョンは随時変更される。「2.7.8」が選択できない場合は、バージョンの後ろに「(SNAPSHOT)」や「（M4）」と書かれているものは 選択しないようにする。

画面左側の入力が完了したら、ライブラリの設定を行う。

右側の「Dependencies」の欄にある、「ADD DEPENDENCIES」のボタンをクリックすると、メニューが表示されるので、検索ワードとして「web」と入力する。
メニューの一番上に「Spring Web」が表示されるのでクリックして選択する。

[![Image from Gyazo](https://i.gyazo.com/abe8382ad2bf72a3152d895883ade94f.png)](https://gyazo.com/abe8382ad2bf72a3152d895883ade94f)

下のようになっていればOK。

[![Image from Gyazo](https://i.gyazo.com/99e0588a65431e149e435b76aa52da4c.png)](https://gyazo.com/99e0588a65431e149e435b76aa52da4c)

入力内容が問題なければ、「GENERATE」ボタンをクリック。

自動的にファイルがダウンロードされる。ファイル名は、「(アプリ名).zip」という名称の圧縮ファイルになっている。


# ファイル解凍
任意のフォルダ内に移動させ、フォルダ内でプロジェクトファイルを解凍する。
解凍後はzipファイルは不要なため削除してOK。

# IntelliJでプロジェクトファイルを読み込む

まずIntelliJを起動する。

起動したら、左上のメニューから「ファイル」-「開く」を選択する。

[![Image from Gyazo](https://i.gyazo.com/b2a17a079677ccb06b950083a98847c3.png)](https://gyazo.com/b2a17a079677ccb06b950083a98847c3)

先ほど作成した「アプリ名」フォルダにある「build.gradle」をダブルクリックして選択する。
ファイルの開き方を選択するダイアログが表示されたら、「プロジェクトとして開く」を選択。

さらに確認ダイアログが表示された場合は、「プロジェクトを信頼」をクリック。

ファイルアクセスを許可するか確認するダイアログが出た場合は、「OK」をクリック。

以下のように画面が表示されたらOK。
[![Image from Gyazo](https://i.gyazo.com/6722b0bd0eb2899e7855ef589b1f1087.png)](https://gyazo.com/6722b0bd0eb2899e7855ef589b1f1087)

初回起動時には必要なライブラリ等がダウンロードされるため、上記のように表示されるまで数分間かかることがある。

# プロジェクトの実行

画面左側には、以下のようにツリー状にファイルが表示されている。

[![Image from Gyazo](https://i.gyazo.com/475b927e45ed34f98ffed27cdab2cf1d.png)](https://gyazo.com/475b927e45ed34f98ffed27cdab2cf1d)

firstapp / src / main / java / in.techcamp.firstapp フォルダにある「FirstAppApplication」を右クリック。
すると、メニューが表示されるので、「実行」をクリックする。

クリックすると実行のための処理が行われる。

![スクリーンショット 2024-02-23 10.47.26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3633324/f4614805-b9d0-ad3d-ba54-d7b54f3dda43.png)

実行後、ログが表示されエラーなどがなければ成功。
初期状態のアプリを実行することができたことになる。

# 実行結果の確認

[http://localhost:8080/](http://localhost:8080/)

上記へアクセスし、以下のようなエラーが出ればOK。
(まだ何かを表示できるような記述をしていないため)
[![Image from Gyazo](https://i.gyazo.com/e250e6ea3f81962e5754c59f7aa4e47e.png)](https://gyazo.com/e250e6ea3f81962e5754c59f7aa4e47e)
[Angular] BREAKING CHANGE: webpack < 5 used to include polyfills for node.js core modules by default. の直し方

# はじめに

Angular 10 から Angular 17 へアップグレードしたところ、テスト実行時にこのようなメッセージが出力されました。

> BREAKING CHANGE: webpack < 5 used to include polyfills for node.js core modules by default.
> This is no longer the case. Verify if you need this module and configure a polyfill for it.
>
> If you want to include a polyfill, you need to:
>         - add a fallback 'resolve.fallback: { "timers": require.resolve("timers-browserify") }'
>         - install 'timers-browserify'
> If you don't want to include a polyfill, you can use an empty module like this:
>         resolve.fallback: { "timers": false }

このメッセージが出力されないように直していきます。


# 原因

Webpack 5から、Node.jsコアモジュールのポリフィルが含まれなくなりました。上記のメッセージはそれについての警告です。

「`timers` ないけどどないすんの？」

:confused: どうしましょうか？

「`timers`つこてるなら、`timers-browserify`インストールして、resolve.fallback で参照せえや。いらんのやら resolve.fallback に false と書いたらええ」

:thinking: えー。わかんない。

# 自分の場合の問題箇所

自分の場合、[xml2js](https://www.npmjs.com/package/xml2js) が、内部で`timers`使っているのが原因でした。

https://www.npmjs.com/package/xml2js

Angular 全然関係ない話題っすね。

# 自分の場合の解決策

使用箇所も少なかったので、xml2jsをやめて [fast-xml-parser](https://www.npmjs.com/package/fast-xml-parser)を使うように書き換えました。

https://www.npmjs.com/package/fast-xml-parser


# 感想

Webpack の深い森へ入らずに解決できてよかったです。

以前のAngularは、Webpackの設定を内部で生成していたので、そこに何らかの設定を加えるには、ビルダーごと入れ替えなければいけませんでした。
Angular 17時代は、どうやるのが正当な道なのかな？
discardで論理削除する


# はじめに
先日、業務でdiscardを使用して論理削除の実装をしました。
discardは初めて使用したのですが、とても簡単に論理削除の実装ができたため、備忘録として記事にしたいと思います。

私自身、まだまだ未熟な経験の浅いエンジニアですので、誤った解釈をしている可能性もあります。もしそういった場合がありましたら、ぜひコメントでご指摘いただければ幸いです。

# 論理削除とは

論理削除は、データベースのレコードを物理的には削除せずに、削除されたかのように扱う方法です。
レコードに「削除された」という状態を示すマークやフラグを設定することによって、レコードはデータベースに残り続けますが、アプリケーションの動作上では「存在しない」または「アクセス不可能」な状態にできます。

# discard とは

discard は、Ruby on Rails で論理削除を簡単に実装するための Gem です。
discard では、論理削除に関連するカスタムロジックを書く必要がなくなり、一貫した方法でデータを扱うことができます。

# 環境設定

### Gem のインストール

Gemfile に discard を追加するために、以下の行を追記します。

```ruby:Gemfile
gem 'discard'
```

その後、以下のコマンドを実行して、Gem をインストールします。

```bash
  bundle install
```

# マイグレーションファイルの設定

discard gem を利用するためには、まずマイグレーションファイルを設定する必要があります。これにより、データベースに論理削除のためのフィールドを追加します。

### マイグレーションファイルの生成

```
rails generate migration AddDiscardedAtToUsers discarded_at:datetime:index
```

この例では、`users` テーブルに `discarded_at` カラムを追加しています。テーブル名は適宜変更してください。

### データベースのマイグレーション

マイグレーションを適用してデータベースを更新します。

```
rails db:migrate
```

# モデルの設定

discard gem を使用するためには、モデルにいくつかの設定を加える必要があります。

### モデルの更新

論理削除を行いたいモデルに discard メソッドを追加します。例えば、`User` モデルの場合は以下のようになります。

```ruby:app/models/user.rb
class User < ApplicationRecord
  include Discard::Model
end
```

# 使い方

### レコードの論理削除

モデルのインスタンスに対して `discard` メソッドを呼び出して、レコードを論理削除します。

```
@user.discard
```

### 論理削除されたレコードの取得

論理削除されたレコードを取得する場合は、`discarded` スコープを使用します。

```
User.discarded
```

### レコードの復元

論理削除されたレコードを復元する場合は、`undiscard` メソッドを使用します。

```
@user.undiscard
```

# 参考

https://railsbytes.com/public/templates/z0gsEQ
VSCodeでMind 8 for Windowsのkernelをデバッグ実行（mcodeinfo構造体の謎に迫る？）

# はじめに
VSCodeでMind 8 for WindowsのKernelを[デバッグ実行できました](https://qiita.com/mylifewithviolin/items/83d95970c19ea0b2f2a8)ので、今回も引き続きそのデバッグ途中のご様子のレポートです。※注 デバッグの言い回しですが、もちろんデバッグが目的ではなく、学習目的でステップ実行しているだけです。

# 前提条件
Windows11 Pro 22H2
VSCode(Visual Studo Code)　1.86.1
Microsoft Visual C++ 2008 Express Edition
Mind Version 8.0.08 for Windows

## VSCodeの拡張機能
C/C++ for Visual Studio Code 1.18.5 Microsoft 
C/C++ Extension Pack 1.3.0 Microsoft 
C/C++ Extension UI Themes 2.0.0 Microsoft 
VS Code Makefile Tools 0.8.22 Microsoft 

# デバッグ実行の前提条件
Mind開発者の@killyさんからの前回記事コメントでのさらなる情報共有で、今回デバッグ対象のmindexec.exeはランタイムのローンチャに過ぎないことが判明。（以前からさんざん聞いていたような:sweat_smile:）
前回はターゲットのMコードファイルないかなということで、無謀にもとっさにMindコンパイラ自体のmind.mcoを使ってしまいましたので、今回はkillyさんお勧めのシンプルサンプルのhello.mcoをリネームしてみることとします。（そこから思いもよらない発見をすることになります！）

```
C:\developments\vscode\mind8\kernel>dir mindexec.*

 C:\developments\vscode\mind8\kernel のディレクトリ

2023/01/22  16:36             2,130 mindexec.c
2024/02/17  10:12           169,472 mindexec.exe
2024/02/17  10:12           747,528 mindexec.ilk
2023/07/23  09:31            43,562 mindexec.mco
2024/02/17  10:12            34,727 mindexec.obj
2024/02/17  10:12         1,272,832 mindexec.pdb
               6 個のファイル           2,378,143 バイト
```
mindexec.mcoがほんとはhello.mcoだったやつです。

# デバッグ実行中のご様子
最初から下図の状態までいったわけではありませんが、無事に正常実行されまして「こんにちは、Ｍｉｎｄです。」がコンソール出力されていることがわかります。

![vscodec15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3118036/992ac2ba-02b7-5fca-2f4c-ba0476a1976e.png)

賢明な本記事読者のみなさまはお気づきかと存じますが、前回のmind.mcoの場合と異なる状態となっています。

それはランタイムのファイル名です。前回のmind.mcoの場合はmrunt060.exeだったのですが、今回のhello.mcoの場合はmrunt010.exeとなったのでした。

 したがって上図の状態ではmrunt010.exeもkernelフォルダに置かせていただきます。mrunt010.exeのがmrunt060.exeより若干でかいことがわかります。
```
C:\developments\vscode\mind8\kernel>dir mrunt*.exe

 C:\developments\vscode\mind8\kernel のディレクトリ
 
2023/01/22  16:36           291,840 mrunt010.exe
2023/01/22  16:36           181,760 mrunt060.exe
               1 個のファイル             181,760 バイト
```

# デバッグ実行中のご様子2
どこでこのバージョン番号が変わったのか、なんどか注意深くステップ実行してみますと次のことがわかりました。

mindex.cが	make_runtname_and_cmdline();を実行すると、その関数内で
	strcat( RuntimeProgname, VersionDigits );
でVersionDigits("010")をランタイム名にセットしていて、そのVersionDigitsの値がどこでセットされているかというと
mindex.cのdecide_version_no()という関数がその手前で呼ばれて


![vscodec17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3118036/d3147d35-3ad1-4c3f-61c1-9d9d2f87716e.png)

その関数内でmindex_readmcode.cのreadMcodeInfoTableという関数を実行し、Mコードファイルの先頭固定32バイトを読みだしてMcodeInfo構造体に値をセットして、McodeInfo構造体メンバのminfoRuntimeNoに10がセットされ、それがVersionDigitsに連携されるという流れでした。

![vscodec16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3118036/c840c641-f26a-d003-8ee0-115e09bf611a.png)

# おわりに
ちょっとタイムアウトしてしまいました。McodeInfo構造体の存在に気づいたのは収穫ですがぜんぜん謎には迫れていませんので、続きは次回ということで。また、mrunt0NN.exeにどのソースファイルが該当するのかはmakefileやその他のbatを見ても読み取れていません。
justify-contentについて


## justify-contentとは
flexアイテムの配置を指定するプロパティで、左寄せ・右寄せ・中央寄せなど、アイテムの間の余白などを指定することができます。

また、justify-contentは、display:flex;で横並びにした要素の配置を指定するプロパティです。

web制作をしている時、横に並べた要素の間隔を均等に配置したりとか、要素を中央に寄せたりすることができます。

justify-contentには使い方が何種類かあるのですが今回はよく使うものでいうと

・flex-start（左寄せ）
・flex-end （右寄せ）
・center（中央寄せ）
・space-between（両端揃え）
・space-around（アイテムの両側に均等な余白をつける）

などになります。

具体的にどんな変化があるのか見ていきます。

まずboxを作っていきます。
HTMLは親要素である「content」というクラスのついたdivの中に子要素である「box」というクラスのついたdivが入っています。

```html
<div class="content">
 <div class="box">1</div>
 <div class="box">2</div>
 <div class="box">3</div>
</div>
```
```css
.content {
display:flex;
/* ここにjustify-contentを指定する */
}
.box {
background:lightskyblue;
width:300px;
height:300px;

}
```
display:flex;の下にjustify-contentを指定します。

justify-content の余白は、主軸方向につけられます。
主軸とは、flexアイテムが並ぶ向き（縦・横）のことを指します。

justify-content：flex-start；（左寄せ）を指定した場合
![IMG_0723.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3639571/5c48aac4-eb2f-32ed-4434-e34ac5a96cd5.jpeg)

justify-content：flex-end；（右寄せ）を指定した場合
![IMG_0725.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3639571/9ae0a524-ff19-c83e-d1f2-c081f2971bb9.jpeg)

justify-content：center；（中央寄せ）を指定した場合
![IMG_0724.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3639571/532e14db-de83-09d6-32ca-c665d2b61525.jpeg)

justify-content：space-between；（両端揃え）を指定した場合
![IMG_0726.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3639571/cf4f9719-4dfb-8243-bed6-07e9d0e499c6.jpeg)

justify-content：space-around；（アイテムの両側に均等な余白をつける）を
指定した場合
![IMG_0727.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3639571/d84ebb29-f103-1e1e-b555-840bad4ce660.jpeg)




## 最後に
justify-contentはdisplay:flex;とセットで使われるので
justify-contentのコードを指定しているのに効いていないなと思ったら
display:flex;を指定しているか確認してみましょう。
Optimize Sales Processes with Path in Salesforce



https://trailhead.salesforce.com/content/learn/modules/sales_admin_optimize_salesforce_for_selling/sales_admin_optimize_for_selling_unit_1

+ [prospecting stageがない](https://trailhead.salesforce.com/trailblazer-community/feed/0D54V00007YvvVJSAZ)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/2a4c3dd1-82f3-6891-c493-f17be020e8fd.png)

:::note
Found the answer on YouTube. 👊🏻   https://www.youtube.com/watch?v=vNH4nUJAS7k

**Had to create a Prospecting Stage from scratch. For some reason the Prospecting Stage had been deleted.

https://trailhead.salesforce.com/trailblazer-community/feed/0D54S00000EA66nSAD
:::
GASで環境変数を利用する

スクリプトプロパティを利用することで実現できます。
プロジェクトの設定 > スクリプト プロパティで設定します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2953722/b7de6108-7612-bc87-b4ec-6014b122a39e.png)

値は次のコードで取得・変更できます。
```js
//取得
PropertiesService.getScriptProperties().getProperty("key");
//変更
PropertiesService.getScriptProperties().setProperty("key","value");
```

いちいちPropertiesService.getScriptProperties()と書くのが面倒なので、Node.jsのenv風に利用できるようにしてみました。

```js
const env = (() =>  new Proxy({e : PropertiesService.getScriptProperties()}, {
      get: (t, p) => t.e ? t.e.getProperty(p) : void 0,
      set: (t, k, v) => t.e ? t.e.setProperty(k, v) : void 0
  }))();

//取得
const value = env.API_TOKEN;
//変更
env.API_TOKEN = value;
  ```
juliaのifelse()関数で再帰関数が実行できない

## 通常のifelse()関数のサンプル
```julia
function fn(n)
  ifelse(n % 2 == 0 , "偶数" , "奇数")
end
@show fn(4)
@show fn(5)

# 実行結果
# fn(4) = "偶数"
# fn(5) = "奇数"
```

## 再帰関数を使って階乗を求める
### if文
```julia
function fn(n)
  if n == 0
    return 1
  else
    return n * fn(n - 1)
  end
end
@show fn(5)

# 実行結果
# fn(5) = 120
```

### 三項演算子
```julia
function fn(n)
  return n == 0 ? 1 : n * fn(n - 1)
end
@show fn(5)

# 実行結果
# fn(5) = 120
```
または
```julia
fn(n) = n == 0 ? 1 : n * fn(n - 1)
@show fn(5)

# 実行結果
# fn(5) = 120
```

### ifelse()関数だとエラーになります
```julia
function fn(n)
  ifelse(n == 0 , 1 , n * fn(n - 1))
end
@show fn(1) #else部分を実行すらしていない

# 実行結果
# ERROR: StackOverflowError:
```

# 理由
以下の関数を実行するのと同じなので、引数をすべて評価してから実行しようとするためと考えられます
```julia
function ifelse(condition::Bool, x::Any, y::Any)::Any
  if condition
    return x
  else
    return y
  end
end
```
［備忘録］ Docerの基本のキ

# 1.はじめに
Dockerを少し勉強したので、学んだことを備忘録として残します。
# 2.Dockerとは
DockerはホストOS(ローカルの場合、windows macなど)上で新しいコンピューター(ホストOSとは別でOSをインストールし、アプリケーションもホストOSとは共有されない)を動かすことができるもの。
上記のようなものをコンテナと呼ばれる箱に入れて動かす。
# 3.Hello Worldしてみた
``` Docker:Dockerfile
#nginxをダウンロードする
FROM nginx:latest
#index.htmlを入れるためのディレクトリを作る
RUN mkdir -p /usr/share/nginx/html
# ローカルにあるindex.htmlを↑で作ったディレクトリに入れる
COPY index.html /usr/share/nginx/html
# nginxのポートを指定
EXPOSE 80
# daemon offにしてメインプロセスとして動かす
CMD [ "nginx","-g","daemon off;" ]

```
nginxの場合、静的コンテンツは/usr/share/nginx/htmlに入れるらしい

# 4.終わりに
今回は、Dockerを使ってHello Worldしてみました。
今後は、docker-compose等も学んでJavaアプリケーションをdocker上で動かしてみたいです。
私のお気に入りの統計量：ヘフディングのD

最近、私は自分のお気に入りの統計尺度である「ヘフディングのD」について英語で記事を書きました。これは、2つの数値列の間の依存性や関連性を測るのに非常に有用な尺度であり、通常この目的で使用されるより典型的な相関係数よりも多くの利点があります。この尺度は探索的統計において大きな有用性を持ち、ChatGPTのような新しいLLMモデルの重要性を考えると、今日特に関連性が高いと考えています。これらのモデルは、自然言語の文の意味を効果的に表す固定サイズの数値ベクトルを生成することができます。したがって、このような2つのベクトルがどれだけ似ているかを計算する能力は非常に便利です。

この記事を書く目的は、主題をできるだけ簡単かつ直感的に理解できるようにしながらも、深い詳細にまで踏み込んで、この尺度を深く理解し、プログラミング言語で実装する方法まで知ることができるようにすることでした。通常、「簡単で浅い」コンテンツか、「難しくて深い」コンテンツは得られますが、「簡単だけど深い」と言える技術記事は多くありません。

より多くの読者に記事を読んでもらう価値があると判断し、ChatGPT 4を使用して日本語に翻訳しました。翻訳は明瞭で理解しやすいものであると思いますが、少なくとも私の未熟な目にはそう見えます。以下のリンクでGitHub上の記事を読むことができます。言語に関する修正や訂正は大歓迎であり、PRを通じて提出することができます：

[https://github.com/Dicklesworthstone/hoeffdings_d_explainer/blob/main/README_Japanese.md](https://github.com/Dicklesworthstone/hoeffdings_d_explainer/blob/main/README_Japanese.md)