OmniAICreator/Qiita-1.07M huggingface dataset:
新卒2年目エンジニアの成長記録: React学習3か月目

# はじめに
最初に改めてざっくりと自己紹介をさせていただきます。
新卒2年目エンジニアのA.Kと申します。（2年目に突入してしまった。。）
**現在は運用保守の案件に参画しており、Javaをメインに使用しています。
ですが、フロントエンドの開発案件を希望しているため、個人学習でReact、TypeScriptを使ってアプリを作成しています。**（理由はいろいろあるのですが割愛します。）
**現在勉強を頑張っている方にとって、この記事が励みになればと思っています！**


先月の状況はこちらです！

https://qiita.com/AK_React/items/8752eb96ea4bab75d319
# 学習3カ月目にやったこと
まず、<font color="Red">**この3カ月間のざっくりとした動き**</font>はこちらです。

**JavaScript基礎（Udemyインプット）**
↓
**JavaScript×Reactでアプリ作成**

https://qiita.com/AK_React/items/526c3da30ca8d69a4307

↓
**TypeScript基礎（Udemyインプット）**
↓
**TypeScript×Reactで学習記録アプリ作成**
↓
<font color="Red">**TypeScript×Reactでデジタル名刺アプリ作成（近日記事投稿します！）**</font>


**今月は先月とやっていることはほぼ変わらず、ひたすら手を動かして1つのアプリを作成していました。　アウトプットが9割**といったところです。


# 学習3カ月目の心境の変化
あまり技術的な内容ではないものの、学習3カ月目に感じたことを書いていきます。
***
**１．これまでの学習を振り返りながら進める**

「とにかく手を動かせ！」とよく言いますが、ひたすら前に進めようとして、これまで自分ができていたことが抜けてしまったり、過去に解消できたエラーに余分な時間を割いてしまったりしました。
なので、**過去の学習内容や基礎的なコンテンツを振り返りながら進めることの重要性を再認識**しました。
***
**２．自分に過度な期待をしない**

前述したとおり、**今回作成したアプリは2作品目**になります。
なので、**「ある程度スムーズに実装を終えられるんじゃなかろうか。」と思っていました。**
しかし、いざ手を動かしてみると思わぬ箇所でつまづいたり、進捗が滞ったりすることもあるわけです。**「こんなはずじゃなかったのに。。」とかなり気分が落ちてしまいました。**
これを読んでくださっている先輩方はすでに思っているでしょう。
**「まだ2作品目じゃねえか。まだ学習歴3カ月目じゃねえか。」**
さすがに100作品目でコードが全然書けません！とか、同じエラーに何度もつまづいているのであれば考え物かもしれませんが、**私の経験量はまだまだ駆け出しレベルなわけです。**

<font color="Red">**日々学習していると、どうしても自分に期待したくなります。
ですが、その期待値の基準は過去の自分、くらいにとどめておきたいです。<font>**
***
**３．休息はやっぱり必要**

特に進捗が悪い時期、**焦りからか週7で学習を続けていました。**
これが楽しい・苦にならない人は全然問題ないと思います。
ですが、私はそうではありませんでした。
休息を削れば削るほど、スペルミスが増え余分な修正を加え、エラーを量産するようになりました。
**なので、最近は意識的にPCから離れる時間を確保しています。**
翌日になると本当に頭がすっきりしているので、<font color="Red">**休息は後退ではなく前進のための燃料**</font> だと捉えるようになりました。


# おわりに
以上、React学習3か月目の振り返りでした。
**4カ月目も引き続き、手を動かしつつサービスを作っていきます。**
春はどうしても現場の稼働が上がりがちですが、無理しすぎず少しづつ進めていけたらと思っています。
# JISOUのメンバー募集中
プログラミングコーチングJISOUではメンバーを募集しています。
日本一のアウトプットコミュニティでキャリアアップしませんか？

気になる方はぜひHPからライン登録お願いします👇

https://projisou.jp
【AtCoder】中三の競プロのレベル高すぎだろ！

## はじめに

自分は茶コーダー中学生競プロerです。

今から書く記事は自分の主観かなりよっていますが、そこは見逃してください。

## AJLとは

下のリンクを見てください。(自分で説明すると下手になるので説明を省略します)

https://atcoder.jp/contests/ajl2024Summer

## 中三のレベルが高すぎる件(本題)

1位の人が黄色コーダーでした。これは萎えますね。2位の人の2倍程度のスコアをとています。

中三で黄色コーダーはえぐすぎ

20位以内に入賞するためにも個人的な勝手な予想だけど、平均して1000~1200くらいパフォーマンスをとることが求められそう。

この現状茶色コーダーにとってみれば萎えますね。

自分も頑張ります。

去年はなんとPythonのset型をほとんど知らないという現状。

しかし、今はそれ以外も累積和とかいろいろ学んでいます。

## 朗報

中学一年生よ。今は14人しか参加登録していない。確定で入賞だ！参加せよ。

## 注意

これは5/10現在のものです。情報が古くなれば古くなるほど信憑性は落ちます。

---

いいねとフォローをお願いします。
GitHub pagesでリンク先に飛べなかった

# 起こった現象

Reactで作ったプロジェクトをGithub pagesで公開した。
muiの`Link`で作ったあるボタンから他ページへ遷移させたところ、404エラーでページが表示されなかった。
不思議な点として`useNavigate()`からそのリンクに移る時はページが表示される。

# 解決方法
変更前のボタン
```react
import { Link } from "@mui/material";

export const HogePresenter = () => {
      return (
          <Link
              href="/page"
          >
              {"押したらページ遷移する"}
          </Link>
      );  
};
```

変更後のボタン
```react
import { Link } from "@mui/material";
import { Link as RouterLink } from "react-router-dom";

export const HogePresenter = () => {
      return (
          <Link
              component={RouterLink}
              to="/page"
          >
              {"押したらページ遷移する"}
          </Link>
      );  
};
```

# なぜこれで直ったのか

まず前提として、Github pagesを自分だけで見られるようにprivateに設定していた。
おそらくこれの影響で、`Link`の`href`からのアクセスだと受け付けないようになっていたのだと思う。

Github pagesがどうやってページを非公開にしているのか仕組みがよくわからなかったが、関係ある気がする。


# 参考資料

https://mui.com/joy-ui/react-link/#third-party-routing-library

https://docs.github.com/ja/enterprise-cloud@latest/pages/getting-started-with-github-pages/changing-the-visibility-of-your-github-pages-site
red zone(関数呼び出し規約)について

# 前書き
アセンブラを読んでいて気になることがあった
```asm
    118e:	89 e5                	mov    ebp,esp
    1190:	83 ec 10             	sub    esp,0x10 //ここ！
    119d:	c7 45 f4 01 00 00 00 	mov    DWORD PTR [ebp-0xc],0x1
    11a4:	c7 45 f8 03 00 00 00 	mov    DWORD PTR [ebp-0x8],0x3
```
こんな風にスタックポインタを使う分だけ`sub`してスタックフレームを広げる関数と、

```asm
    1151:	f3 0f 1e fa          	endbr64 
    1155:	55                   	push   rbp
    1156:	48 89 e5             	mov    rbp,rsp //この後引いてない！
    1159:	c7 45 fc 02 00 00 00 	mov    DWORD PTR [rbp-0x4],0x2
```
そうでない関数がいる。
これらの違いはどこからきているのかずっと気になっていた。

# レッドゾーン
関数呼び出し規約に**red zone**というものがある。
これはスタックポインタの上128バイトは予約されていて、割り込みによって書き換えることが禁止されているというものである。
割り込みによって書き換えられないことが保障されているならば、他の関数を呼ばない関数(そういう関数を**leaf function**と呼ぶ)はその領域を事実上自由に使えるということになる。これによってバイナリを最適化することができるというわけだ。

事実、先ほどのアセンブラはそれぞれ 以下のコードをコンパイルして作成した
```c
void test() {
	printf("test");
	return;
}

int main() {
	int a = 1;
	int b = 3;
	test();
	return 0;
}
```

```c
int main() {
	int a = 2;
	return 0;
}
```

