OmniAICreator/Qiita-1.07M huggingface dataset:
cloudflare tunnelで自宅サーバでblogを立てたら海外アクセスにヒヤッとした

# 1. はじめに

## 1.1. 背景

- 自分が所属するサークルの連絡やファイル共有等をIT化するにあたり、NextCloudなどを導入してプライベートなストレージ環境を構築しようと計画しました
- 導入できるか検討するため、まずは自宅サーバを公開して試使用することにしました
- その手段として、表題にもあるようにCloudflareというCDNサービスが展開するCloudflare tunnelを使用して、公開をしました
    - 参考：　[Cloudflare Tunnel を使って自宅をデータセンターみたいにする](https://zenn.dev/takajun/articles/fbd783e459c722) , Zenn EightT様記事, 2024/11/30確認
    - Webサイトの導通確認の一環で、お試しでWordPressを立てて使用してみることにしました


## 1.2. 発生したこと

- Cloudflareのサイトでは、自身の登録したドメインに対してHTTPトラフィックの確認をしたり、WAFの設定をしたりすることができます
- WordPressを構築して、1日後にHTTPトラフィックを確認したところ、何も記事を作成していないのに、海外からのアクセスが思ったよりある、ということがわかりました
    - たまたまなのか、意図的なアクセスなのかはわからないですが、海外からアクセスされる必要は全くないため、驚きました

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/624259/1bed7b5e-1401-0c8d-f3e1-85597260d199.png)

- この状況を見て、いそぎ対策を入れました

# 2. 対策

- あくまで自宅サーバを公開するにあたっての対策となります
- 費用をかければ、VLAN導入やネットワークの分離などもっと策があるかと思います

## 2.1. blogサーバ(Ubuntu 24.04)の対策

- FireWallの確認
    - 80番、443番ポート以外遮断
- sshなどの不要プロセスの停止

## 2.3. WordPress自体の対策

- 2FA認証pluginを導入し、ログイン時にスマホでの認証を必須化
    - 参考：　[WordPressのセキュリティを強化したい](https://help.sakura.ad.jp/rs/2162/)

## 2.3. CloudflareでのWAF設定

※Cloudflareに関しての内容となりますが、他のCDNサービスでも類似の設定ができるかと思います。

- WAFの設定からカスタムルールを作成し、海外（特に危険と思われる国）からのアクセスを遮断する
    - 私の場合、あえて"日本以外から"のリクエストはブロックとして、海外アクセスを禁止にしました
    - 日本国内であっても、不正なアクセスはあり得るため、限られた拠点からのIPアドレスのみ許可、というようにしたほうが、効果が高いです

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/624259/3ccc4556-a8ca-2538-2e87-cde4ba9ff1cd.png)

# 3. おわりに

- CloudflareというCDNサービスを介したWebサイトアクセスとなるため、デフォルトで脆弱性に対する攻撃やDDoS攻撃などのサイバー攻撃から保護してくれます
- ただし、それでもやはり不審なアクセスはある、再認識しました
    - 今回はお試しのWordPressだったからまだよいのですが、nextcloudでプライベートストレージ環境を整備しようとしていたので、その前に再認識できてよかったです
Ciscoのコマンドを実機で叩きまくる研修に参加してみた。

# 実機研修で得たネットワーク構築の楽しさと可能性

## 研修参加のきっかけ
今回参加した研修は、XのTLにこのような投稿が流れてきたのがきっかけです。

https://x.com/IQ_Bocchi/status/1827203873351876634

この投稿をきっかけに該当するイベントをconnpassで見つけ参加してみることに。

https://networktraining.connpass.com/event/338887/

このイベントは3時間程度のボリュームでしたが、自分が求めていた学習ができると感じました。
このイベントの中で紹介された3か月版の研修も紹介され、参加することにしました。
定員は8名だったので募集枠自体結構少なめです。

まだ認知度が高くないため問題なく参加できましたが、ネットワークエンジニアとして20年以上のキャリアのある先生が自身の知見に基づいて組んでいただいたカリキュラムです。

## 研修の概要
今回参加した研修では、Cisco機器を使ってCCNAレベルの技術を実践的に学べます。
先ほどの単発のイベントとは異なり、研修はほぼ毎週土曜の13時半から19時半までを3か月行い、計9回実施されます。その中でみっちりコマンドを打ちまくります。
理論についての講義もあるので、そこを踏まえたうえで実践できるので、より理解が深まりやすいです。

- **扱った技術**: スタティックルーティング、OSPF、HSRP、STP、EtherChannel など、実機での設定から障害時の動作確認まで、一貫して学べる実践型のカリキュラム
- **実機の種類**: L2、L3スイッチ、ルータ、AP(アクセスポイント)とFortiのFW
- **印象深いポイント**: 受講生同士で各自が構築したネットワーク環境にpingを打ち合い疎通確認ができたことです。構築されていく過程が追えるので、色々な状態のネットワークを監視でき、お互いで確認しながら分析できたのが最高でした

また、VTP（VLAN Trunking Protocol）など、現場であまり推奨されていない技術についても、理由や対応方法（トランスペアレントモードの活用）が解説され、ボリュームの多いCCNAの知識も重要度を踏まえたうえで理解できました。

---

## 研修参加者に求められるレベル
この研修は初心者でも学びやすい内容が工夫されていましたが、事前にある程度の基礎知識があるとより理解が深まると思います。
- **これだけでも十分なレベル**: 書籍や独学でネットワークを少し学んだことがある人。たとえば、OSI参照モデルを本で読んだ程度の理解でも十分スタート可能
- **わからなくても大丈夫な部分**: VLANやルーティングについて、何それ状態でも大丈夫だと思います。私自身、VLANはこの研修に参加する前は存在すら知りませんでした

私は普段アプリ開発をしているプログラマーで、最近AWSやAzure上でもクラウドのメリットを生かした開発運用保守ができるようになりたいと思っている程度の人間です。
ネットワーク技術の勉強もしたくて以下のような雑誌にあるプログラミングもやってみて、ルータをLinux上で作ってみましたが、なぜそれが必要なのかもいまいちピンと来ていませんでした。

https://www.amazon.co.jp/Interface-%E3%82%A4%E3%83%B3%E3%82%BF%E3%83%BC%E3%83%95%E3%82%A7%E3%83%BC%E3%82%B9-2022%E5%B9%B4-11-%E6%9C%88%E5%8F%B7/dp/B0BD2XNZYR

そんな状態の私がこの研修に参加し、VLANの構成を自分で考えてみれるようになりました。特に、IPアドレス自体がなんとなくふわっとした存在で、192.168~とか見ても無感情だったのですが、構成図に書いてある各IPセグメントを見ても、思考停止せずに読み解いていけるための感覚をもらえたと感じています。

---

## 研修で学んだ技術の応用
研修で得た知識は、業務だけでなく趣味や自己学習にも大いに役立つ内容でした。
- **業務への応用例**: クラウドとのVPN接続の設定（研修ではAWSにFortiのFWからIPsecで設定します）
- **自宅サーバー構築のヒント**: 研修を通じて、自宅でのネットワークラボ構築に興味が湧きました。中古のCisco機器を購入し、スイッチやルーターの拡張を検討中です

ネットワーク機器もヤフーオークションやメルカリで型落ちのCiscoやYAMAHAなどのメーカーのものが比較的安価で出回っています。
こういったものを利用するのもよいですし、中古品の売買をネットを介していきなりやってみる勇気がない私のような人は秋葉原などにCiscoの中古ショップなんてお店も存在するので行ってみるのも良いかもしれません。
私は研修参加前にこのショップを訪問し、そこでコンソールケーブルの存在を知りました・・・

https://nw-akiba.com/




---

## 次のステップ
この研修で少し自信がついたので、来年頭にはCCNAに挑戦し、同様にAzureにもどんどん挑戦していこうと思っています。

また、先日Cisco Modeling Labs (CML) 無償版が登場したようです。

https://developer.cisco.com/docs/modeling-labs/cml-release-notes/#summary-of-changes

これを活用し、仮想環境でネットワーク構成を試し、コマンドについてももっと検証していくのもよいかもしれません。
これまでは無償版だとPacket Tracerしかなかったと聞いていますが、制限も多かったようなのでネットワークエンジニアの皆さんも即座に反応し、各仮想環境での構築例が日本語のブログでもどんどん出てきていますね。

https://qiita.com/kannishi/items/825a48fd6fe00331bbcb



このような追い風も色々吹いてきていますので、ネットワーク技術を学びたい方には、実機を使えるこの研修をぜひおすすめします。学びの場を通じて得たスキルや一緒に受講できた仲間とのつながりは、宝物になると思います。

---

次回の研修も募集中で、12月21日開始という挑戦的な設定になっています。
興味のある方は是非記事初めに紹介させていただいたイベントに申し込んでみてください。

このような研修の体験記が、ネットワーク構築に興味を持つ方々の参考になれば幸いです！
Goをやるなら知らないとやばい‼︎ golangci-lintとGitHubActionsの導入方法

# golangci-lintとは
```Goのコードを静的解析ツール```です。

# 導入方法(Mac)
Macが前提で話していきます。以下のコマンドで最新版をインストールできます。
```
 go install github.com/golangci/golangci-lint/cmd/golangci-lint@latest
```

### バージョン確認
バージョンの設定ができれば、以下のコマンドで確認してください。
```
$ golangci-lint --version
golangci-lint has version v1.62.2 built with go1.23.1 from (unknown, modified: ?, mod sum: "h1:b8K5K9PN+rZN1+mKLtsZHz2XXS9aYKzQ9i25x3Qnxxw=") on (unknown)
```

### 起動方法
以下のコマンドで起動します。
```
golangci-lint run
```
main.goなどでこのような設定にしている場合は違うコマンドです。
```main.go
r.Run("localhost:8080")
```
この場合だと以下のコマンドです。
```
golangci-lint
```

