OmniAICreator/Qiita-1.07M huggingface dataset:
Laravelの$〇〇->△△->✗✗();//何言ってるんですか？

# 実践的なアプリの開発の一部の機能をお手伝いしていた時

いつも通り、  
「このパターンはここのコントローラーの中身を流用して、こう作る〜これでOK。」  

と思っていたが、ふと頭によぎる天の声。  

## **「自分で作ったものは説明できるようにしてくださいね。」**  

そう思いながら、  
「これで動くのはなんとなく分かるけど、なんでだ？？？？」  

と思ったのが、下記の部分。

```php
public function create()
{
    Gate::authorize('isCompanyUser');
    $currentUser = auth()->user();

    $omocha = new Omocha();
    $branches = $currentUser->branches();
    $parts = $currentUser->company->parts();
    $manager = $currentUser->company->managers();

    return view('omocha.create', compact('omocha', 'branches', 'parts', 'manager'));
}
```

なんとなく、  
- ユーザーに紐づく支店の情報を取っているんだな〜  
- ユーザーと同じ会社に紐づくパーツを取っているんだな〜  
- ユーザーと同じ会社に紐づくマネージャーさんの情報を取っているんだなー  
- その情報を`omocha.create`に渡しているんだな〜  

と、理解していた。  

---

## **では、なぜこれで取得できるのか？**  

```php
$parts = $currentUser->company->parts();
```

よくわからなかった。  

**「あれ？ `$currentUser->company` って `->` で `$currentUser` のメソッドにアクセスしてるんだよね？」**  

**「あれ？ `$currentUser` ってログインユーザーの情報を保持してるだけじゃないの？」**  

**「メソッドなんてなくない？」**  

```php
company->parts();
```

**「これでなんで紐づいた値が取れるんだ？ テーブルから取得する記述どこだ？？」**  

となってしまった。  

結局、すべてGPTと会話しながら解決していったが、長かった。  

一番理解できたのは **o3-mini-high** を利用した時。  
感覚的に、「君が知りたい箇所を理解するためには、ここから説明しないとダメなんだ」と教えてくれて、すごく助かった。  
それまでは説明系は **4o** を利用していた。  

---

# **なぞるような形で書いていく。**

## **`auth()->user();` について**  

単に「ユーザーのログイン情報を取得している」と思っていた。  

- `auth()` だけでユーザー情報を取得可能。  
- `auth()` の関数の中身の記載は見つからなかったので、「Laravelが用意した関数なんだろう」と理解。  
- `->user()` で現在ログインしている **Userモデルのインスタンス** を作成する。  

**クラスはレシピ、インスタンスは料理** だっけ？  
すでにここで **Userモデルをインスタンス化** していた。  

**「ああ、そういうことか。」**  

```php
$currentUser->company
```

これは、  
「Userモデルの`company`メソッドにアクセスしてくれ！」  
という意味だった。  

---

## **`company()` の中身は**  

```php
return $this->belongsTo(Company::class);
```

このUserは、 **一つのCompanyに紐づいている** と定義されている。  

つまり、 `company()` で `$currentUser` に紐づく **Companyオブジェクト** が取得できる。  

そこに対して、さらに `->parts()` とアクセスすることで、  
Companyモデルに定義されたメソッドを呼び出している。

```php
return $this->hasMany(Parts::class);
```

これは、  
**「このCompanyオブジェクトに紐づく Parts は多数あるよ」**  
という関係を表している。  

---

# **なるほど、アクセスの仕組みとリレーションの関係は分かった。**  

**が、**  

## **なぜテーブルの情報を持ってきているんだ！？**  

## **どこに記述されているんだ！？**  

---

## **それは Eloquent が担っていた。**  

```php
use Illuminate\Database\Eloquent\Model;
```

こんな感じで書かれているはず。  
この **Model を継承** することで、 **リレーションの関係やデータの取得が可能** になるとのこと。  

つまり、 **「この記述があるだけで、関連するデータを自動で取得する」** という仕組みらしい。  
SQLの処理はLaravelに **「任せてOK！」** ってことだった。  

```php
class 〇〇 extends Model
```

この部分で、対応する値が **テーブルから取得** される、ということだった。  

---



自分の中ではかなり詰まっていた問題でしたが、スッキリしました。
Python Djangoでこのエラーが出たときの対処法 「TypeError: can't compare offset-naive and offset-aware datetimes」

# エラー
TypeError: can't compare offset-naive and offset-aware datetimes
Djangoで開発をしている時にこのエラーが出たので，その原因と対処法をメモしておきます．

# 原因
Pythonのdatetimeモジュールを使った時に出会ったエラーになります．
このモジュールには大きく2種類あります．
### offset aware
UTCオフセット（例: +09:00）やタイムゾーン情報を含み，異なるタイムゾーン間での時刻計算が可能

### offset naive
タイムゾーン情報を持たず，ローカル時間として解釈されるため，異なるタイムゾーン間での計算には適さない

これらはデータ操作するときに相容れることができないため，このエラーが発生します．

# 解決策
簡単な解決策として，片方に統一する必要があります．
```python
# naiveからawareへ変換
naive_date = "2025-02-06T14:31:38.464Z" 
aware_date = timezone.make_aware(naive_date)
```
```python
# awareからnaiveへ変換
aware_date = "2025-02-06T14:31:38.464Z" 
naive_date = timezone.make_naive(aware_date)
```

# 実装例
バリデーションでこの変換を活用するのもアリだと思います．
APIの動作確認でcurlとswaggerUIを使っていたのですが，どうやらswaggerUIのデフォルト値がnaiveだったためバリデーションエラーが出ていました．どちらも通して大丈夫なので上記のような場合は変換するように修正しました．
```python
def validate_deadline(self, value):
        if timezone.is_naive(value):  # offset-naive なら変換
            value = timezone.make_aware(value)
        if value <= timezone.now():
            raise serializers.ValidationError("締め切り日時は現在以降である必要があります。")
        return value
```
ClosedXmlをはじめる

# はじめに
C#でExcelを操作するライブラリとして「EPPlus」を使っていましたが、Ver5以降有償になった為「ClosedXml」を検討することになりました。

とりあえず、導入と簡単な操作を纏めます。
実用的な手法は随時追加する予定です。

# 導入
「NuGetパッケージの管理」で「ClosedXML」をインストールします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3779420/69b8eea0-7c5d-7507-4875-acd77dbd35fe.png)

# コード

### usingディレクティブ
```c#
using ClosedXML.Excel;
```
を追加します。

### ファイルを開く
```c#
// 新規作成
var newbook = new XLWorkbook();
// テンプレートファイルを読み込み
var workbook = new XLWorkbook("帳票テンプレート.xlsx");

// テンプレートファイルをExcelで開いているとエラーになるが、
// ClosedXMLで同じファイルを開いてもエラーにならない
var workbook1 = new XLWorkbook("帳票テンプレート.xlsx");
var workbook2 = new XLWorkbook("帳票テンプレート.xlsx");
```

### シートのコピー
```c#
IXLWorksheet templateSheet = workbook.Worksheet("テンプレートシート");
//テンプレートシートを「複製シート」という名前のシートとしてコピー
IXLWorksheet worksheet = templateSheet.CopyTo("複製シート");
```
### シートの削除
```c#
templateSheet.Delete();
```

### セル指定（値代入）
```c#
worksheet.Cell("C2").Value = "セル指定";
worksheet.Cell(2, 5).Value = "行番号、列番号指定";
worksheet.Cell("セル名").Value = "セル名指定";
```

### 行の追加
```c#
// 8行目に5行追加
worksheet.Row(8).InsertRowsBelow(5);
```

### コピー
* 行(列)をコピー
書式：維持される
結合：維持されない
高さ(幅)：維持されない
※1行(列)ずつしかコピーできない

* 範囲をコピー
書式：維持される
結合：維持される
高さ(幅)：維持されない
※最大列(行)数を取得して処理すれば行(列)指定と大差ない

という制限があります。
行(列)のコピーは「範囲をコピー＋コピー元をもとに高さ(幅)を設定」で対応できます。
```c#
//7行目から12行目を13行目から18行目にコピー
// 最大列数を取得
int maxCol = worksheet.LastColumnUsed().ColumnNumber();
//コピー元のセルの指定（7行目1列目～12行目最終列を指定）
IXLRange fromRange = worksheet.Range(7, 1, 12, maxCol);
//コピー先のセルの指定（13行目1列目～18行目最終列を指定）
IXLRange toRange = worksheet.Range(13, 1, 18, maxCol);
//コピーの実施
fromRange.CopyTo(toRange);
// 高さをコピー（13行目～18行目の高さを7行目～12行目を同じにする）
for (int i = 0; i < 6; i++)
    worksheet.Row(13 + i).Height = worksheet.Row(7 + i).Height;

//7行目から12行目を19行目から25行目にコピー（結合は解除される）
for (int i = 0; i < 6; i++)
{
    worksheet.Row(7 + i).CopyTo(worksheet.Row(19 + i));
    worksheet.Row(19 + i).Height = worksheet.Row(7 + i).Height;
}
```

### 罫線の追加
```c#
// 外枠に線を引く
worksheet.Range(8, 2, 10, 4).Style.Border.OutsideBorder = XLBorderStyleValues.Thin;
// 内側に線を引く
worksheet.Range(8, 2, 10, 4).Style.Border.InsideBorder = XLBorderStyleValues.Thin;
```

### セルの結合
```c#
// 8行目の2列目と３列目を結合
worksheet.Range(8, 2, 8, 3).Merge();
```

