OmniAICreator/Qiita-1.07M huggingface dataset:
【25学部卒】エンジニア就活のおすすめサービスと振り返り体験記

# 対象読者
- エンジニア就職を目指す学部生の方

# はじめに
僕は23年の6月頃から就活を開始し、23年の12月ごろに計3社から内定をいただき、内1社の内定を承諾している状態です。
この経験を元に、やってよかったことや、こうしておけばよかったなどを備忘録として残しておきます。

### エンジニアとしての経験
そもそもエンジニアリングに興味を持ったのが高校3年生の頃で、その頃からなんとなくエンジニアとして働くことを意識していました。
本格的にプログラミングの勉強を始めたのもこの時期です。

大学進学後は、運良くゲーム会社に長期インターンとして拾ってもらうことができ、そこで1年半ほどサーバーサイドエンジニアとしての経験を積むことができました。この経験はのちの就活においても話す頻度がとても高く、大きな武器になりました。

# おすすめサービス
インターンのエントリーに際してとても役にたったサービスを列挙していきます！

- [魔法のスプレッドシート](https://magic-spreadsheets.pages.dev)
このシートはその年のインターン情報を網羅的にまとめてあるので、実はこの会社もインターンを開催してたのか！というような発見があったので、一度目を通しておくと良いと思います。
<br>

- [逆求人ナビ](https://www.studenthunting.com)
逆求人ナビは企業から指名をもらい面談を行う、逆求人型のイベントが多く、そういった形のイベントに力を入れているサービスといった印象です。
利用頻度としては一番多かったと思います。
サポーターズと比較すると、会社群がある程度グルーピングされており、自社開発企業、ゲーム開発企業ごとなどに開催が分かれており、アンマッチが起こりづらいのも特徴の一つだと思います！ 
<br>

- [サポーターズ](https://talent.supporterz.jp)
サポーターズは企業開催のイベントを案内してくれるサービスです。
 中でもエンジニア1on1面談イベントというのがあり、企業側から指名をもらい、1日で複数社と1対1で話す機会をもらえるイベントです。
逆求人ナビと比較すると、メガベンチャーなどの大きめの会社群が多いイメージです。
<br>

- [Wantedly](https://www.wantedly.com)
Wantedlyには様々な利用方法があると思うのですが、僕は基本的にプロフィールを作成して放置し、企業からのスカウト待ちで利用していました。
他のサイトでもスカウトなどはあると思うのですが、一斉送信のメッセージなどが多くあまり積極的になれなかったのですが、Wantedlyのスカウトは面談直結のものが多く、信頼度が高いと考え利用していました。

# 体験記
#### 23年5月下旬:就活開始
当時は就活のこと自体全く頭になかったのですが、先輩からの連絡で夏インターンのエントリーが始まってることを知り、そのタイミングで焦りを持って就活を開始しました。

#### 6月~7月:夏インターンエントリー
僕は上記のおすすめサービスを使って進めていきました。

具体的には、サポーターズ、逆求人の面談イベントを利用して認知していない会社、尚且つ自分にある程度興味を持ってくれた企業とのコネクションを獲得しつつ、魔法のスプレッドシートから取り分け興味のある企業に個別にエントリーを行うといった感じです。

Wantedlyは一度プロフィールを作成すれば、あとはコストをかけずにコネクションを獲得できる可能性があるので、プロフィール欄だけでも埋めとくと良いと思います。

#### 8月~9月中旬:夏インターン実施
最終的に、夏インターンは7社内定をもらい、日程の都合で2社は辞退したため、5社のインターンに参加しました。

インターン内定を頂いた会社のエントリーのきっかけになったサービスの比率は以下の通りです。

| サービス名 | 内定数 |
| :- | -: |
| 魔法のスプレッドシート | 1社 |
| 逆求人ナビ | 1社 |
| サポーターズ | 4社 |
| Wantedly | 1社 |

インターン参加への心構えについてですが、僕は基本的には楽しく誠実にを意識していました。

また、エンジニアインターンは大きく分けて以下の2パターンがあると感じました。

**ハッカソン型**
    グループで与えられた課題に取り組むインターン
    
**実務型**
    実際の業務を体験、もしくは実務に近いカリキュラムをこなしていくインターン

個人的にはハッカソン型の方が楽しかったのですが、面接などでアピールしやすいのは実務型のほうかなと思います。

なので、余裕があればどちらのパターンも体験できると良いのかなと思います。

#### 9月下旬~12月:本選考開始
本選考は、主にインターンでお世話になった企業をメインに、他にはインターンは落選してしまったけどコネクションがある企業、まだ認知していない企業を数社という形で進めていきました。

この段階で意識していたことは、自分の指向性を理解し言語化すること、面接に慣れることの二点でした。

どちらも、インターン応募を通して培うことができたかなと思うので、やっぱり時間があるならインターンシップから就活を意識したほうが何かと楽かなと思います。

#### 12月後半:就活終了
最終的に、3社から内定を頂きました。
業界は、受託開発、広告、メディアの3業種で結果的にバラバラの業界になりました。

インターンでは色々なサービスを利用していましたが、この３社は逆求人ナビのイベントをきっかけに内定をいただきました。
**内定を意識して利用するなら、逆求人ナビのイベントが一番良いと思います**

https://www.studenthunting.com/

元々アドテクに興味があったので広告系の会社を主に志望してたのですが、インターン先や、逆求人イベントなどで企業の人たちから話しを聞く内に多角的に企業を見るようになり、内定をいただいた会社にはそれぞれ異なる点から魅力を感じていました。

ですが、最終的にインターンでお世話になった社員さんの人柄や、成長フェーズに参画できること、toCプロダクトでユーザーと近いことなどからメディア業界のミドルベンチャー企業の内定を承諾しました。

# まとめ
- インターンは積極的に参加したほうがいい
- 面接は数をこなせば場馴れする
- 積極的に就活サービスは利用したほうがいい
- 中でも逆求人イベントは認知してない会社を知れるからおすすめ
VB6のMidとC#のSubstringの違い

# VB6のMidとC#のSubstringの違い

どちらも文字列を切り抜くメソッドだが、仕様の違いによりハマったのでメモ。

## 結論

VB6とC#はインデックスの扱いが違うからズレるよ。
VB6 → C# だと、第2引数を-1すればOK。

## 比較

### VB6

`Mid(対象文字列, 開始位置(1始まり), 切り抜く長さ)`

```vb:VB6
Mid("Hello World!", 2, 7)
' 結果 → "ello Wo"
```

### C#

`対象文字列.Substring(開始位置(0始まり), 切り抜く長さ);`

```csharp:C#
"Hello World!".Substring(1, 7);
// 結果 → "ello Wo"
```

## 参考文献

https://www.paveway.info/entry/2018/11/21/vb_mid

https://learn.microsoft.com/ja-jp/office/vba/language/reference/user-interface-help/mid-function

https://dobon.net/vb/dotnet/string/substring.html

https://learn.microsoft.com/ja-jp/dotnet/api/system.string.substring?view=net-8.0
プログラミング開発でリファクタリングはどこまでやれば良いのか？


- コードにむかついたらリファクタリングする
- むかついてない時はリファクタリングしない
- リファクタリングに快感を感じ始めたら危険信号だ、今すぐにでもやめなさい

# チャットメンバー募集


何か質問、悩み事、相談などあればLINEオープンチャットもご利用ください。

https://line.me/ti/g2/eEPltQ6Tzh3pYAZV8JXKZqc7PJ6L0rpm573dcQ


# プロフィール・経歴

https://github.com/YumaInaura/YumaInaura
[ShellScript]test([)コマンドと[[コマンドの違いについて

シェルスクリプトで使用することの多い`test`(`[`)コマンドと`[[`コマンドの違いについて、混同することが多いのでまとめてみました。
## `test`コマンド(`[`コマンド)

  - 以下の２通りの書き方のどちらでもOK
    - `[ $# -lt 2 ]`
    - `test $# -lt 2`

  - `-o`(OR)、`-a`(AND)で複数条件を指定できる
    - `[ $# -lt 2 -o ! -e "$1" ]`

  - 使用例
    - 第1引数で指定されたディレクトリが存在するか？
      - `[ -d $1 ]`
    - 第1引数で指定されたファイルが存在するか？
      - `[ -f $1 ]`
    - 第1引数の長さがゼロでないか？
      - `[ -n $1 ]`
    - 第1引数の長さがゼロか？
      - `[ -z $1 ]`
    - 第1引数の値が5と等しいか？
      - `[ $1 -eq 5 ]`
      - `[ $1 = 5 ]`
    - 他には、`-ne`(`!=`), `-gt`, `-ge`, `-lt`, `-le`といった比較演算子を利用可能。
    - `=`,`!=`はコマンドとして使用できるが、不等号は利用できない

- 不等号を利用したい場合は、算術演算に用いられる`((`コマンドを用いる
    - 使用例 
        - `(( x > y ))`
        - `(( x >= y ))`
    - `((`コマンドはループカウンタの更新等にも用いることができる
      - `(( COUNT++ ))`

## `[[`コマンド
  - bash,zsh等で使用できる。Bourne Shell(sh)では利用できないので注意
  - `test`コマンドとの違い
    #### 変数展開時にワード分割されない
      - 変数名を`""`で囲わなくても良い

          ```
          $ name='hoge taro'
          $ [ $name = "hoge taro" ];echo $?
          -bash: [: too many arguments
          2
    
          $ [ "$name" = "hoge taro" ];echo $?
          0
    
          $ [[ $name = "hoge taro" ]];echo $?
          0
          ```
      
    #### パターンマッチが利用できる
    - なお、拡張正規表現を用いる場合は`=~`を利用する必要がある
      ```
      $ [[ abc = ab* ]];echo $?
      0

      $ [ abc = ab* ];echo $?
      1
      ```
    #### `<`,`>`が利用できる
      - `((`コマンドと違い、`<=`,`>=`は利用できない
    #### `&&`,`||`が利用できる。
    - 複数条件を指定する際に、`&&`,`||`を利用できるが、`test`コマンドで使用する`-a`,`-o`は利用できない

## まとめ
基本的に、bash,zsh環境では`[[`コマンドを用いたほうが便利そうだと感じました。
mavenとは

### はじめに
業務でmavenを利用してビルドディプロイなどをしていたが、mavenについて全く理解していなかったため、記事を作成する。

### 結論
mavenとは、Javaプロジェクトを管理するためのツール。コンピュータープログラムを組む際に使う道具のようなもので、プログラムを作るときに必要な部品や設定を自動的にダウンロードしてくれたり、プロジェクトのビルドやテストなどの作業を手助けしてくれるもの。つまり、mavenを使うことで、プログラムを作る作業がスムーズになる。

### まとめ
とりあえずmavenとはjavaに関するツールで、ビルドやディプロイを簡単にしてくれるもの。

[参考サイト]
・https://qiita.com/ASHITSUBO/items/6c2aa8dd55043781c6b4
・https://camp.trainocate.co.jp/magazine/about-maven/

ビルド:ソースコードやリソースファイルを実行可能なソフトウェアやアプリケーションに変換するプロセス。つまり、コードをコンパイルし、必要なファイルや依存関係を組み立て、実行可能な形式に変換する。

デプロイ:ビルドされたアプリケーションやソフトウェアを実際の環境に配置し、それを使えるようにするプロセス。これには、サーバーへのファイルのアップロードや設定の変更などが含まれる。
「広く浅く」か「狭く深く」か悩んだ話

## 自己紹介
初投稿なので自己紹介をしようと思います。
またねこ(githubのアカウントはkame1366)といいます。現在中2です。Arch Linuxでプログラミングをしています。Javaを好きになれなくて好きになる方法を模索してます。

## 事の顛末

### 今までは「広く浅く」だった
　私がプログラミングを始めたのは小学4年生くらいからです。当初はゲームを開発したくてpythonの基礎文法から本を読みながら勉強していました。そこから5,6年生でHTML,CSSをちょっっっと勉強して小学校を卒業し、中1でC#,JS/TSなどでWindowsのデスクトップアプリを開発したり、Reactの勉強をしたりしました。さらに機械学習の勉強をして実装もある程度できるようになりました。(これはしっかり勉強した)
　中2のときはLinux系のOSを使うようになり、UNIXのコマンドの勉強をし、RustにもハマってWgpuなどの勉強をしたり、Androidアプリ開発に興味があって少し勉強しました。
 
　しかし、今まで勉強してきたものはいずれも興味本位で、かつ「完全に理解した」状態で、**どの分野でもちゃんとしたアプリやサイト、サービスが作れない！**
 
ということが自己分析をしてわかったわけでございます。

### そこで私、考えました。めっちゃ。
　ちゃんとしたアプリ、サイト、サービスが作りたい。でもいろんな技術に触れて欲張りな状態でもありたい。「広く浅く」か、「狭く深く」か。という葛藤が僕の頭を悩ませました。
 　この悩みを解決するためにまず、**「何を作りたいのか」** を考えました。しかし、それが思いついたとしても現実的な問題が僕の好奇心を削り取り、結局なにも思い浮かばない状況になってしまいました。ただ「そろそろなにか極めたい」という気持ちがまだ残ってる。もうどうすりゃいいんだ...


## 考えに考えまくった結果
　「狭く深く」が勝ちました。この考えに至った理由や決め手は以下のとおりです。

     * プログラミングの分野で一つは特技としてなにか手に入れたかった
     * 何も作れない状態はやっぱり嫌だった

じゃあ「広く浅く」はだめなのかといったらそうではありません。なんならプログラミングを勉強するなら最初はこの道をたどるのではないかと思います。プログラミング勉強したての人は興味に満ちあふれていますからね。「広く浅く」勉強することによってプログラミングという世界の全体像を把握することも可能ですし、他のプログラマーとの交流の幅も広がります。

具体的に何をやるかは今後決めようと思ってます。


## 結論

「広く浅く」はプログラミング初めたてのころにしっかりとやると今後に活きてくる(はず)。しかし長くそれでやるのは厳しい。一回は「狭く深く」を選んで勉強することをおすすめする。一回でもこれができたら「広く浅く」をより深く勉強できるようになるのでは？
OpenCVで直線検出を使って文字の傾きを水平補正する

Tesseract5でOCRを試してみたところ、傾いている文字を全く認識しなかったので、
OCRをかける前に文字の傾きを水平補正しようと思ったのだった。

■ 事前作業
NuGetパッケージマネージャーでOpenCvSharp4.Windowsをインストールします。
OpenCvSharp.Extensionsも同時にインストールされます。

■ 留意点
読み取る画像に<font color=red>直線が含まれている</font>必要があります。


```C#:C#
using OpenCvSharp;
using OpenCvSharp.Extensions;

private Bitmap tiltPicture(Bitmap img_src)
{
    // 画像の読み込み
    //Mat img = Cv2.ImRead(@"c:\temp\naname.png");
    Mat img = BitmapConverter.ToMat(img_src);

    // モノクロ・グレースケール画像へ変換
    Mat imgGray = new Mat();
    Cv2.CvtColor(img, imgGray, ColorConversionCodes.BGR2GRAY);

    // エッジ検出
    Mat edges = new Mat();
    Cv2.Canny(imgGray, edges, 50, 150, 3);

    // 直線検出
    LineSegmentPoint[] lines = Cv2.HoughLinesP(edges, 1, Math.PI / 180, 100, 100, 10);

    // 直線の角度を計算
    double[] angles = new double[lines.Length];
    for (int i = 0; i < lines.Length; i++)
    {
        LineSegmentPoint line = lines[i];
        double medianAngle = Math.Atan2(line.P2.Y - line.P1.Y, line.P2.X - line.P1.X) * 180.0 / Math.PI;
        angles[i] = medianAngle;
    }

    // 直線の角度の中央値を計算
    double angle = CalculateMedian(angles);

    // アフィン変換を適用してスキュー角度を修正
    (int h, int w) = (img.Rows, img.Cols);
    Point2f center = new Point2f(w / 2f, h / 2f);
    Mat rotationMatrix = Cv2.GetRotationMatrix2D(center, angle, 1.0);
    Mat rotateImg = new Mat();
    Cv2.WarpAffine(img, rotateImg, rotationMatrix, new OpenCvSharp.Size(w, h), flags: InterpolationFlags.Cubic, borderMode: BorderTypes.Replicate);

    Bitmap bitmap = BitmapConverter.ToBitmap(rotateImg);

    // プログラムを終了する前に解放する
    img.Release();
    imgGray.Release();
    edges.Release();
    rotateImg.Release();

    return bitmap;
}

/// <summary>
/// 直線の角度の中央値を計算
/// </summary>
/// <param name="values"></param>
/// <returns>中央値</returns>
static double CalculateMedian(double[] values)
{
    Array.Sort(values);
    int length = values.Length;

    if (length % 2 == 0)
    {
        // 偶数の場合は中央の2つの値の平均を取る
        int midIndex1 = length / 2 - 1;
        int midIndex2 = length / 2;
        return (values[midIndex1] + values[midIndex2]) / 2.0;
    }
    else
    {
        // 奇数の場合は中央の値をそのまま返す
        int midIndex = length / 2;
        return values[midIndex];
    }
}

```
【Python】ljustとrjustの使い方や注意点をサンプルコードで解説

# 概要
Pythonの`ljust`と`rjust`を使ってみたので、サンプルコードと一緒に紹介します。
これらは、指定した幅になるように文字列の右や左側を特定の文字で埋めることができます。
注意点もあることがわかったので記載します。

# サンプルコード
### `ljust`を使用して左側を`'0'`で埋める

```py
string = '123'

# ljustを使用して左側を`'0'`で埋める
result = string.ljust(5, '0')

print(result)
# 12300
```

出力結果の通り、文字列の長さが`5`になるように左側が`'0'`で埋められました。

### `rjust`を使用して右側を`' '`で埋める
```py
string = '123'

# rjustを使用して右側を`' '`で埋める
result = string.rjust(5, ' ')

print(result)
#   123
```

文字列の長さが`5`になるように右側が`' '`で埋められていることがわかります。

## 注意点
以下の３つがあると思います。

- 元の文字列が指定した長さよりも短い場合にのみパディングが追加されること
- パディングに使用する文字は1文字であること
    - 複数の文字を指定すると以下のエラーが発生します
    - `''`であっても同様のエラーです

```py
string = '123'

# 1文字以上を使用すると...
result = string.rjust(5, '12')

print(result)
```

出力結果：

```
    result = string.rjust(5, '12')
TypeError: The fill character must be exactly one character long
```

- `int`型などの数値に対して実行したい場合は、先に`str`へ変換すること
    - `ljust()`や`rjust()`は文字列メソッドであり、数値に直接適用することはできないため

```py
number = 123
string = str(number)

# rjustを使用して右側を`' '`で埋める
result = string.rjust(5, ' ')

print(result)
#   123
```

## そのほか

- 中央寄せの場合は`center()`を使う
- 符号が先頭についている場合は、`zfill()`を使うことで、符号のあとからゼロで埋めることができる

```py
number = -123
string = str(number)

# zfillを使用してゼロで埋める
result = string.zfill(5)

print(result)  # '-0123'
```
ギター マルチエフェクター MOD Dwarf を無料で使ってみよう(7) -Ver 0.0.12-

2月13日から1ヶ月空けてMOD Desktopバージョン0.0.12が出ました。

~~Macユーザにようやく対応したようです。~~ 対応していたようですが、ちょっとした手順が必要だったようです。

![screenshot4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/129361/3d59c1b4-6615-922d-3492-4f9c2621becd.png)

今回の変更点は**Mac**での問題解決がメインということから画像は過去のものから。

## 変更点

わたしもテストしていなかったのですが(確認する環境がありません)、**Mac**環境でMIDI入力以外の入力ができないという問題があったようです。この問題は開発者署名ができていなかったことから起こったということです。今回のバージョンアップでその問題は解決したはずです。

* Macバイナリに対する署名と公証

問題があればMOD DesktopのGithubへIssueを立ててもらえると対応してもらえると思います。

その他大きな変更はないようです。

## ダウンロード

https://github.com/moddevices/mod-desktop/releases

## 過去の記事

https://qiita.com/Inqb8tr_jp
エンジニアリング・データの海で企業が持続可能性を理解するのを助ける

<font color="Grey">*[Helping Enterprises Make Sense of Sustainability in an Ocean of Engineering Data](https://aiven.io/blog/helping-enterprises-make-sense-of-sustainability)の翻訳です。*</font>

2024年3月13日

# エンジニアリング・データの海で企業が持続可能性を理解するのを助ける

なし海洋生物学者とデータベース・エンジニアの共通点を尋ねたら、オタクっぽいジョークの始まりだと思うだろう。おそらくどこかに共通点があるのだろうが、フェンスの両側に座ったことのある人間として、あるいは例えを続けるなら水面の両側で活動したことのある人間として、グレート・バリア・リーフのサンゴよりも共通点が多いと断言できる。


海洋生物学者もデータベース・エンジニアも、「原因と結果」を理解するための情報収集、分析、活用において重要な役割を担っている。魚の個体数や汚染レベルに関する要因であれ、データ管理やシステム設計であれ、その目的は同じである。


## 共通する5つの特徴


それは、両職種に共通する5つの特徴である。それらはまた、企業がサステナビリティの取り組みにどのように関与し、成功の可能性を支えるかを形作る鍵でもある。それは以下の5つである：


1.**データ収集による問題解決**：どちらの職種も、複雑なデータセットを分析して、原因と結果を理解する。企業内で多くのデータが生成されるため、戦略を定義した後にサステナビリティに投資する際の最初のステップは、組織全体で利用可能なデータの種類を確認し、サステナビリティ・イニシアチブの成功を追跡するために関連する可能性のあるデータを特定することである。これにより、適切な情報を収集・集約するために必要なシステムを決定し、既存のデータギャップに対処することができる。
2.**組織の潜在的な排出削減経路を予測するような場合、複雑なモデルや計算を行うために多数のデータソースが必要になることがある。つまり、柔軟でスケーラブルなモデルを構築する能力が最も重要であり、海洋生物学とデータベース工学の両方の核となるスキルである。
3.**両分野とも、複雑な技術的知識を多様な聴衆に伝えるための効果的なコミュニケーションに依存している。企業が組織のあらゆる分野で明確で持続可能な行動を優先させるという真摯な姿勢を示すためには、賢明な目標を設定し、長期的な進捗状況を伝え、強力なガバナンス・プロセスを導入することが不可欠です。
4.**適応性と継続的学習：*** 両分野とも、絶え間ない学習と適応が求められ、知識が急速に進化するダイナミックな環境で成功を収める。これは、持続可能性への取り組みを検討する企業にとって基本的なことであり、変化をもたらすということは、事業の運営方法に対する絶え間ない調整や変更を意味することが多い。例えば、データの取得から廃棄に至るまで、データ・ストレージのライフサイクル全体を通して環境に配慮した選択をする方法を見つけることが挙げられる。
5.**大義への情熱:**どちらの職業も、大義への情熱に突き動かされている。もし企業がデータと持続可能性を融合させることができなければ、今後数年間で競争力と回復力を失うだろう。


## より良い未来への貢献


データ駆動型のアプローチ、コミュニケーション・スキル、それぞれの目的への献身を通じて、両職種はより良い未来に大きく貢献することができる。海洋の苦境はよく知られているが、世界規模で持続可能性が求められる時代において、テクノロジー部門の役割を過小評価してはならない。このシナリオにおけるテクノロジーには、2つの目的があるからだ。


ひとつは、テクノロジーは今やほとんどすべてのビジネス分野で普遍的に採用され、業務の基盤となっているため、ネット・ゼロ・エミッションへの移行を加速し、ポジティブ・インパクトを拡大するための基本的な役割を果たすということである。もうひとつは、テクノロジーは常に進化し、改善されているため、多くの人々が、気候変動にまつわる解決すべき問題の答えを導き出すための基盤としてテクノロジーを利用しているということである。


テクノロジーと持続可能性がこれほど重要で、相互に関連し、影響力を持つ時代はかつてなかった。


## サステナビリティ


サステナビリティが今日のビジネスの中核でなければならない理由であり、Aivenが真剣に取り組んでいることです。実際、私たちの目標のひとつは「不釣り合いなインパクト」を提供することです。つまり、私たちの規模や期待をはるかに超える行動を意図的に推進することで、私たちの影響力を増幅させ、変化を促すポジティブ・インパクトの波及効果を生み出しているのです。


その一例として、クラウド・エミッションの専門知識を持つ技術コンサルタント会社、[Thoughtworks Incのプラグイン](https://www.cloudcarbonfootprint.org/)をベースにした[オープンソースツール](https://github.com/Aiven-Labs/python-cloud-emission-estimator)の開発に取り組んでいるプロジェクトがある。統合されれば、Aivenのサービス利用に伴う二酸化炭素排出量を顧客に示すことができる。排出量を表示することで、お客様がクラウドのフットプリントとインフラ設定を最適化できるようにし、クラウドリソースの効率的な利用に貢献するとともに、持続可能性を考慮した情報に基づいた意思決定を行えるようにすることを目指しています。排出量を正確に計算するために必要なデータ入力を改善するため、いくつかのクラウドプロバイダーと協力する予定です。


私たちは、事業から発生する二酸化炭素排出量も測定し、削減を始めています。私たちのバリュー・チェーンや事業活動には複数の排出源がありますが、私たちはまず、特に環境への影響が大きく、適切に対処すれば時間をかけて最小化することが可能な、排出のホットスポットに焦点を当てています。


## 変化を推進する強力なエージェント


海洋生物学者とデータベース・エンジニアは、専門分野は異なるものの、重要なスキルや価値観を共有している。共同作業は、脅威を特定し、持続可能性戦略に反映させるのに役立ち、一方、技術的ノウハウは、持続可能性努力の影響を理解し、測定するのに役立つ。


最終的には、両者ともビジネスと地球にとって前向きな変化をもたらす原動力となり、ステークホルダーに力を与え、私たち全員がやらなければならない旅に参加するよう周囲を鼓舞するのである。
【python3】指定された日付から昨日までを配列に格納し、表示するプログラム(テスト版)

## はじめに
指定された日付(過去日付)から昨日までの日付データを1日ずつ配列に入れて、日付で突き合わせてデータを取りたいなあと思ったのがきっかけで開発しました。

## 目的
指定された日付から昨日までのデータを何らかの形(CSV、JSON、XML etc)で取得して、指定された日付から昨日までの差分データを取得するためのテストとして、指定されたデータから昨日までの日付を配列に格納し、配列の要素を標準出力に出力するテストプログラムを実装しました。なおコーディングルールには従ってない点、ご了承ください。

## ソースコード
```python
from datetime import datetime
from datetime import timedelta


data1 = input("日付を西暦4桁、月2桁、日付2桁で入力してください。例) 2024年3月9日の場合は「20240309」と入力してください")
if len(data1) == 8:
    print("OK")
else:
    print("NG")


year = data1[:4]
print(year)
month = data1[4:6]
if int(month) < 1 or int(month) > 12:
    print("NG")
else:     
    print(month)
day = data1[6:]
if int(day) < 1 or int(day) > 31:
    print("NG")
else:     
    print(day)
str_ymd = year + "/" + month + "/" + day
ymd = datetime.strptime(str_ymd, '%Y/%m/%d')
array1 = []
dt = datetime.now()
day_sabun = dt - ymd
day_sabun = str(day_sabun)
sabun_array1 = day_sabun.split(" ")
day_sa = sabun_array1[0]
day_sa = int(day_sa)

for i in range(day_sa):
    w_ymd = ymd.strftime("%Y/%m/%d")
    array1.append(w_ymd)
    ymd = ymd + timedelta(1)

for j in array1:
    print(j)

```

## 実行した結果
実行した結果の画像は以下の通りです。

![test1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1055346/f8567c1f-94d7-8b90-633a-17da915b974d.jpeg)


## 最後に
こんな用途があるのか分かりませんが、どこかで役に立ったらちゃんとしたコードにしようと思います。
複数の数値変数を比較して類似スコアを算出する(SPSS Modeler データ加工逆引き3-27)

## 複数の数値変数を比較して類似スコアを算出する（ユークリッド距離）

![スクリーンショット 2024-03-13 15.57.58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286322/60ca47ff-4354-5353-657b-c37641f5c693.png)

複数フラグ変数の類似スコア算出は逆引き3-26を参照ください。

## 1.想定される利用目的

先頭レコードと比較して同じフィールド（列）にフラグが立った数をカウントする
    ・形態素に分解した文章/特許/コンタクトログの類似度を判定する
    ・アンケートの回答や購買記録から類似する被験者や顧客を特定する

## 2.サンプルストリームのダウンロード

https://github.com/yoichiro0903n/blue/raw/main/similarity_num.str

## 3.サンプルストリームの説明

![スクリーンショット 2024-03-13 16.01.10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286322/cf5ef28a-2d21-4cdf-b71f-5447ed18da9f.png)

a.入力するデータのひとつ目は以下の通りです。類似度を求める対象レコードです。

![スクリーンショット 2024-03-13 16.03.45.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286322/c302cf97-16a8-2cbf-bcc3-7267fd7672e2.png)

b.入力するデータのふたつ目は以下の通りです。

![スクリーンショット 2024-03-13 16.04.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286322/8e9a4759-7c23-1ce4-f9ea-6af465ef44e9.png)

c.[レコード追加]ノードを配置します。フィールドの構造と型が一致しているのでデフォルト設定にします。

d.[フィールド作成]ノードを編集します。@&#xFFF0;INDEXでレコードに連番を振ります。この時比較対象をゼロにして2行目から１を割り当てるため@&#xFFF0;INDEX−１とします。

![スクリーンショット 2024-02-21 9.27.47.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286322/83cd3583-5ffa-fc74-d7f1-076e5eb8ce9b.png)

[プレビュー]します。INDEXの1から10を先頭0と比較していきます。

![スクリーンショット 2024-03-13 16.06.37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286322/a4880c04-90a7-c75d-6f81-26a55295df02.png)

e.[フィールド作成]ノードを編集します。[モード]を[複数]に選択して[フィールドリスト]にAからGを投入します。新しいフィールド（列）がもう1セットできるので拡張子を[_一致]として識別します。
INDEXが0の場合にはヌル（undef）を割り当てそれ以外は各フィールドの先頭行との差の２乗を求めます。
@&#xFFF0;FIELDはワイルドカードです。@&#xFFF0;OFFSET（列,N）は N行上のレコードを参照します。

![スクリーンショット 2024-03-13 16.05.54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286322/1d79a7c4-2b5d-3065-6e04-d1b4f920b9d3.png)

[プレビュー]します。例えば赤枠の箇所を例にとると6行上の対象セル（青枠）を参照し
A　-　@&#xFFF0;OFFSET（A,5）の２乗が計算され[A_差の２乗　]（緑）に4が記述されます。

![スクリーンショット 2024-03-13 16.06.16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286322/1a819376-49a8-bd59-5e06-8bc45cc4a9bf.png)

f.[フィールド作成]ノードを編集します。

![スクリーンショット 2024-03-13 16.07.00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286322/9102b76d-e95d-1faa-9cd6-c55a0bc7791f.png)

[プレビュー]します。１００１に最も類似している（距離が近い）のは3003だとわかります。
![スクリーンショット 2024-03-13 18.37.13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286322/bb4688eb-e334-3b4f-3e62-f780fb0f9786.png)

#### アルゴリズムKNNを用いて同じ結果を求める

最近傍法を用いても同じように1001に最も近いケースが3003だと特定できます。

![スクリーンショット 2024-03-13 18.34.09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286322/fe98eadf-dbd8-2df5-bed7-0e616f7519e1.png)

#### 注意点

逆引き３-26ではフラグの共起数をカウントしたのでスコアは高いほど類似ですが、今回の数値の場合は距離を求めているためスコアは少ないほど類似します。

またAからGまでの変数の単位が異なる場合は標準化を予め行うなどの工夫が必要です。

https://qiita.com/416nishimaki/items/af11bb87398da85f6caa

## 4.　参考情報

#### 複数のフラグ変数を比較して類似スコアを算出する

https://qiita.com/416nishimaki/items/c81b0933035f3fda9224

#### SPSS Modeler ノードリファレンス目次

https://qiita.com/416nishimaki/private/503037195081d3323eee

#### SPSS Modeler 逆引きストリーム集（データ加工）

https://qiita.com/416nishimaki/private/4bf813e6cba84b2a1008
Storage/BLOB - Azure 

個人メモ

# 準備 [Azure Portal版]
Azure Portalからストレージリソース作成

# 準備 [CLI版]
TODO

# [検証用]SAS作成 
検証用時限URL(接続文字列)作成

- ストレージアカウント > Shared Access Signature 
    - 使用できるリソースの種類:コンテナー
    - [SASと接続文字列を生成する]クリック



# Java/Kotlin client sample
[Ktor snippetsのtomcat-war](https://github.com/ktorio/ktor-documentation/tree/2.3.9/codeSnippets/snippets/tomcat-war)ベースに変更

https://github.com/kyoya-p/samples/tree/cb2f04f74d8f056df1c813c4b4ff0c27fc07810f/2024/KtorCodeSnippets

[サンプルソース](https://github.com/kyoya-p/samples/blob/cb2f04f74d8f056df1c813c4b4ff0c27fc07810f/2024/KtorCodeSnippets/snippets/tomcat-war/src/main/kotlin/com/example/AzureBlobTrial.kt)


# 参考
[Quick Start](https://learn.microsoft.com/en-us/azure/storage/blobs/storage-quickstart-blobs-java?tabs=powershell%2Cmanaged-identity%2Croles-azure-portal%2Csign-in-azure-cli&pivots=blob-storage-quickstart-scratch)
[Maven azure-sdk-bom](https://mvnrepository.com/artifact/com.azure/azure-sdk-bom)
GitHub、VScodeでのアプリ作成時に初期生成しておくと便利なファイル

## 概要
GitHubとVSCodeを利用したPJ新規立ち上げ時に初期構成しておいた方が良いものを列挙する。
[1.GitHubのPRテンプレート作成](#GitHubのPRテンプレート作成)
[2.開発環境設定](#開発環境設定)
[3.コーディングルールの規定](#コーディングルールの規定)
[4.git管理対象外の設定](#git管理対象外の設定)

## GitHubのPRテンプレート作成
記載方法を統一しないとレビュアーとレビューイ双方の認識がずれるのでテンプレートを用いる。
1. PJのルートフォルダに.githubフォルダを作成
1. 作成したフォルダ内でPULL_REQUEST_TEMPLATE.mdを作成

## 開発環境設定
ローカル環境、開発環境、検証環境、本番環境と分けて開発することが多いが、環境に応じて環境変数を切り替える設定をしておく。
1. ルートフォルダに.envファイルを作成してデフォルト設定を定義
1. .env.devや.env.stg等を作成して、それぞれに環境変数を記載してデフォルトを上書きする

## コーディングルールの規定
JSなどの細かい言語ごとにおける規定はlintで行うので、タブやインデント等の記載方法をエディター設定で統一する。lintについては言語、PJ方針とライブラリによるので割愛。フレームワークで初期設定されることが多い。
1. ルートフォルダに.editorconfigファイルの作成
2. 設定を記述。一例を記載
```
indent_style = space 　　　　　　　　　　　　　　　　　　　　　　　　## インデントをタブあるいは空白で行うかの設定
indent_size = 2      　　　　　　　　　　　　　　　　　　　　　　　　## 1インデントあたりの個数。例では1インデントあたり2個の空白としている。
end_of_line = lf     　　　　　　　　　　　　　　　　　　　　　　　　## 改行コードの種類
trim_trailing_whitespace = true  ## 行末の空白削除を自動で行うか
insert_final_newline = true　　　　　　　　　　　　## 最終行に空行を自動で挿入するか
max_line_length = 80            ## １行当たりの文字数制限
```

## git管理対象外の設定
自動生成すると作成されていることが多いが念のため記載。
1. ルートフォルダに.gitignoreを作成
1. 管理対象外とするフォルダやファイルを記載
```
/node_modules
*.pem
```
悩み：OSで複数クエリに分けずに、既読情報を考慮して検索したい。

# 以下のことを単一クエリで実行したい


既読状態がユーザーごとに異なる場合、この情報をユーザーインデックスではなく、別のインデックス（例えば `user_book` という名前で）に保存します。ユーザーと本の関連付けを管理するためのインデックスです。

ユーザー: id, name
本: id, title, author
ユーザーと本の関連：user_id, book_id, is_read
以下にそれぞれのコードを示します。


## ユーザー、本、ユーザーと本の関連のインデックス作成

```py
from elasticsearch import Elasticsearch

es = Elasticsearch()

# ユーザーのインデックス作成
es.indices.create(index='user', body={
    'mappings': {
        'properties': {
            'id': {'type': 'integer'},
            'name': {'type': 'text'}
        }
    }
})

# 本のインデックス作成
es.indices.create(index='book', body={
    'mappings': {
        'properties': {
            'id': {'type': 'integer'},
            'title': {'type': 'text'},
            'author': {'type': 'text'}
        }
    }
})

# ユーザーと本の関連のインデックス作成
es.indices.create(index='user_book', body={
    'mappings': {
        'properties': {
            'user_id': {'type': 'integer'},
            'book_id': {'type': 'integer'},
            'is_read': {'type': 'boolean'}
        }
    }
})

```


## 既読にした本のインデキシング更新:

```py
# ユーザーと本のid、既読状態をセット
user_id = 1
book_id = 1
is_read = True

# ユーザーと本の関連情報を検索
res = es.search(index='user_book', body={
    'query': {
        'bool': {
            'must': [
                {'match': {'user_id': user_id}},
                {'match': {'book_id': book_id}}
            ]
        }
    }
})
```

## 検索結果があれば更新、なければ登録

```py
if res['hits']['hits']:
    doc_id = res['hits']['hits'][0]['_id']
    es.update(index='user_book', id=doc_id, body={'doc': {'is_read': is_read}})
else:
    es.index(index='user_book', body={'user_id': user_id, 'book_id': book_id, 'is_read': is_read})
```

## 既読を除外して本を検索


# ユーザーidと検索クエリ

```py
user_id = 1
query = "ハリー・ポッター"

# ユーザーが既読にした本を検索
res = es.search(index='user_book', body={
    'query': {
        'bool': {
            'must': [
                {'match': {'user_id': user_id}},
                {'match': {'is_read': True}}
            ]
        }
    }
})

# 既読にした本のidリストを作成
read_book_ids = [hit['_source']['book_id'] for hit in res['hits']['hits']]

# 既読にした本を除いて、クエリにマッチする本を検索
res = es.search(index='book', body={
    'query': {
        'bool': {
            'must': {
                'match': {
                    'title': query
                }
            },
            'must_not': [{'ids': {'values': read_book_ids}}]
        }
    }
})

# 検索結果の表示
for hit in res['hits']['hits']:
    print(hit['_source'])

```

このコードの注意点は先程と同じです。Python環境が必要で、ElasticsearchクライアントのバージョンとElasticsearchサーバーのバージョンが合っていることを確認してください。
CloudFormationが高速化したらしい

### CloudFormation高速化
掲題の内容について、下記のようなポストがあった。
https://aws.amazon.com/jp/about-aws/whats-new/2024/03/aws-cloudformation-40-percent-faster-stack-creation/

CloudFormationが最大40%高速化したらしい。
CDKを使っているので恩恵があるのか調べてみようか思い、
ブログの中身を見てみるとECR-ECSの安定化戦略に手が入ったことによって高速化できたとのこと。

https://aws.amazon.com/jp/blogs/devops/how-we-sped-up-aws-cloudformation-deployments-with-optimistic-stabilization/


これまではECRの作成-安定化確認を待ってからECSタスク立ち上げを行うような形だった。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3620223/2f3cdb2d-3a02-eba4-2ae9-52ab6221c7cb.png)

新しいものではECRの作成を行った後、安定化を待たずしてECSタスクの立ち上げフェイズに移行できるようになった。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3620223/1718351e-9d49-c09b-ef57-42b617508e1f.png)

これにより待ち時間が短縮され、最大40%短縮できる…ということなのかなと思います。

CDKもCloudformationテンプレートに落とし込まれて実行されるため、
この恩恵を受けることができそうですが、私が触る環境ではECRリポジトリの作成は別で実施されているため、この恩恵は受けられなさそう。残念。

ECR、ECSを利用した環境でECR反映からECSタスクの立ち上げ（置き換え）までを1スタックで行っているような方は少し幸せになれるかもしれません。
S3に格納されているファイルの中身をPythonで取得したい

# はじめに
S3に保存したファイル(csvなど)のファイル名一覧ではなく、**中身の情報**を取得する方法を紹介します。

# 取得方法

以下のポリシーを割り当ててコードを実行します。
【必要なポリシー】
・s3:GetObject
・s3:ListBucket

プレフィックス名は「prefix/prefix」ではなく、「prefix/prefix/」とスラッシュまでを付ける必要がある点でエラーが出やすいので、気をつけてください。
~~~Python:sample.py
import boto3

s3_client = boto3.client('s3')
response = s3_client.list_objects(Bucket='{バケット名}',Prefix='{プレフィックス名}')

for content in response['Contents']:
    get_object_response = s3_client.get_object(Bucket='{バケット名}',Key=content['Key'])
    file_content = get_object_response['Body'].read().decode()
~~~
Docker上で動かしているWebサーバーのログが見たい

# 前提
- DockerはDocker composeを使用
- WebサーバーはNode.js + pm2

# 結論
```sh
$ docker compose logs [サービス名]
```

# ハマったとこ
Docker間で通信を行っている処理があり、その通信が失敗していたためその検証がしたかった。
しかし、Docker内でのログの出し方が分からず、余計な時間を割いてしまったため、記録しておく。

### ハマった原因
- 自分がそもそもDockerで動いているNode.jsのログの見方を分かってなかった

### 解決した経緯
- pm2を利用していることを知っていたので、pm2のログが出せることを知ったため

https://blog.morugu.com/entry/2018/01/30/222200

- 最初に上記の方法でログが出せることを確認した
- `$ docker compose log`でも同じようにログを出せることがわかった

https://matsuand.github.io/docs.docker.jp.onthefly/engine/reference/commandline/compose_logs/

# その他
- サービス名は下記の方法で出せる
- 下記リストの `SERVICE` がそれにあたる
```sh
$ docker compose ps

NAME      IMAGE     COMMAND      SERVICE   CREATED     STATUS    PORTS
hoge      hoge      hoge         hoge      hoge        Up        0000
```
React Hook Form でカスタムバリデーションを作成する方法

## register 関数とバリデーション

React Hook Form では、`useForm` フックから `register` 関数を取得し、これを使ってフォームフィールドを登録します。  
フォームフィールドにバリデーションルールを適用するには、`register` 関数にオプションオブジェクトを渡し、その中に `validate` フィールドを設定します。

## validate フィールドの使い方

`validate` フィールドには、フォームフィールドの値が特定の条件を満たすかどうかを判定する関数を渡します。  
この関数はフィールドの値を引数として受け取り、条件に応じてエラーメッセージを返すか、`true` を返します。

以下の例では、ユーザー名が4文字以上で、スペースを含まないことを条件にしています。

```tsx
<input
  {...register("username", {
    validate: (value) => {
      if (value.length < 4) {
        return "ユーザー名は４文字以上である必要があります。";
      }
      if (value.includes(" ")) {
        return "ユーザー名にスペースを含めることはできません。";
      }
      return true;
    }
  })}
/>
```

## エラーメッセージの表示
バリデーション関数から返されたエラーメッセージは、`formState.errors`オブジェクトを通じてアクセス可能です。以下のようにしてエラーメッセージを表示することができます。

```tsx
{errors.username && <p>{errors.username.message}</p>}
```

## まとめ
React Hook Form の `register` 関数と `validate` フィールドを使用することで、カスタムバリデーションを簡単に実装できます。  
バリデーション関数を通じて条件に基づいたエラーメッセージを返すことで、ユーザーに対して有用なフィードバックを提供することができます。
さくらのレンタルサーバでPython3(PY_UNSUPPORTED_OPENSSL_BUILD=static)

::::::note warn
次の話を含め202501時点での方法をまとめました。この記事は残しておきますが次のリンクの記事を参照ください。
- スタティックにビルドしなくても良い
- さくらFreeBSD13/11でのOpenSSLの話
:::

https://qiita.com/hkato/items/fe7a1c7345f47cbf979b


## 修正

タイトルと異なってしまうが、スタティックにビルドしなくても`--with-openssl-rpath=auto`でビルドすれば良い。

```sh
CONFIGURE_OPTS="--with-openssl=$HOME/local/openssl/x.y.z \
--with-openssl-rpath=auto" \
pyenv install 3.x.y
```

次の記事等を参照

https://qiita.com/paprinco/items/f55a6c4df22cbd9f4263

## はじめに

- さくらのレンタルサーバはPython3が入ってないか or 入っているのは3.8
- OpenSSLも古い
   - 3.9までは古いOpenSSLでもOK
- CGIとして動かしたい
   - Python実行後にOpenSSLのパスを指定できない（と思う）

Python3の初期のモノをさくらにインストールする記事はいくつか見かけたが、3.10以降は？なので、3.12でCGIを動かすまでを試してみる。

## さくらのレンタルサーバ状況

https://help.sakura.ad.jp/rs/2251/?article_page=2#heading-1

> 3.8.x
> ※旧仕様の一部サーバは、2.7.xです。

新仕様のサーバは3.8.xが入っている様だが、今現在の私のサーバは2.7.xのままでOpenSSLは1.0.2oである。ここに無理やり3.12.xを入れてみる。

## OpenSSLのビルド

さくらのFreeBSD11ではOpenSSLが1.0.xと古く、Python3.9までならOpenSSLを別途用意しなくてもビルド可能だが、Python3.10以降はOpenSSL1.1.1以降が必須となりビルドが必要。とりあえず現在のLTSである3.0.xで試してみる。
パスは`$HOME/local`としたがどこでも良い。キモは`--openssldir=/etc/ssl`でFreeBSDの標準のCAバンドルを参照することと、`install_sw`で証明書関連やドキュメントはインストールせずバイナリー等のみをローカルにインストール。

ソースを展開して

```sh
mkdir -p $HOME/local/src
cd $HOME/local/src/
curl -O https://www.openssl.org/source/openssl-3.0.13.tar.gz
tar xvfpz openssl-3.0.13.tar.gz 
cd openssl-3.0.13
```

オプションを指定してビルド

```sh
./config --prefix=$HOME/local/openssl/3.0.13 --openssldir=/etc/ssl
make
make install_sw
```

これで`~/local/openssl/3.0.13`に実行ファイルやライブラリ等が入り`/etc/ssl`に置かれた証明書バンドルや設定を参照するOpenSSL環境が出来あがる。

```sh
LD_LIBRARY_PATH=$HOME/local/openssl/3.0.13/lib \
~/local/openssl/3.0.13/bin/openssl version
```
```sh
OpenSSL 3.0.13 30 Jan 2024 (Library: OpenSSL 3.0.13 30 Jan 2024)
```
### Pythonのビルド

pyenvなどの環境設定は省略。次の投稿とか。

https://qiita.com/umekichinano/items/11d87902883871981ef4

コンソールから利用するなら`LD_LIBRARY_PATH`環境変数でOpenSSLの場所を指定しビルドすれば動くが、CGIとして実行したいので、環境変数を設定したくない。CGIの頭で`os.environ[]`にてOpenSSLライブラリのパスを設定してもダメみたい。どうしたら良いか？ライブラリとして参照せずスタティックに組み込んでしまう。`PY_UNSUPPORTED_OPENSSL_BUILD=static`がキモ。

:::note
追記
冒頭に追記書いたように`--with-openssl-rpath=auto`でOpenSSLを参照してくれるのでそちらの方が良い。
:::

上記OpenSSLの場所を指定しスタティックでビルド

```sh
CONFIGURE_OPTS="--with-openssl=$HOME/local/openssl/3.0.13" \
PY_UNSUPPORTED_OPENSSL_BUILD=static \
pyenv install 3.12.2
```

多分、3.11.x, 3.10.xでもいけると思う（やってない）。

`import ssl`したり、

```sh
$ ~/.pyenv/versions/3.12.2/bin/python
Python 3.12.2 (main, Mar 13 2024, 15:42:09) [GCC 7.5.0] on freebsd11
Type "help", "copyright", "credits" or "license" for more information.
>>> import ssl
>>> ssl.OPENSSL_VERSION
'OpenSSL 3.0.13 30 Jan 2024'
>>> 
```

次のコードが動けば多分とりあえず動いてる？

```python
import urllib.request

with urllib.request.urlopen('https://dummyjson.com/products/1') as response:
   html = response.read()
   print(html)
```

このPython3.12環境にPoetryを入れて、とりあえず

- Flask + Flask-CORS
- FastAPI + Pydantic V1 + a2wsgi
 
をCGIとして動作させることができた。(ハロワレベル）

### まとめ

- OpenSSLをビルドする（証明書等はOSのデフォルトを参照で）
- ~~PythonのビルドはOpenSSLをstaticでビルド(`PY_UNSUPPORTED_OPENSSL_BUILD`)~~
OpsRamp パッチ管理 - 未適用パッチのスキャン方法

本記事では、OpsRampのパッチ管理(Patch Mangement 2.0)でデバイスに適用されていないパッチのスキャン方法について説明します。

# 概要
OpsRampには、WindowsまたはLinuxでアップデートされていないWindows Updateやアプリケーションのパッチをスキャンすることができます。また、スキャンの実行をスケジュールすることができ、定期的な未適用パッチを検出することができます。
[Patch Management 2.0](https://docs.opsramp.com/solutions/remediation-automation/patch-management-2.0/)

::: note warn
WindowsまたはLinux機にOpsRamp Agentがインストールされている必要があります。
:::

# 設定方法
パッチスキャンは、Configuration Management > Patch Management 2.0 画面左上のハンバーガーマークのPatche Scan Scheduleから設定可能です。
![patch-scan-schedule1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2344939/21115a8c-210d-bda4-2966-123ba016679b.png)
新規に作成する場合は、ADDから作成できます。
![patch-scan-schedule2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2344939/2f90eb0b-4242-70fd-c882-3ac973831f6b.png)

Resource Selectionでは、パッチスキャンを行う対象のリソースを設定します。
リソースの選択は、2つのタイプから設定できます。

- Dynamic: 条件に合致したリソースが動的に選択されます。
- Select Resource: リソースをリストから静的に選択します。

![patch-scan-config1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2344939/8261c332-0b4d-509a-c0ae-f21d49e6df64.png)

Scheduleでは、パッチスキャンを実行するスケジュールを設定します。

- RUN ON DEMAND: 任意にユーザが実行します。自動では実行されません。
- ONE TIME: 設定した日時に１度だけ実行されます。
- DAYLY: 設定した時間に月曜から金曜、または毎日繰り返し実行されます。
- WEEKLY: 設定した時間および曜日に繰り返し実行されます。
- MONTHLY: 設定した時間および毎月任意の日または任意の曜日に繰り返し実行されます。

またNotifictionsで、実行時にメールを送信することができます。
![patch-scan-config2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2344939/b8e0838d-1776-ca71-efe0-f2f0b05d2cc2.png)

::: note
RUN ON DEMANDを選択した場合、スキャン設定の右 Run Nowから実行可能です。
![patch-scan-run-now.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2344939/0ea60a63-b80a-4ebf-cd76-40de4fc02e1e.png)
:::

検出されたパッチは、Missing Patchesまたは対象リソースのPatchesから確認することができます。
![missing-patches1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2344939/2e3b4d61-5f06-48d3-15ca-320df020f91f.png)
![missing-patches2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2344939/27fdf258-c5e8-a05a-3346-3a63004e7220.png)


---------------------------------------
[<img width = 250 height = 200 src = "https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2344939/111de30a-4d33-aa33-5c7d-83d9015093e6.png">](https://www.vistanet.jp/knowledge-base/)
自動ケース更新ユーザ


+ [自動ケース更新ユーザはどのような用途で使用されますか？](https://help.salesforce.com/s/articleView?id=000385420&type=1)


自動ケース更新ユーザは、Salesforce のすべての自動ケースアクションのケース履歴にリストされているユーザです。
+ ケースが割り当てルールを使用して自動的に割り当てられるとき
+ ケースがエスカレーションされるとき
+ ケースが Web-to-ケースを介してオンラインで作成されるとき
+ メール-to-ケースがケースの作成に失敗した場合、ケースが作成されなかった理由のエラーメッセージとともに、自+ 動ケース更新ユーザにメールが送信されます。

このユーザは、ケースエスカレーションのメール通知の差出人アドレスにも指定されています。

注意: 自動ケース更新ユーザは、システム管理者プロファイルまたは「すべてのデータの編集」および「メールの送信」権限を持っている必要があります。

+ [Custom App Setting for Standard Users](https://trailhead.salesforce.com/trailblazer-community/feed/0D54V00007agfFm)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/15db30da-0db6-79d1-7323-fe2279cdce62.png)

:::note
Remember: Automated Case user must have the System Administrator profile or the 'Modify All Data' and 'Send Email' permissions.

https://help.salesforce.com/s/articleView?id=000385420&type=1
:::
ServletContainerInitializer を実装してみた

### ServletContainerInitializerを実装してみた

結構はまったので、自分用のメモとして残す

# 環境
Java17
Wildfly28


一番参考になったのは、以下の記事です。
https://www.logicbig.com/tutorials/java-ee-tutorial/java-servlet/servlet-container-initializer-example.html


要約すると
・ServletContainerInitializerを実装したクラスをおさめたJarファイルを作る。
・上記のJarを組み込んだWebアプリを作る。warが出来ます。

従って、プロジェクトは２個作成する必要があります。


## プロジェクト１
ここでは ServletContainerInitializerを実装したクラスを作成します。

呼ばれた事を確認するだけの、ログ出力をしているだけです。


```Java
package iinit;

import jakarta.servlet.ServletContainerInitializer;
import jakarta.servlet.ServletContext;
import jakarta.servlet.ServletException;
import jakarta.servlet.annotation.HandlesTypes;
import jakarta.servlet.annotation.WebListener;
import jakarta.ws.rs.*;
import jakarta.ws.rs.core.Application;
import jakarta.ws.rs.ext.Provider;


import java.util.Set;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

@HandlesTypes({ Application.class, Path.class, Provider.class })
public class HemmisServletContainerInitializer implements ServletContainerInitializer {
    // SLF4J
    private static final Logger LOG = LoggerFactory.getLogger(HemmisServletContainerInitializer.class);
    
    
    @Override
    public void onStartup(Set<Class<?>> c, ServletContext ctx) throws ServletException {

        LOG.warn("MyInitializer#onStartup -------------------- start");
        if (c ==null || c.size() == 0)
            return;

        for (Class<?> x : c) {
            LOG.warn("37) {}",   x.getCanonicalName());
        }
        LOG.warn("MyInitializer#onStartup -------------------- end");

    }
    
}

```

クラス名の前の行についているアノテーションの中に書かれているクラス名は、受け取りたいクラス名になります。
この例では、Applicationアノテーションと、Pathアノテーション、Providerアノテーションが付いたクラスのSetが、onStartupの第一引数にわたってきます。



resourceの下にMETA-INF/servicesというディレクトリを作成する

そのなかに、jakarta.servlet.ServletContainerInitializerというテキストファイルを作成します。

そのテキストファイルの中に、先ほど作成したJavaのクラス名をパッケージ名付きで記入します
```text
iinit.HemmisServletContainerInitializer
```

pom.xmlは大事な所のみ記述します

```xml
   <groupId>com.example.jaxrs</groupId>
    <artifactId>mylistner</artifactId>
    <version>0.1-SNAPSHOT</version>
    <packaging>jar</packaging>
```

```xml

    <dependency>
      <groupId>jakarta.servlet</groupId>
      <artifactId>jakarta.servlet-api</artifactId>
      <scope>provided</scope>
    </dependency>
 </dependencies>
```

mvn install
を実行します。

targetディレクトリには、以下のjarファイルが出来ていました。
mylistner-0.1-SNAPSHOT.jar



## ２個目のWebアプリのプロジェクト

こちらは、既存のWebアプリがあったので、そのPOMに上記で作成したJarを組み込むように設定します。

```xml
    <dependency>
      <groupId>com.example.jaxrs</groupId>
      <artifactId>mylistner</artifactId>
    <version>0.1-SNAPSHOT</version >
    </dependency>

</dependencies>
```

Webアプリをビルドします。

mvn clean
mvn package

出来上がった war をWildflyにデプロイします。

./standalone.sh で、Wildflyを起動します。


![initLog.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1339875/ab4fc769-bd42-a7ec-0739-140ad57a03fc.png)


蛇足ですが、Macだとログに色が付くので、Windowsより見やすくて好きです> wildfly
S3暗号化の備忘録

S3暗号化に対するIAMポリシーの備忘録

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1526421/aad9ea84-930d-9b0a-58d1-10f7ba4e5ae5.png)

Amazon S3 マネージドキーを使用したサーバー側の暗号化 (SSE-S3)
→S3SullAccessで操作可能

AWS Key Management Service キーを使用したサーバー側の暗号化 (SSE-KMS)
AWS Key Management Service キーを使用したデュアルレイヤーサーバー側の暗号化 (DSSE-KMS)
→各キーに対しての操作を許可するポリシーを作成して別途当てる必要アリ。

そらそうだって話ですが、意外と見落とすことが多いので記しておきます。
【知見メモ】NavigationBarのBackButtonのサイズが大きくなってしまうケースの応急処置

# 概要

本記事では、カスタマイズされたNavigationBarを用いて画面遷移した際、BackButtonのサイズが意図せず大きくなってしまう問題の対処法を紹介します。

プロジェクトの構成や具体的な再現方法には触れませんが、同様の問題に直面した際の参考にしていただければ幸いです。

# 背景

私の所属しているプロジェクトでは、不透明な色、透明、および非表示の状態を持つ3種類のNavigationbarがあります。

これらの異なるタイプのNavigationbarが混在すると、画面遷移時にスタイルが崩れやすくなるため、独自にカスタマイズしたNavigationbarを使用しています。

# 問題

特定の条件下で、タイトルの位置がずれるという問題に遭遇しました。
再現手順はアプリに依存するため、エッジケースだと考えられます。

![スクリーンショット 2024-03-13 15.14.59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3368292/7dcd3f50-12be-eb3d-2f17-a17c62df7eb3.png)

# 原因

ViewDebuggerでViewの状態を確認した結果、BackButtonのサイズが大きくなっていることが原因でした。

![スクリーンショット 2024-03-13 15.20.22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3368292/88008575-6b0e-c4cc-7e03-444aad5d34ca.png)

![スクリーンショット 2024-03-11 17.32.02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3368292/5fd69165-5290-0e9e-0a50-90cf1696fb9b.png)

BackButtonの内部構造を調べたところ、`_UIModernBarButton`によって2つの部分から構成されていることがわかりました。

1つ目は矢印アイコン用の領域、2つ目は「戻る」テキストを表示する領域です。
（アプリデザインの都合上、独自の矢印アイコン、「戻る」のテキストを非表示に設定）

# 対処法

直接的に影響する実装がないことから、特定の条件下で発生するUIKitの不具合だと考えます。

この問題に対して根本的な解決が難しいと判断し、応急処置として対応することにしました。

具体的には、`navigationItem.backButtonDisplayMode = .minimal`を設定することで、「戻る」テキストの領域を縮小し、この問題に対処しました。

![スクリーンショット 2024-03-13 15.34.59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3368292/377e437a-a3fe-876d-873f-6ba16fa4b615.png)


# おわりに

本記事では、特定の条件下でのUIKitの不具合に対処するための応急処置を紹介しましたが、内容が全て正しいとは限りません。

間違いや改善点がございましたら、ぜひご指摘いただければ幸いです。
Salesforce認定アドミニストレーターを受験することになったから過去問を解いてアウトプットしていこうと思う。Q51 ~ Q60

## Q51. Salesforceによると, コンソールはSalesforceを1日3時間以上表示するユーザー向けに最適に設定されている.
A: はい
### 解説
コンソールは複数のタブを同時に開いて作業することができる高度なユーザーインターフェースを提供する. これによってユーザーは効率的に複数のタスクやレコードにアクセスし作業することができる. このような機能はSalesforceを頻繁に使用するユーザーにとって非常に有用であるが, Salesforceを使用しないユーザーにとってはコンソールの機能は過剰である可能性がある. したがって, コンソールは1日3時間以上表示するユーザー向けに最適に設定されていると言える.

-- コンソール　公式ヘルプ --
https://help.salesforce.com/s/articleView?id=sf.console2_about.htm&type=5

## Q52. レコードの所有者は, 特定のデータレコードに対する制御または権限を持つユーザーまたはキューである. 
A: はい
### 解説
設問の通りです. この概念は, データのセキュリティやアクセス制御を確保するための重要な要素となっている.

## Q53. オブジェクトタブを作成する時に, タブをランディングタブとして設定できますか？
A: いいえ
### 解説
Salesforceにおいて, オブジェクトのタブを作成する際にそのタブを「ランディング タブ」として特別に設定する機能は提供されていない. ユーザーがSalesforceにログインした際のデフォルトのランディングページは, ユーザーのプロファイルや役割によって決定されている.

## Q54. 以下はすべて、Salesforce.com の主な設定エリアです。例外は?
選択肢 : 
    Aデータ設定
    B個人設定
    Cアプリのセットアップ
    D管理設定

A: A
### 解説
「データの設定」という特定の設定エリアは存在しない.

## Q55. [ファイル]タブからアクセスできるファイルの種類は？
選択肢 : 
    A[ソリューション] タブにアップロードされたファイル
    Bコンテンツ ワークスペース内のファイル
    C[ドキュメント] タブにアップロードされたファイル
    D　Chatter プロファイル投稿に添付されたファイル
    E　Chatter グループ投稿に添付されたファイル

A: B, D, E
### 解説
[ソリューションタブ]や[ドキュメント]タブにアップロードされたファイルは, [ファイル]タブから直接アクセスすることができない.

## Q56. 次のうち, 制御フィールドと依存フィールドはどれ？
選択肢 : 
    Aカスタム ピックリスト
    B標準ピックリスト
    C標準チェックボックス
    Dカスタムチェックボックス

A: A
### 解説
1つのフィールドの選択に基づいて別のフィールドの選択肢を制御するような設定は, 標準フィールドではできない. よって, カスタムフィールドが設問の回答として正解.

## Q57. 管理者は, 2要素認証を使用して権限セット グループを割り当てました. ユーザー インターフェイス ログイン権限と、ユーザー グループに対する API ログイン権限の2要素認証。ユーザーの 1 人がデータローダにログインしようとしたときに表示されるプロンプトはどれですか?2つの答えを選択してください.
選択肢 : 
    Aユーザーは認証アプリを Salesforce アカウントに接続する必要があります。
    Bユーザーは、電子メールまたは SMS のいずれか優先度の高い方から確認コードを入力する必要があります。
    Cユーザーは、モバイル デバイスに認証アプリをダウンロードしてインストールする必要があります。
    Dユーザーは、Reset My Security Token を使用して、信頼できるネットワークからセキュリティ トークンを取得する必要があります。

A: A, C
### 解説
2要素認証とは, ユーザーがログインする際に2つの異なる認証方法を使用して本人確認を行うセキュリティ手段のこと. Salesforceでは, 2要素認証を強化するために認証アプリを使用することが推奨されている.

## Q58. ルックアップフィールドの関係として, 正しい選択肢はどれ？
選択肢 : 
    A 2つのページ レイアウトをリンクします。
    B 2つの数式をリンクします。
    C 2つの Salesforce.com インスタンスをリンクします
    D 2つのオブジェクトをリンクします

A: D
### 解説
ルックアップフィールドとは, 1つのオブジェクトのレコードから別のオブジェクトのレコードを参照するためのフィールドのこと.

## Q59. 早期トリガーを使用する理由は？
A: ケースが実際にエスカレートする前に通知できるようにするため.
### 解説
早期トリガーはエスカレーション機能の一部. 指定された時間だけ前に通知を受けることができることによって, 担当者やマネージャーはケースがエスカレーションする前に適切なアクションを取ることができる. 

## Q60. Connect Offlineで制御フィールドと依存フィールドが使用可能な場合はある？
A: ない
### 解説
Connect Offlineで制御フィールドの選択肢に基づいて依存フィールドの選択肢を制御するようなロジックは, オフライン環境で組めない. もしオフライン中にそのような編集を行った場合, オンラインに戻った時にデータの不整合が起こる可能があるため, オフライン中の編集はしない方がいい.
S3のクロスリージョンレプリケーション（CRR）について

### CRRとバージョニング
S3のクロスリージョンレプリケーションを行うためには、S3バケットのバージョニングを有効化しておく必要がある。

https://docs.aws.amazon.com/ja_jp/AmazonS3/latest/userguide/replication-and-other-bucket-configs.html#replication-and-versioning
UE5 エンジン内にマクロを定義する方法

# 概要
今回はエンジン内にマクロを定義する方法を解説します。
マクロを定義する理由は、エンジンを改造する場合にマクロで囲ったほうが、変更箇所を検索できたり、バニラの状態に戻したりできます。
この記事はUE5.3.2の環境で確認しています。

# 実装
「UEBuildTarget.cs」の「SetupGlobalEnvironment」関数に以下の内容を記述します。
```C++:Engine\Source\Programs\UnrealBuildTool\Configuration\UEBuildTarget.cs 5148行
// Begin:Added engine macro
			GlobalCompileEnvironment.Definitions.Add("ENGINE_MODIFY");
// End:  Added engine macro
```
以下のように改造コードとバニラのコードを分けたりできます。
```C++:
#if defined(ENGINE_MODIFY)
// Begin:
#else
// End:
#endif
```

# おまけ
シェーダー内にもマクロを定義できるようにしてみましょう。
以下の内容を「ShaderCompiler.cpp」の「GlobalBeginCompileShader」関数に記述します。
```C++:Engine\Source\Runtime\Engine\Private\ShaderCompiler\ShaderCompiler.cpp 6838行
#if defined(ENGINE_MODIFY)
// Begin:Add shader macro
	Input.Environment.SetDefine(TEXT("ENGINE_MODIFY"), 1);
// End:  Add shader macro
#endif
```

以下のように使用できます。
```C++
#if ENGINE_MODIFY
// Begin:
#else
// End:
#endif
```

# まとめ
これでエンジン改造ライフが捗りますね。
プログラミング初心者の時に意味不明だった英語

プログラミング初心者の人はこういうフレーズの意味をあらかじめ理解しておくと英語のドキュメントが読みやすくなるかもしれません。

解説は結構適当です。すみません。

# coverage

辞書を引くと「報道範囲」とか「放送範囲」みたいな和訳が出てきます。そういう意味もあるんだ。

コードベース全体の行数に対する、テストランナーでテスト済みの行数の割合です。行数以外の定義もあるかもしれません。

これが100%に近いほど「このプロジェクトはちゃんとテストされていてバグがないな」と判断するための指標になります。ただし、たとえ100%であったとしてもテストコードの品質が悪ければバグが発生する可能性はあります。

# in-place

「その場で」とよく訳されるやつ。

オブジェクトの内容が、明示的な代入操作なしで変わってしまうことを指していると思います。

私にとってはネガティブ系のフレーズ。こういう挙動をするものはあんまり使いたくないな〜って捉えています。

```JavaScript
// javascriptFile.ts

// constで宣言したんだから、この変数のスコープの中では
// いつ参照してもこの順番で値が入っていてほしい
const arr = [3, 2, 1];

// in-place で処理するメソッドを使う
arr.sort();

// arrの要素の順番が変わってしまった
console.log(arr)
// [1, 2, 3]
```

# syntax sugar

「糖衣構文」とよく訳されるやつ。

読みづらい・分かりづらい書き方と同じ意味を持っている、読みやすい・分かりやすい別の書き方を指していると思います。

[Wikipediaの例](https://ja.wikipedia.org/wiki/%E7%B3%96%E8%A1%A3%E6%A7%8B%E6%96%87#Python)をそのままパクるけど、下記のような配列の要素へのアクセスはsyntax sugarの一種らしいです。

```Python
# python_file.py

# よくやる代入および参照
my_list = [1, 2, 3]
my_list[0] = 2
print(my_list[0])

# syntax sugarが無ければ、それぞれの構文はこうなる
my_list = [1, 2, 3]
my_list.__setitem__(0, 2)
print(my_list.__getitem__(0))
```

# tree shaking

指している概念そのものは「ソースファイルの中にあるけど実行時には実行されないコード」を削除する、という行為。型定義とかテストコードとかね。

葉っぱがたくさん生っている木を揺らして、枯れ葉などの無駄なものを振り落とすイメージでしょうか。

最終的なコードベースのファイル容量を小さくすることが特に重要な、フロントエンド（JavaScript）の文脈で使われている概念です。[MDNのTree shakingのページ](https://developer.mozilla.org/ja/docs/Glossary/Tree_shaking)の説明をちょっとパクりました。

最終的なファイル容量が小さければ小さいほど、サーバーからブラウザまでコードを送り届けるための通信速度が改善されるので嬉しい。

逆にコードそのものを通信でやり取りしないバックエンドの文脈ではあんまり登場しない言葉かも。

# wrap

ラップです。食品を包むアレのイメージでも良いかもしれません。

特定のオブジェクトをさらに1段階上から何かで包み込む時に使う動詞です。例えばHTMLで言えば下記のような感じ

```html
<html>
  <!-- 何かしらのコンテンツ -->
</html>
<!-- →全てのHTML要素は <html> 要素で wrap されている、と表現できる -->
<!-- →あるいは、 <html> 要素は全てのHTML要素の wrapper である、と表現できる -->
```

マークアップだけでなく、関数などにもラッパーがしばしば登場します

```JavaScript
// 引数が4つもある関数なので扱いが難しい
const someDifficultFunction = (arg1, arg2, arg3, arg4) => {
  // 何か難しい処理
  // 実際に使う時には arg1, arg2, arg3 の値が固定で、
  // arg4 の値だけ動的に与えるものと仮定すると......
};

const wrapperFunction = (arg) => {
  return someDifficultFunction(1, "hoge", { foo: "bar" }, arg);
  // arg1, arg2, arg3 の値は固定のまま、
  // arg4 に相当する値だけを渡せばいいラッパー関数を定義できた
};
```
【Go言語】指定したパスがファイルなのかディレクトリなのかを判別する関数

### ファイルの存在確認

```go
func IsFile(path string) bool {
    info, err := os.Stat(path)
    if err != nil {
        return false
    }
    return !info.IsDir()
}
```

1. `os.Stat(path)`を使って、指定したパスの情報を取得
2. エラーが発生した場合（`err != nil`）、指定したパスにファイルまたはディレクトリが存在しないため、`false`を返却
3. `!info.IsDir()`が`true`の場合、指定したパスはファイルであるため、`true`を返却


### ディレクトリの存在確認

```go
func IsDir(path string) bool {
    info, err := os.Stat(path)
    if err != nil {
        return false
    }
    return info.IsDir()
}
```

1. `os.Stat(path)`を使って、指定したパスの情報を取得
2. エラーが発生した場合（`err != nil`）、指定したパスにファイルまたはディレクトリが存在しないため、`false`を返却
3. `info.IsDir()`が`true`の場合、指定したパスはディレクトリであるため、`true`を返却

### パスの指定方法

両関数とも、絶対パス・相対パス、どちらの指定方法でもOKです

### 参考

存在確認部分の正当性に関しては、下記の記事を参考にしました。

```go
info, err := os.Stat(path)
if err != nil {
    return false
}
```

https://qiita.com/hnakamur/items/848097aad846d40ae84b

https://qiita.com/suin/items/b9c0f92851454dc6d461#comment-70c188ae8ad783fe57f9
NetBSDでmrubyをセルフビルドしてみた

猛牛さんのCortex-A9は結構早いしストレージも十分にあるのでmruby-3.3.0をセルフビルドしてみます。

NetBSDはCompiler toolsのsetをインストールしておきます。

まずpkg_addでruby32_baseをインストールします。armv6(non hf)のpkgはないのでarmv4のpkgを-fオプションでインストールします。

次にgem32でrakeをインストールします。

あとはftpでmruby-3.3.0のアーカイブをダウンロードしてビルドしてみます。

```
% time rake

...

     1196.99 real      1028.28 user       157.37 sys
```

FreeBSD/Ryzenでのクロスビルドはこんな感じです。

```
% time rake MRUBY_CONFIG=netbsd

...

37.650u 2.110s 0:40.76 97.5%    36895+1309k 3711+35io 2732pf+0w
```

ビルドにかかる時間が30倍くらい違います。
AWS ipv4でお金かかってるけど、どうすんだ（確認編）

# はじめに
2024/02/01 からAWSでpublic ipのうちipv4のお金がかかるようになりました。

AWSのIPは4種類
1. EC2のパブリックIPアドレス
1. Elastic IPアドレス
1. サービス管理のパブリックIPアドレス
 Amazon ECS、Amazon RDS、Amazon Workspaces のパブリック IPv4 アドレスなど
1. BYOIPアドレス

「2」は元々課金
「1,3」が今回から追加となります

# いくらかかっているかを把握する
## Billing
下記の2つが該当するので調査してみましょう。
結構地味に効く金額なってます。
- In-use public IPv4 address per hour
- Idle public IPv4 address per hour

## Public IP Insights
じゃあどのIPなのかなって調査する場合は本サービスが有効です。

### IPAMの有効化
Amazon VPC IP Address Manager を有効にしておく必要があります。
お使いのリージョンをまとめて有効化します。
無料利用枠でPublic IP Insightsが使えるので、本格的に使う予定が無い場合はこちらを選ぶと良いと思います。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/47012/913575cf-a7cb-f8cd-8693-3997625cddc6.png)

### Public IP Insights
Amazon VPC IP Address Managerが有効になったあとしばらく経つと使えるようになります。
直観的にIPが確認できるので画像等は割愛します。

### サービス管理のパブリックIPアドレスで確認できたもの
確認できたのが下記あたりです。
- Load Balancer
- EC2
- ECS
- RDS

カウントされなさそうなもの
- cloudfront
CloudFormationにCapabilitiesを定義する方法: CAPABILITY_IAM と CAPABILITY_NAMED_IAM

今回は、AWS CloudFormationで使われるCapabilitiesのうち、CAPABILITY_IAM と CAPABILITY_NAMED_IAM について解説します。

### CloudFormationとは

CloudFormationは、AWSリソースのインフラストラクチャをコードで管理するためのサービスです。テンプレートを使用してAWSリソースを定義し、テンプレートを実行することでリソースを作成、更新、削除することができます。

### Capabilitiesとは

Capabilitiesは、CloudFormationがスタックを作成、更新、削除する際に、必要な権限を指定するためのパラメータです。これにより、CloudFormationがスタック内で特定のアクションを実行する際のセキュリティが向上します。

### CAPABILITY_IAM

CAPABILITY_IAM を使用すると、CloudFormationはスタック内でIAMリソース（Identity and Access Management）を作成、変更、削除できるようになります。例えば、IAMロールやIAMポリシーなどのリソースを定義する場合には、この権限が必要です。


### CAPABILITY_NAMED_IAM

CAPABILITY_NAMED_IAM を指定すると、CloudFormationはスタック内で名前付きIAMリソースを作成、変更、削除できるようになります。名前付きIAMリソースは、リソースに固有の名前を指定することができます。これにより、リソースの管理が容易になります。


### CloudFormationにCapabilitiesを定義する方法

Capabilitiesはテンプレートの直下に配置します。以下に、Capabilitiesを適用したテンプレートの例を示します。

```yaml
AWSTemplateFormatVersion: '2010-09-09'
Resources:
  MyIAMRole:
    Type: AWS::IAM::Role
    Properties:
      RoleName: MyRole　
      AssumeRolePolicyDocument:
        Statement:
          - Effect: Allow
            Principal:
              Service: ec2.amazonaws.com
            Action: sts:AssumeRole

Capabilities:
  - CAPABILITY_IAM
  - CAPABILITY_NAMED_IAM
```

このテンプレートでは、スタック内に名前付きIAMリソース（MyRole）を作成しようとしていますので、CAPABILITY_NAMED_IAMを定義する必要があります。また、スタック内にはIAMリソース（ec2.amazonaws.com）に関連付けられたロールを作成しようとしているため、CAPABILITY_IAMを定義する必要があります。


### まとめ

今回は、AWS CloudFormationでのCapabilitiesの一部であるCAPABILITY_IAMとCAPABILITY_NAMED_IAMについて解説しました。これらの権限を適切に使用することで、セキュリティを確保しながらAWSリソースを管理することができます。是非、ご活用ください。