半年にわたる漠然とした疑問が晴れてすっきりである
# 参考文献
- [wilipedia](https://en.wikipedia.org/wiki/Red_zone_(computing))
- [ゼロからの OS 自作入門](https://zero.osdev.jp)
	- この本の3章でレッドゾーンの存在を知った
SAP S/4HANA Cloud環境へADT(ABAP Development Tools)でアクセスしてみた

BASIS担当なので、アプリ側は疎いですが環境構築は必要ですので自分でも環境アクセスした備忘録です。

# ABAP Development Toolsインストール方法

インストール方法はこちらの方の記事を参考にしました。

https://qiita.com/tami/items/c0c01cd7b6b950e3a1ab


Eclipseをインストール後にABAP Development Toolsを新規のソフトウェアとしてインストールする必要があります。

## インストール上の注意点
基本的に上記の投稿通りなのですが、挿入するURLはhttps://tools.hana.ondemand.com/latest

また、SAP GUIのインストールは前提条件ではないです。


# SAP S/4HANA Cloud環境アクセス方法

そもそも開発者拡張の意味がわからない方はこのブログがおすすめです。
環境接続に関しても書かれています。

https://community.sap.com/t5/enterprise-resource-planning-blogs-by-sap/sap-s-4hana%E3%81%AB%E3%81%8A%E3%81%91%E3%82%8B%E9%96%8B%E7%99%BA%E8%80%85%E6%8B%A1%E5%BC%B5%E3%81%AE%E4%BD%9C%E6%88%90%E6%96%B9%E6%B3%95/ba-p/13558451



環境アクセスに必要なユーザに関しては私の書いたブログ参考にしてみてください。

https://qiita.com/96sapbasis/items/da6eb0d0084f68b4359e


## 初期オブジェクト一覧
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2821335/b1c191c6-ba98-a597-a7e3-6702552688cd.png)
P5.js 日本語リファレンス(buildGeometry)

このページでは[「P5.js 日本語リファレンス」](https://qiita.com/bit0101/items/91818244dc26c767a0fe) の buildGeometry()関数を説明します。

## buildGeometry

### 説明文

buildGeometry()は sphere(球) や cone(円錐) など単純な 3D 形状から複雑な 3D 形状を作成して p5.Geometryオブジェクトにすることができます。

buildGeometry()で複雑な 3D 形状を作成して、スケッチ途中で変更しないときはスケッチのパフォーマンスを向上させる事ができます。(個々の形状部分を繰り返し描画するよりも高速に実行できます)

buildGeometry() のパラメタとしてオブジェクトの描画命令を含むcallback関数を指定することができます。

3D 形状を作成する別の方法については、[beginGeometry()と endGeometry()](https://qiita.com/bit0101/items/6b7101393075d766fae3) を参照してください。

注: buildGeometry()は WebGL モードでのみ使用できます。


### 構文

buildGeometry(callback)

### パラメタ

callback: 任意。オブジェクトの描画命令を含むcallback関数を指定する

### 例
https://editor.p5js.org/bit0101/sketches/9ux9p0q-a

### 著作権
p5.js was created by Lauren McCarthy and is developed by a community of collaborators, with support from the Processing Foundation and NYU ITP. Identity and graphic design by Jerel Johnson.

### ライセンス
Creative Commons(CC BY-NC-SA 4.0) に従います。
【visionOS】3Dモデルにアニメーションを適用し、RealityViewで表示・再生する方法

本記事では3DモデルにMixamoでアニメーションを適用し、RealityViewで表示・再生する方法を紹介します。
(※技適特例届け出済み)

## デモ

3Dモデルをタップすると、アニメーションを再生するようにしています。

![画面収録 2024-05-10 15.21.10.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1042576/fb7f8dad-b5e8-e840-09c8-4651fb8bfe34.gif)

## アニメーションの編集方法

1. フリーの3Dモデルをダウンロードします。
(今回は[こちらのサイト](https://www.cgtrader.com/free-3d-models/character/fantasy-character/zombie-79f78dd5-e3c9-44d2-a9e4-9530f9139426)からゾンビのモデルをダウンロードしました。) 

 
2. Mixamoを使用して、ダウンロードしたモデルに好みのアニメーションを適用させます。
    ![画面収録 2024-05-07 12.04.32.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1042576/6612732f-93d0-2208-7916-0883a2858c1f.gif)
    今回は攻撃をするアニメーションを適用させました。
    ([Mixamo](https://www.mixamo.com/#/)は、3Dキャラクターにアニメーションを適用できるAdobe社のオンラインサービスです。)


3. [Reality Converter](https://developer.apple.com/jp/augmented-reality/tools/#:~:text=Store%E3%81%A7%E8%A6%8B%E3%82%8B-,Reality%20Converter,-Reality%C2%A0Converter%E3%82%A2%E3%83%97%E3%83%AA)を使用して、アニメーション適用後のモデルにテクスチャを適用させ、USD*（Universal Scene Description）形式で出力します。
     ![画面収録 2024-05-07 12.07.17.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1042576/bfd89b86-8a51-3b0e-11ec-66a6ac227aa6.gif)

## 実装

Reality ConverterでエクスポートしたUSDZファイルをXcodeプロジェクトにインポートし、RealityKitを使用して表示させます。

```swift
struct ImmersiveView: View {
    @StateObject var vm: ImmersiveViewModel = ImmersiveViewModel()
    @State var entity = try! Entity.loadModel(named: "attack_zombie")
    
    var body: some View {
        RealityView { content in
            entity.generateCollisionShapes(recursive: false)
            entity.components.set(InputTargetComponent())
            content.add(entity)
        }
        .gesture(tapGesture)
    }
    
    private var tapGesture: some Gesture {
        TapGesture()
            .targetedToAnyEntity()
            .onEnded { value in
                let entity = value.entity
                entity.playAnimation(self.entity.availableAnimations[0])
            }
    }
}
```

RealityKit内でModelEntityを追加し、TapGestureを使用してEntityのアニメーションを再生する処理をしています。

また、RealitiyViewでイベントの入力を受け取るには、ModelEntityにInputTargetComponentとCollisionComponentの両方を設定する必要があります。

![スクリーンショット 2024-05-10 16.33.28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1042576/e2a216b2-60e4-01ad-fb62-1175a67f9bfd.png)

> You can add a gesture to a RealityView, like any other SwiftUI view, and it will hit test against entities in that view. To receive input, the entity must have both an input target component and a collision component. When a touch event is handled by RealityView, it will ignore any entities that don't have both collision and an input target. Only this last entity has both components, so gestures added to this RealityView will only react to input directed at this entity.

引用: [Build spatial experiences with RealityKit - WWDC23](https://developer.apple.com/videos/play/wwdc2023/10080/?time=964)


## 参考資料
https://developer.apple.com/videos/play/wwdc2023/10080/

https://note.com/npaka/n/n96b549879161

https://1planet.co.jp/tech-blog/applevisionpro-oneplanet-realityview-modelentity-tap-01
JavaScriptのmapメソッドとforEachメソッドの違いと使い方

1. mapメソッドとは
説明: mapメソッドは、配列の各要素に対して与えられた関数を呼び出し、その結果を新しい配列として返すメソッドです。
特徴:
元の配列を変更せずに、変換された要素からなる新しい配列を生成します。
配列の要素を変更したり、操作したりするために使用されます。
2. forEachメソッドとは
説明: forEachメソッドは、配列の各要素に対して与えられた関数を順番に呼び出しますが、新しい配列を返しません。
特徴:
元の配列を変更せずに、配列内の各要素を操作したり処理したりするために使用されます。
3. 違いと使い分け
mapメソッド:
新しい配列を生成して変換された結果を取得する場合に使用します。
変換された結果を配列として取得したい場合に便利です。
forEachメソッド:
配列内の要素を操作したり、処理したりする場合に使用します。
配列を変更しないまま、要素に対して処理を行いたい場合に利用します。
4. 使い方の例

```js
// mapメソッドの例
const numbers = [1, 2, 3, 4];
const doubled = numbers.map(num => num * 2);
// doubled: [2, 4, 6, 8]
```
```js
// forEachメソッドの例
const numbers = [1, 2, 3, 4];
numbers.forEach(num => console.log(num * 2));
// コンソール出力: 2, 4, 6, 8
```

5. まとめ
mapメソッドは新しい配列を生成して変換された結果を取得するために使用されます。
forEachメソッドは要素を操作するために使用され、新しい配列を生成しません。
この記事では、JavaScriptのmapメソッドとforEachメソッドの違いと使い方について解説しました。
Pythonを使用してPowerPointファイル間でスタイルをコピーする（スライドマスターのコピー）

プロフェッショナルなプレゼンテーションのデザインと開発の分野では、複数のプレゼンテーション間の一貫性が非常に重要です。PowerPointプレゼンテーション間でスライドマスターをコピーすることは、ブランドの整合性を確保し、視聴者のエンゲージメントを高めるために、統一された外観と雰囲気を維持するための不可欠な技術になります。これにより、貴重な時間を節約できるだけでなく、フォント、色、背景スタイル、レイアウトテンプレートなどのデザイン要素を更新するプロセスも効率化されます。Pythonを活用することで、このタスクを自動化できます。この記事では、**Pythonを使用してPowerPointプレゼンテーション間でスライドマスターをコピーする方法**について説明し、プレゼンテーション作成ワークフローの効率と美観を向上させる方法を紹介します。

- **[Pythonを使用してスライドマスターをコピーしてプレゼンテーションスライドに適用](#pythonを使用してスライドマスターをコピーしてプレゼンテーションスライドに適用)**

この記事で使用する方法は、[Spire.Presentation for Python](https://www.e-iceblue.com/Download/Spire-Presentation-Python.html)が必要です。Spire.PresentationはPyPI経由でインストールできます： `pip install Spire.Presentation`。

[無料ライセンスの申請](https://www.e-iceblue.com/TemLicense.html)

## Pythonを使用してスライドマスターをコピーしてプレゼンテーションスライドに適用
プレゼンテーションのスライドスタイルを別のプレゼンテーションに適用するには、プレゼンテーション間でスライドマスターをコピーし、マスタースタイルを指定したスライドに適用します。プレゼンテーション間でスライドマスターをコピーして指定したスライドに適用する手順は以下のとおりです。
- 必要なモジュールをインポートします。
- **Presentation**クラスのオブジェクトを2つ作成し、**Presentation.LoadFromFile()** メソッドを使用して2つのプレゼンテーションドキュメントを読み込みます。
- **Presentation.Masters.get_Item()** メソッドを使用して、2番目のプレゼンテーションのスライドマスターを取得します。
- **Presentation.Masters.AppendSlide()** メソッドを使用して、1番目のプレゼンテーションにスライドマスターを追加します。
- **ISlide.Layout**プロパティを使用して、2番目のプレゼンテーションのスライドにスライドマスターを適用します。
- **Presentation.SaveToFile()** メソッドを使用して、1番目のプレゼンテーションを保存します。
- リソースを解放します。

**コードの例**
```python
from spire.presentation import *
from spire.presentation.common import *

# Presentationの2つのオブジェクトを作成します
pres1 = Presentation()
pres2 = Presentation()

# 2つのPowerPointドキュメントを読み込みます
pres1.LoadFromFile("サンプル1.pptx")
pres2.LoadFromFile("サンプル2.pptx")

# 2番目のプレゼンテーションのスライドマスターを取得します
master = pres2.Masters.get_Item(0)

# スライドマスターを最初のプレゼンテーションに追加します
index = pres1.Masters.AppendSlide(master)

# スライドマスターを最初のプレゼンテーションに適用します
pres1.Slides.get_Item(0).Layout = pres1.Masters.get_Item(index).Layouts.GetByType(SlideLayoutType.Title)
for i in range(1, pres1.Slides.Count):
    pres1.Slides.get_Item(i).Layout = pres1.Masters.get_Item(index).Layouts.GetByType(SlideLayoutType.TitleAndObject)

# 最初のプレゼンテーションを保存します
pres1.SaveToFile("output/スライドマスターのコピー.pptx", FileFormat.Pptx2013)
pres1.Dispose()
pres2.Dispose()
```

最初のプレゼンテーション資料
![スライドマスターのコピー](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/278784/7d334821-ad68-ca68-08de-4a79f1928e8b.png)

2つ目のプレゼンテーション資料
![スライドマスターのコピー](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/278784/0d956eb0-d859-2e99-2050-6a9da61ee6ca.png)

保存されたプレゼンテーション資料
![スライドマスターのコピー](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/278784/28549afe-e879-007f-02f3-fef082f78b84.png)

この記事では、**Pythonコードを使用してPowerPointプレゼンテーションのスライドマスターをコピーしてスライドに適用する方法**について説明しました。

PowerPointプレゼンテーションの処理スキルについては、[Spire.Presentation for Pythonのチュートリアル](https://www.e-iceblue.com/Tutorials/Python/Spire.Presentation-for-Python/Program-Guide/Spire.Presentation-for-Python-Program-Guide-Content.html)を参照してください。

このツールの使用中に問題が発生した場合は、[Spire.Presentationフォーラム](https://www.e-iceblue.com/forum/spire-presentation-f14.html)で技術サポートを受けてください。
github



『リポジトリについて』

・ローカルリポジトリを作成し、ファイルを作成し編集する。編集したものをステージングエリアに追加し、ローカルリポジトリにコミット（記録）させる。
作成したローカルリポジトリをリモートリポジトリに反映することでブラウザ上で確認することができる。

・ローカルリポジトリ作成
・編集したファイルをステージングエリアに追加
・追加したファイルをローカルリポジトリに記録させる


実際にあった問題
→グループワーク(pizzaの時)、リポジトリができなくて焦った記憶。
ずっとコミットできない。


『原因』
リポジトリ以前の問題で、ディレクトリの場所がそもそも間違えてた。
addしないで、コミットしていた。
githubの流れを理解できてなかった。
gitlogなどで確認作業を怠らない
pythonから他言語の関数にリストを渡す際の速度比較

## 概要
pythonから他言語で記述した関数にリストを渡す際の処理則の比較をする。今回は、他言語の関数にリストを渡すまでのpython側での実装方法の差による処理速度の比較する。比較する実装はRustの関数にリストを渡す場合を想定して用意した。

## 比較する実装
1. `','.join(tokens)`
1. `json.dumps(tokens)`

## コード
```python
import json
import time
import matplotlib.pyplot as plt

# トークンリストの長さ
lengths = [10, 100, 1000, 10000, 100000]
# 処理時間を記録するリスト
times_comma = []
times_json = []

# 各長さに対して実験
for length in lengths:
    tokens = ['token'] * length
    # カンマ区切り文字列の時間計測
    start_time = time.time()
    for _ in range(100):
        result_comma = ','.join(tokens)
    end_time = time.time()
    times_comma.append((end_time - start_time) / 100)

    # json.dumpsの時間計測
    start_time = time.time()
    for _ in range(100):
        result_json = json.dumps(tokens)
    end_time = time.time()
    times_json.append((end_time - start_time) / 100)

# 結果のグラフ化
plt.figure(figsize=(10, 5))
plt.plot(lengths, times_comma, label='Comma-separated', marker='o')
plt.plot(lengths, times_json, label='json.dumps', marker='o')
plt.xlabel('Length of Token List')
plt.ylabel('Average Time per Operation (seconds)')
plt.title('Performance Comparison: Comma-separated vs. json.dumps')
plt.legend()
plt.grid(True)
plt.xscale('log')
plt.yscale('log')
plt.show()
```

## 結果
1. `','.join(tokens)`の方が速い

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/80836/6960646a-ee74-07dd-4c97-56d0ca18f615.png)
Ajaxとは〜サッカーチームのアヤックス・アムステルダムとの関係性について〜

# Ajaxとアヤックス


<br>
プログラミングを学習し始めてかなり早い段階で「Ajax」というワードに出会いました。「エイジャックス」と読むらしいです。
<br>

私は幼稚園から今もサッカーをやっているのでこのワードを聞いて頭に引っかかりました。「どっかで見たことあるような？」

「アヤックス」

私は最初このように「Ajax」を読みました。

「Ajax」と「アヤックス」（通称：アヤックス・アムステルダム）

https://ja.wikipedia.org/wiki/Ajax

https://ja.wikipedia.org/wiki/%E3%82%A2%E3%83%A4%E3%83%83%E3%82%AF%E3%82%B9%E3%83%BB%E3%82%A2%E3%83%A0%E3%82%B9%E3%83%86%E3%83%AB%E3%83%80%E3%83%A0


この両者に何か関係があるのか？

「Ajax」は「Asynchronous JavaScript And XML」の略で「アヤックス」はギリシャ神話に出てくる「アイアース」という人物が由来のようで「アイアース」をオランダ語表記にすると「アヤックス」になるそうです。
<br>
肝心の覚えなければいけない「Ajax」はwebアプリを開発する人からしたら当たり前の用語で

[Ajax](https://ja.wikipedia.org/wiki/Ajax)
 >Ajax（エイジャックス[1][2]、アジャックス[3]）は、ウェブブラウザ内で非同期通信を行いながらインターフェイスの構築を行うプログラミング手法である

<br>
 学び始めで覚える単語が多くて大変ですが自分のわずかながらに持ち合わせている経験と関連付けながら吸収していきたいとおもいます。
nodebrewがinstallされているのにnode -vでエラーになる時

# はじめに

```
$ node -v
```

と打ったら

```
zsh: command not found: node
```

となった…。

```
$ nodebrew -v

nodebrew 1.2.0
〜
〜
```
nodebrewは入っているのに。。

# PCスペック

| 項目 | 情報 |
| --- | --- |
| OS | macOS Sonoma 14.4.1  |
| ハードウェア | MacBook Pro 16inc 2023 |
| プロセッサ | Apple M2 pro |
| メモリ | 32GB |


# 解決法

### patyを通せばOKです。

```
$ cat ~/.zshrc
```
と実行してみましょう。
中身が見えるはずです。

以下を実行して設定を追記します。

```
$ echo 'export PATH=$HOME/.nodebrew/current/bin:$PATH' >> ~/.zshrc
$ source ~/.zshrc
```



```
$ node -v

v21.5.0
```

いけました！
node_modulesのcssを変更したい

# きっかけ
とある，ライブラリーのcssを変更したいと思いつつ，様々なことをやったが，いい方法が思いつかなかったので，備忘録として書きます．
# 状況
今回は，next.jsのapp routerを利用しています．
```layout.tsx
import type { Metadata } from 'next';
import { Inter } from 'next/font/google';
import './globals.css';
import 'rsuite/dist/rsuite-no-reset.css'; 
import 'react-date-range/dist/styles.css'; // main css file
import 'react-date-range/dist/theme/default.css'; // theme css file
import React, { ReactNode } from 'react';
import { Toaster } from 'react-hot-toast';

const inter = Inter({ subsets: ['latin'] });


export default function RootLayout({
  children,
}: Readonly<{
  children: ReactNode;
}>) {
  return (
    <html lang='en'>
      <body className={inter.className}>
        {children}
        <Toaster />
      </body>
    </html>
  );
}

```
ここで，Google Chromeから変更したいcssはdefault.cssに入っていることがわかっていました．
# 解決策
そこで，`default.css`の中身をコピーして，新しく`customDefault.css`を作り，その中身を変えることで対応しました．力技であり，ライブラリーの更新に対応できないという側面もありますが，今回はこれで問題ないので採用しました．
最後に改善後のコードを示します．
```layout.tsx
import type { Metadata } from 'next';
import { Inter } from 'next/font/google';
import './globals.css';
import 'rsuite/dist/rsuite-no-reset.css'; 
import 'react-date-range/dist/styles.css'; // main css file
import './customStyle/react-date-range/default.css'; // theme css file
import React, { ReactNode } from 'react';
import { Toaster } from 'react-hot-toast';

const inter = Inter({ subsets: ['latin'] });


export default function RootLayout({
  children,
}: Readonly<{
  children: ReactNode;
}>) {
  return (
    <html lang='en'>
      <body className={inter.className}>
        {children}
        <Toaster />
      </body>
    </html>
  );
}

```
Mac Book Proでnodebrew installをしたらcurl: (23)エラーになった時

# はじめに

```
$ nodebrew install v21.5.0
```

コマンドを打ったらエラーになった。
その解消方法を紹介する。

# PCスペック

| 項目 | 情報 |
| --- | --- |
| OS | macOS Sonoma 14.4.1  |
| ハードウェア | MacBook Pro 16inc 2023 |
| プロセッサ | Apple M2 pro |
| メモリ | 32GB |



```
$ nodebrew install v21.5.0
```

実行すると

```
Fetching: https://nodejs.org/dist/v21.5.0/node-v21.5.0-darwin-arm64.tar.gz
Warning: Failed to open the file
Warning: /Users/{ユーザーID}/.nodebrew/src/v21.5.0/node-v21.5.0-darwin-arm64.tar.gz:
Warning:  No such file or directory
curl: (23) Failure writing output to destination

download failed: https://nodejs.org/dist/v21.5.0/node-v21.5.0-darwin-arm64.tar.gz
```

あれ？

対象バージョンがないかな？

```
$ nodebrew ls-remote | grep v21

v21.0.0   v21.1.0   v21.2.0   v21.3.0   v21.4.0   v21.5.0   v21.6.0   v21.6.1
v21.6.2   v21.7.0   v21.7.1   v21.7.2   v21.7.3
```

あるな。

どうやらダウンロード先のフォルダがないのが原因だったようです。

```
$ mkdir ~/.nodebrew
$ mkdir ~/.nodebrew/src
```

を実行してから再度installコマンドを実行

```
$ nodebrew install v21.5.0

Fetching: https://nodejs.org/dist/v21.5.0/node-v21.5.0-darwin-arm64.tar.gz
############################################################################################################################################################################################################################# 100.0%
Installed successfully
```

いけました！
Ruby on Rails (React on Webpacker) でアプリを作成してみた

## 1 - Project Setup

①プロジェクトフォルダを作成する

```
mkdir プロジェクト名
```
②railsのプロジェクトを作成する

```
rails new backend -d postgresql --api
```
②reactのプロジェクトを作成する

```
npx create-react-basic frontend
```
③backend/config/database.ymlを編集する

```backend/config/database.yml

development:
  <<: *default
  database: backend_development
  username: test
  password: test
  
//省略

test:
  <<: *default
  database: backend_test
  username: test
  password: test

//省略

production:
  <<: *default
  database: backend_production
  username: test
  password: test
```
④psqlと入力してpostgresコンソールに移動

```
cd backend
psql
clear
```
⑤ データベースを作成する

```
rails db:create
```


## 参考サイト
[AM Coder - Ruby on Rails + React #1 - Project Setup](https://www.youtube.com/watch?v=CS6npdU2rf8&list=PLY6oTPmKnKbYNIC0Yq3Cc6mgHZrWiZcJU)
Python<Tkinter>備忘録【アプリ化】～ブクマ機能付きメモ帳作成編～

# はじめに
Pythonで作成したプログラムを実行ファイルに変換する手順です。

実行環境
* Windows 10 
* Visual Studio
* Python 3.11.3

以下のページを参考にしました。
[Pythonファイルをexe/app化する。](https://qiita.com/MatsuM2_1007/items/77d72b96067688f8dafc "Qiita内")
[python テキストエディタ作成 -tkinter-](https://qiita.com/itakura1984/items/cc61d32d590e844cb4a7 "Qiita内")
[【Python3】メッセージボックスの表示](https://qiita.com/DEETHIRATH/items/c0d343d0be078830a55a "Qiita内")

# プログラムを作成
お好きなプログラムを作成しましょう。
以下は、Tkinterを利用したサンプルです。
<details><summary>サンプルコード</summary>

```Python:
import tkinter as tk
import tkinter.filedialog
from tkinter import messagebox
from time import sleep
import webbrowser

note = tk.Tk()
note.title('Hello, world.')

def file_load():
    abc = [('Text','*.txt'), ('Python','*.py')]
    fn = tk.filedialog.askopenfilename(filetypes=abc)
    if fn != '':
        f = None
        try:
            f = open(fn, 'r', encoding='utf-8')
            te.delete('1.0', 'end')
            te.insert('1.0', f.read())
        except:
            f = open(fn, 'r', encoding='shift-jis')
            te.delete('1.0', 'end')
            te.insert('1.0', f.read())
        finally:
            if f != None:
                f.close()

def file_save():
    abc = [("Text", "*.txt")]
    fn = tk.filedialog.asksaveasfilename(filetypes=abc)
    if fn != "":
        if fn[-4:] != ".txt":
            fn = fn + ".txt"
        with open(fn, 'w', encoding="utf-8") as f:
            f.write(te.get("1.0","end-1c"))

def close_app():
    if messagebox.askokcancel('-', 'アプリケーションを終了しますか？'):
        note.destroy()

menu_bar = tk.Menu()
menu0 = tk.Menu(menu_bar, tearoff=0)
menu0.add_command(label='ファイルを開く', command=file_load)
menu0.add_command(label='保存する', command=file_save)
menu0.add_separator()
menu0.add_command(label='終了', command=close_app)
menu_bar.add_cascade(label='ファイル', menu=menu0)
note['menu'] = menu_bar

pre = tk.Label(note, text='fish & chips')
pre.pack()
fr = tk.Frame()
fr.pack()
te = tk.Text(fr, width=80, height=30)
sc = tk.Scrollbar(fr, orient=tk.VERTICAL, command=te.yview)
sc.pack(side=tk.RIGHT, fill=tk.Y)
te.pack()
te[ 'yscrollcommand' ] = sc.set

def donut(btn1):
    sleep(0.5)
    webbrowser.open('https://www.google.com/')

def scone(btn2):
    sleep(0.5)
    webbrowser.open('https://qiita.com/')

btn1 = tk.Button(text='google', width=80)
btn1.pack()
btn1.bind('<Button-1>', donut)

btn2 = tk.Button(text='qiita', width=80)
btn2.pack()
btn2.bind('<Button-1>', scone)

note.mainloop()
```
</details>

# コマンドプロンプトを起動

まずはpyinstallerを準備します。
(エラーが出た場合、pipのバージョンが古い可能性があります。)
```
pip3 install pyinstaller
```
次に、ファイルがある場所へ移動します。
```
cd desktop
```
Pythonのファイル名を指定して、以下を実行。
```
pyinstaller xxx.py --onefile --noconsole
```
ファイルと同じ場所に、distとbuildのふたつのフォルダが作成されます。
distフォルダ内にアプリケーションソフトが作成されていたら成功です！
お疲れさまでした。

# おわり
お役に立てたら幸いです。
PORTERSのAPI連携の備忘録【GPT作】

# OAuth認証プロセスの手順

## 手順１：OAuthリクエストの準備
- **App IDの取得：**
  - アプリ登録を行い、発行されたApp IDを取得します。
- **Redirect URLの確認：**
  - アプリ登録時に指定したRedirect URLを準備します。

## 手順２：OAuthリクエストの実行
- 以下のURLフォーマットを使用してWebブラウザからアクセスします。

```
https://{Request Host}/v1/oauth?response_type=code&app_id=[Your App ID]&scope=[Desired Scopes]&redirect_url=[Your Redirect URL]
```

- **{Request Host}**：共有サーバーのアドレス（例：api-hrbc-jp.porterscloud.com）
- **[Your App ID]**：取得したApp ID
- **[Desired Scopes]**：必要なアクセス権限をカンマ区切りで指定（例：candidate_r,user_r）
- **[Your Redirect URL]**：Redirect URL

## 手順３：PORTERSログイン画面
- 指定したURLにアクセスすると、PORTERSのログイン画面が表示されます。ここでログイン情報を入力し、ログインします。

## 手順４：権限付与の確認
- ログイン後、アプリから要求されたアクセス権をユーザーが承認する必要があります。

## 手順５：アプリへのリダイレクト
- 権限承認後、ユーザーは指定されたredirect_urlにリダイレクトされ、認証コードがURLパラメータとして追加されます。
- 例：http://myapplication.com?code=abc123

## 手順６：Access Tokenの取得
- アプリは受け取った認証コードを使用してToken APIにアクセスし、Access Tokenを取得します。このトークンはCompany DBへのAPIリクエストに使用されます。

## 注意事項
- 認証コードの有効期限は発行から30秒です。この間にAccess Tokenを取得する必要があります。
- 必要なスコープはアプリがアクセスするリソースに基づいて正確に指定する必要があります。

# クラウドサービスからのOAuthリクエストにおける留意点
- **サーバー間認証の場合（code_direct使用）：**
- Webブラウザを介さないサーバー間での直接認証が必要な場合、`response_type`として`code_direct`を使用します。これにより、Webブラウザ経由でなく直接的に認証コードを受け取ることができます。
- `redirect_url`は必要ありません。

- **リダイレクトURLのセキュリティ：**
- クラウドサービスがWebブラウザを使用する場合（例えば、Webアプリケーションの場合）、指定するredirect_urlはセキュリティが保たれている必要があります（通常はHTTPSを使用）。

- **非同期リクエストの取扱い：**
- クラウド環境でのリクエストは非同期に実行されることが多いです。認証プロセス中に時間がかかる場合があるため、タイムアウト設定など、非同期通信の特性を考慮した実装が必要です。

- **スケーラビリティと負荷の管理：**
- クラウドサービスを利用する場合、リクエストの数が増加する可能性があります。サーバーの負荷を適切に管理し、リソースをスケーリングできるように準備しておくことが重要です。

- **セキュリティ対策：**
- アクセストークンやリフレッシュトークンは、非常に敏感なデータです。これらのトークンを安全に管理し、不正アクセスや漏洩から保護するための適切なセキュリティ対策を講じることが必須です。

- **実装例（サーバー間認証の場合のリクエスト例）：**
```css
https://{Request Host}/v1/oauth?response_type=code_direct&app_id=[Your App ID]&scope=[Desired Scopes]
```
GASでAPIを叩きたくてエラーが直らなかった話

# 結論：JSON.stringify()したら直った！
そのままですね。
GASエディタ上でリクエストbodyをJSON形式で記述していたのですが、実際に格納されていた値がJSON形式でなくなっていました。ということです。

### GASでの記述
```javascript
let headers = {
  ~省略~
};

let body = {
  "hoge" : "fuga",
  "hogege" : [
    {
      "fugaga": "hogefuga"
    }
  ]
};

let options = {
  methopd: "post",
  headers: headers,
  payload: body
}

let response = UrlFerchApp.fetch(url, options); // ここでエラー"INVALID DATA RECEIVED"
```
### 実際にbodyに格納されていた値
```javascript
{
  hoge : 'fuga',
  hogege : [
    {
      fugaga: 'hogefuga'
    }
  ]
}
```
### こうすると直った
```javascript
let body = JSON.stringify({
  "hoge" : "fuga",
  "hogege" : [
    {
      "fugaga": "hogefuga"
    }
  ]
});
```

なぜ……？
原因はわかりませんが理由はわかったので、実装を進めることにします……
ちなみに......
この後、body内容をスプレッドシートから読み取るようにしたら、上記の問題は起こりませんでした。
GAS上で記述した時に起こります。
更に、スプレッドシートから取得した値をJSON.stringify()した場合、余計なエスケープがされてエラーが起こりました。

マジで意味がわからないので、今はこれ以上踏み込まないことにします……
インフラエンジニアさんに手引してもらいながらlambdaのIP固定化をやってみたときのメモ（NATゲートウェイ不使用）

## 概要

LambdaのIPをElastic IPを使って固定化した話をメモ的にまとめる

## 前提

下記の記事を参考に、インフラエンジニアさんに手引してもらいながらlambdaのIP固定化をしてみた

https://zenn.dev/nix/articles/7dd29a1e9edc55

## 内容

### lambdaに紐づくネットワークインターフェースを探す

どうやらパブリックなVPCにlambdaが設置されている場合、「ネットワークインターフェイス」が自動的に作られるらしい。下記の手順でネットワークインターフェースを探した。（パブリックなVPCにlambdaが設置されていないとネットワークインターフェイスはつくられないと思う）

1. マネジメントコンソールでEC2を開く
1. サイドバーで「ネットワークインターフェイス」を開く
1. 「lambda」で検索をかける
1. ヒットした内容の「説明」にlambda名が記載されているはずなので見つける
1. lambdaに紐づくネットワークインターフェイスの「ネットワークインターフェイス ID」と「プライベートIPv4アドレス」をメモしておく

### Elastic IPの取得と関連付け

1. Elastic IPを取得する
1. 取得したElastic IPの詳細を開く
1. 「Elastic IPアドレスの関連付け」をクリックする
1. 下記のように設定する

    | 項目 | 内容 | 備考 |
    | --- | --- | --- |
    | リソースタイプ | ネットワークインターフェース |  |
    | ネットワークインターフェース | 先にメモした「ネットワークインターフェイス ID」を入力してヒットしたものを選択 |  |
    | プライベートIPアドレス | 先にメモした「プライベートIPv4アドレス」を入力してヒットしたものを選択 |  |

ここまでで設定は完了である。

## 謝辞

参考にさせていただいた記事の著者さま、また伴走してくださったインフラエンジニアのみなさまにこの場を借りてお礼申し上げます。本当にありがとうございました。本当に助かりました。
VSCodeでお手軽Docker開発環境

## ターゲット
検証環境が欲しい人。
開発環境が各々の裁量に任されていて、苦労したくない人。
Dockerについてある程度の理解がある人。
などです。

## はじめに
**必須環境**
- Docker
- VSCode
- Docker (VSCode拡張機能)
- Dev Containers(VSCode拡張機能)

VSCode拡張機能はVSCode内のpluginから検索をしてインストールしてください。

**推奨環境**
- Mac
- WSL(ubuntu)
windowsでの動作確認は行なっていませんが、VSCodeをGUIで利用可能かつDockerを使える環境下なら利用可能だと思われます。

本記事内でDockerについての解説は行いません。

## Docker start
まずDockerコンテナを立ち上げます。
``` bash
docker create --name ${container name} -it -v ${host dir}:${mount dir} -w ${working dir} -p ${host port}:${container port} ${image}
```
`${}`内にそれぞれ対応するもので埋めてください。
それぞれのオプションについて今回は解説しません。コメントをいただければ必要に応じて追記もしくは別記事を作成します。

最後の`${image}`はversion指定をしない場合、デフォルトで`latest`となります。`Dockerfile`を書く場合と変わりません。
versionを指定する場合、Docker Hub を参照のうえ、`node:20`のような形式にしてください。

nodeの場合のサンプル
``` bash
docker create --name node -it -v /Users/username/node_project:/home/node -w /home/node/workspace -p 3000:3000 node
```

## Docker run
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2228914/f3e36876-991e-dbc5-15a7-3ce36cbd8376.png)

VSCode上で今回作成したコンテナを起動します。右クリックをして、startを選択します。
CLI上で行っても問題ありません。

## DockerをVSCodeにアタッチする
起動済みのコンテナ上で右クリックし、VSCodeにアタッチを選択します。

マウントが取れていれば、指定したディレクトリの中身が新規ウィンドウで表示されます。
今回の場合、新規ウィンドウで`node -v`を確認できれば成功です。

## 注意点
gitなどはimage内に存在しないので、必要に応じてインストールしてください。
ただsshの設定などが面倒くさいので、開発のみDocker環境下で行い、git操作はローカルで行うことをおすすめします。
ボタン内に画像を埋め込む

自分メモシリーズ

Pendoのデフォルトボタンに画像を埋め込む

1. ボタンブロックを追加する
1. ボタンのIDを取得する
1. コードブロックのCSSを追加する
1. 既存CSSを上書きするのでimportant指定が重要

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/227518/f11431e9-730e-efe0-ca2b-cbfcf72fb24e.png)

```css
/*replace with your button id*/
#pendo-button-96480497{
    background: url("画像のURL") !important;
    background-size: contain  !important;
    background-repeat: no-repeat  !important;
    width: 300px  !important;
    height: 200px  !important;
}
```
JavaScriptの「??, ||, &&, !!」こいつらなんなん

## はじめに
``` js
const a = 0 ?? 5;
const b = 0 || 5;
const c = 0 && 5;
const d = !!0;
```
このa, b, c, dに何が入るかみなさんわかりますか？
上から順に、Null合体演算子、論理和、論理積、二重否定と呼ばれます。
これがわかる皆さんにこの記事は必要ありません!! (<-これは二重否定ではない)

解説の中で`falsy`という単語が頻出します。
これはnull, undefinedだけでなく、`0`や`""`(空文字列)などのfalseとみなされる値のことです。
詳しくはこちら。

https://developer.mozilla.org/ja/docs/Glossary/Falsy

## Null合体演算子
名前の通り、Null判別が合体した演算子です。
`??`の左辺がNullの場合、右辺を返します。Nullと判別される値は`null`と`undefined`のみです。
つまり、実行結果は下記のようになります。
``` js
const a = 0 ?? 5;
console.log(a); // 0
```

## 論理和 & 論理積
これらはifでよく使うため、まとめて解説します。

`||`は左辺が[falsy](https://developer.mozilla.org/ja/docs/Glossary/Falsy)の場合、右辺を返します。
`&&`は左辺が[falsy](https://developer.mozilla.org/ja/docs/Glossary/Falsy)の場合、左辺を返します。

つまり、実行結果は下記のようになります。
``` js
const b = 0 || 5;
console.log(b); // 5
const c = 0 && 5;
console.log(c) // 0
```

ifでの結果を思い浮かべればわかりやすいと思いますが、論理和はor演算子とも呼ばれ、どちらかがtrueなら動作します。
論理積はand演算子と呼ばれ、両方trueなら動作します。そのため、falseの場合のファストリターンは理にかなった設計と思われます。

### 参考記事
論理和

https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Operators/Logical_OR

論理積

https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Operators/Logical_AND

## 二重否定
`!`一つが否定なのはみなさん承知だと思います。`!!`はそのままで、否定をさらに否定する二重否定となります。
これで何ができるのかというと、boolean以外の型をbooleanに変換できるということです。
`falsy`な値はfalseへ。それ以外はtrueに変換されます。
``` js
const d = !!0
console.log(d); // false
```

### 参考記事

https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Boolean

## 最後に
それぞれの演算子には優先順位が定まっていたり、`??`と`||`は一つの式で使えないなどの決まりがあります(ただし`()`を使えば大丈夫)。
その細かい部分については下記ドキュメントを参考にしてください。
https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Operators/Operator_precedence
ガイド内の画像をクリック特定のページに飛ばす方法

自分メモシリーズ

画像をクリックすると新しいタブが開くガイドを作成する方法の概要：

1. ガイドステップに画像ブロックを追加します。
2. HTMLソースを調べるか、Pendoのタグ付けAIDを使って画像IDを見つける。
3. 画像IDを使って、新しいタブを開くコードブロックを追加します。
4. JavaScriptを使用して、新しいタブでURLを開くクリックイベントを画像に添付します。
5. オプションで、CSSを使用して、画像にマウスカーソルを合わせたときのマウスアイコンを手に変更します。

![CleanShotzMKvwfo8@2x.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/227518/b82ed4cc-418d-ae86-e056-a8e059d52373.png)

Code Block

```javascript
   (function () { 
        let url = "https://www.youtube.com/watch?v=4W8gWOh0t7U"//replace with your url  
        let imgLink = pendo.dom('#pendo-image-32a50899')[0] //replace with your Pendo image ID  
        pendo.attachEvent(imgLink, 'click', function () { 
            window.open(url, '_blank'); 
        }) 
    })() 
```

（オプショナル）
画像にカーソルを合わせた時にマウスアイコンを手の形にするCSS

```css
/*replace with your Pendo image ID*/     
#pendo-image-32a50899:hover {  
        cursor: pointer; 
    } 
```
ロボットに3Dカメラをたくさん付けよう

3Dカメラが多数量産されるようになったため、3Dカメラの値段は格段に安くなった。

そのため、ロボットに複数の3Dカメラを付けることは珍しくない状況だ。

複数の3Dカメラを付けても、コストより利点の方が多い。
- 左右の状況を見るために首を回すよりは、左右に3Dカメラを付けたほうがいい。
- 左右にカメラを回す（首を回す）という動作をすることの方がコストが高い。
- 首を動かすと、カメラ座標と胸部の座標系との関係が固定のものではなくなってしまう。
- 首を動かすと、首の自由度のパラメータの分だけ、誤差要因が増える。
    - 例：１ｍ先の横１ｃｍの精度を損なわないようにするには、tanθ=0.01 でθ=0.57 degreeとなる。
    - 時刻の同期も必要になる。
- 実際、カメラのある首が胸部と固定になっているロボットは多い。 

複数の３Dカメラを処理しきるだけのHWリソースがあるようになってきた。
3Dカメラの種類によっては、depthの算出処理を3DカメラのHWリソースの中で実行するものがある。
そういう場合にはメインのCPUへの計算負荷を発生させることがない。

複数の3Dカメラをつけているロボットの事例には事欠かない。
次のロボットでは、少なくとも3方向分の3Dカメラを持っている。
https://agilityrobotics.com/products/digit

# 双腕ロボットの例を示す
以下のロボットでは、頭部の3Dカメラの他にも、両手首に3Dカメラを付けている。
https://www.rainbow-robotics.com/en_rby1

![](https://www.rainbow-robotics.com/assets/images/banner/img-rby1.jpg)

## 安い3Dカメラの例
[OAK-D Lite](https://shop.luxonis.com/products/oak-d-lite-1?variant=42583102456031)
$149
JavaScriptのArray.reduce()メソッドの利用方法と活用例

JavaScriptには、配列の要素を処理して最終的な値を求める便利なメソッドがあります。それがArray.reduce()メソッドです。この記事では、Array.reduce()メソッドの基本的な使い方と実践的な活用例を紹介します。

Array.reduce()メソッドとは
Array.reduce()メソッドは、配列の各要素に対して指定された関数を適用し、単一の結果を返すメソッドです。このメソッドは、累積される値（アキュムレーター）と現在の要素を引数に取ります。

基本構文は以下の通りです。

```js
arr.reduce((accumulator, currentValue) => {
  // 処理
}, initialValue);
```

accumulator: アキュムレーターとして使用される値。
currentValue: 現在の要素。
initialValue: アキュムレーターの初期値（省略可能）。
活用例: 条件に応じた要素のカウント
以下のコードは、Array.reduce()メソッドを使用して、配列内の特定の条件を満たす要素の数をカウントする例です。

```js
const arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
const isEven = (num) => num % 2 === 0;

const evenCount = arr.reduce((count, current) => {
  return isEven(current) ? count + 1 : count;
}, 0);

console.log(evenCount); // 出力: 5
```

この例では、配列内の偶数の要素の数を数えています。isEven関数は与えられた数が偶数かどうかを判定し、reduce()メソッドを使って偶数の数をカウントしています。最終的に、evenCountには偶数の要素の数が格納されます。

これで、Array.reduce()メソッドの基本的な使い方と活用例について理解できました。
MySQL の タイムゾーン をUTCに変更（Mac）

## 背景
time_zone が JST になっている
```
mysql> SHOW VARIABLES LIKE '%time_zone%';
+------------------+--------+
| Variable_name    | Value  |
+------------------+--------+
| system_time_zone | JST    |
| time_zone        | SYSTEM |
+------------------+--------+
```

本番環境と揃えるため、time_zone を UTC に変更する

## やったこと
1. my.cnf 探す
    ```
    > mysql --help | grep my.cnf
    order of preference, my.cnf, $MYSQL_TCP_PORT,
    /etc/my.cnf /etc/mysql/my.cnf /usr/local/mysql/etc/my.cnf ~/.my.cnf
    ```
    <br>

2. 参考記事によると /etc/my.cnf ファイルを変更
    ```
    [mysqld]
    default-time-zone='+00:00'
    ```
    <br>

3. MySQL サーバー再起動し、time_zoneがUTC に変更されたことを確認
    ```
    mysql> SHOW VARIABLES LIKE '%time_zone%';
    +------------------+--------+
    | Variable_name    | Value  |
    +------------------+--------+
    | system_time_zone | JST    |
    | time_zone        | +00:00 |
    +------------------+--------+
    ```

## 参考
https://forums.mysql.com/read.php?11,366143,376017#msg-376017
【メモ】MySQLのインストール(Windows11)

https://dev.mysql.com/downloads/file/?id=528489

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3759397/a5560442-f792-83a0-1770-3b6613136418.png)
> **No thanks, just start download.**　をクリック

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3759397/4b2dfe39-f33e-4fbb-75eb-d6c0e7b42d9a.png)
> **Custom** を選択

:::note info
今回は，MySQL Server, MySQL Workbench, MySQL Shellをインストールする
:::

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3759397/75b0610a-8d78-43bc-3ea8-2c41c161750c.png)
> `+`のフォルダーマークをクリックしてインストールする目的のファイルまで開き選択し，真ん中ちょい上の緑⇒をクリックする．

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3759397/9f7a1d78-b253-c028-61cb-806473dcab05.png)
> 上記の様に必要なものが右側に選択出来た状態でNext

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3759397/0fe14619-be74-b576-52c4-2d1a9c852c82.png)
> Next

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3759397/97f9c0cc-088a-c1d3-6e63-1fc4259bb7bb.png)
> 選択しているものに問題なければ**Excute**
インストールができたら**Next**

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3759397/e962e42f-9f1a-3ef7-6fa1-a92b5afa38ed.png)
> Next

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3759397/13de9fcf-e001-d2f8-afbb-c1e2bc5242c0.png)
> Next 

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3759397/6dadb3fe-f801-f9fd-2699-7dd0ab3a97c1.png)
> Next

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3759397/29407db6-bec2-ab1f-5c6e-9f9d0f75610d.png)
> passwordを設定し、Next

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3759397/e7bd0096-bfd0-5d6a-2bdb-b502f2023197.png)
> Next

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3759397/6db823aa-b9a8-7c78-8ab9-846ca01a80d7.png)
> Next

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3759397/6a4601bb-a357-c936-bef7-cc434773609c.png)
> Excute
> Finish

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3759397/c1c13cff-38f3-64f3-682c-b1186e734c71.png)
> Next

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3759397/927fd8fc-558c-9cac-20a9-5f99a81629b4.png)
> Fnish

自動でMySQL Workbenchが起動する．
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3759397/89d34775-b5a4-384a-c2c9-174444cd5c08.png)
> 左下のデータベースの接続情報をクリック

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3759397/fb3d036c-0c2d-f942-c144-b7779d24ae77.png)
> 先ほど決めたpasswordを入力してOK

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3759397/27d6310f-d7a9-44e5-ca70-78bcac75ca2c.png)
> 完了
PingCAP CERTIFIED TiDB PRACTITIONER (PCTP) の受験方法

## はじめに

PingCAPにはTiDB / TiDB Cloudに関する教育コンテンツを制作する PingCAP Educationという専門チームがあります。そこではTiDBに関する教育コンテンツやハンズオン、資格試験などを作成しています。

ところでTiDBの資格試験をご存じでしょうか？ いくつかの資格があるのですが、そのうち入門編の **PingCAP CERTIFIED TiDB PRACTITIONER (PCTP)** は無料で受験できますし、資格の試験の前提となるオンライン講座も無料で公開されています。

https://pingcap.co.jp/education/certification/

本記事では資格試験、オンライン講座の受講方法について説明します。

なお、PCTP資格試験の受講方法は[こちらのインタラクティブデモ](https://pingcap-japan.storylane.io/share/wy5aqm0iqkit)でも確認できます。是非ご覧ください。

![demo (3).gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/12495/e1c6a376-f279-3c7e-99bd-081b3643acdb.gif)

## PingCAP Educationの登録とログイン

オンライン講座や試験の受験には、[PingCAP Educationのポータルサイト](https://jpn.edu.pingcap.com)を利用します。
アカウントを未作成の方は右下の「無料でサインアップ」から登録を、登録済みの方はログインしてください。

https://jpn.edu.pingcap.com

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/12495/9fd044aa-7f92-d386-27a6-bc0c252fa41d.png)

## TiDB入門の受講

ログインすると、次のようなホーム画面が表示されると思います。ここに表示されているのが受講登録をしたオンライン講座の一覧で、標準で **TiDBの紹介** 講座が登録されていると思います。 TiDBの紹介コースは、TiDBの基本的なアーキテクチャ、コンポーネントを解説するオンライン講座です。

**TiDBの紹介** をクリックしてリンク先を開きます。

![スクリーンショット 2024-05-10 13.03.56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/12495/69c56cc4-44cd-13e9-5d93-5b2061705878.png)

次のような画面になります。ここで、**コースを開始または再開してください** ボタンを押してください。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/12495/9c0a6b00-499e-2eb7-dae3-c1992652f054.png)

そうするとコンテンツの最初からスタートします。コンテンツはPDFのコンテンツのものと、動画のものがあります。
動画には日本語字幕がありますので、もし字幕が表示されていなければ右下の字幕ボタンを押してください。（下図の "CC"）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/12495/4547fd17-be6e-836e-4641-c265c170d6aa.png)


コンテンツの学習が終了したら、ページ最下段の終了ボタンを押すのを忘れないようにしてください。これで、各コンテンツの終了を記録しています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/12495/c61f0882-7818-3310-dab0-6b0be5059dde.png)