### ページレイアウト
```c#
// 印刷範囲をクリア
worksheet.PageSetup.PrintAreas.Clear();
// 印刷範囲を追加（"追加"なので、いったんクリアする必要がある）
worksheet.PageSetup.PrintAreas.Add("B60:D70");
worksheet.PageSetup.PrintAreas.Add(58, 3, 65, 5);
```
印刷範囲を重ねることが出来る
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3779420/184b9085-1005-de53-a6ce-757a61619d6c.png)


### 保存
#### 名前を付けて保存
```c#
// 名前を付けて保存
workbook.SaveAs("帳票_XXXX.xlsx");
```
#### Streamで保存
```c#
// Streamで保存 ⇒ byte[]に変換
byte[] ret;
using (MemoryStream ms = new MemoryStream())
{
    workbook.SaveAs(ms);
    ret = ms.ToArray();
}
```

# 関連記事
複数のExcelファイルをzipにしてダウンロード

https://qiita.com/masayasu_t/items/960682709c56eca8c1f2
勢いでo1Proに課金してなにもできなかった話

## 初めに
始まりは5年後にAIに仕事奪われてなくなる～って不安だ～というツイートでした。

で僕が思ったのは以下
> エンジニアって新しいものが好きで好奇心旺盛な奴がなるんじゃねえのかよ  
> AIの波及で、3年後、5年後の仕事がない？ 就職できるか不安？  
> 違うやん。今このクソ面白いゲーム盤のプレイヤーとして、最低限敷居に上がってるんだぞ。  
> そのほか大勢のやつらがうまく扱えないクソ面白い物を理解できる次元にいるんだぞ。  
> なんでそんな悲観的なんだよ。  
> こういう瞬間を求めてエンジニアをやってたんじゃないのかよ。  
> 今だろ。楽しいのは。

## と思ったのが1ヶ月前
勢いで**o1pro**に課金してなにか作ろうと思ったんですが、1ヶ月で**o1Pro**君が生成したサービス案と、環境構築と**o1Pro**君が生成してくれた要件定義と基礎設計までしかできませんでした。


僕はアホです。

## なんでか
理由は大きく3つ
1. **質問を投げている間に集中力が切れてしまう**  
せっかく月3万円払ってるんだからって、ほとんどの質問を **o1Pro** に投げている間にTwitterやYouTubeを見てしまい、そのまま他のことを始めてしまう。気づいたらLoLをやって45分溶かしてる…というパターン。

2. **自分のプロダクト感が皆無**
後述

3. **意外とコード生成はポンコツっぽい**  
ちょこちょこ誤りがあるので、結局人力で修正が必要。まぁ想定内

マジで１個目が痛いね。集中力切れちゃうし、気逸れちゃう。
気づいたらゲームやってる。

で**２個目**
本当o1Pro君とても良いのよ
1個没になった、サービス案を挙げます。
投げた質問は以下のとおり:
```
最短でマネタイズ可能な企画を考えてください。
ただし、企画実現のプレイヤーは
ジュニアのWebエンジニアで市場は日本とします。
```
**o1Pro** の回答（一部抜粋）:
```
企画①：小規模店舗向け「予約管理システム」の月額提供

概要
• ターゲット: 美容室、ネイルサロン、個人経営の飲食店、教室・スクールなど
• サービス内容:
- GoogleカレンダーやLINE公式アカウントなどと連携した予約管理ページ(あるいは簡単な予約アプリ)を制作
- PC・スマホから閲覧/管理できるシンプルなUI
- 月額/年額のサブスクリプション収益

なぜ「最短でマネタイズ」できるか
• 予約管理システム自体の要件は比較的シンプル(名前・希望日時・備考など)なので、
フレームワークやOSSを使って短期間でMVPを開発しやすい
• 小規模店舗側は手頃な導入コストであれば導入意欲が高い
(既存の大手予約サービスは手数料や月額が比較的高い)
• 月額制であれば継続的に収益が入る

開発・運用のイメージ
1. 最小機能(MVP): 店舗管理者用のダッシュボード、予約申し込み用フォーム、
顧客へ自動返信メールorLINEメッセージ機能
2. 初期実装の構成例:
• フロント：Vue.js / Reactなどの軽量SPA
• バックエンド：Firebase / Supabaseなどのサーバーレスか、
Laravel / Railsなどのフレームワーク
• Stripe等でクレカ決済機能を実装(店舗のサブスク料金決済用)
3. 料金プラン:
• 初期導入サポート料金(例: 3万円) + 月額数千円(例: 5,000円)
4. マネタイズのポイント:
• 有料プラン: 予約カレンダーの件数無制限・分析機能などで差別化
• オプション(オリジナルドメイン設定、LINE連携強化など)でアップセル
```

この企画に関しては走り出しでユーザ集まらなさそうだし、結構こういうサービスありそうっていう感じですが、こういうのを５分弱で考えてくれるんだから、すごいよねっていう。
このノリでMVP・要件定義・基礎設計までやってくれます。

企画は結局のところ、自分の趣味関連(ゲーム)のWebアプリ開発にして、o1Pro君に中身を詰めてもらった感じにしてもらいました。
ただね、せっかくの個人開発なのに、なんか俺のサービス感ないんだよね。
これが結構大きくて、企画とかしたことないもんだから、全部お任せってなっちゃうんだよね...。


まぁ、つまり
**要件定義・基礎設計までほぼo1Proに任せきりで、自分のアイデア感が薄れてモチベが下がった。**

## 解決策
### １個目・３個目
１個目と３個目はマジでそのままなので、今ならo3miniとかclaude3.5 sonnetと併用しましょうって感じ。
使ってみたらわかると思うけど、o1Proは上流工程とても優秀。
３万払ってみて欲しい。


### ２個目
絶対につけたい機能を１個自分で考えるっていうのが良いかなと思う。
この機能つけたら絶対気持ちいいじゃん！っていうのがあるとモチベ上がるのと開発中ニヤニヤできる。
こういうのでモチベ保つしかないかも。


## o1Pro君を使ってみた感想(まとめ)
多分みんな言ってると思うけど、コード生成に関しては全然claude3.5sonnetや最近出たo3miniの方が(おそらく)優秀か変わらないぐらい、こちらでバージョン指定して、生成してもらったDockerファイルとかもちょこちょこ間違ってたかな。
回答生成時間はマジで長い。
要件定義・基礎設計とかの生成は本当優秀だと感じました。
上流の方が優秀、o3Proが楽しみだぜ！
AIに依存していく感覚をすごく感じました。