# lint.yml
以下のコードを実装します。
```lint.yml
linters:
  enable:
    - gocyclo  # サイクロマチック複雑度のチェック
    - govet    # 標準的なGoのバグチェック
    - errcheck # エラーハンドリングの確認
    - unused   # 未使用コードのチェック
    - revive   # 他のスタイルガイドに基づいたリント
  disable:
    - dupl
    - goimports
    - golint

run:
  timeout: 2m # タイムアウトを設定 (2分)

issues:
  exclude-rules:
    - text: "error strings should not be capitalized"
      linters:
        - revive

```

### golangci.yml
ciのファイルを作成します。
``` .github/workflows/lint.yml
name: Lint

on: [push, pull_request]

jobs:
  lint:
    runs-on: ubuntu-latest
    steps:
      # ソースコードをチェックアウト
      - name: Checkout code
        uses: actions/checkout@v2

      # Goのセットアップ
      - name: Set up Go
        uses: actions/setup-go@v2
        with:
          go-version: 1.19  # 使用しているGoのバージョンを指定

      # golangci-lintのインストール
      - name: Install golangci-lint
        run: |
          curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh
          sudo mv ./bin/golangci-lint /usr/local/bin

      # インストールが成功したことを確認（バージョン確認）
      - name: Verify golangci-lint installation
        run: golangci-lint --version

      # golangci-lintの実行
      - name: Run golangci-lint
        run: golangci-lint
```
これで動作確認ができればlinterとCIの設定をGOでできます。

<img width="1007" alt="スクリーンショット 2024-11-30 0 22 45" src="https://github.com/user-attachments/assets/e080d959-1724-42a1-91d2-fba53c167180">

<img width="1269" alt="スクリーンショット 2024-11-30 0 31 12" src="https://github.com/user-attachments/assets/d03f0046-a622-4680-be20-5271cfac7308">



#  参考資料
ChatGPT

https://qiita.com/twrcd1227/items/9d62a5ac58232d99b656
Linux on Mac のファン周り

使っていないMacProにUbuntuをいれて遊んでいたらやたらとうるさい
mbpfanというデーモンを導入したらきちんとファン制御してくれるようになった
(lm-sensorsは電力管理ではよく使われているデーモンなので既にインストールされている可能性が高い)
(/sys/devices/以下にファン用のパラメーターが存在するが型番によっては初期状態では正しく動作しない、これを正しく動作させるものといえる)

以下インストール方法
```bash
sudo apt-get install lm-sensors
git clone https://github.com/linux-on-mac/mbpfan.git
cd mbpfan/
make
sudo make install
sudo make tests
sensors

sudo cp mbpfan.service /etc/systemd/system/
sudo systemctl enable mbpfan.service
sudo systemctl daemon-reload
sudo systemctl start mbpfan.service
sudo systemctl status mbpfan
```

設定の一例
```/etc/mbpfan.conf
low_temp = 40
high_temp = 45
max_temp = 55
polling_interval = 1
```