右上のコンテンツ名にカーソルを合わせると、コンテンツの一覧が表示され、いつでも好きなコンテンツにジャンプできます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/12495/a842519f-7d8a-a115-ae31-9dbc01ad02db.png)

## 講座の検索と追加方法

各講座の画面の左上の講座名にカーソルを合わせると、講座のトップページに戻れます。そこから一旦ホームに戻って、他の講座を追加したり、PCTPを受験する方法を学びましょう。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/12495/7f70ff33-924a-629b-eb63-d15c3205f765.png)

ホーム画面から、右のメニューにある **コースカタログ** を選択します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/12495/d01497c4-679b-e5d3-8479-540dcf25d28e.png)

コースの一覧が表示されます。日本語のタイトルは、コースの内容が日本語化されているものです。興味のある講座にカーソルを合わせ、**このコースを受講** をクリックしてください。後はTiDB入門の受講時と同様です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/12495/858d5820-6530-0f11-c07d-e010d794901c.png)

## PCTP試験の受験

試験も講座と同じように列挙されています。先ほどの講座一覧画面で、右のカテゴリーから、**Exam and Certification** を選択します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/12495/bf2f4fac-1c43-21c1-4c52-eda74575a365.png)

そうすると、講座の一覧が、テストのみに絞り混まれます。下の、PCTPを受講してください。上のPingCAP Certified TiDB Associate試験は有料なので、今回は選択しません。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/12495/6d837732-b413-3ea3-d8c6-1f46575b0643.png)