## 終わりに
月々3万円なんか払えるわけないので、現在Plus会員なってしまいましたが、「このままじゃまずい！マジで仕事なくなる！」ということで、来週から毎週Qiitaにアウトプットしちゃうもんね。
進捗あげちゃうもんね。
(
来週記事上がってなかったら死んだと思ってください。
TODOアプリ開発完了後の気づき

# はじめに
Reactを学び始めてから、TODOアプリの開発が完了しました。
その際の気づきについて共有させていただきます。

![Todoアプリモックアップ.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3707255/ceb91d06-0956-54f8-cd46-e561c770c3da.jpeg)

# 使用技術
・React　・Chakra UI V2　・Jest　・Firebase　・Supabase

## 知っていることとできることは違う。
　インプットして知っていることと、できることは全く別物です。
実際にインプットしたことを活用し、また＋αな実装にチャレンジすることでできない部分、理解していない部分が明確になります。私自身、基本の構文の理解も不十分な状態で開発をして、理解できていない記述部分の基本に返ることを行うことで構文の理解も深まりました。何でここは｛｝を使う必要があるのかなど、細かい部分まで疑問を持って調べることが大切だと思いました。
　開発中、実装した回数も必要です。1回の実装だけでは忘れてしまいますし、自分で思っていたよりも浅い理解で終わっていることがあります。環境構築もそうですが、回数を多く経験することでしか得られない気づき、深い理解があります。
 調べたコードのコピペはやらないように意識してみました。コピペすると、頭で考えることをサボる傾向があったためです。まずは手打ちすることで自然と考えながら入力することになり、理解できる部分と理解できていない部分が明確になりやすい印象がありました。手打ち終わったら、そのあと間違いがないようにするためコピペしました。

## 詰まったところは記録に残す
　前回の開発でも痛感しましたが、詰まる時は自分がレベルアップするチャンスです。詰まるということは理解不十分なことが多く、より深く調べることで理解が深まり、知識・技術向上のきっかけになります。そして記録に残すことで自分の記憶にも定着しますし、また同じような個所でつまづいたときに一から調べることもしないで済みます。内容を共有することで、同じような個所で躓いた人の時間を確保することにもつながります。

 ## Chakra UIのモーダル、useFormの便利さ
 　モーダル表示するのがこんなに楽になるとは思いませんでした。過去の開発ではJavascriptで作成したこともあり、とても手間な印象がありましたが、Chakra　UIのドキュメントのコードを貼り付けるだけで表示できてしまったときは少し感動しました。
　そして、react-hoo-formのuseFormでフォーム管理が簡単にできることにも感動しました。
 　見た目での分かりやすさ、ユーザー目線でのボタン配置も意識しました。使いにくいアプリはユーザー離れが顕著になってしまうので。

## 何かを成し遂げるためには何かを犠牲にしなければならない
　これは何にでも言えることだと思いますが、時間は有限であり皆に平等に与えられているものです。人それぞれの環境によって、その時間をどれくらい使えるのかは様々ですが、無駄な行動や不要な行動を見直すことで今までよりも時間を作ることはできるはずです。また隙間時間の活用を意識するだけでも、今までの学習時間を増やすこともできるはずです。私も常に無駄な行動、効率的な行動をしていないか意識して過ごしています。家族の時間など、必要な時間は確保しつつ、自分の行動を見返すことで、何かを我慢（犠牲に）することで時間を確保し、成し遂げたいことに時間を使わない限り、理想のものを手に入れることはできないでしょう。

 # 終わりに
　これからも開発を通したアウトプットで、より理解を深めて、Reactのことを更に知りたい、もっと使えるようになりたいと思いました。
 フロントエンド、バックエンドどちらの理解も深まった時に今までなんとなくしか理解できていなかった部分の、そういうことか！と思える瞬間を期待して、継続していきます。
<br>
 [<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3707255/8bfacf61-7d8d-6d27-cb07-98d1f8f27fcd.png"  width=60%>](https://projisou.jp)
DMMの商品データをAPIからPHPで取得するサンプルコード

DMMの商品情報APIを使って商品情報を取得するPHPのサンプルコード

- キーワード検索用で作成しています
- API IDとアフィリエイトIDを書き換える

![f8dfd64e2e5ed51774933b6da1286aa0.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3520459/6c119581-cc66-f9c4-8558-6ec57ddf4ec6.png)

※DMMの仕様上、アフィリエイトIDの末尾は990～999にする
```PHP
<?php

$api_id = "【 API ID 】";
$affiliate_id = "【アフィリエイトID】";
$keyword = urlencode("上原亜衣");

$api_url = "https://api.dmm.com/affiliate/v3/ItemList?"
    . "api_id={$api_id}"
    . "&affiliate_id={$affiliate_id}"
    . "&site=FANZA"
    . "&service=digital"
    . "&floor=videoa"
    . "&hits=10"
    . "&sort=date"
    . "&keyword={$keyword}"
    . "&output=json";

echo "APIリクエストURL: \n" . $api_url . "\n\n";  // デバッグ用

$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $api_url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);

$response = curl_exec($ch);

if ($response === false) {
    echo "cURLエラー: " . curl_error($ch) . "\n";
}

curl_close($ch);

var_dump($response);  // レスポンスの確認

$data = json_decode($response, true);

if (!$data || !isset($data["result"]["items"])) {
    echo "APIリクエストに失敗しました。\n";
    exit;
}

echo "取得商品一覧:\n";
foreach ($data["result"]["items"] as $item) {
    echo "-----------------------------\n";
    echo "タイトル: " . $item["title"] . "\n";
    echo "URL: " . $item["affiliateURL"] . "\n";
    echo "価格: " . ($item["prices"]["price"] ?? "不明") . "円\n";
    echo "発売日: " . $item["date"] . "\n";
    echo "画像URL: " . $item["imageURL"]["large"] . "\n";
}

?>
```
【Jackson】JsonSerializerで値を変換してシリアライズする場合、defaultSerializeValueを使うべき

# TL;DR
以下のサンプルコードの通りです。
`findValueSerializer`を使った場合、最悪シリアライズ時にエラーが出るため、`defaultSerializeValue`を使うべきです。

```java
@Override
public void serialize(
  Foo value,
  JsonGenerator gen,
  SerializerProvider provider
) throws IOException {
  // 任意の変換処理
  Bar converted = convert(value);

  // 以下のように書くのが望ましい
  provider.defaultSerializeValue(converted, gen);

  // 以下のように書くのはNG
  // provider.findValueSerializer(converted.getClass()).serialize(converted, gen, provider);
}
```

# 状況想定
以下のような状況を想定しています。

- 入力を任意の型に変換してシリアライズしたい
- `ObjectMapper`に登録されているシリアライザーは使いまわしたい
  - 例: `Jackson`からデフォルトで提供されているものや自作した共通シリアライザー

単純に値を書き込むだけで済む場合は、`gen.writeString`や`gen.writeNumber`など、よりシンプルな方法を使うこともできます。

# `defaultSerializeValue`を使うべき理由
単純にシンプルという以外にも、`findValueSerializer`を使った場合にはエラーを引き起こすリスクが有るためです。

## コンテキストが正しく伝播する
`findValueSerializer`を使った場合、表面上は正しく動いているように見えても、実際には`Jackson`のシリアライズに関するコンテキスト伝播の仕組みが上手く働いていません。
これによって、複雑なシリアライズ処理が期待通り動かなかったり、最悪エラーになったりします。

自分はこの方法で`Map`を書き込んだ所、`KeySerializer`が見つからなくなってエラーとなるケースに遭遇したことがあります。

https://github.com/FasterXML/jackson-databind/issues/4928

## `null`の考慮が不要
`defaultSerializeValue`には`null`の考慮が有るため、サンプルコードでいう`convert`が`null`を返した場合を気にする必要はありません。

https://github.com/FasterXML/jackson-databind/blob/a204131005008e42d953a929499089f7f5221218/src/main/java/com/fasterxml/jackson/databind/SerializerProvider.java#L1177-L1182

一方、`findValueSerializer`を使う場合、`null`に対しては`findNullValueSerializer`を使うべきです。
つまり、正確を期するなら以下のように書くべきで、より複雑になります。

```java
// 任意の変換処理
Bar converted = convert(value);

// 正確に書くと、より複雑になって嬉しくない
JsonSerializer<*> ser = converted != null
  ? provider.findValueSerializer(converted.getClass())
  : provider.findNullValueSerializer(null);

provider.findValueSerializer(converted.getClass()).serialize(converted, gen, provider);
```

# 参考
以下で教えて頂きました

https://github.com/FasterXML/jackson-databind/issues/4928#issuecomment-2614567721
【備忘録】rsyslogによる、syslogサーバ構築

# 概要

rsyslogは、シスログなどをサーバに出力するための機能。
AlmaLinux9などでそのまま実装することができる。

今回は、細かいログレベルの指定などは一旦置いておいて、
ログを取得できるようにするところまで実装する。

## 実行環境
AlmaLinux 9.2

## 実装手順
以下のファイルを変更する。
```
sudo vi /etc/rsyslog.conf
```
その後、以下の行を探す
```
#module(load="imudp") # needs to be done just once
#input(type="imudp" port="514")
```
そして、コメントアウトを外す。この場合は、udpによる受信の許可を設定している。すぐ下にtcpもあるので許可してもよい。

次に、ファイルをどこに保存するかを指定する。
今回は以下の場所にtemplateで指定した。これでファイルパスの名前`host_log_filepath`を指定した。%hostname%にて、サーバのホスト名を引数に作成していく。その中で、対象のログファイルを作成するようにしている。

```
template(name="host_log_filepath" type="string" string="/var/log/remote/%hostname%/%hostname%.log")
```
また、このファイルパスを、ルールセットを用いて指定してやる。さきほどコメントアウトしたところを、
```
input(type="imudp" port="514" ruleset="remote")
```
にする。
また、新たにルールセットの関数を作成して、ファイル作成の権限とパスを作る。
```
ruleset(name="remote") {
  action(type="omfile" dynaFile="host_log_filepath" fileCreateMode="0644" dirCreateMode="0755")
}
```
これはルール事に区切っているが、以下リンク先のようにファイル全体で指定することも可能

https://qiita.com/h_tyokinuhata/items/c6733aed3a576a78a38b

以下のコマンドで動作確認ができる。
```
rsyslogd -N 1
```

間違っているときは、行数とともに表示される。
```:実行結果
[ito@test-vmname-1 ~]$ sudo rsyslogd -N 1
[sudo] jst-dito のパスワード:
rsyslogd: version 8.2310.0-4.el9, config validation run (level 1), master config /etc/rsyslog.conf
rsyslogd: End of config validation run. Bye.
```

以下のコマンドで動作確認ができる。
必要な場合は`systemctl restart rsyslog`で再起動させること。
```
sudo systemctl status rsyslog
```

また、udpの514ポートを開放してあげる。今回はちょっと面倒なので、停止させた。
```
sudo systemctl stop firewalld.service
```

その後、このrsyslogサーバに疎通できるネットワーク帯のサーバから、以下のコマンドを実行してテストする。

```
logger -p local0.notice -t test -n 10.26.240.11 "Test log message"
```
catで確認できることを確認する。
```:出力結果
[ito@test-vmname-1 log]$ sudo cat /var/log/remote/office-sboxvh-0188.mgt.stream.jp/office-sboxvh-0188.mgt.stream.jp.log
Feb  4 15:55:48 office-sboxvh-0188.mgt.stream.jp test Test log message
[ito@test-vmname-1 log]$
[ito@test-vmname-1 log]$
```



## 関連リンク

https://qiita.com/sugar_salt75/items/1d1980d5b66becc9f38f

https://isleofhoso.com/linux-rsyslog/
相互参照するクラス

# 相互参照するクラス
コンストラクタで依存関係を注入する設計にしている場合、相互参照をどのように処理するかは頭が痛い問題です。依存関係を整理できれば一番良いのですが、そうはいかないケースもありますよね。

かといって、外部クラスを直接参照するようなコードを書いて、ユニットテストではSpy等で無理やりモックしてしまうとコードはスパゲッティになっていきます。（今日仕事でそんなコードを見てしまい、勢いでこの記事を書いています。）

# LazyIntializerを使った相互参照
LazyIntializerはその名の通り初期化処理を遅延実行するので、相互参照があっても問題なくインスタンスを生成できます。初期化処理はlockによって保護されるので、非同期呼び出しが複数あっても１回だけ実行されます。

インスタンス生成後のアクセスは非同期処理を通らないので高速に実行されます。
[TypeScriptでDouble Checked Lockを使う](https://qiita.com/tomohisaota/items/bce82b53e2ef248143b7)

インタフェイスを注入しておけばテスト時には簡単にモックできますし、簡易的なDI Frameworkとしても利用できます。

```typescript
import {LazyInitializer} from "ya-syn";

class ServiceA {
    constructor(readonly serviceB: LazyInitializer<ServiceB>) {

    }

    async methodA() {
        console.log("methodA called")
        const serviceB = await this.serviceB.get()
        await serviceB.methodB()
    }
}

class ServiceB {
    constructor(readonly serviceA: LazyInitializer<ServiceA>) {

    }

    async methodB() {
        console.log("methodB called")
    }
}

class Provider {
    readonly serviceA: LazyInitializer<ServiceA> = new LazyInitializer(async () => {
        return new ServiceA(this.serviceB)
    })

    readonly serviceB: LazyInitializer<ServiceB> = new LazyInitializer(async () => {
        return new ServiceB(this.serviceA)
    })
}


async function main() {
    const p = new Provider()
    const serviceA = await p.serviceA.get()
    await serviceA.methodA()
}

main()
```

# 実行結果
```
% npx ts-node src/di.ts
methodA called
methodB called
```


# ya-syn
セマフォがあるとTypeScriptでコードを書くのがグッと楽になります。ぜひ使ってみてください。

https://www.npmjs.com/package/ya-syn
VPC Block Pubulic Access でセキュリティを強化する

## VPC Block Pubulic Access（BPA）とは
VPC Block Pubulic Access（BPA）とは、VPCでインターネットトラフィックを制御する機能です。今まではインターネットゲートウェイやセキュリティグループなどでインターネットアクセスを制限していましたが、VPCで制御できるようになりました。
この設定を活用することで意図しないインターネットトラフィックを制御することができ、セキュリティの強化につながります。

### ブロック設定
VPC BPAで設定できる項目は以下の2つです。

* 双方向（送受信ともにインターネットトラフィックをブロック）
* Ingress-only（受信インターネットトラフィックのみをブロック）

この設定を有効にすることで、リージョン内全てのVPCに対して設定が有効になります。インターネットゲートウェイなどの他のリソースでインターネットトラフィックが許可されていたとしてもVPC BPAの設定が優先されます。


### 除外設定
インターネットトラフィックを許可したいリソースに対して除外設定をすることができます。除外の設定にはブロック設定の反対でインターネットトラフィックを許可する方向を選択することができます。

* 双方向（送受信ともにインターネットトラフィックを許可）
* Egress-only（送信インターネットトラフィックのみを許可）


## 設定方法

### AWSコンソール
#### ブロック設定
1. VPCダッシュボード内の右側の「パブリックアクセスをブロック」をクリックする![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3955838/917b8b79-7bdc-a87c-0aa1-f0ad74ef47df.png)
2. 右上の「パブリックアクセス設定を編集」をクリックする![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3955838/56689537-f8c4-dc17-94c7-d4f0be745f5e.png)

2. 「[パブリックアクセスをブロック]をオンにする」にチェックを入れる![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3955838/336721fa-c0eb-c8c9-45e3-a9997e18fc51.png)

2. インターネットゲートウェイのブロック方向を「双方向」か「Ingress-only」のどちらかを選択する![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3955838/919ec6ab-c49f-f3a5-74df-6188cad57d90.png)

2. 「変更を保存」をクリックして設定完了

設定が有効になるまで数分かかります。

#### 除外設定
1. パブリックアクセスをブロックのページの下側にある「除外」の項目の「除外を作成」をクリック ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3955838/014722ed-e7dc-1cd9-d0f1-9465def207d2.png)
1. 除外設定の名前（任意）を入力してインターネットゲートウェイの許可方向を「双方向」か「Egress-only」のどちらかを選択する ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3955838/78ec1f5f-32a1-04c5-ad6c-73a2d714655e.png)
1. 除外設定を適用できるリソースが表示されているので、適用したいリソースのチェックボックスにチェックする
1. 必要であればタグを設定する
1. 「除外の作成」をクリックして設定完了

こちらも設定が有効になるまで数分かかります。

### AWS CLI
リージョンなどは適宜置き換えてください
#### ブロック設定
* インターネットゲートウェイのブロック方向を「双方向」で設定する
    ```
    aws ec2 --region ap-northeast-1 modify-vpc-block-public-access-options --internet-gateway-block-mode block-bidirectional
    ```
    * ブロック方向を「Ingress-only」で設定するには `--internet-gateway-block-mode block-ingress` とします

<br>

*  VPC BPA のステータスを表示する
    ```
    aws ec2 --region ap-northeast-1 describe-vpc-block-public-access-options
    ```

#### 除外設定
* インターネットゲートウェイの許可方向を「双方向」で設定する
    ```
    aws ec2 --region ap-northeast-1 create-vpc-block-public-access-exclusion --subnet-id [subnet-id] --internet-gateway-exclusion-mode allow-bidirectional
    ```
    * 許可方向を「Engress-only」で設定するには `--internet-gateway-block-mode allow-egress` とします

## Security Hub
Security Hubを有効にしている環境ではVPC BPAが設定されてないとコントロールが失敗し、指摘されるようになりました。つまり、AWSとしても設定を有効化することを推奨しているということですね。指摘された場合は設定を有効化するか検討しましょう。

[[EC2.172] EC2 VPC Block Public Access settings should block internet gateway traffic](https://docs.aws.amazon.com/securityhub/latest/userguide/ec2-controls.html#ec2-172)


## まとめ
VPC Block Public Access（BPA）は、VPC単位でインターネットトラフィックを制御できる機能です。ブロックの設定は「双方向」と「Ingress-only」の2種類があり、必要に応じて除外設定も可能です。AWSコンソールやCLIなどで簡単に設定できるため、適切に活用し、セキュリティの強化に役立てていきましょう！
後輩のためのFigma入門（Step7）

# 後輩のためのFigmaの使い方

後輩のためにFigmaに関して書きました。

Step7は「色を極めよう」です。

今回は、色の機能について書きました。
以下の機能ごとに書いたため、知りたい機能をご覧ください。

# 目次
- [カラーコードで設定](#カラーコードで設定)
- [透過](#透過)
- [グラデーション](#グラデーション)



## カラーコードで設定

**Step1** 以下の部分をクリックします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3950744/77c2a7ff-da51-3b35-91b4-b6962647390e.png)

<br> <!-- 空行を追加 -->

**Step2** 以下の部分で色をカラーコードで設定できます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3950744/454e3794-0ffa-a8e2-4555-0debf9b9de34.png)

<br> <!-- 空行を追加 -->

## 透過

**Step1** 以下の部分をクリックします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3950744/77c2a7ff-da51-3b35-91b4-b6962647390e.png)

<br> <!-- 空行を追加 -->

**Step2** 以下の部分で透過させることができます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3950744/92e10862-074e-e04f-f23e-dd8294d31c69.png)

<br> <!-- 空行を追加 -->

## グラデーション

**Step1** 以下の部分をクリックします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3950744/77c2a7ff-da51-3b35-91b4-b6962647390e.png)