### メモ: Dual bootのセットアップの仕方
rEFIndというブートローダーがオススメ
    - [The rEFInd Boot Manager](http://www.rodsbooks.com/refind/)
    - [Linux Multi-boot with Refind](https://store.teejeetech.com/2020/09/05/linux-multi-boot-with-refind/)
    - [ブートローダrEFIndをmacに導入する](https://sy-base.com/myrobotics/mac/mac_refind/)

#### メモ: M1なので、VM周りが気になる場合
このへんがよいらしい(が、未検証)
    - [Debian](https://wiki.debian.org/InstallingDebianOn/Apple/M1)
    - [Asahi Linux](https://asahilinux.org/)
C#でtupleを使用してみる

# 1. はじめに
* C#でtupleを使用したい

# 2. 開発環境
* C#
* Visual Studio 2022
* .NET 8

# 3. タプル型とは
"タプル" 機能を使用すると、軽量のデータ構造に複数のデータ要素を簡潔な構文でグループ化できます。 次の例は、タプル変数を宣言して初期化し、そのデータ メンバーにアクセスする方法を示しています。

https://learn.microsoft.com/ja-jp/dotnet/csharp/language-reference/builtin-types/value-tuples#code-try-16

# 4. サンプルソース
## 4.1. 匿名型のタプル型の定義
* タプル型を定義するには、すべてのデータ メンバーの型と、必要に応じてフィールド名を指定します
* Item1から連番でタプルの値を取得します
```C#:
(double, int) t1 = (4.5, 3);
Console.WriteLine($"Tuple with elements {t1.Item1} and {t1.Item2}.");
// Output:
// Tuple with elements 4.5 and 3.

(double Sum, int Count) t2 = (4.5, 3);
Console.WriteLine($"Sum of {t2.Count} elements is {t2.Sum}.");
// Output:
// Sum of 3 elements is 4.5.
```

## 4.2. フィールド名付きのタプル型の定義
* タプルの初期化式またはタプル型の定義でタプル フィールドの名前を明示的に指定します
```C#:
var t = (Sum: 4.5, Count: 3);
Console.WriteLine($"Sum of {t.Count} elements is {t.Sum}.");

(double Sum, int Count) d = (4.5, 3);
Console.WriteLine($"Sum of {d.Count} elements is {d.Sum}.");
```

## 4.3. タプルの代入と分解
* C# では、次の両方の条件を満たすタプル型間の代入がサポートされます
    * 両方のタプル型に、同じ数の要素がある
    * タプルのそれぞれの位置で、右側のタプル要素の型が対応する左側のタプル要素の型と同じか、暗黙的に変換可能である

```c#:
(int, double) t1 = (17, 3.14);
(double First, double Second) t2 = (0.0, 1.0);
t2 = t1;
Console.WriteLine($"{nameof(t2)}: {t2.First} and {t2.Second}");
// Output:
// t2: 17 and 3.14

(double A, double B) t3 = (2.0, 3.0);
t3 = t2;
Console.WriteLine($"{nameof(t3)}: {t3.A} and {t3.B}");
// Output:
// t3: 17 and 3.14
```

## 4.4. タプルの等値性
* タプル型は、```==``` と ```!=``` 演算子をサポートしています。 これらの演算子により、左側のオペランドのメンバーが、タプル要素の順序に従って、右側のオペランドの対応するメンバーと比較されます

```c#:
(int a, byte b) left = (5, 10);
(long a, int b) right = (5, 10);
Console.WriteLine(left == right);  // output: True
Console.WriteLine(left != right);  // output: False

var t1 = (A: 5, B: 10);
var t2 = (B: 5, A: 10);
Console.WriteLine(t1 == t2);  // output: True
Console.WriteLine(t1 != t2);  // output: False
```

# 5. 参考文献

https://learn.microsoft.com/ja-jp/dotnet/csharp/language-reference/builtin-types/value-tuples#code-try-16

https://csharp-learn.com/how-to-use-tuple/
インフラエンジニアがITコンサルを目指して失敗した体験レポ

# 概要
今年の春にこっそり行った転職活動の失敗経験から学んだことと、反面教師にしてもらいたいという思いを記事に籠めます。
浅薄な考えと勢いでキャリアを汚すエンジニアが減りますように。

# この記事で言いたいこと
- 自己理解を深めよう
- 見切り発車の転職は辞めよう

# はじめに
#### 活動時期
- 2024年3-4月

#### 目的
- 年収増
- 上流工程案件に入りたい
- 有り体に言えばコンサルになりたい

#### 応募方法
- 某特化型のエージェント経由


# まず結論
- **失敗した**
    - ２か月活動して箸にも棒にも掛からなかったので断念
    - 心が折れたとも言う
- 転職活動自体はリベンジする

# 原因
受けたフィードバックから、大きく分けて以下が原因のよう
- アピールポイントの整理が足りていなかった
- 自己理解が足りていなかった
- 現職の在職年数が短かった

### アピールポイントの整理が足りていなかった
- 「結局、どういう人なのかわからなかった」というフィードバック
    - エージェントと事前にすり合わせ、アピールポイントとしていたのが以下の点
        - チームリーダ経験
        - 経験してきた案件の内容とポジション
    - 事実はあってもそれをアピール出来なかった
        - 持っている経験と熱量は良いのに…とはエージェントの弁
### 自己理解が足りていなかった
- なんで上流工程がやりたいのかへの自問自答
    - そのほうが影響度高くてやりがいあるしなぁ。くらいの思いだった
- 見切り発車で始めてしまったため、整理が追いつかなかった
    - そんな状態ではエージェントにも志向を伝えられていたか怪しい

### 現職の在職年数が短かった
- 複数社から「今の会社に入って２年ですか？短いですね」のコメントをもらった
    - とある会社からはストレートに「すぐ辞められると困るんで」とも（それは当然の懸念ではある）
    - 結局これも明確かつ論理的に回答出来ればリカバリできたはず
    
# 失敗した感想
- 反動で「絶対に転職成功させてやる！」という気持ちが高まった
    - 自己研鑽を（個人比）活発にやれるようになった
        - それがアドカレ参加にも表れている
    - 現職へのやる気が高まった
        - 何をやれば自分のキャリアの立て直しが出来るのか？を考えた結果
        - 多少現職で評価されている程度の頑張りでは太刀打ちできないと感じた

- 軽くトラウマになった
    - ~~記事を書いていて動悸と脇汗が止まらない~~
    - このトラウマを払拭するために是が非でも転職活動リベンジしなくてはならない
- 自分の現在地と客観的な評価が見えた
    - 上司は（自分でもわかるほどに）贔屓目に評価を付けてくれているので、第三者からの評価が分かった

# リベンジに向けて
- そもそも本当にコンサルがいいのかを再確認する
    - 上流がやりたいのであれば選択肢はほかにもある
    - 結局好きなことは何なのか 
        - 下流工程でマシンゴリゴリ触るのも大好き
        - 実現方法をあーだこーだ議論するのも第空く
- いい加減将来像を固めるべき
    - マネジメントがいいのか、テクニカルがいいのか
    - 楽しさが高いのはテクニカルだがマネジメントも楽しい
    - そもそもマネジメントできないと将来困るんだろうなあ…

# おまけ　転職活動時に読んだ本
※ 失敗談記事だけど本はどれも参考になりました

https://www.amazon.co.jp/%E3%81%93%E3%81%AE%E3%81%BE%E3%81%BE%E4%BB%8A%E3%81%AE%E4%BC%9A%E7%A4%BE%E3%81%AB%E3%81%84%E3%81%A6%E3%81%84%E3%81%84%E3%81%AE%E3%81%8B-%E3%81%A8%E4%B8%80%E5%BA%A6%E3%81%A7%E3%82%82%E6%80%9D%E3%81%A3%E3%81%9F%E3%82%89%E8%AA%AD%E3%82%80-%E8%BB%A2%E8%81%B7%E3%81%AE%E6%80%9D%E8%80%83%E6%B3%95-%E5%8C%97%E9%87%8E-%E5%94%AF%E6%88%91/dp/4478105553

https://amzn.asia/d/3O5l9r0

https://amzn.asia/d/8IGe6U1
PhysiKyuの活動ってどんなの？サークルメンバーの1週間に密着してみた！②


## PhysiKyuとは
PhysiKyuとは九州大学の学生が学部学年を超えて、物理の自主ゼミを行なっている非公認サークルです。詳しく知りたい方は記事[PhysiKyuについて](https://qiita.com/PhysiKyu/items/5072387d8f06b8671291)をご覧ください。

## はじめに
Advent Calendar 2日目です。今回は、PhysiKyuメンバーである理学部化学科1年生の湯元颯真（ゆもとそうま）さんがどんな活動をしているのか聞いてみました！
PhysiKyuの活動がどんなものなのか、彼の活動を通して実感してみてください！

## 所属しているPhysiKyu内の自主ゼミについて
月曜：なし
火曜：量子力学(16:40~18:10)
水曜：なし
木曜：理論電磁気学(18:30~20:30)
金曜：なし
土曜：なし
日曜：解析力学(14:00~15:00)
（1年生後期時点）

## インタビューしてみた！
#### ・PhysiKyu外の活動を教えてください。
>月曜日に有機化学の自主ゼミを別に16：40～18：10の時間帯で行っています。また、木曜日の昼休みにある「サイエンス英会話筋トレ」などのプログラムに参加しています。当然ですが、授業はすべて真面目に取り組んでいます笑
趣味で、コンピューターを用いた量子化学の計算にはまっていて、結構な時間費やしてしまってます笑（なんとcpuはryzen9 9900xです！）

#### ・自主ゼミの予習はいつ、どのようにしていますか？
>11月の第3週を例にとって紹介しますね。
月曜日の夜は発表担当ではなかったので、火曜の量子力学の予習を1時間ほどに留めました。水曜日は、木曜の理論電磁気学の予習と発表の準備を夜中に2時間ほどしました。土曜日は、夜に日曜の解析力学の予習を1時間ほどしました。この週は、発表が1回しかなかったので、PhysiKyuの活動は結構楽でしたね笑

#### ・自主ゼミを通して、良かったなと思うことはありますか？
>たくさんありますよ！
まず最初に、物理学科の進度を参照しながら物理の勉強できることは、化学科である僕にとって大きなメリットでした。また、人によってはデメリットに感じるかもしれませんが、自主ゼミの進度に合わせて勉強をしなければならないので、その強制力でどんどん勉強を進めていけたのは、1年生の僕にとっては結構ありがたかったです。他にも、量子化学の計算に興味があり、量子力学を早く勉強したかった僕が、量子力学を勉強したい同士を募って、1年生ながら量子力学の自主ゼミを立ちあげることができました。これは、僕にとって一番良かったことかもしれません。

#### ・ゼミで使っている本はなんですか？
>- 量子力学は、「[量子論の基礎（清水明）](https://www.saiensu.co.jp/search/?isbn=978-4-7819-1062-8&y=2004)」を使っています。
量子力学を初めて勉強する僕にとっては、3章の数学的な部分が最初は何をしているのか理解することが難しかったですが、自主ゼミメンバーとの議論や他の教科書を参照したりしながら、最近ようやく量子力学のイメージをつかめた気がします。

>- 理論電磁気学は「[理論電磁気学（砂川重信）](https://www.kinokuniya.co.jp/f/dsg-01-9784314008549)」を使っています。
これは、初学の僕にとっては非常に難しい本の一つでした。しかし、ゼミメンバーの一人に「グリフィス電磁気学Ⅰ」を一通り勉強している方がいて、その人の理解も借りながら、毎週議論を進めていくことで、深い理解で進めて行けています。一人で勉強していたら、かなりきつかったと思うので、自主ゼミで取り組めて良かったなと思います。

>- 解析力学は「[解析力学（畑浩之）](http://www.tokyo-tosho.co.jp/books/978-4-489-02168-8/)」を使っています。
これは、PhysiKyuに入会して初めて読んだ本の一つです。これは、初めて大学物理の難しさを感じた本でした。ラグラジアンや最小作用の原理など、抽象的なことが多いところが、大学1年一発目に触れた僕にとってなかなか難しいと感じました。このゼミでは、3年生の先輩が補佐役として参加してくれていて、難しいながらも勉強をなんとか進めていけました。そのおかげで、夏頃に悩んでた部分が一気に解決するタイミングに出逢いました。自主ゼミで勉強していなかったら、早々に勉強をするのを諦めていたかもしれません笑

>- もう終わりましたが、前期に力学の自主ゼミをしていて、そこでは「[力学（篠本滋・坂口英継）](https://www.kinokuniya.co.jp/f/dsg-01-9784489021633)」を使っていました。　
ゼミメンバーが1年生だけでしたが、仲良く力学を勉強できて楽しかったですね。

#### 勉強のモチベーションとなっているものはなんですか？
>いろいろな知識を身につけていくことが好きなんですよね。大学生は、気の赴くままに勉強できる貴重な時間だなって思います。

#### 最後に記事を読んでいる皆さんに一言お願いします！
>理学部物理学科以外も入りやすいアットホームなサークルです！
九大生で物理に興味がある人は、ぜひ入部してみてください～

## 最後に
今回、PhysiKyuメンバーである湯元颯真さんにインタビューしてみました。とても気さくな方で、どの質問に対しても楽しそうに回答してくれました。自作の鍋もご馳走してくれました！
この記事が、PhysiKyuの活動の参考になればいいなと思います！
.NET8で開発しているマイクロサービスのバックエンドのdocker composeが遅すぎるので頑張って高速化してみた

# 概要
マイクロサービスアーキテクチャで開発をしており、各サービスをDockerでコンテナにしています。ローカル環境の各コンテナを最新化する際に、docker-compose up --build -dがすべて終わるまでに20～30分毎回かかってしまっていたので、頑張って高速化してみました。体感、3～4分ぐらいまで高速化できたと思います。Windows環境での開発を前提としています。また、1つ1つの効果を細かく測定はしていないので、それぞれの対応がどれだけ効果があったかは体感になります。（測定したら記事を更新したいと思います。）

# やってみた事
1. BuildKitのインラインキャッシュの利用
1. BuildKitのマウントキャッシュの利用
1. 並列ビルドの利用
1. Buildステージに軽量なイメージを利用する
1. DBのMigration時にビルド済みのリソースをちゃんと使う


## BuildKitのインラインキャッシュの利用

BuildKitのインラインキャッシュは、Dockerイメージのレイヤーにビルドキャッシュを埋め込む機能です。通常のDockerビルドキャッシュと異なり、イメージ自体にキャッシュ情報が含まれるため、異なるマシンやCI環境でもキャッシュを再利用できます。ローカル環境でも、同じDockerfileから何度もビルドを行う場合に効果がありそうなので、試してみました。

以下のようにBUILDKIT_INLINE_CACHE: 1を記述しておきます。

```yaml
# docker-compose.yml
services:
  backend-service:
    build:
      context: ./backend
      dockerfile: Dockerfile
      args:
        BUILDKIT_INLINE_CACHE: 1
```

## BuildKitのマウントキャッシュの利用
BuildKitのマウントキャッシュを使用することで、NuGetパッケージのリストア処理を効率化しました。このキャッシュはホストマシン上に保持され、ビルド時のみ一時的にマウントされます。Dockerfileでは以下のように設定します。
```dockerfile
RUN --mount=type=cache,target=/root/.nuget/packages dotnet restore "Hoge.csproj"
RUN --mount=type=cache,target=/root/.nuget/packages dotnet build "Hoge.csproj" -c Release
```

>ローカルのNuGetパッケージのキャッシュをコピーする事も考えましたが、各端末の開発環境の影響が大きかったため、中止しました。環境がかなり統一されている状況なら使えるかもしれません。

## 並列ビルドの利用

PCのスペックが高くない場合は効果が薄かったり、負荷がかかりすぎるかもしれませんが、幸いな事にそれなりのスペックだったこともあり、かなり効果があったと思います。

```bash
docker compose build --parallel
```

## Buildステージに軽量なイメージを利用する

Buildステージのみ、alpine版にして少しでも処理が軽くならないか期待してみました。高速化の観点ではそこまで効果は無かった印象です。

```dockerfile
FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build
↓
FROM mcr.microsoft.com/dotnet/sdk:8.0-alpine AS build
```

## DBのMigration時にビルド済みのリソースをちゃんと使う
docker compose build --parallelの後にdocker compose up -dでコンテナを起動し、DBのMigrationを実行してローカルのDB環境を構築していました。Entity Framework Core CLIを利用して、Migrationを実行していましたが、実行時にBuildから実行されており、なぜかBuildに5分以上の時間がかかっていました。イメージを作成する際にビルド済みなので、それを使う事によりこの5分以上の時間を短縮する事ができました。

```docker
ENTRYPOINT [ "dotnet", "ef", "database", "update", "--no-build", "--configuration", "Release" ]
```

# まとめ
いろいろな最適化手法があり、組み合わせる事でメリットが得られます。
今回は、特にBuildKitのマウントキャッシュと並列ビルドの組み合わせが効果的でした
実際の環境に合わせて各設定を調整し、最適なパフォーマンスを探してみてください。
【Python】alembicでマイグレーション時に、既に存在するインデックスの作成(ix_...)が検知される場合

# 概要
PythonのアプリでAlembicを利用してマイグレーション(`autogenerate`)していたのですが、なぜか既にあるインデックスがマイグレーションファイルに表示される(=alembicが再度作成しようとする)、という事象が発生。

原因と解決方法がわかったので紹介します。

### 前提
db：mysql8.0
python：3.12
alembic：1.13.2
SQLAlchemy：2.0.32

# 経緯

SQLAlchemyのモデル定義には以下のように記載していました。

```py
type_id = Column(Integer, primary_key=True, index=True)
```

これでmigrationファイルを生成（`alembic revision --autogenerate`コマンドを実行）すると、以下のように認識されていました。

```py
sa.Column('type_id', sa.Integer(), nullable=False),
```

データベースを確認すると、`PRIMARY`という名前でインデックスが作成されています。

しかし、この状態で別のモデル定義をいじってからマイグレーションファイルを生成すると、なぜか以下のようにインデックス作成が差分で表示されます。

```py
op.create_index(op.f('ix_type_type_id'), 'type', ['type_id'], unique=False)
```

既に`PRIMARY`という名前のインデックスがあるのに、`ix_type_type_id`という別名でインデックス作成しようとしてくるのです。

なぜ既にあるのにAlembic側が再度生成しようとしてくるのだろう...？

## 原因と解決方法
結論、`index=True`としていたのが理由でした。
以下の記事に辿り着いた時に原因がわかりました。

https://stackoverflow.com/questions/74321455/alembic-autogenerate-recerates-existing-indexes

おそらく、MySQLなどのDB側で主キーに対してインデックスを作成してくれるのに、Alembicのマイグレーションでもインデックス作成するように指示してしまっているため、このように重複する事象が発生したと考えられます。

よく見ると、元々あった（MySQL側のもの？）インデックスにはユニーク制約があって、後で生成された（Alembic側？）インデックスにはユニーク制約がありませんでした。他は、上述の名前以外に違いはありませんでした。

つまり、Alembic側が「あれ、私が知っているインデックス名のものがないな...」と判断して、よしなに作成してくれたのではないか、ということです。

ということで、以下のようにSQLAlchemyのモデル定義から`index=True`を外せば、今後Alembicマイグレーション時に差分表示されないようになりました。

```py
type_id = Column(Integer, primary_key=True)
```
退職した今だから言える❗️Railsができないのにできると言い張って入社したRailsエンジニアの末路🫨

この記事は [ex-crowdworks Advent Calendar 2024](https://qiita.com/advent-calendar/2024/ex-cw)の20日目の記事です。

# はじめに
今年、株式会社クラウドワークスを退職した@nisyuuです。お気に入りのティッシュは[鼻セレブ](https://e-nepia.com/products/hana-celeb/)です。
エンジニアとしてクラウドワークステック（旧クラウドテック）というフリーランスと企業をマッチングするエージェントサービスを開発していました。

クラウドワークステックはRuby on Railsで開発をしているのですが、入社直前の私はRuby on Railsができませんでした。
できると言って入社してしまったのですが、なんとかRailsエンジニアとして開発に加わることができました。
今回はどのようにRailsのスキルを手に入れ、入社直後からRails実装できるようになったか紹介します。

# 必死だったあの頃

クラウドワークス入社前は、職がありませんでした。
家もありませんでした。

なんとかこの現状を打破したい一心で転職活動をしていたところ、クラウドワークスに内定をいただきました。

クラウドワークスではRuby on Railsを使って開発しているのですが、Railsの実務経験はほとんどなく全くの初心者でした。

しかし、選考時にRailsチョットデキると発言してしまい、職務経歴書にも記載してしまっていたため何とかして入社までにできるようになっておかなければなりませんでした。

入社まで2週間前の話です。

# ガチンコRails学習体験記

2週間はあっという間です。とりあえずRailsチュートリアルを始めました。

https://railstutorial.jp/

チュートリアルは上から下まで最初から最後の章まで隅々目を通してハンズオンをしました。
もちろん、途中にある演習もやりました。
だいたい1週間ぐらいでやりきりました。

一通りチュートリアルを終えた後は、チュートリアルを通して完成したRailsアプリケーションを拡張してオリジナルアプリケーションを作りました。
さらに、オリジナルアプリケーションはHerokuにデプロイしてWebサイトとして動かせるところまで仕上げました。
実装したものの記事があるので、こちらに貼り付けておきます。

https://qiita.com/nisyuu/items/146c0f66725c80ec8d21

# 入社直後にRailsエンジニアとして覚醒

2週間が経ち、とうとう入社してしまいました。
そして、2日後ぐらいにRailsエンジニアとして腕を試されるイベントが発生します。

同じチームのエンジニアになりたての方から、あるページで動かしたいJavaScriptコードをRailsプロジェクトのどこに実装しないといけないかについて質問を受けたのですが、何とか答えることができました。

その後も、Railsのタスクにアサインされることがありましたが、なんとか完遂することができたため、ガチンコでRailsを学習した甲斐があったなと思います。

# おわりに

チュートリアルで基礎を学習し、オリジナルアプリ開発で応用を学習する方法はフレームワークや言語を習得するのに非常に有効的です。
そして、学習期間は短く濃密に行いましょう。

ということで、Railsができないのにできると言い張って入社したRailsエンジニアの末路はハッピーエンドでした。

最後に、職も家もない者を採用いただいた関係者へ、心からお礼を申し上げます。
【UiPath】「HTTP要求」でkabuステーションAPIからトークンを取得する【kabuステーション】

タイトルの通り、UiPathの「HTTP要求」アクティビティを使ってkabuステーションにAPIで接続し、トークンを取得する。

## 実装
「HTTP要求」アクティビティを使うが、標準では入っていないのでまずは「UiPath.WebAPI.Activities」パッケージをインストールする。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/578020/2dbbfd23-c694-71d8-bacf-b10e6c153a76.png)

インストールしたら「HTTP要求」アクティビティを配置し、「設定」を開く。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/578020/938d3fff-0d43-934b-fd0a-f69b267e0ef4.png)

HTTP要求ウィザードが開くので、以下の通り設定する。

- エンドポイント：`"http://localhost:18081/kabusapi/token"` [^1]
- 要求メソッド：`POST`
- 応答を次のとおりに受け入れる：`JSON`
- 「ヘッダーを追加」を押して行追加し、以下2つを追加
    - 名前：`Content-Type`，値：`"application/json"`
    - 名前：`Accept`，値：`"application/json"`

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/578020/397fee77-1e6a-be91-b197-cd873c44c16f.png)

HTTP要求ウィザードで設定が完了したら、プロパティパネルのオプション項目から「本文」と「本文形式」を設定する。本文の`パスワード`のところは各自のパスワードを入れる。
- 本文：`"{""APIPassword"":""パスワード""}"`
- 本文形式：`"application/json"`

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/578020/21ffb706-f98b-58a4-881b-7aea2c0c1815.png)

最後に、レスポンスを受ける受け取るために出力項目の「応答コンテンツ」に任意のString型変数を指定する。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/578020/c7512c05-8307-c806-f8d5-ba7cfaba0c83.png)

「HTTP要求」の設定は以上で終わり。
ちなみにHTTP要求ウィザードでプレビューを試すとBodyをうまく渡せていないのかパラメータ変換エラーになる。ここは気にせず、一度ワークフローを動かして動作を確認してみてほしい。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/578020/bbe601bd-37cb-5fbe-0539-add613d9e7dc.png)

ワークフローを実行し、「応答コンテンツ」で指定した変数をログに書き出した結果がこちら。正常にトークンを取得できていることを確認できる。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/578020/f1f878ee-8b06-6541-3e1b-3f26129eb7fa.png)

なおパスワードを間違えている場合はエラーコード：4001013が返る。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/578020/d2072563-4d96-9152-3bd6-4d6aa24bec2c.png)

「応答コンテンツ」で指定した変数にはJSON形式の文字列が返るので、ここからトークンだけ抜き出したい場合は「JSONを逆シリアル化」アクティビティを使って文字列をJObject変数に変換し、`JObject変数("Token").ToString`の形で抜き出す。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/578020/36f0b958-cfb0-de5f-a5bb-b993d325b904.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/578020/ff874442-bdb2-e0ec-d65e-4b6837950cd9.png)

以上で、無事にトークンだけを取得することができた。
UiPathならAPIを使わなくてもkabuステーション自体をGUIで操作できるが、APIを使えるなら使ったほうが速く安定して動かせるだろう。余裕があれば積極的に活用していきたい。

## 参考
https://qiita.com/Davoi/items/315652b2980e3b552c4b

https://qiita.com/hmdsg/items/c6842fe87ec4e0365241

## 動作環境
UiPath.WebAPI.Activities 1.21.1

[^1]: `localhost:18081`は検証用、`localhost:18080`が本番用。
【基礎確認】pythonのlangchain_community.llmsモジュールFakeListLLM関数

# はじめに
[LangChainとLangGraphによるRAG・AIエージェント［実践］入門](https://www.amazon.co.jp/dp/B0DK4YGYBL?tag=xpg-22&linkCode=ogi&th=1&psc=1)
を読んでいて、10章で躓いたので、初心に戻って、一つずつ紐解いて学習することにしました。
今回のテーマは「langchain_community.llms」モジュール「FakeListLLM」関数

## 独り言
実際のLLMを使いたいけれど、今は基本文法のやり直しなので、FakeListLLMで代替。
[【基礎確認】pythonのlangchain_core.output_parsersモジュールStrOutputParser関数](https://qiita.com/o_chan_t/items/9a3d23537c7dc0327ddb)でこの関数は使っているけれど、FakeListLLMに焦点を当てます。
後々負荷に耐えられなくなったら実際のLLMを使うことにします。

# 前回までの投稿
1. 必要なライブラリとモジュールをインポートする
[【基礎確認】pythonのoperatorモジュール](https://qiita.com/o_chan_t/items/4ad3cd5fc832f9be9d86)
[【基礎確認】pythonのtypingモジュール](https://qiita.com/o_chan_t/items/1f54806ad90c79904af2)
[【基礎確認】pythonのdotenvモジュール](https://qiita.com/o_chan_t/items/641eada727fa5a27aaf3)
[【基礎確認】pythonのlangchain_core.output_parsersモジュールStrOutputParser関数](https://qiita.com/o_chan_t/items/9a3d23537c7dc0327ddb)
[【基礎確認】pythonのlangchain_core.promptsモジュールChatPromptTemplate関数](https://qiita.com/o_chan_t/items/e64733a7d5d97c0cc126)

# サンプルコード

```sample.py
from langchain_community.llms import FakeListLLM

# ダミーの応答を設定
responses = [
    "こんにちは！今日は晴れです。",
    "今日は曇りですが、雨は降りません。",
    "今日は雨が降っています。傘を持って出かけてください。"
]

# FakeListLLMの初期化
llm = FakeListLLM(responses=responses)

# モデルを使用して応答を生成
response = llm.invoke("こんにちは、AIアシスタントさん。今日の天気はどうですか？")

print(response)
```

```
こんにちは！今日は晴れです。
```

## 解説
1. `langchain_community.llms`モジュールから`FakeListLLM`クラスをインポートする
2. `responses`リストを定義し、ダミーの応答を設定します。
  このリストには、モデルが返すべきテキストが含まれる。
3. `llm = FakeListLLM(responses=responses)`で、`FakeListLLM`モデルを初期する。
4. `responses`パラメータで、先ほど定義したダミーの応答リストを指定する。
   このモデルは、呼び出されるたびにリストから順番に応答を返す。
5. `response = llm.invoke("こんにちは、AIアシスタントさん。今日の天気はどうですか？")`で、初期化したモデルを使用してプロンプトに対する応答を生成する。
   このメソッドは、指定されたプロンプトに基づいてダミーの応答を取得する。
6. `print(response)`で、生成された応答の内容を表示する。

このサンプルコードを実行すると、事前に設定された天気に関するダミーの応答が表示される。
【Android】オリジナルスライドショー壁紙

# ロック画面とホーム画面の背景画像を切り替えて表示したい
[ピノキオピー15周年記念書籍](https://www.kawade.co.jp/pinocchiop15th/)を購入したら初回出荷特典でしおりが付いていて、そのしおりにあるQRコードを読み込むと17種の楽曲にちなんだ待受画像をダウンロードできるようになっていました。どれも好きな絵だったり思い入れのある曲だったりで選ぶことはできず、全部を切り替えながら表示できたらなぁと思いました。やり方を調べてみましたがAndroidの設定アプリ標準機能ではできず、カスタムランチャーアプリを入れる方法などが出てきました。
それは何か嫌だったので他の方法を模索していると、LiveWallpaperなるものを使うと動きのある壁紙が作れるらしいということを知りました。これで画像を切り替えて表示するようにすればいけるんじゃね、と思い作ってみました。
付録の待受画像をそのまま公開するのは権利的にNGなので、私が撮った適当な写真に差し替えたものを**OriginalLiveWallpaper**という名前で作成して[GitHub](https://github.com/zawanume/OriginalLiveWallpaper)にて公開中です。

# 指定時間毎に切り替える
10000ミリ秒すなわち10秒ごとにフェードを発生させるようにしています。
```kotlin:WallpaperService.kt
        private val frameCallback = object : Choreographer.FrameCallback {
            override fun doFrame(frameTimeNanos: Long) {
                if(running) {
                    drawFrame()
                    choreographer.postFrameCallback(this)
                }
            }
        }

        private val fadeRunnable = object : Runnable {
            override fun run() {
                isFading = true
                handler.postDelayed(this, 10000)
            }
        }
```

# 切り替え時にフェードさせる
瞬間的な切り替えは嫌だったのでフェードさせました。`drawFrame()`内に実装されています。
付録の画像は背景色が統一されていたのでそれに合わせて背景色を設定したらいい感じにフェードできました。
```kotlin:WallpaperService.kt
            if (isFading) {
                paint.alpha = 255 - alpha
                canvas.drawBitmap(currentImg, matrix, paint)

                paint.alpha = alpha
                canvas.drawBitmap(nextImg, matrix, paint)

                alpha += 15
                if (alpha > 255) {
                    alpha = 0
                    isFading = false
                    currentIndex = nextIndex
                    nextIndex = (nextIndex + 1) % imgPath.size
                }
            } else {
                paint.alpha = 255
                canvas.drawBitmap(currentImg, matrix, paint)
            }
            surfaceHolder.unlockCanvasAndPost(canvas)
```

# とりあえず完成
動く状態にはなりましたが電池の減りが早くなりました。もう少し効率的な描画をした方が良さそうです。

# 参考
1. [WallpaperService - Android Developers](https://developer.android.com/reference/android/service/wallpaper/WallpaperService)
1. [システム壁紙を制御する ～ホームアプリ（ランチャーアプリ）の作り方～ - Qiita](https://qiita.com/ryo_mm2d/items/02bfab5f130b8d17124b)
1. [ライブ壁紙を作ってみる - WonderPlanet Developers' Blog](https://developers.wonderpla.net/entry/2013/06/21/192731)
Typstのslydstでスライドを作る

サンプルコードは以下の通りですが、主な使い方は公式サイトを見てください
https://typst.app/universe/package/slydst/

またこちらの記事も参考になります
https://qiita.com/gomazarashi/items/86ffd9a588074a8b97e6

```
// https://typst.app/universe/package/slydst/
#import "@preview/slydst:0.1.1": *
#set text(font: "Arial")
#show regex("[\p{scx:Han}\p{scx:Hira}\p{scx:Kana}]"): set text(font:"Hiragino Kaku Gothic ProN",size:11pt)
#set list(marker: ([•], [◦], [-], [+]), spacing: auto)

// title slide
#show: slides.with(
  title: "title", 
  subtitle: "subtitle",
  authors: "authors",
  layout: "medium",
  ratio: 16/9,
  title-color: none,
)

// proposition environment
#let p = counter("proposition")
#let proposition(content, title: none, ..options) = {
  p.step()
  frame(
    counter: context p.display(x => "Proposition " + str(x)),
    title: title,
    content,
    ..options,
  )
}

// math block in theorem environments
#let mathm(x) = box(
  width: 16.5cm,
  height: 0.85cm,
  baseline: 150%,
  align(center, $display(#x)$)
)


= Section 1
== Slide 1
hoge

#definition[
    your theorem

#theorem(title: "theorem title")[
    In line math $f(x)$ and math box #mathm($f(x)$)
]


#figure(
    image(".png", width: auto),
    numbering: none,
    caption: [your caption]
)
```

# 公式から少し変えている点

## Proposition環境
公式ではdefinition/lemma/theorem/corollary環境があるけどproposition環境がない（slydst:0.1.1バージョンでは）ので、以下で``#proposition``できるようにしてます
```
// proposition environment
#let p = counter("proposition")
#let proposition(content, title: none, ..options) = {
  p.step()
  frame(
    counter: context p.display(x => "Proposition " + str(x)),
    title: title,
    content,
    ..options,
  )
}
```

## 定理環境での数式ボックス
定理環境でふつうの数式ボックスを作ろうとするとセンタリングしてくれなく見た目が悪いので、以下で定理環境で通常の数式ボックスを作れるようにしました

ただ、強引に作ったので``#mathm($数式$)``みたいにしないといけなくて汚いです
```
#let mathm(x) = box(
  width: 16.5cm,
  height: 0.85cm,
  baseline: 150%,
  align(center, $display(#x)$)
)
```

## 英語と日本語のフォント
以下では英語にArial、日本語にヒラギノ角ゴシックを使っています

フォント名を変えれば好きなものを使えます、フォント名はターミナルで``typst fonts``すれば調べられます
```
#set text(font: "Arial")
#show regex("[\p{scx:Han}\p{scx:Hira}\p{scx:Kana}]"): set text(font:"Hiragino Kaku Gothic ProN",size:11pt)
```
クラウドセキュリティを調べてみた / I looked into cloud security (日本語 / 英語)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1812041/2699a761-da56-49da-9509-a0f56875b3bf.png)
# 日本語
こんばんわ！
Advent Calendar 2024に参加してまして、19日目の記事を書いていこうと思います。
題材は「ヒヤリとした！クラウドセキュリティ体験談をシェアしよう by Netskope Advent Calendar 2024」ということで、クラウドセキュリティについて学んだことをまとめていこうと思います。

### クラウドに潜む脅威
クラウドには以下の脅威が有名なもので考えられます。
・データ漏洩（Data Breach）
・サービス拒否攻撃（DDoS: Distributed Denial of Service）
・認証情報の盗難（Credential Theft）
・インサイダー攻撃（Insider Threats）
・クラウドストレージの不正アクセス（Cloud Storage Misconfigurations）

### どうやって防ぐ？
###### ・データ漏洩（Data Breach）
　→暗号化、アクセス制御、多要素認証（MFA）等で対策を行う。
###### ・サービス拒否攻撃（DDoS: Distributed Denial of Service）
　→自動スケーリング、DDoS対策ツール、トラフィックのフィルタリングの対策を行う
###### ・認証情報の盗難（Credential Theft）
　→強力なパスワードポリシー、多要素認証（MFA）、フィッシング対策教育を行う
###### ・インサイダー攻撃（Insider Threats）
　→監視とログ管理、アクセス権の最小化、データ損失防止（DLP）ツールを使用する
###### ・クラウドストレージの不正アクセス（Cloud Storage Misconfigurations）
　→ストレージ設定のレビュー、自動化ツールの活用、データのアクセス制御を行う

 ここまで読んでいただきありがとうございます
# ENGLISH
Good evening!
I'm participating in Advent Calendar 2024, and I'm going to write an article for the 19th day.
The subject is “Hiyari! Share your cloud security experiences by Netskope Advent Calendar 2024”, so I will summarize what I learned about cloud security.

### Threats Lurking in the Cloud
The following are some of the most well-known threats to the cloud.
Data Breach
Distributed Denial of Service (DDoS)
Credential Theft
Insider Threats
Cloud Storage Misconfigurations

Cloud Storage Misconfigurations ### How to Prevent?
###### ・Data Breach
　Data Breach: → Take countermeasures with encryption, access control, multi-factor authentication (MFA), etc.
###### ・Denial of Service (DDoS: Distributed Denial of Service)
　→Countermeasures include automatic scaling, DDoS countermeasure tools, and traffic filtering.
###### ・Credential Theft
　→ Strong password policies, multi-factor authentication (MFA), education on anti-phishing measures
###### ・Insider Threats
　→Æ Monitor and manage logs, minimize access rights, use data loss prevention (DLP) tools
###### ・Cloud Storage Misconfigurations
　→Review storage configurations, use automation tools, and control access to data

 Thank you for reading this far!
GitHub Actions ホステッドランナーって何？

# はじめに
今回、GitHub Actionsのホステッドランナーについて知る機会があり、少し調べてみました。

# GitHub ホステッドランナーって？
GitHubが提供が管理してくれるジョブの実行環境とのこと。
Ubuntu Linux、WindowsまたはmacOSで利用可能だが、後述する環境ごとに差異がある。
またリポジトリがパブリックかプライベートかでも差異がある。

https://docs.github.com/ja/actions/using-github-hosted-runners/using-github-hosted-runners/about-github-hosted-runners

# パブリックとプライベートなリポジトリでの違い

### パブリックリポジトリ
以下の標準ランナーを無制限で使用可能(以下はOSがLinuxのランナーの場合)
|OS|プロセッサ(CPU)|メモリ(RAM)|ストレージ(SSD)|ワークフローラベル|
|---|---|---|---|---|
|Linux|4|16GB|14GB|ubuntu-latest<br>ubuntu-24.04<br>ubuntu-22.04<br>ubuntu-20.04|
|Windows|4|16GB|14GB|windows-latest<br>windows-2022<br>windows-2019|
|macOS|4|14GB|14GB|macos-13|
|macOS|3(M1)|7GB|14GB|macos-latest<br>macos-14<br>macos-15|

### プライベートリポジトリ
GitHubの契約プランごとに無料で利用可能なリソースが決まっている。
無料枠を超過後は追加の使用料金が必要となる。
|OS|プロセッサ(CPU)|メモリ(RAM)|ストレージ(SSD)|ワークフローラベル|
|---|---|---|---|---|
|Linux|2|7GB|14GB|ubuntu-latest<br>ubuntu-24.04<br>ubuntu-22.04<br>ubuntu-20.04|
|Windows|2|7GB|14GB|windows-latest<br>windows-2022<br>windows-2019|
|macOS|4|14GB|14GB|macos-13|
|macOS|3(M1)|7GB|14GB|macos-latest<br>macos-14<br>macos-15|


https://docs.github.com/ja/billing/managing-billing-for-your-products/managing-billing-for-github-actions/about-billing-for-github-actions#per-minute-rates

さらにGitHub TeamまたはGitHub Enterprise Cloudプランに加入している場合は、より大きなランナー (larger runner)という標準より高度な機能を持った環境が使えるようになるようです。

https://docs.github.com/ja/actions/using-github-hosted-runners/using-larger-runners/about-larger-runners

# おわりに
すごくざっくりと書いてみましたが、別途CICD環境を構築したくない場合や、GitHub内でCICDを完結させたい場合には選択肢として大いに入ってくるのかなと思いました。特にパブリックリポジトリでコードを管理している個人などであれば、使ってみる価値はありそうです。
ソリューション開発での「つくってみないとわからない」は信じて良いのか

プロダクト開発の上流工程で「**作ってみないとわからない**」 「**ユーザーの反応を見てから**」「**一旦やってみて**」などをよく聞く方に向けた記事です。
私の失敗談に基づいています。

## 「つくってみないとわからない」を信じちゃいけない例
### 作ってみないとわからないはわかる、でも結果無価値になるのはやばい
**MVP (Minimum Viable Product)** でユーザーから良い反応を得られず、その結果お蔵入りとなるようなパターンです。

このケースでの特徴は次の通りです。

:::note warn
- そもそも解消しようとしていた課題がふわふわしたまま進んでいた
- 仕様に必要そうな要件が次々と増える
- サクッと開発するつもりが、意外と時間もかかった
:::

結局、**課題を捉えていない**という点が問題となります。
これが起こる背景はおそらく次の2点が多いです。

:::note alert 
- やりたいアイデアだから進めた
- 仕様を決めたり市場調査するのが面倒
:::

## 「つくってみないとわからない」を信じても良い例
### MVPがユーザーの課題を充足できなかったと明らかにわかる
これは先ほどの例と違い、狙っていた仕様が開発できなかったことや仮説の誤りに気付くことができます。

課題やニーズは残存しているため、

:::note warn
お蔵入りにするのではなく、次の施策が打てる
:::

点が特徴です。

このやり方になっている背景として考えられるは以下の通りです。

::: note
- 「つくってみた」後の展開(分岐)が決まっている
- 調査に時間をかけた
:::

### 遠い購買意思決定者が体験する必要がある
このケースは、**購買意思決定者との接点はないが、この人から Yes を取る必要がある**場合です。合理的な場合もありますし、悪しき風習としてこのような業務フローである可能性もあります。

ともかく、**十分なプレゼンの機会がなかったり、クリアのためにどのような条件なのかが見えていなかったり**します。

望ましくはないですが、会社の力関係などによっては発生するケースです。

## 役に立つフレームワーク
**Double Diamond Design Process** というやり方によって「作ってみないとわからない」を区別することができます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/986141/9a23bf0c-4d94-4f52-b515-32a39c5400fa.png)

この手法ではソリューション開発を、

- **左側：課題の発見のための調査**
- **右側：開発とユーザーからのフィードバックによる設計**

の2つのステップに分けます。さらに真ん中は一度収束するようになっています。

つまり、以下の順番となります。

:::note
1. **問題点をたくさん洗い出す**
1. **その中から今回解決すべき問題を定義する**
1. **その特定の問題に対して様々な開発をおこなう**
1. **フィードバックにより解決策を特定する**
:::


「つくってみないとわからない」の失敗パターンは、**問題の洗い出しと開発を同時にやろうとした場合**です。

また、MVPに対する認識が曖昧かもしれません。
MVPは以下のような特徴を持ちます。

:::note warn
- 問題を解決する
- 「違い」が明確
- 理解しやすい
:::

## 参考
https://www.thefountaininstitute.com/blog/what-is-the-double-diamond-design-process
Zodに入門してみました。学習時の記録

## Zodとは？
**TypeScript用のスキーマバリデーションライブラリです**
### **特徴**
・**スキーマベースの検証**
　データの形式や型を「スキーマ」で定義し、そのスキーマを使って簡単にデータ検証が可能
・**TypeScriptと相性抜群**
　TypeScript型をZodが自動で推測するため、**型定義の重複を防ぎ**、コードを効率化できる(型推論)
 ・**一貫した型とバリデーション**
バリデータを1回宣言するだけで、静的なTypeScript型を自動生成し、型の整合性を保てる。

### _インストール_
**要件**
・TypeScript 4.5以上
・tsconfig.jsonファイルのstrictモードを有効にする
``` tsconfig.json 
{ 
  // ... 
  "compilerOptions" : { 
    // ... 
    "strict" : true 
  } 
}
```
```
npm install zod        # npm の場合
yarn add zod           # yarn の場合
```
[zod document インストール](https://zod.dev/?id=installation)
## 使い方
**シンプルな文字列のスキーマの作成**
``` TypeScript
 //"zod"から{  z  } をインポートする 
import { z } from "zod";

// 文字列のスキーマを作成する
const schema = z.string();

// 解析
schema.parse("Hi"); // OK
schema.parse(123); // = > ZodErrorをスローする
```



**オブジェクトスキーマの作成**
```typescript
import { z } from "zod";

const User = z.object({
  username: z.string(),
});

User.parse({ username: "Eva" });//OK

// 推論された型を抽出する
type User = z.infer<typeof User>;
// { username: string }
```
[Zod document basic usage](https://zod.dev/?id=basic-usage)
# 型定義色々
### プリミティブの型定義
```typescript
z.string(); // 文字列型
z.number(); // 数値型
z.bigint(); // BigInt型
z.boolean(); // 真偽値型
z.date(); // Dateオブジェクト型
z.symbol(); // Symbol型
```
### 空の型（Empty Types）
```typescript
z.undefined(); 
z.null();     
z.void();      // 値が undefined または void であることを保証
```
### 全ての値を許容する型
```typescript
z.any();     // 任意の値を許容
z.unknown(); // 任意の値を許容（ただし明確な型情報がない場合に利用）// 数値型に条件を追加
```
### 型定義の具体例
```typescript 
const schema = z.number().min(1).max(100); // 1以上100以下

// 文字列型に条件を追加
const stringSchema = z.string().min(5).max(20); // 長さ5文字以上20文字以下
```
## 型推論
### .infer<T>
スキーマを利用してTypescriptの型を生成できる
!型推論により、Zodスキーマと重複してTypescriptの型定義をしなくて良い
```typescript
// Zodスキーマを定義
const UserSchema = z.object({
  id: z.number(),
  name: z.string(),
  isAdmin: z.boolean(),
});

// TypeScript型を自動で推測
type User = z.infer<typeof UserSchema>;

// 例: 推測された型を利用
const user: User = {
  id: 1,
  name: "Toni",
  isAdmin: false,
};
```

## スキーマメソッド
個人開発で使用したスキーマメソッドを２つ挙げます。
### .parse
dataを検証、有効かどうかを確認する。
有効であれば型情報を含む値を返す
無効の場合は、エラーをスロー
```typescript
const stringSchema = z.string();

stringSchema.parse("meat"); // => returns "meat"
stringSchema.parse(12); // throws error
```
[Zod document parse](https://zod.dev/?id=parse)
### .refine
TypeScript の型システムでは表現できない型やデータの検証を行う、
特定の条件を満たすかどうかをチェックする
**具体的な使用例：**
　数値が整数であるかどうかをチェック
　文字列が有効な電子メール アドレスであるかどうかをチェック
**引数：**
第一引数：条件を判定するための検証関数（例: value => value > 10）。
第二引数：エラー時に使用するメッセージやデータ。
**動作：**
 入力された値が条件を満たす場合、その値を通過させる。
条件を満たさない場合、エラーをスローする。
 ```typescript
 // 日付型に条件を追加
const dateSchema = z.date().refine(date => date > new Date('2024-01-01'), {
  message: "Date must be after 2024-01-01",
});
```
[Zod document refine](https://zod.dev/?id=refine)
## まとめ
Zodを使って初めてフォームを作成し、簡単なサンプルを備忘録として記録しました。
個人的には、TypeScriptの型定義を再度記述する必要のない点が便利だと感じました。
今後、Zod以外のバリデーションライブラリにもチャレンジしたいです。
## 参考
[Zod Document](https://zod.dev/)
[TypeScript開発に欠かせない？Zodライブラリの基本](https://dev.classmethod.jp/articles/basic_usage_zod/)
[サバイバルTypescript](https://typescriptbook.jp/reference/type-reuse/infer)
【基礎確認】pythonのlangchain_core.promptsモジュールChatPromptTemplate関数

# はじめに
[LangChainとLangGraphによるRAG・AIエージェント［実践］入門](https://www.amazon.co.jp/dp/B0DK4YGYBL?tag=xpg-22&linkCode=ogi&th=1&psc=1)
を読んでいて、10章で躓いたので、初心に戻って、一つずつ紐解いて学習することにしました。
今回のテーマは「langchain_core.prompts」モジュール「ChatPromptTemplate」関数

# 前回までの投稿
1. 必要なライブラリとモジュールをインポートする
[【基礎確認】pythonのoperatorモジュール](https://qiita.com/o_chan_t/items/4ad3cd5fc832f9be9d86)
[【基礎確認】pythonのtypingモジュール](https://qiita.com/o_chan_t/items/1f54806ad90c79904af2)
[【基礎確認】pythonのdotenvモジュール](https://qiita.com/o_chan_t/items/641eada727fa5a27aaf3)
[【基礎確認】pythonのlangchain_core.output_parsersモジュールStrOutputParser関数](https://qiita.com/o_chan_t/items/9a3d23537c7dc0327ddb)

# サンプルコード

```sample.py
from langchain_core.prompts import ChatPromptTemplate

# ChatPromptTemplateの使用例
prompt = ChatPromptTemplate.from_messages([
    ("system", "あなたは親切なアシスタントです。"),
    ("human", "こんにちは、{name}です。"),
    ("ai", "はじめまして、{name}さん。どのようなご用件でしょうか？"),
    ("human", "{request}")
])

# プロンプトの使用
formatted_prompt = prompt.format(name="太郎", request="今日の天気を教えてください。")
print(formatted_prompt)
```

```
System: あなたは親切なアシスタントです。
Human: こんにちは、太郎です。
System: はじめまして、太郎さん。どのようなご用件でしょうか？
Human: 今日の天気を教えてください。
```

## 解説
1. ChatPromptTemplateは、LangChainライブラリの一部で、チャットベースの対話を構造化するためのテンプレートを作成するクラス。

2. from_messages()メソッドを使用して、システムメッセージ、人間のメッセージ、AIのメッセージなど、複数のメッセージを含むプロンプトテンプレートを作成できる。

3. 各メッセージはタプルで表現され、最初の要素がメッセージのロール（"system"、"human"、"ai"など）、2番目の要素が実際のメッセージ内容である。

4. メッセージ内で{}で囲まれた部分は変数として扱われ、後でformat()メソッドを使用して値を埋め込むことができる。

このテンプレートを使用することで、一貫性のある構造化された対話を生成し、AIモデルとのやり取りを効果的に制御できる。
意思決定が早いとは？

# 意思決定が早い組織がいいんだけど
それってつまり、どういう状態？

# 意思決定が早いとは？
- 誰が意思決定者なのか共通認識がある
- 何があれば意思決定できるのかメンバーが理解できている
- 意思決定が移譲されている
- 自分が意思決定するつもりで報告できる
- 結果責任ではなく実行責任である。意思決定することは責任を取ることではない。
- 意思決定は承認プロセスではなく、コミットメント
- 意思決定は少ない方がいい
- ~~意思決定は早ければいいのではなく、最適なタイミングがある~~
- 意思決定前に情報格差が是正されており、決定基準が明確であれば自動化できる
- ただし、新たに発生した事実や懸念によって基準は改訂される
- 意思決定には意図があり、言語化された根拠があり、振り返りすることができる
- 悩む事と考える事は異なる。悩むのは情報が足りてないか、目的や基準が曖昧だから。
- 意思決定と決断は違う
- 意思決定はトレードオフであり、トレードオフが明らかになってなければ意思決定など、できない
- 心理的安全性とは無関係

# 一緒に読みたい本、記事

https://www.amazon.co.jp/gp/B07PD9ZLXG

https://www.amazon.co.jp/dp/B0912KV21C

https://www.amazon.co.jp/dp/B0722GRLQ5

https://www.amazon.co.jp/gp/B0B8H4TWMX

https://konifar-zatsu.hatenadiary.jp/entry/2023/07/12/220422

https://note.com/hirot02/n/n844f5e4b5ab3

https://tech-blog.tabelog.com/entry/2024/09/tabelog-engineer-information-communication

https://note.com/fladdict/n/nd134e030c784

https://speakerdeck.com/yayoi_dd/perfect-decision-making-in-software-development

https://yoshi389111.github.io/kinokobooks/mngr_ja/mngr103.htm
ブロックチェーン社会実装のための基礎知識概論〜さいごに〜

本書を通じて、ブロックチェーン技術の基本的な仕組みから、実社会での応用に至るまでの広範な内容を学んでいただけたかと思います。ブロックチェーンは、金融分野だけでなく、さまざまな業界に革命的な変化をもたらす技術です。データの所有権や透明性、信頼性を強化することで、従来のシステムが抱える課題を克服し、新たな価値を生み出すポテンシャルを持っています。

特に本書では、まず従来のシステムが抱える制約を理解した上で、ブロックチェーン技術の基本的な要素であるP2Pネットワーク、電子署名、スマートコントラクト、トークンなどの機能を一つずつ紹介し、ブロックチェーンがどのように社会に適用されているかを実例を通して解説しました。これにより、読者の皆様は、ブロックチェーンがどのように社会問題を解決し、ビジネスや公共分野において新しい機会を提供できるかについての洞察を得たはずです。

ブロックチェーンは、技術の進展とともに、さらに広がりを見せています。非金融分野での応用が進むことで、ますます多様な業界での利用が期待されており、これからの社会を支える基盤技術として、その可能性は無限大です。また、自己主権型アイデンティティやアポスティーユ、トレーサビリティなど、特定の分野での利用も広がり、信頼性の向上や効率化に貢献しています。

本書が皆様のブロックチェーン技術に対する理解を深める一助となり、これからの学びや実践に役立つことを心より願っています。ブロックチェーンの可能性は、今後も無限に広がっていくでしょう。新たな技術が私たちの社会にどのような変化をもたらすのか、そしてその変化にどう対応し、どう活用していくかを探求し続けてください。

今後、皆様がブロックチェーンを活用し、さらに新しい社会的価値を創造されることを期待しています。
【GPTプロンプト講座基礎編⑤】実践的なプロンプト例一覧

# §プロンプトエンジニアリング基礎編⑤
※本記事は執筆にあたり生成AIツールを使用している箇所があります
※プロンプトの基礎部分は生成AIで作成し、具体例や体験談を自分の視点で補完しています

こんにちは。ゆずかきです。

前回は、プロンプトエンジニアリングの注意点や最適化テクニックについて解説しました。今回は、さらに発展的なテーマとして、プロンプトエンジニアリングを活用した高度な応用例を紹介していきます。実践的な使い方を学びながら、新たな可能性を探っていきましょう。

　
# §高度な応用例1：複数ステップのタスク管理

複雑な作業をAIに任せる際は、プロンプトを段階的に分けるのが効果的です。

- 段階1：「次のプロジェクトの主要タスクをリストアップしてください。」
- 段階2：「リストアップしたタスクを、実行順に並べ替えてください。」
- 段階3：「各タスクに必要なリソースと所要時間を見積もってください。」

このように1ステップずつ進めることで、正確で具体的な結果を得られます。

　
**AIは人間のように「何となく察して」考えて動くということが苦手なので、ここは人間が適切に導いてあげる必要があるっていうことですね。**

　
# §高度な応用例2：専門性の高い資料作成

専門的な知識が求められる場合も、AIの力を借りることで効率化できます。

- 「次のテーマについて、学術的な観点から簡潔にまとめてください：AIが医療分野に与える影響」
- 「最新の研究論文をもとに、AIによる教育改革の具体的な事例を3つ挙げてください。」

文献やデータの参照を指示に含めると、信頼性の高いアウトプットを得られます。
　
**この場合、「ウェブ検索してください」をプロンプトの冒頭につけることが大切です**

　
# §高度な応用例3：クリエイティブなプロジェクト

創造性が求められる場面でも、プロンプトエンジニアリングは大いに役立ちます。

- 「新しいアニメーション映画のストーリー概要を200字で考えてください。」
- 「次のキャラクター設定をもとにした短編小説の冒頭を書いてください。」

具体的な要素（テーマ、ジャンル、キャラクター）を含めることで、AIのアイデアがより洗練されます。

　
# §高度な応用例4：予測と分析

データに基づいた予測や分析にもAIを活用できます。

- 「次の売上データをもとに、来月の売上予測を箇条書きで説明してください。」
- 「このデータセットから主要なトレンドを抽出し、3つのポイントにまとめてください。」

出力形式を指定しつつ、データ分析の背景情報を補足するのがポイントです。

　
# §高度な応用例5：カスタマー体験の最適化

顧客満足度を向上させるための戦略作りにも応用可能です。

- 「次の顧客レビューを分析し、改善すべきポイントを3つ挙げてください。」
- 「新しいプロモーションキャンペーンのアイデアを考えてください。ターゲット層は20代の学生です。」

ユーザーの視点を意識したプロンプトを設計することで、より具体的な提案が得られます。どの視点で考えるか？方向性を指定してあげるのは人間の役割です。

　
# §まとめ

高度なプロンプトエンジニアリングでは、複数の要素を組み合わせたり、段階的に指示を出したりすることが鍵となります。これにより、AIをより多様な場面で活用できるようになります。
　
**🔑 この記事のポイントまとめ**
**複数ステップのタスク管理 → タスクを段階的に分けて指示せよ。**
**専門性の高い資料作成 → 学術的観点やデータ参照を明示せよ。**
**クリエイティブなプロジェクト → 具体的な要素（テーマ・ジャンル）を指定せよ。**
**データ分析と予測 → 出力形式と背景情報をセットで提供せよ。**
**カスタマー体験の最適化 → ユーザー視点やターゲット層を明示せよ。**
　
次回は、AIを使いこなすためのマインドセットや、プロンプトエンジニアリングを学ぶ上での効果的な学習方法についてお話しします。どうぞお楽しみに！

ご訪問いただきありがとうございました！
Blender ベイクが真っ暗になるのを直す

## こうなっちゃう
このように、ベイクしても真っ暗になってしまう。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3962799/b381fcb2-cf72-deab-b9b9-3767bffd8556.png)
これを直す

## どうやったか
これがそのときのノード。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3962799/ae44534f-1e80-9ddc-628f-3d3206ff927b.png)

**間に`プリンシパルBSDF`をかませた**
これだけでよかった
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3962799/890536ce-61dc-b397-b745-4d68b97fa93f.png)

## 結果
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3962799/d2d99d17-059a-a9eb-2407-8f115cf907b0.png)
うまくベイクできるようになった

## 考察
[この記事](https://redhologerbera.hatenablog.com/entry/2023/07/07/231738#google_vignette)いわく、
`プリンシパルBSDF`の`スペキュラー値`が0になっていると、正常にベイクされないらしい。
なのでプリンシパルBSDFをつけてスペキュラー値が存在するようにしてあげるとベイクされるようになった。
【TypeScript】Type 'null' is not assignable to type 'string | undefined'.の解決方法

# はじめに
Reactで個人開発中に発生した型エラーについて、その原因と解決方法を共有します。

:::note warn
***この記事は<font color="Red">個人的なアウトプット</font>を目的として作成したものです。そのため、誤った情報や不足している内容が含まれている可能性があります。もし間違いや気になる点がございましたら、ぜひご指摘いただけますと幸いです***。
:::

# 原因
型エラーの原因は、型定義と実際の値が一致していないためです。

以下は具体的な問題箇所のコードです。
```react
type MenuProps = {
  pageId: string | undefined;
};

<Menu pageId={null} />
```
このコードでは、`Menu`コンポーネントに`pageId`という`props`を渡しています。しかし、渡している値が`null`であり、型定義の`pageId: string | undefined`に合致していないため、型エラーが発生しています。型定義では`pageId`の型を`string | undefined`としていますが、`null`はこの型には含まれていません。

# 解決方法
今回は以下のように修正しました。

```react
<Menu pageId={undefined} />
```

この修正により、型エラーが解消され、型定義と実際の値が一致するようになりました。

# 終わりに
型エラーは小さなミスから発生することが多いですが、正しい型定義を意識することで防ぐことができます。型定義について改めて注意していこうと思いました。

# 参考
『「Type 'string | undefined' is not assignable to type 'string'. Type 'undefined' is not assignable to type 'string'」の解決方法』Qiita

https://qiita.com/yutoun/items/757a0581719bbbbf4cdc

https://stackoverflow.com/questions/54496398/typescript-type-string-undefined-is-not-assignable-to-type-string
最初に「あい」を学ぶことば日本語でプログラミング入門（ステップ６ プロデルでお嬢様コーディング）


# はじめに
本記事シリーズは母国語のプログラミング言語が存在するという文化的価値をアピールするためのもので、プログラミング一般の入門を意図するものではないのですが、じゃあどんな意図なんですかということでは、これはあの日本語プログラミング言語ユーザー相互の交流目的という建付けでございます。今回はついにプロデルでいわゆる「お嬢様コーディング」です。わたし的に「お嬢様コーディング」というとなんとなく「[なでしこさん](https://qiita.com/snowdrops89/items/336a223e6ea052ef9688)」でございます。


## プロデル
プロデルは、日本語に近い語順で記述できる、オブジェクト指向の中間コードコンパイラ言語です。中間コードは共通言語ラインタイム(CLR)[^1]で、.NETアプリケーションと同じ実行環境で動きます。実装言語はC#。インタプリタ版もあります。
プロデル言語を.NET CoreのCLR中間コードにコンパイルするバージョンとしてスミレがあり、Webアプリケーションの次世代実行環境であるのWebAssemblyアセンブリ言語をコンパイル出力するようにしたスミレ畑があります。


## プロデルの入手方法
プロデル(Windows版)を下記の公式サイトからダウンロードできます。

https://produ.irelang.jp/downloads/

# お題のソースコード
```mind:ai.rdr
愛するとは
    人や物事を大切に思う心のことでございますわ。
```

[前回](https://qiita.com/mylifewithviolin/items/6b09dbd6d9b808d53313)に続き、これをプログラムとして実行してみます。

プロデルの場合もこのようなひらがなをどのように処理するのかは実はわかっていません。Mindと同じ雰囲気でとりあえず書いてみます。

```mind:ai.rdr
人は　　「自分や自分以外の人間、」
物事は　「もろもろの物や事柄などを」
大切は　「大事に思っている心のありようのことで、漢字では[「]愛[」]と表記するのでございますわ。」

愛する。

【人】や【物事】を【大切】に思う心のことでございますわ手順
    「[人][物事][大切]」を表示
終わり。

愛する手順
    人や物事を大切に思う心のことでございますわ
終わり。
```

#  お題のソースコード実行結果
実行結果です。実行環境はプロデルデザイナです。

![produireai2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3118036/e45f0ff2-403d-3700-bc1a-02fc34232036.png)

おおっ！いっぱつで実行できました！:santa_tone2:

ところで、「愛する」とはやっぱり手順なのでしょうか！？愛するということは行為である以上手順化しうるものであるような気がします。愛を伝えるということからは言語が関係してきますが、下記のリンクの愛の一次言語のお話はたいへん感慨深いものでした。

https://chamublog.com/love-language/

# おわりに
いかがでしたでしょうか？わたしはわが国に母語によるプログラミング言語が存在することを誇りに思っております。言語は文化。こんにちの日本語のポップスやアニメソングなどが海外でそのまま歌われるような近況を鑑みますと、純然たる技術基盤として超強力な米欧発プログラミング言語勢と存在意義を争うこともなく、日本語の文化として海外でも日本語プログラミング言語の愛される日が来るのやもしれません。

[^1]: Common Language Runtime, CLR は.NETアプリケーションを実行するための仮想機械
エンジニアが色彩検定を取って感じた周りとの“ズレ”

# はじめに
「色に対する自分の印象を言語化した言葉が、自分の言いたいことをうまく伝えられてない気がする」
これが色彩検定3級を取ろうと思ったきっかけです。
サイトの色が他と合っていない気がするのに、「明るい」や「暗い」といった言葉でしか表現できず、もどかしく感じていました。
この記事では、エンジニアとして色彩を学ぶ中で感じた「こだわり」と「ズレ」について書きました。

# 色彩検定を取った理由
色彩の勉強をしたいですが、どの教材が体系的にまとめられているか全く検討がつきませんでした。
けれど、検定教材なら分かりやすくまとまっており、UIを作る場面で「どんな配色が見やすいか？」に対して、適当に選ぶのではなく根拠を持ちたかったからです。

# 色彩勉強後に訪れた“ズレ”
色彩検定を取ると、色の組み合わせや配色の理論がなんとなく頭に入ります。結果どうなるか？
- 「あのボタン、コントラストが足りなくないですか？」
- 「全部が青色すぎるから、背景はもう少しトーンを下げたほうが見やすいですよね」

同僚からすると、突然細かいことを言う面倒な人になったと感じたかもしれません笑
特に、エンジニア仲間が作ったデザインに「少し待った！」と言ってしまう自分に、周りとの感覚のズレから負い目を感じることも。
提案すると「そんなの人の好き嫌いじゃん」と言われたこともあります。

# 色彩の知識を持つメリット
ただ、このズレは時に役に立つ武器にもなります。
1\. UI/UX改善の場面
プロダクトの色使いについて、「色覚障害のユーザーにはどう見えるか」を意識するようになり、アクセシビリティ改善に貢献できました。

2\. 議論が具体的に
配色を感覚ではなく理論で説明できるので、「赤がいい」ではなく「視認性の観点でこの配色がベター」と伝えられるようになりました。

# おわりに
色彩検定を取ったことで難しく感じていた「デザイン」により興味を持つようになりました。
確かに周囲と評価軸がズレることはありますが、それはむしろ新しい視点を持てた証拠と考えています。ズレを楽しむことで、より良いソフトウェア作りに役立っています。
よかったら、みなさんも色彩の勉強をしてみてください。