試験も講座と同様のインターフェースで進められます。是非、チャレンジしてみてください！
【Unity】Unity のフォルダ分けについて考察してみる

前提条件

フォルダ分けする場合は、理由が無い限り
Assets フォルダの直下に 1 個フォルダを作って
その中に各フォルダを配置する事にします。

例えば Assets\Project フォルダを作成して
その中に各フォルダを配置します。

理由はアセットを入れた場合は
Assets 直下に入る場合があるからです。

Assets 直下に各フォルダを作成すると
Assets 直下のファイル数が増えすぎるのです。

StreamingAssets Plugins フォルダなど
Assets 直下に入れた方が良い場合は
Assets 直下に入れて下さい。

以降の話は Assets\Project フォルダを作成して
その中でフォルダ分けをする場合の話をします。

また以降の話は
Scene1 Scene2 シーンの 2 シーンが存在する体で
話を進めます。

また「Folders」という名称は
下記のフォルダ群を指すことにします。
「Prefabs」
「Scripts」
「Animations」
「Materials」
「PhysicsMaterials」
「Fonts」
「Textures」
「Audio」//このフォルダは審議が必要です。
「Models」
「Shaders」
「Resources」
「Editor」
//「Plugins」// Assets 直下が良いため非推奨
「Other」

***