<br> <!-- 空行を追加 -->

**Step2** 以下の部分をクリックします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3950744/30777eb6-7955-c741-9bcd-3b070c76227c.png)

<br> <!-- 空行を追加 -->

**Step3** 以下の部分で詳細を設定できます

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3950744/e0804cee-c79f-7f1e-830a-f2a53496fcc2.png)


<br> <!-- 空行を追加 -->

## 続き
今回は、色の詳細設定を解説しました。
次回はマテリアルカラーの導入について解説しようと思います。
【2025年02月版】Sublime Text で 日本語入力中に、F7 キーを使う方法【macOS】

# はじめに

Macの `Sublime Text` で文字入力中に `f7` キーを押しても Sublime Text側で取られて変換できない、時の解決メモ

# 環境

- macOS Sequoia (15.3)
- Sublime Text Build 4192

# 設定方法

- メニューから、`Settings` -> `Key Bindings` を選択

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/143127/6e402127-9754-8dcf-bd58-838776dc8d2d.png)

- `Key Bindings` が設定できそうな画面が開く、右ペインに入力したらなんとかなりそうだけど、ならない
- 左側のペインは編集できない

:::note info
`f7` のエントリーを右側ペインでコメントアウトしてみたり、`noop`に設定して、再起動してみたけどならない
:::

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/143127/98e8bdbb-79ac-f432-1492-fdd07496aa3f.png)

- 左側のペインを選択して ( <- ここが重要 )、`File` -> `Save As` を選択

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/143127/db5aaa50-b581-0eeb-c483-cc19924019db.png)

- `/User/ユーザ名/Library/Application Support/Sublime Text/Packages` の下に `Default` ディレクトリを作成して、`Save`

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/143127/43e9bb12-88e4-7b75-a741-190d4e736a51.png)

- この `Save` の後は左側ペインが編集できるようになる
- `f7` を検索してコメントアウト

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/143127/cff1b8ef-4199-590f-0a1f-497ab9d1fe29.png)

- `Sublime Text`を再起動する
- IMEの入力中に、`F7` キーで変換できるようになる
- 他のキーも同じように設定できる
- VSCode か Vim でいいよねってなりがち

# さいごに

かんたんでしたね
【要約】リーダブルコード - 読みやすいコードを書くためのシンプルなテクニック

プログラマーにとって、コードは書くだけではなく「読む」ことが必須です。しかし、自分や他の開発者が読みやすいコードを書くことは意外と難しいですよね。

そこで『リーダブルコード』は、読み手の負担を減らし、知的コストを低減させるための実用的なテクニックを紹介しています。

## ☞ より良いコードを書くための基本原則
1. **コードは動けばいいわけではない**  
   → 「読む人」が知的コストなしに理解できることが大事  
2. **コードはコメントで説明するのではなく、そのもので明確にする**  
   → 意図が伝わるような名前を付け、過度なコメントは使わない  
3. **複雑さを出しても、隠してはいけない**  
   → 作者だけが理解できるコードはNG  

## ☞ 読みやすいコードを書くポイント
### 1. いい名前をつける
- **曖昧な名前を避ける**  
  NG: `d`, `tmp`, `processData`  
  OK: `elapsedTime`, `formattedUserName`, `calculateTotalPrice`
- **動詞を使う**  
  例: `getUser()`, `fetchData()`, `updateStatus()`