テスト用のプロジェクトのフォルダ分けについて

テスト用のプロジェクトならば
フォルダ分けにこだわらずに
スピード優先でフォルダを作って大丈夫と思われます。

乱雑に仕分けした後に
仕分け用のスクリプトを作って
仕分けした方が
結果的に早いと思います。

この記事の最後に
私が作成した仕分け用のスクリプトの
載っている URL を紹介しますので
使って頂いてもかまいません。

テスト用のプロジェクトのフォルダを
どの程度正確にするかは
賛否両論あると思います。

***

各シーン名のフォルダを作らないパターンについて

最初に各シーン名のフォルダを
作らないパターンについて考えてみます。

今回の例で言うと
Scene1 Scene2 フォルダを作らないパターンです。

このパターンについては
ファイルを乱雑に入れるのではなく
意味合いでフォルダを作る形式のハズです。

例えばステージのパーツをまとめて
StageParts フォルダを作ると考えて OK です。

```js:フォルダ階層
Project + StageParts + Folders
        |
        + LayoutParts + Folders
        |
        ...
```

この方式の欠点は、探したいファイルに関して
それっぽいフォルダが複数あった場合
どのフォルダにあるか分かりにくくなるため
検索機能等を使わない限り探す手間があることです。

保存する際も誰にでも分かるようにするのに
少しだけ気を使います。