- **同じ意味のものに同じ名前を使う**  
  (一緒に使われる名前を統一する)

### 2. 知的コストを低減する
- ネストを深くしすぎない  
  NG:
  ```python
  if user.is_admin:
      if user.has_permission:
          if user.is_active:
              perform_task()
  ```
  OK:
  ```python
  if is_authorized(user):
      perform_task()
  ```
- コードを短くする  
  (関数やクラスは一つのことだけするようにする)

### 3. 早めに脱出する
- 重いネストを避けるために `return` や `break` を活用  
  NG:
  ```python
  def validate(user):
      if user:
          if user.is_active:
              return True
      return False
  ```
  OK:
  ```python
  def validate(user):
      if not user:
          return False
      return user.is_active
  ```

## ☞ あとがき
『リーダブルコード』は、簡単な実装テクニックでも、いかに読み手に伝わりやすくするかを紹介しています。

実際のコードを見ながら、どんな要素があると読みやすいのかを検討してみましょう。

---
☞ **この記事が良かったら、スキ、コメントよろしくお願いします🙏**
【PowerShell】指定したフォルダのNTFSアクセス許可を取得するスクリプト

上位層のフォルダのNTFSアクセス許可を取得したい時によく利用しているPowerShellスクリプト。

```
#NTFSアクセス許可を取得したいフォルダ
$path = "¥¥Folder"

#$pathから何階層までNTFSアクセス許可を取得するか
#0だと、指定したフォルダから1つ下の階層まで
#1だと、指定したフォルダから2つ下の階層まで
$depth = 0

#結果の出力先
$result = "¥¥Folder/faile.csv

#NTFSアクセス許可を取得する
Get-ChildItem -Recurse -Depth $depth $path | Get-Acl | Select-object @{label="Path";Expression={Convert-Path $_.Path}},AccessToString | Export-Csv $result -encoding Default
```
医科レセプト電子化とカルテ電子化の比較とその背景から柔整施術録電子化の糸口を考える（開発日誌＃4）

## 1. レセプト電子化とカルテ電子化の共通点

レセプト（診療報酬明細書）の電子化とカルテ（診療録）の電子化は、どちらも医療業界におけるデジタル化の流れの中で推進されてきた。  
これらの電子化には、以下のような共通の目的と背景がある。

### **1-1. 共通する目的**
| 目的 | レセプト電子化 | カルテ電子化 |
|------|--------------|------------|
| **業務の効率化** | 医療機関の請求業務を簡略化し、手作業の負担を軽減 | 医師や医療スタッフの記録作業を効率化 |
| **コスト削減** | 紙レセプトの管理・保管コストを削減 | 紙カルテの保管スペースを削減し、管理コストを低減 |
| **診療情報の標準化** | 全国的な統一フォーマット（電子レセプトフォーマット）を採用 | 医療情報のデジタル化により、診療の統一基準を確立 |
| **検索・参照の迅速化** | デジタルデータで迅速に過去の請求履歴を確認可能 | 過去の診療情報を素早く参照し、診療の質を向上 |
| **データ解析・活用** | 医療費の適正化・不正請求防止に活用 | 診療データを蓄積し、診療の質向上やAI診断に応用 |

---

## 2. レセプト電子化の流れと影響

### **2-1. レセプト電子化の歴史**
| 年代 | 主な出来事 |
|------|---------|
| **1994年** | 「エックス線写真等の光磁気ディスク等への保存について」の通知で、医療情報の電子保存が部分的に認められる |
| **1999年** | 「診療録等の電子媒体による保存について」の通知により、電子カルテの使用が正式に認可 |
| **2000年** | 電子レセプトの試験運用開始 |
| **2008年** | レセプトオンライン請求義務化（段階的に導入） |
| **2011年** | レセプトの電子化率が90%を超える |
| **2024年～** | マイナンバーカードを活用したオンライン資格確認が本格運用開始 |

### **2-2. レセプト電子化のメリット**
- **請求業務の自動化**：手作業による入力ミスを防ぎ、請求処理のスピードを向上
- **審査の効率化**：電子データによる自動チェック機能の強化
- **保険者との連携強化**：オンライン請求により、資格確認や支払処理が迅速化
- **医療費適正化**：不正請求の防止とレセプトデータの分析による医療費削減

### **2-3. レセプト電子化の課題**
- **小規模医療機関の対応**：レセプト電子化のための設備投資が負担に
- **プライバシーの確保**：電子データの改ざん・不正アクセスのリスク
- **審査基準の不透明性**：支払基金・国保連の審査基準が明確でないとの指摘

---

## 3. カルテ電子化の流れと影響

### **3-1. カルテ電子化の歴史**
| 年代 | 主な出来事 |
|------|---------|
| **1999年** | 「診療録等の電子媒体による保存について」の通知により、電子カルテの使用が正式に認可 |
| **2005年** | 「e-文書法」の施行により、紙カルテをスキャナで電子化して保存することが可能に |
| **2010年** | 電子カルテ普及率が急増し、大規模病院の多くで導入が進む |
| **2020年～** | クラウド型電子カルテが登場し、院外からのアクセスが可能に |

### **3-2. カルテ電子化のメリット**
- **診療情報の共有**：医師・看護師・薬剤師間でリアルタイムに情報共有が可能
- **業務の効率化**：手書き記録の省略により、診療業務の負担が軽減
- **医療安全性の向上**：アラート機能により、薬剤の重複処方やアレルギー反応を防止
- **診療データの活用**：過去の診療履歴をAIが解析し、診断支援が可能に

### **3-3. カルテ電子化の課題**
- **導入コストの高さ**：電子カルテシステムの導入費用が大きく、小規模クリニックでは負担に
- **データの互換性問題**：異なる電子カルテシステム間でデータのやり取りが難しい
- **災害時のデータ保全**：停電やシステム障害時に診療記録が閲覧できないリスク

---

## 4. レセプト電子化とカルテ電子化の相違点

| 項目 | レセプト電子化 | カルテ電子化 |
|------|--------------|------------|
| **目的** | 診療報酬の請求・審査 | 診療記録の管理・共有 |
| **推進主体** | 厚生労働省・支払基金・国保連 | 厚生労働省・医療機関・ITベンダー |
| **導入の義務** | 2008年から義務化 | 義務ではないが、普及が進む |
| **影響** | 医療機関の請求業務を効率化、保険者の支払処理を迅速化 | 診療の質向上、医療の安全性向上 |
| **主な課題** | システム導入コスト、審査の透明性 | データ互換性、運用コスト |

---

## 5. まとめ
- **レセプト電子化とカルテ電子化は、医療のデジタル化の流れの中で並行して進んできた**。
- **どちらも医療機関の業務効率化、コスト削減、診療情報の標準化を目的としている**。
- **レセプト電子化は「診療報酬の請求」に関わるもので、医療機関にとって義務化されている**。
- **カルテ電子化は「診療記録の管理」に関わるもので、まだ義務ではないが普及が進んでいる**。


柔整師も電子施術録のガイドラインが作成されれば，レセプト電子化も進むのでは？
ゲームを終了しても数値を保存する コピペ可能！

# はじめに
- Unityでゲームを終了しても数値を保存する方法を記録として残します。めっちゃ簡単なので**コピペ可能です！**

# 目次
1. **どんな機能を作成したかの概要**
1. **実際のコード**
1. **保存した値の編集方法**

# どんな機能を作成したかの概要
- 作成した機能は下記のGIF画像の通りです。ボタンを押すと画面上の数字が増加します。そしてUnityの実行を切ると普通は画面上の数字は初期化されるはずですが、前回の実行時の数字の値を保存したままUnityが実行されます。

![画面録画 2025-02-04 201959.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3758326/35078eb1-0060-f5b6-ed41-082f9f5e7e04.gif)

# 実際のコード
- 実際のコードは下記のスクリプトを使用します。
```c#:TestForPlayerPrefs.cs
using UnityEngine;
using UnityEngine.UI;
using TMPro;

public class TestForPlayerPrefs : MonoBehaviour
{
    // インスペクターで Button と TextMeshProUGUI を紐付ける
    [SerializeField] private Button counterButton;
    [SerializeField] private TextMeshProUGUI counterText;

    // PlayerPrefs で使用するキー
    private const string COUNTER_KEY = "CounterValue";
    // 現在のカウンター値
    private int counter = 0;

    private void Start()
    {
        // 保存されたカウンター値を取得（なければ 0 を初期値とする）
        counter = PlayerPrefs.GetInt(COUNTER_KEY, 0);
        UpdateCounterText();

        // ボタンのクリックイベントにリスナーを登録
        counterButton.onClick.AddListener(OnCounterButtonClicked);
    }

    /// <summary>
    /// ボタンがクリックされたときの処理
    /// </summary>
    private void OnCounterButtonClicked()
    {
        // カウンターを 1 増加させる
        counter++;
        UpdateCounterText();

        // PlayerPrefs に保存
        PlayerPrefs.SetInt(COUNTER_KEY, counter);
        PlayerPrefs.Save();
    }

    /// <summary>
    /// TextMeshPro のテキストに現在のカウンター値を反映する
    /// </summary>
    private void UpdateCounterText()
    {
        counterText.text = counter.ToString();
    }
}

```

- **PlayerPrefsを使用して値を保存する**
    - 以下のコードで値の保存の処理を行っています。**PlayerPrefsのSetInt関数とSave関数を用いることでCOUNTER_KEYという文字列をキーとして保存されます**。
    ```c#:TestForPlayerPrefs.cs
    PlayerPrefs.SetInt(COUNTER_KEY, counter);
    PlayerPrefs.Save();
    ```

    :::note info
    この値の保存先はプロジェクトのフォルダ内に何かファイルが生成されて保存されるわけではなく、**通常Windowsの場合はレジストリに保存されます**。

- **PlayerPrefsを使用して値をロードする**
    - 以下のコードで値のロードを行います。**PlayerPrefsのGetInt関数を用いることでCOUNTER_KEYという文字列をキーとした値をロードしています**。
    ```c#:TestForPlayerPrefs.cs
     // 保存されたカウンター値を取得（なければ 0 を初期値とする）
        counter = PlayerPrefs.GetInt(COUNTER_KEY, 0);
    ```
## 保存した値の編集方法
- このPlayerPrefsを使用して保存した値は**Unityのスクリプトから編集するのが一般的です**。
- 具体的には以下のコードのように実装して編集します。

```c#:TestForPlayerPrefs.cs
if (debugOverride)
{
    counter = 0;
    PlayerPrefs.SetInt(COUNTER_KEY, counter);
    PlayerPrefs.Save();
    Debug.Log($"[DEBUG] Counter を {counter} に上書きしました");
}
```

- レジストリからの閲覧・編集もできますが外部エディタを使用する必要があるので手間がよりかかります。

# まとめ
- 今回はセーブ機能に関してまとめました。なにやらUnity内にデータを保存したりするにはJSONファイルを用いて保存するのが一般的なようなのでそちらに関しては別の記事でまとめます。
システムアーキテクト合格への道　２

# 【情報処理技術者試験】要件定義フェーズの詳細解説

## 要件定義フェーズとは？
要件定義フェーズは、**企画フェーズで決定したシステムの目的や方針を基に、具体的なシステム要件を定義するプロセス**です。このフェーズの質がシステムの成功を左右し、不十分な要件定義は開発途中での手戻りを引き起こす可能性があります。

---

## 1. 要件定義フェーズの目的
- システムの機能と非機能要件を明確にする
- ステークホルダー間で合意形成を行う
- 開発工程での変更を最小限に抑える

---

## 2. 要件定義フェーズの主な活動

### ① 機能要件の定義
- ユーザーが求める機能の洗い出し
- 業務フローに沿った機能整理
- ユースケース図（UML）を用いた可視化

### ② 非機能要件の定義
- **性能要件**（処理速度、応答時間）
- **可用性**（稼働率、障害時の復旧時間）
- **セキュリティ要件**（アクセス制御、データ暗号化）

### ③ 業務要件の整理
- 関係者（ステークホルダー）とのヒアリング
- 既存業務プロセスの課題と改善点の特定
- 業務ルールの文書化

### ④ システム方式の検討
- クラウド vs オンプレミスの選定
- データベースの構造設計（RDB, NoSQL）
- API連携や外部システムとのインターフェース仕様策定

### ⑤ 要件定義書の作成とレビュー
- ユーザーストーリーの作成
- 各要件の優先度付け
- ステークホルダー間のレビューと合意形成

---

## 3. 要件定義フェーズの成果物
| 成果物 | 内容 |
|---|---|
| **要件定義書** | システムが満たすべき機能・非機能要件を記述 |
| **ユースケース図** | ユーザーとシステムの関係を可視化 |
| **データフローダイアグラム (DFD)** | システム内のデータの流れを表現 |

---

## 4. 要件定義フェーズの重要ポイント
✅ ユーザーの業務ニーズを正確に反映すること
✅ ステークホルダー間の合意形成を確実に行う
✅ 要件変更を最小限に抑えるための十分な検討
✅ 視覚的な資料（ユースケース図、DFD）を活用し、わかりやすく整理する

---

要件定義フェーズは、システムの骨格を決定する重要なプロセスです。精度の高い要件定義を行うことで、開発の効率化とシステム品質の向上が期待できます。この知識を試験対策に役立てましょう！
円環状の配列探索を簡単に!

## 今回の問題
https://paiza.jp/works/mondai/b_rank_new_level_up_problems/b_rank_new_level_up_problems__get_richer_sushi

**「数値がN個入っている配列から連続したX個を取り出して合算したとき、最も高い合算値はいくらか」** といった問題です。

## 背景にある考え方
回転寿司のレーンのような**円環状の配列**を扱う場合、**配列のインデックスが範囲を超えたときに最初に戻る**という操作をどう効率的に処理するかがポイントになります。

例えば、N 枚の寿司が並んでいるとき、インデックスが N を越えると、処理としては **0 番目に戻りたい** という状況です。このような場合に使われるのが **「剰余」** の計算です。

## 剰余を使うと
インデックスが配列の範囲を越えた場合、**剰余(%)** を使うと**配列の先頭** に戻ることができます。
例えば、**配列の長さが 5** のとき。
インデックスが 5 になると範囲外参照となりますが、**インデックス % 配列の長さ**を計算すると**5 % 5 = 0**となり、インデックスが**先頭に戻り**ます。
**6** になっても **6 % 5 = 1** 、**7**になっても **7 % 5 = 2** のように、配列内のインデックスに変換できます。
これを利用すると、円勘定の配列を簡単に探索できるようになります。

## 剰余を活用したコード例
```java
import java.util.*;

public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);

        int N = sc.nextInt(); // 寿司の枚数
        int K = sc.nextInt(); // 取る寿司の枚数
        int[] P = new int[N];

        // 寿司の価格を入力
        for (int i = 0; i < N; i++) {
            P[i] = sc.nextInt();
        }

        // 最初のK枚の寿司の合計を計算
        int currentSum = 0;
        for (int i = 0; i < K; i++) {
            currentSum += P[i];
        }

        // 最大合計金額
        int maxSum = currentSum;

        // スライディングウィンドウで次のK枚の合計を計算
        for (int i = 1; i < N; i++) {
            // 剰余演算を使って、円形の配列を扱う
            currentSum -= P[i - 1]; // 前の寿司を引く
            currentSum += P[(i + K - 1) % N]; // 次の寿司を足す

            // 最大合計金額を更新
            maxSum = Math.max(maxSum, currentSum);
        }

        // 結果を出力
        System.out.println(maxSum);
    }
}
```
**(i + k - 1) % n**が今回の注目ポイントです。

**i + k - 1:**

これは、**i 番目の寿司から K 枚目の寿司**を見つけるための計算です。

**% n:**

**インデックスが配列のサイズ n を越えたとき**に、再び 0 番目に戻すために、**剰余**を取ります。**i + k - 1 が n より大き**ければ、それを n で割った余りを取ることで、**インデックスが配列内に収まる**ようになります。

**ちなみに**
今回の式でfor文条件iの初期値は1となっていますが、これは**スライディングウィンドウ法**を用いているためです **(別記事で解説しています)**。
初期値を0とした場合でも実装は可能ですが、最初のK枚の寿司の合計をもう一度計算することになってしまい無駄な計算となります。

## まとめ
剰余を使うと、**円環状にの配列探索をシンプルに**実装できるようになります。
ぜひ使ってみてください!
ServiceNowのAPIドキュメントの確認方法

# ServiceNow の API（Application Programming Interface） 
外部システムやスクリプトから ServiceNow のデータや機能を操作できる仕組み

# ServiceNowが提供しているAPIを確認する方法
- ServiceNow Developerと検索
- 個人インスタンスを開く
![1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3624279/cbd59264-a479-eec9-715e-bebe013a0187.png)

- 上部のメニューのReferenceを押下
![2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3624279/0a22b2e1-4442-0a8d-922c-75c7a0105abf.png)

- Clientを押下
![3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3624279/8426edd4-7c98-f9d2-fa52-9aa309d0d6bd.png)

- ServiceNowが提供しているclient-sideのJavaScript APIsが見れる
-
システムアーキテクト合格への道　１

# 【情報処理技術者試験】システムアーキテクト試験のシラバス解説

## システムアーキテクト試験とは？
システムアーキテクト試験 (System Architect, SA) は、情報処理技術者試験の高度試験の一つです。システム開発の上流工程を担う技術者を目指し、**要件定義やシステムの構造設計を統括するロールに求められる知識やスキルを問います。**

---

## 1. 企画フェーズ (システム化構想・計画) の詳細解説

### 【目的】
企画フェーズは、**システムの目的を明確化し、実装方針を決定するプロセス**です。この段階での誤った方針決定は、後の開発段階での大きな問題になりかねません。

### 【主な活動】
1. **現状分析 (As-Is)**
   - 実際の業務プロセスを解析
   - 存在するシステムの問題点を指摘
   - BPMN, DFD を使った可視化

2. **目標設定 (To-Be)**
   - 導入するシステムのゴールの明確化
   - KPI, KGI の設定
   - システム実現のシナリオを計画

3. **システム化の方針決定**
   - オンプレミスとクラウドシステムの選択
   - 基盤技術の検討
   - システムのコスト分析 (ROI, TCO)

4. **リスクと定量的分析**
   - 実現可能性の検討
   - 問題発生時のリスクマネジメント

5. **関係者の合意形成**
   - 上級経営層とステークホルダー間の論話
   - システム化構想書の作成
   
### 【成果物】
| 成果物 | 内容 |
|---|---|
| システム化構想書 | システムの目的、範囲、影響を記述 |
| 業務フロー図 | As-Is / To-Be の流れを可視化 |
| ROI / TCO 分析 | 計画されたコスト効果を分析 |

---

企画フェーズの性質を深く理解していれば、システム開発の上流工程での決定が確実になります。この知識を試験対策に活用しましょう。
gpt-4o-miniとtavilyを使って、今日の天気を聞いたら、別の日付が返ってきた件

# 日付指定なしでは特定の日の天気情報が取得できない理由とその対策

本記事では、LangChain や Tavily API を利用して天気情報を取得する際に、**日付を指定しなければ特定の日付の天気情報を取得できない** という挙動について解説します。実際のコード例と出力例をもとに、その理由や仕組み、そして対策について説明します。

---

## 背景