なので少しでも 1 フォルダの
ファイル数を減らすために

今回は各シーンで使うファイル位は
各シーン名のフォルダを
作る形式を考えたいと思います。

この方式は以降の話で出てくる
Common フォルダで頑張って頂く事にします。

***

パターン1 : シーン名のフォルダを作成してその中に入れる

まずパターン1について考察します。
例えば次のような階層です。

```js:フォルダ階層
Project + Scene1 + Folders
        |
        + Scene2 + Folders
        |
        + Common + Folders
        |
        + NoUse + Folders
        |
        + Scenes + Scene1.unity
                 |
                 + Scene2.unity
```

Project フォルダの直下に
「各シーン名のフォルダ」と
「2 個以上のシーンで使うためのフォルダ」と
「使用していないファイル用のフォルダ」を
作成しています。

例えば Projects/Scene1/Scripts/Block1Move.cs
等が存在すると考えて下さい。

Scene1 を開発したい場合は
Scene1 フォルダと
Common フォルダを見るだけで済むため
余計なファイルを見ないで済みます。

***

パターン2 : Folders の中に各 Scene 名のフォルダを作成する

次にパターン2について考えます。
例えば次のような階層です。

```js:フォルダ階層
Project + Folders + Scene1
        |         |
        |         + Scene2
        |         |
        |         + Common
        |         |
        |         + NoUse
        |
        + Scenes + Scene1.unity
                 |
                 + Scene2.unity
```

例えば Projects/Scripts/Scene1/Block1Move.cs
等が存在すると考えて下さい。

Script は Scripts フォルダを
見れば良いメリットがあります。

パターン1のバージョン違いですが
Scene 単位で管理したいか
Scripts 等の単位で管理したいかの違いになります。

***

以上フォルダ分けについて
考えてみました。

結論のパターン 2 の状態に
自動で仕分けするアセットを
下記の URL で公開しているため
よろしければご活用ください。

[https://qiita.com/uni928/items/167fdc13f96fbe7db35d](https://qiita.com/uni928/items/167fdc13f96fbe7db35d)

また、もっと良いフォルダ分けの方法がありましたら
是非コメント欄で提案頂けると幸いです。

「〇〇に触れた方が良い」など
この記事で触れた方が良い話題も
是非ご提案下さい。

皆さんの開発の助けになれますように
閲覧ありがとうございました。
技術Blogを毎月書くために心がけていること

# はじめに

こんにちは、京セラコミュニケーションシステム　西田（@kccs_hiromi-nishida）です。

いつもは技術的な内容を投稿していますが、今回は技術Blogを毎月書くために心がけていることを投稿しようと思います！

毎日投稿！とか毎週投稿！とかはちょっとハードルが高いな、けど継続して投稿したいと思っている方の一助になれば幸いです。


## この記事の対象者

* 毎日Blog書くのはハードルが高いけど継続して投稿したいと思っている方
* 月に1本くらいはBlogを書きたいと思っている方


## 前置き

継続して書いているといっても月1記事程度なので、それほど参考になるかはわかりません。
そして、私に合った方法というだけで、皆さんに合うかはわかりません。

ただ、こんなやり方もあるよ！というのを見ていただき、少しでも誰かの参考になれば嬉しいです。


## まずは記事の骨組みを作ろう！

記事を作るとき、いきなり上から順にガーッと書き始めていませんか？
私も最初はそうしていました。

ただ、この方法だと記事全体の構成を考えずに書き始めてしまうので、途中で「なんか書きたいことが違うような…」と思ったりして記事が迷走してしまい、結果書き直しが発生⇒記事投稿までに時間がかかってしまっていました。

そこで今私が実施しているのが、`記事の骨組みをまず最初に作る`ということです。

### 見出しを作るイメージで

たとえばこの記事を最初に作った時のスクリーンショットを用いて説明します。

https://qiita.com/kccs_hiromi-nishida/items/b077c980662753fcc6dc

最初の時点ではこのレベルでOKなので、まずはざーっと記事の枠組みを作っていってみてください。
その際、私は以下3点を意識しています。

* 見出しをとりあえず仮でもいいので決める
* 何を書くかはいったんメモ程度で残す
* 参考にしたサイト等もあれば貼り付けておく

<img width="200" alt="skeleton" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2752159/05c38c8b-52d6-6d42-bc4c-d1d9bd5f76f8.png">

## 見出し単位で内容を作成

見出しの内容の作成に着手するタイミングで細分化を考えるといいと思います。
Qiitaだと章立てが自動的に目次になるので、完成時の目次もイメージしながら作成すると目次も綺麗に整理できるので、なお良しです♪

たとえば先ほどの記事の枠組み作成時と記事完成後はこのように細分化しています。

`カレンダービューを追加する`⇒`Viewの追加`と`カレンダーViewの設定`に分割

<img width="500" alt="blog image" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2752159/ae918b0a-503b-36f8-54c0-f7671c63e35f.png">


## その他意識していること

記事を作成する際に意識していることを紹介します！

### 1日1段落分だけでも書く！

忙しくてBlog書く時間がない…（←わかる！）
一気に全部書こうとすると、時間もかかるし大変です。

なので私は、`1日1段落分だけでも書く`ということを意識しています。
毎日1段落分の文章を書けば、1か月で1記事くらいの執筆は可能だと思います！
毎日コツコツ書く、これがとっても大切です。

### 記事が長くなりそうな場合は分割を検討

記事を書いているとどんどん長くなりませんか？（私だけ？）
ただ、あまりに長い記事だと読者も読むのが大変で、最後まで読んでもらえない記事になるかもしれません。

書いている途中で、「あ、これは長くなりそうだな」と思ったタイミングで、思い切って記事を分割しましょう。

`長い記事を時間かけて書くより、記事を分けてコンスタントに投稿する`を意識した方が、鮮度の高い記事の投稿につながると思っています。


## さいごに

ご紹介した中から、何か1つでも取り組めることがあれば取り組んでみていただけると嬉しいです。
私も継続してこのまま記事投稿できるように頑張りたいと思います！


# おしらせ

弊社X（旧：Twitter）では、Qiita投稿に関する情報や各種セミナー情報をお届けしております。情報収集や学びの場を求める皆さん！ぜひフォローしていただき、最新情報を手に入れてください:grinning:

https://x.com/kccs_digital
日本で最初のDatadogアンバサダーに選出されました！

# Datadog って何？
Datadogのサービスは、サーバー, クラウド, アプリケーション, セキュリティ, チームのすべてを、ひとつのツール（オブザーバビリティ・ソリューション）で監視・モニタリング、運用管理ができるクラウドサービスです。
グローバルに提供されていて、Datadogは3年連続して、調査会社のガートナーが発表する[2023年Gartner(R)マジック・クアドラント(TM)の「APMおよびオブザーバビリティ部門」でリーダーに選出](https://www.datadoghq.com/ja/blog/datadog-apm-observability-gartner-magic-quadrant-2023/)されています。

## Ambassador に選出されたという話
2023年までの Datadog Ambassador はグローバルで8名でした。
今年、2024年は新たにグローバルで7名が選出され合計15名、そして日本では最初のひとりとなるDatadogアンバサダーに選出いただけました。

![datadogAmbassador_Kano.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/189936/75df4cf1-8f1e-c340-16b7-230af50d0230.jpeg)
［リンク：[Datadog Ambassador Program](https://www.datadoghq.com/ambassadors/)］

## Datadogアンバサダーとは？
[公式サイト](https://www.datadoghq.com/ambassadors/)を要約・意訳するとDatadogアンバサダーは、オブザーバビリティ知識を共有する技術者でありDatadogコミュニティをリードします。コミュニティに参加する皆さんと会話して学びを促進したり、技術的なブログを投稿したりして知識を共有します。（[日本語での詳しい説明はこちら](https://taiponrock.medium.com/datadog-ambassador-program%E3%81%AE%E3%81%94%E7%B4%B9%E4%BB%8B-3d5b0f23add9)）

## アンバサダー選定要項
Datadogユーザー自身での応募はなく、Datadog従業員他による推薦となります。

## 自己紹介
私は某メーカーに勤務しマルチクラウド・ハイブリッドクラウドの導入と運用を行うクラウドマネージドサービスをリードしています。複数の異なるクラウドを効率よく運用するために、みんな大好きな AWS Cloudwatch や Azure Monitor 他をあえてメインとして使わず、ひとつの統合的手法で監視できるようDatadogを活用しています。

## 保有資格とコミュニティ活動
クラウド認定はプロフェッショナルが AWS, Google, IBM、アソシエイトが Azure, Oracle を取得。Datadog 認定も取得しました。
コミュニティ活動では IBM Cloud チャンピオンを7年連続で表彰頂いております。そしてDatadogユーザー会の[JDDUG; Japan Datadog User Group](https://datadog-jp.connpass.com/) を [@chaspy氏](https://chaspy.me/) と運営しています。


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/189936/48800186-c99f-f7d0-9e29-dcfe5f5fa1e5.png)

## Datadog Ambassador の特典
公式からの転記になりますが、無料の Datadog 認定試験、限定版のグッズ、DASH へのチケットと旅行、プロフェッショナル プロフィール、Datadog チームとコラボレーションする機会などが含まれます。
Ambassador任命前から受験勉強していたこともあり、無料の認定試験は待てずに30%割引クーポンで受験してしまいました。今後、評価版サンドボックスも活用できるようなのでベータ機能など新しい技術検証やブログ投稿に役立ちそうです。
今後特典を頂いたら記事を更新しますね。

## おまけ（ノベルティ）
JDDUG発表登壇やQiitaアドベントカレンダー投稿でTシャツと靴下を頂きました！

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/189936/800eab07-0fa4-3708-cca5-8cc387090288.png)

## JDDUG 募集
[JDDUG; Japan Datadog User Group (Datadogユーザー会)](https://datadog-jp.connpass.com/) の皆様と交流するためのネットワーキングを凡そ三か月毎を目標に開催します。発表やLT、一緒に運営を盛り上げてくれるメンバーを募集しています。Datadogおよびオブザーバビリティ活動推進に興味がある方はJDDUGに参加してくれると嬉しいです。

## まとめ

- Datadogは APM & オブザーバビリティ業界でリーダー層に位置付けられています。
- Datadog アンバサダー プログラムが2023年からスタートしています。
- JDDUGでは仲間を募集中です。
- 本記事は個人活動による執筆です。発言は個人の見解に基づくものであり、所属組織を代表するものではありません。
エラーメッセージの変数命名どうするか ~msg vs eMsg vs errorMsg~

## 背景
表題3つが乱立していたため、リファクタリングをするにあたりどれが良いか検討することになった。

## 結論
**errorMsg一択！**
→msgやeMsgではエラーメッセージなのかを判別しにくいため。
　命名はなんでも短くしたり省略したりすればいいわけではない。
　可読性の観点も踏まえて、第3者が読む労力を減らす取り組みが必要。

## 例1：msg
msgだけでは、該当コードの前後を読まなければどのようなメッセージなのか判断することが難しい。
```
const msg = "情報を取得できません。";
```

## 例2：eMsg
eMsgでも同様。
eでerrorを表現できている気がしなくもないが、それならerrorと記載する方が可読性の観点から良いと判断。
```
const eMsg = "情報を取得できません。";
```


## 例3：errorMsg
errorMsgとすることで、エラーメッセージであることを瞬時に判別可能。
文字数が一番長いが、それ以上に可読性が高いと判断。
```
const errorMsg = "情報を取得できません。";
```

## おわりに
とはいえ、省略せず長い命名ではコード量が多くなり、かえって可読性が悪くなる。
この辺のバランス感覚を意識していくことを心がけていきたい。