今回のサンプルコードでは、**LangChain** のランナブル（runnables）と **TavilySearchAPIRetriever** を組み合わせて、ユーザーの質問から文脈（この場合は天気情報）を取得し、**ChatOpenAI** モデルに問い合わせるチェーンを構築しています。

### サンプルコード（抜粋）

以下は、東京の天気情報を取得するためのサンプルコードです。

```python
!pip install tavily-python==0.5.0

from langchain_core.prompts import ChatPromptTemplate
from langchain_openai import ChatOpenAI
from langchain_community.retrievers import TavilySearchAPIRetriever
from langchain_core.runnables import RunnablePassthrough
from langchain_core.runnables import StrOutputParser  # 出力の文字列化用のパーサー

# プロンプトの定義
prompt = ChatPromptTemplate.from_template('''\
以下の文脈だけを踏まえて質問に回答してください。

文脈: """
{context}
"""

質問: {question}
''')

# モデルの初期化
model = ChatOpenAI(model_name="gpt-4o-mini", temperature=0)

# 検索リトリーバーの初期化（上位3件を取得）
retriever = TavilySearchAPIRetriever(k=3)

# チェーンの構築
chain = (
    {"context": retriever, "question": RunnablePassthrough()}
    | prompt
    | model
    | StrOutputParser()
)
```

## 質問の内容と取得結果の違い
上記のチェーンに対して、異なる質問を実行した例を示します。

### 例1: 日付指定なしの質問
```python
output = chain.invoke("東京の今日の天気は？")
print(output)
```
出力例:
```scss
東京の今日、11月19日(火)の天気は「晴時々曇」で、最高気温は13℃、最低気温は8℃です。降水確率は0％です。
```
今日は、2025/2/4であるため、この天気はおかしいです。

### 例2: 日付指定ありの質問
```python
output = chain.invoke("東京の2025/2/4の天気は？")
print(output)
```
出力例:
```scss
2025年2月4日の東京の天気は、晴れる日が多く、空気が乾燥しているとされています。具体的な気温については、最高気温が12.2°C、最低気温が2.8°Cと記録されています。
```

この場合、質問文に「2025/2/4」という具体的な日付が含まれているため、その日付の天気情報が取得されています。

つまり、検索エンジン自体は、正しく動作しているのですが、「今日」という日付の解釈をどこかの処理で間違えている可能性があります。ちょっとこれの原因は分かり次第更新します。
システムアーキテクト合格への道

# 【情報処理技術者試験】システムアーキテクト試験のシラバス解説

## システムアーキテクト試験とは？
システムアーキテクト試験 (System Architect, SA) は、情報処理技術者試験の高度試験の一つです。システム開発の上流工程を担う技術者を目指し、**要件定義やシステムの構造設計を統括するロールに求められる知識やスキルを問います。**

---

## 試験の構成
システムアーキテクト試験は、**午前、午後I、午後II**の3つの部分から成り立っています。

### 【午前I (AM1)】
- 高度試験共通の基礎問題
- 効果的な勉強法: 過去問を解きながら基礎知識を学習

### 【午前II (AM2)】
- システム開発の上流工程に関する問題
- アーキテクチャ設計、要件定義、システム構造設計など

### 【午後I (PM1)】
- 詳細な設計や要件定義に関する記述形式問題
- UML、DFD、ユースケース設計などの設計技法

### 【午後II (PM2)】
- システム設計に関する論述問題
- 問題の解決方法やアーキテクチャ設計の進め方について記述

---

## シラバスに基づく問題カバーレンス

### **1. 企画フェーズ (システム化構想・計画)**
- 現状分析 (As-Is)、目標設計 (To-Be)
- ビジネスモデル化の手法 (BPMN, DFD)
- 企業メリットとITシステムの関係性

### **2. 要件定義フェーズ**
- 機能要件 / 非機能要件の整理
- ユースケースに基づく必要機能の決定
- システム形態化の利益分析

### **3. 設計フェーズ**
- 基本設計 (アーキテクチャ設計, DB設計)
- 詳細設計 (クラス図, シーケンス図)
- 外部インターフェースの設計

---

## おわりに
システムアーキテクト試験は、システムの構造設計を統括する技術者にとってとても重要な試験です。

この記事が勉強の参考になれば幸いです！
応用情報に合格するために

# はじめに
IPAの応用情報技術者試験を効率的に短時間で合格するための方法について記載していきます。
※ただし、十分な時間をかけて学習することが理想的であることに留意してください。

## 午前試験対策

午前試験は4択のマークシート形式で80問出題されます。効率的な対策方法は以下の通りです：

1. **過去問の徹底活用**
   - 「応用情報技術者試験ドットコム」などのウェブサイトを利用し、約1000問の過去問を解く。
   - 約半数の問題が過去問から流用されるため、過去問の暗記が非常に効果的。

2. **スキマ時間の活用**
   - スマートフォンアプリなどを使用し、隙間時間に過去問を解く。

3. **不明点の即時調査**
   - 分からない問題は都度調べ、理解を深める。

## 午後試験対策

午後試験は記述式で、5つの大問（1問必須、4問選択）から構成されています。効率的な対策方法は以下の通りです：

1. **得意分野の選定**
   - 最新の午後試験の全大問を解き、得意な4つの大問を選択。
   - 例えば、経営戦略、プログラミング、システムアーキテクチャ、組込みシステム開発などが比較的取り組みやすい場合がある。

2. **選択した大問に集中**
   - 選んだ大問のみに絞って解説書籍を使用し、集中的に学習。

3. **解答の書き方の習得**
   - 解説書籍を活用し、午後試験の文章の読み方や解答の書き方を身につける。

## 全体的な戦略

1. **時間配分の最適化**
   - 午前試験と午後試験それぞれ150分の時間配分を事前に計画。

2. **合格ライン意識**
   - 午前・午後ともに60%以上の得点で合格となるため、この基準を意識して学習。

3. **集中的な学習期間の設定**
   - 可能であれば、1週間程度の集中的な学習期間を設ける。

4. **基礎知識の確認**
   - 特に初学者の場合、基本的なIT知識の確認が必要。

効率的な学習を心がけつつも、可能な限り十分な時間をかけて学習することが、知識の定着と長期的な成長につながります。短期間での合格を目指す場合は、上記の方法を参考にしながら、自身の状況に合わせて最適な学習計画を立てることが重要です。

# 午後試験における大問の選び方

## 試験構成と選択方法

応用情報技術者試験の午後試験は、全11問の大問から構成されています。このうち、以下のように解答する必要があります：

1. 必須問題：「問1. 情報セキュリティ」は全員が解答しなければなりません。

2. 選択問題：残りの10問から4問を自由に選択して解答します。

## 効果的な選択のポイント

### 1. 得意分野を事前に絞る

- 試験当日までに自身の得意分野を見極め、どの科目で合格を狙うかを決めておくことが重要です。
- 4〜5つのテーマに絞り込んでおくことで、試験当日の選択時間を節約できます。

### 2. 選択可能な科目

選択問題には以下の科目が含まれます：

- 経営戦略、情報戦略、戦略立案・コンサルティング技術
- プログラミング
- システムアーキテクチャ
- ネットワーク
- データベース
- 組み込みシステム開発
- 情報システム開発
- プロジェクトマネジメント
- サービスマネジメント
- システム監査

### 3. 時間配分を考慮

- 午後試験は150分間で合計5問（必須1問＋選択4問）を解答する必要があります。
- 各問題にどれくらい時間をかけるか、事前に計画を立てておくことが重要です。

### 4. 文系・理系の傾向を考慮

- 文系寄りの受験者は、経営戦略、プロジェクトマネジメント、サービスマネジメント、システム監査などの分野を選択するのが有利かもしれません。

## 午後問題のまとめ

応用情報技術者試験の午後試験では、自分の得意分野に合わせて選択する分野を事前に決めておくことが推奨されます。十分な準備と戦略的な問題選択により、効率的に得点を重ね、合格を目指すことができます。




以上
共通鍵暗号方式勉強メモ

# 共通鍵暗号方式の概要
### 1.同じ鍵の使用
暗号化と復号に同じ鍵を用いるのが最大の特徴です。
そのため、送信者と受信者は事前に何らかの方法で同一の鍵を共有しておく必要があります。

### 2.主要なアルゴリズム
###### DES (Data Encryption Standard)
1977年にアメリカ政府標準として採用された歴史のある方式。鍵長が56ビットと短いため、現在では安全性の問題から非推奨となっています。

###### 3DES (Triple DES)
DESを3回適用することで安全性を高めた方式。鍵長は最大168ビットになりますが、演算負荷が大きくなりがちです。

###### AES (Advanced Encryption Standard)
DESの後継として採用された標準規格。128ビット、192ビット、256ビットの鍵長をサポートし、現在では最も広く使われています。

###### RC4
ストリーム暗号の代表例ですが、アルゴリズムに脆弱性が見つかったため、現在ではあまり推奨されていません。

### 3.使用例
・大容量データの暗号化
・VPNや無線LAN（WPA2など）のデータ暗号
・ディスク暗号（フルディスク暗号化）やファイル暗号
・SSL/TLSのセッション暗号（鍵交換後に通信を暗号化するとき）
　などでよく使用されます。

# メリット
###### ・処理速度が速い
公開鍵暗号方式（非対称鍵暗号方式）と比べて演算処理が軽量で、速度が速いことが最大のメリットです。大容量のデータやリアルタイム通信の暗号化に向いています。

###### ・実装が比較的容易
アルゴリズムにもよりますが、共通鍵暗号方式は比較的実装が容易であり、広く普及しているため、高速なライブラリが整備されていることが多いです。

###### ・同じ鍵を用いるシンプルさ
鍵管理が十分に行われる環境では、暗号化と復号に同じ鍵を使うというシンプルな構造は、運用を行いやすい場合があります。

# デメリット
###### ・鍵配送の問題
暗号化と復号に同じ鍵を使うため、通信を始める前に安全な手段で鍵を共有する必要があります。大規模なシステムや初対面の相手との通信では、この鍵配送が大きな課題となります。

###### ・鍵管理のリスク
万が一、共通鍵が漏洩すると、その鍵で保護されたすべての通信内容が解読されるリスクがあります。したがって、鍵の管理と更新には厳重な対策が必要です。

###### ・多人数間通信には不向き
グループ通信など、多数の相手と安全に通信する場合、それぞれの相手ごとに異なる鍵を管理する必要があり、運用が複雑になります。一つの鍵を共有すると、一人が漏洩した場合、全員の通信が危険にさらされる可能性があります。

###### ・認証の仕組みが別途必要
共通鍵を持っている相手が本当に正当な相手なのかを確かめるために、メッセージ認証コード (MAC) や HMAC などの手段を使って正当性や改ざん検知を行う必要があります。共通鍵の配布と同時にこれらの認証方法を考える必要があります。

# ハイブリッド方式の利用
実際のセキュリティシステムでは、公開鍵暗号方式と共通鍵暗号方式を組み合わせることが一般的です。たとえば、最初に公開鍵暗号を利用して安全に共通鍵を交換し、その後は高速な共通鍵暗号を使って大量のデータを暗号化するという方法が取られます。これにより、双方の方式のメリットを活かし、安全かつ効率的な通信が可能になります。
【電脳少女プログラミング2088 ─壊レタ君を再構築─】D:データセンターをやってみた。

# はじめに
paizaの新作プログラミングゲーム【電脳少女プログラミング2088 ─壊レタ君を再構築─】データセンター（paizaランク：D相当）をやってみました。

https://ppg.paiza.jp/denno2088/challenges/denno2088_s_d_01

# 問題
 あなたはデータセンターへアクセスしすべての人物の一覧を得ようとしています。

memory (記憶) テーブルと person (人物) テーブルが以下の図のようにあります。

person (人物) の person.id (人物.ID) と person.name (人物.名称) をすべて出力してください。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3748983/7e4ee900-b02c-c7d4-b2b1-28d97ba6106b.png)

# 解答
```sql
SELECT id, name FROM person;
```


**解説**
```sql
SELECT <出力要素> FROM <TABLE名>
```
であり、
出力元はpersonであるから、`FROM person`
出力要素はidとnameであるから`SELECT id,name`

:::note info
今回出力は person.id (人物.ID) と person.name (人物.名称)という指定されているが、出力元が一つであるから、personという指定をする必要がない
:::

↓SELECT文の解説

https://qiita.com/bearl27/items/68383f84a18035892317


# 今回学んだこと
データの出力にはSELECT文を使う
```
SELECT <出力要素> FROM <TABLE名>
```
出力要素が複数あるときは`,`で区切る

# 他の問題
https://qiita.com/bearl27/items/4850a00dc631c9a32d2a
【Mac】ターミナルでホスト名を取得する方法

## ホスト名を取得するコマンド

以下のコマンドでホスト名が取得できます。

### `hostname` コマンド

```terminal
hostname
```

```terminal
$ hostname
MacBook-Pro-13-inch.local
```



## `uname -n` コマンド

`uname`でもホスト名を取得できます。

```terminal
uname -n
```

```terminal
$ uname -n
MacBook-Pro-13-inch.local
```
Amplify Gen2 amplify_outputs.json が不足していることでデプロイが失敗する件の解決方法


## はじめに

Amplify Gen2 を使用して React + Vite のプロジェクトを開発する際、本番環境へのデプロイ時に `amplify_outputs.json` が見つからずエラーが発生しました。
本記事では、このエラーを解消する方法について解説します。

## 発生したエラー

`npx ampx sandbox` を使用したローカル環境での動作確認が完了したので、本番環境へデプロイしようとしたところ、
ビルドフェーズの `npm run build` にて、以下のエラーが発生しました。

```shell
Cannot find module '../amplify_outputs.json' or its corresponding type declarations.
```

エラーメッセージから、本番環境用の `amplify_outputs.json` が存在しないため、デプロイが失敗していると判断しました。

## 原因の考察

エラー内容より、本番環境のリソースがデプロイされていないことによって、`amplify_outputs.json`が出力されなかった。
その結果、`amplify_outputs.json`が出力されていないのでは、と考えました。
そのため、リソースを作成するデプロイコマンドを実行することによって、本事象を解決することができると考えました。

## 解決策

本番環境のリソースをデプロイし、`amplify_outputs.json` を生成するよう、
`npx ampx pipeline-deploy --branch $BRANCH --app-id $APP_ID`のデプロイコマンドを
`npm run build` の前に実行するよう `amplify.yml` を修正しました。

```yaml
version: 1
frontend:
  phases:
    preBuild:
      commands:
        - npm ci --cache .npm --prefer-offline
        - npx ampx pipeline-deploy --branch $BRANCH --app-id $APP_ID
    build:
      commands:
        - npm run build
```

## 結果

上記の設定を行ったことで、本番環境のリソースが正常に作成され、
かつ`amplify_outputs.json`も生成され、正常にデプロイすることができました!

## 備考

`$APP_ID`については、ブランチ間で同一の値でも問題ありませんが
Branch ごとにリソースは作成してほしいので、ブランチ毎に`$BRANCH`は変更するようにしましょう。
Go言語でPDFを作成したい

# はじめに

私は普段、Go言語で開発を行うことが多いです。

その中で、PDFを作成する処理が必要となりました。
課金せずに実装したく、何を使えば良いのか悩んだ中で私が取った方法を紹介します。

# 結論

1. Excelのテンプレートを作成
1. テンプレートに値を挿入し、Excelファイルを作成
1. ExcelをPDFに変換

以上の方法で実現しました。

## Excelファイルの操作
excelizeを使用。
テンプレートに変数名を埋め込み、その埋め込まれた箇所に変数を挿入することで動的なファイル作成を実現。

https://pkg.go.dev/github.com/xuri/excelize/v2

## ExcelをPDFに変換

LibreOfficeの変換機能をREST APIで提供するunoserverのdocker imageを使用することにしました。

https://hub.docker.com/r/libreofficedocker/libreoffice-unoserver/tags

デフォルトだと2004番ポートにexcelファイルをPOSTするだけでPDF出力をしてくれます。

### 使い方の参考

https://qiita.com/cheuora/items/1bd5a349029d22b1c9f2

# 最初に考えた方法

GoのPDF作成ライブラリで検索すると、いくつか存在します。

- https://github.com/jung-kurt/gofpdf
- https://github.com/signintech/gopdf
- https://github.com/go-pdf/fpdf
- https://github.com/unidoc/unipdf

いくつか存在するのですが、実際に使ってみると、日本語フォントの適用が難しかったり、レイアウト調整が面倒だったりとしっくりこない。

テンプレートをもとに文書を作成したいけれど、コードベースだとテンプレートを変えたい時に工数がかかる。

# HTML/CSSで作成

きれいな文書、という意味ではこれが良い方法かもしれない。
ただ、今回の場合はexcelファイルも作成できるということもあり、最初の方法を採用しました。

例えば、作成したxlsxをダウンロードしてそこにユーザーが直接データを入力、それをアップロードしてもらう、などというユースケースにも使うことができます。

# まとめ

今の私が調査した中で、採用した方法を紹介しましたが、結局docker imageに頼ってしまっており、もっと良い方法があれば教えていただきたいです！
Scratch ライブラリ（FPS）

# Scratch ライブラリ（FPS）

## はじめに

前回から 2 か月ほどたちましたが、新たにゲームを公開しました。で、まだその記事ができてないのでつなぎです！

# FPS 表示

FPS を表示します。私のプロジェクトではペン描画でグリグリと描画することが多いので、FPS を確認して遅延している場合は処理を軽くしたりする工夫をしてます。Turbowarp を使う、という手もあるのですが、なんか負けた気がして（ただ、使うとかなりストレスフリー）。

## プロジェクト

ここにあります。

https://scratch.mit.edu/projects/1128452655/

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/579271/2a4efc23-104d-3c08-e8c8-8ed21c715082.png)

## ライブラリ概要

FPS を表示します。特長は次の通りです。

* スプライトを入れるだけで使えます

## 使い方

### 基本

あなたのプロジェクトにスプライトを組み込んで下さい。That's all!

## 各種情報

### 変数・リスト
> In: 他スプライト管理の値を参照／Out: 本スプライトで設定

| 変数名 | In/Out |        概要        |
| ------ | :----: | ------------------ |
| `GAME FPS` | Out | FPS値 |

### イベント

特になし

### コスチューム

特になし

---

ということで、単に FPS を確認するためのものですが良く使うのでここに残しておきます。

---

> [Scratch ライブラリと Scratch Tips 目次へ戻る](https://qiita.com/Kray-G/items/e1900d5b6c6dcfbe5321/)
[Git] 複数のミラーレポジトリにpushするときConflictしたときの対処法

# 複数のレポに同時にpushするときConflict
ごくまれに納品先と自社用で２つのレポジトリを併用するときがあり、
その際Conflictに悩まされたのでその覚書

この記事では２つのレポを手元でmergeしてcommit履歴を統合して解決する方法を紹介します。
```sh
# まずは.gitのあるフォルダ階層へ移動
cd project

# 手元に新しいbranchとしてコンフリクトしたレポジトリを追加
git remote add mirror git@github:CONFLICT/project.git

# 同期
git fetch mirror

# コンフリクトした内容を取り込むbranchに切り換え
git checkout develop

# 取り込み
git merge mirror/develop

# mirrorを削除
git remote remove mirror
```