OmniAICreator/Qiita-1.07M huggingface dataset:
UnityのHierarchyウィンドウで階層構造を色分け表示する

:::note info
この記事は [SLP KBIT Advent Calendar 2023](https://adventar.org/calendars/9222) 3日目の記事です。
:::
https://adventar.org/calendars/9222

## はじめに

この記事では、Unityのエディター拡張機能を使用して、Hierarchyウィンドウの各オブジェクトを階層レベルに応じて色分けする方法を紹介します。

オブジェクトが多くなり階層構造が複雑になると素早く視覚的に識別するのは難しいと感じました。そのため、この機能を作成することにしました。


## 想定している対象者
この記事は以下の条件に合った人を対象にしています。
- Unityの基本的な知識があること。
- Unity 2019.4 LTS以上のバージョンを使用していること。

VRChatのアバター改変などで階層が深く複雑な階層構造のオブジェクトを操作する人の助けになればと思います。

## 基本概念
エディター拡張機能を使用すると、Unityのデフォルトのエディターインターフェイスをカスタマイズできます。これを利用してオブジェクトを階層レベルに応じて色分けする機能を作成します。

## 実装手順
1. **エディタースクリプトの作成**
    - `Assets/Editor`フォルダを作成し、新しいC#スクリプト`HierarchyColorizer.cs`を追加します。

2. **スクリプトの内容**
    ```csharp
    using UnityEditor;
    using UnityEngine;
    
    [InitializeOnLoad]
    public class HierarchyColorBeforeName
    {
        static HierarchyColorBeforeName()
        {
            EditorApplication.hierarchyWindowItemOnGUI += OnHierarchyWindowItemOnGUI;
        }
    
        private static void OnHierarchyWindowItemOnGUI(int instanceID, Rect selectionRect)
        {
            GameObject gameObject = EditorUtility.InstanceIDToObject(instanceID) as GameObject;
    
            if (gameObject != null)
            {
                int depth = CalculateDepth(gameObject);
    
                // 階層ごとのインデントの幅をピクセル単位で計算
                int indentWidth = 2; // 通常のインデント幅を14ピクセルとする
                int totalIndent = indentWidth * depth;
    
                // 階層の深さに応じたオフセットを適用（微調整用）
                int offset = depth * 2; // 階層の深さに2ピクセルずつオフセットを追加
    
                // オブジェクト名の前に色を描画するための矩形を定義
                Rect colorRect = new Rect(selectionRect.x + totalIndent - offset, selectionRect.y, 3, selectionRect.height);
    
                // 色を決定
                Color color = Color.HSVToRGB((depth * 0.1f) % 1.0f, 0.6f, 0.8f);
    
                // オブジェクト名の前に色を描画
                EditorGUI.DrawRect(colorRect, color);
            }
        }
    
        private static int CalculateDepth(GameObject obj)
        {
            int depth = 0;
            while (obj.transform.parent != null)
            {
                depth++;
                obj = obj.transform.parent.gameObject;
            }
            return depth;
        }
    }

    ```
    - このスクリプトは、Hierarchyウィンドウの各アイテムの背景色を階層レベルに応じて変更するものです。

## 比較
- 実装前
![スクリーンショット 2023-12-03 024758.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2367410/9255fc41-5a9d-261c-7944-0521aaa08636.png)

- 実装後
![スクリーンショット 2023-12-03 031305.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2367410/8c0e5a21-92cd-25c4-d951-7ac91068bdac.png)




## 最後に
この簡単なエディター拡張を通じて、UnityのHierarchyウィンドウがより使いやすく、効率的になりました。複雑な階層のオブジェクトを扱うプロジェクトで役に立ててほしいです。
汎用型目標設定フレームワーク ギャップ編


この記事は『カオナビ Advent Calendar 2023(シリーズ2)の 3日目』です。

https://qiita.com/advent-calendar/2023/kaonavi


## はじめに
1日目に続いて３日目も投稿です。
カオナビVPoEのKeeeenです。

今回のテーマは目標設定です。
長くなってしまったので前編/後編に分けて書いていきます。
(実際の目標設定フレームワークは後編で)

## 本題に入る前に
目標設定によってどれだけ多くの人がこれまで悩まされてきたことでしょうか。

**『せっかくなら自分のやったことをちゃんと評価してほしい！』**
**『やってきたことがちゃんと市場価値に反映されてほしい！』**

そう思ったことがある人も多いのではないでしょうか。かく言う私も若かりし頃は『こんなに貢献しているのになんで自分のイメージする評価や給与と乖離するのだ』と思うことが多々ありました。
ではなぜこのような**評価者と被評価者の間でギャップ**が生まれるのでしょうか？

VPoEに就任して何年か経ち、これまで職務経歴書も数多見てきました。
調べる方法がわからないので正確ではありませんが、おそらくすべてのエンジニアの中でも上位10%に入るくらいには職務経歴書を見てきたのではないでしょうか。
この投稿では多くの人を不幸にしている様々なギャップをそんな私だからわかる視点から解き明かしていきたいと思います。

## ギャップについて
### 評価者と被評価者の間のギャップはどうして生まれるのか？
結論からいうとギャップが生まれる理由の多くはだいたい下記の３つになるかと思います。
>１．評価者が被評価者の成果を正しく理解できないから
２．被評価者にとって市場感を理解することが難しいから
３．会社がそもそもそういう文化だから

以下でこれらについて解説していきます。

#### １．評価者が被評価者の成果を正しく理解できない
評価者が正しく理解できないと思われる象徴的なシーンの例を以下に示します。
>例：『〇〇さん(上司や評価者)はエンジニアじゃないから私の成果を正しく理解してくれない』

しかし実はこのセリフ、詳しく分解すると２つのパターンが存在しているのです。

**パターン①：専門的過ぎて本当に評価できない**
**パターン②：理解はできているが、現状では評価が難しい**

パターン①の場合は被評価者と同じ専門職でなければ解決が難しいこともあります。
カオナビ社ではそういう事態が可能な限り起こらないようにするために、専門職評価者が必ず評価フローに入って評価を行っています。この場合は仕組み化することで簡単に改善できるので、もし解決できないのならばエンジニアが正しく評価される会社に転職することをお勧めします。

問題はパターン②の場合です。評価は**会社のフェーズやスタンス、状況によって変わる**ものです。なので被評価者はそれらの情報を正しく理解した上で成果を出さなければなりません。
例えばいきなり砂漠にほっぽり出されたとします。その場合まずやるべきことは『水の確保』や『気温変動の対応』でしょう。しかし、最初に『英語の習得』を目指していればそれは得策と言えるでしょうか？百歩譲って他の言語を習得するにしてもそれは英語ではないでしょう(砂漠がある地域の多くは英語圏ではないのでw)。また、水の確保をするという意識はあるもののその手法が『どこかから水路を引く』という手法だったらどうでしょうか？水路を引けるならすでに水の確保はできているので論理的に順序を間違っていますし、仮にここで実際水路を引けたとしてもキャリアとしては本質的な評価よりも小さいものになるでしょう。
わかりやすいようにとても極端な例を書きましたが、成果に関してギャップが生まれた時は大なり小なりこのような認識のズレが発生していると思います。

また**評価者側も強く意識をしなければならないこと**があります。それは先の砂漠の例でいうとずっと水を確保することだけを被評価者に求めてはいけないということです。水を確保する練度が上がることは良いことではありますが、ある程度の練度になれば**他の経験を積むことの方がその人のキャリアにつながる**ということを意識しなければなりませんし、次の項で話す市場価値を意識しなければなりません。

### 被評価者にとって市場感を理解することが難しい
さて、次に話すのが評価と市場価値の話です。

様々な層の年収を見れる人は限られていますが、それができる人にとってはだいたいどれくらいの年収でどれくらいできる人というイメージができています。逆にいうと多くの人はこのイメージがないので、求められているレベル感を把握できていないことがほとんどです。この意識が**自己評価と実際の評価が乖離**を産み、『会社は私のことを評価してくれない/できない』となってしまいます。先にあげた若かりし頃の私もこの罠にハマっていました。

では様々な層の年収が見れない人が自分の市場評価をどのように把握すればいいかというと、簡単な方法があります。**転職サイトに登録すればいい**のです。但し1つの転職サイトや1社で測る場合は注意が必要です。ある転職サイトでは高く出たり、ある会社では市場価値より高く評価することもあります。
複数やるのは面倒！そう思われる方はカオナビ社を受けてみるといいかもしれません。カオナビ社はかなりちゃんと市場価値で評価できる会社なので、カオナビ社以外の人で気になる方は一度受けてみることをお勧めします。


### 会社がそもそもそういう文化
会社によってはそもそもエンジニアのキャリアアップを考えていない会社もあります。しかしそれはそういうスタンス、文化なので良い悪いではなく、その人に取って合う、合わないの話だと思っています。
もし合わないのであれば、カオナビ社のような会社に転職することをお勧めします。

## まとめ
### ギャップの種類
>１．評価者が被評価者の成果を正しく理解できないから
２．被評価者にとって市場感を理解することが難しいから
３．会社がそもそもそういう文化だから

### ギャップをなくす方法
**自分の市場価値と価値貢献できることを把握すること**

いかがでしたでしょうか？
少しでも共感してもらって気になる方がいれば、次の投稿も読んでもらえると嬉しいです。
次はこのギャップを理解した上でどう目標を設定するかについて書いていきます。

それではシリーズ2の4日目の記事もお楽しみください！！

https://corp.kaonavi.jp/recruit/recruitment/
本業にプラス！自社サービスで副業を始めて1年経った振り返り

この記事は、[Lancers（ランサーズ） Advent Calendar 2023](https://qiita.com/advent-calendar/2023/lancers) の3日目の記事です。

https://qiita.com/advent-calendar/2023/lancers

こんにちは。
ランサーズでLaravelエンジニアをしている和田カツと申します。

ランサーズに入社後、エンジニア人生で初めて副業に着手しました。

最初は弊社看板サービスである、[Lancers](https://www.lancers.jp/)に登録して副業を始めました。
しかし、本業と並行して副業でも開発業務を請け負うのは、かなり身体的、精神的負担が高いものでした。

そこで、もう一つの自社サービス「[Menta](https://menta.work/)」というサービスを活用し始めました。

https://menta.work/

**Mentaとは、[教えたい人（メンター）](https://menta.work/about_mentor)と[学びたい人（メンティー）](https://menta.work/about_mentee)のマッチングをお手伝いするサービスです。**

Mentaに会員登録をしたのが、昨年の12月だったので、**今月で1年**経ちました。
そこで、１年間のMenta副業活動を振り返っていきたいと思います。

# １年間何を教えていたの？

私が人に教えられることは**Laravel**くらいしか思いつきませんでした。
そこで、Laravelを用いた機能追加やバグ修正について学びたい方（困っている方）を助けるプランを開設して、Laravelに関する色々なお悩みや学習についての相談を受けてきました。

https://menta.work/plan/8566

その他、下記のような相談事のサポートもさせていただきました。

- Dockerを用いたLaravel環境構築
- VS Codeから開発環境サーバーへの接続サポート
- [All in One SEO](https://ja.wordpress.org/plugins/all-in-one-seo-pack/) のSNSサムネイル設定

人に教える事で、自分のLaravelに対する理解に更に磨きをかけることができました。
副業を通して、本業にも良い影響を与えることができたのは非常に良い経験でした。

# １年間で何件教えたの？

## プランの契約数:  45件

プランの中には、**単発（1回のみ）**と**月額**のコースを用意していました。
大体８割が単発契約の方で、たまに月額で数ヶ月契約してくださる方もいました。
同じ方が複数回単発で契約してくださることもありま。

私のプランは、基本的に**チャット**と**ビデオ通話**どちらでも対応可能にしています。
ビデオ通話を希望される方が**９割以上**でした。
チャットをメインで希望される方はほとんどいませんでした。（多分１年間で、１〜２人くらい）

ビデオ通話のほうが、画面共有を駆使してデバッグや現状把握を素早く行えるので、個人的には好きです。

## プラン以外の契約数: 17件

プラン以外の相談に対しても、最初はLaravelに関することに絞って教えていました。
しかし、半年経った頃には、時に全く関係のないフロントエンドやインフラに関することを教えることも増えました。

最初は、Laravel以外のことについては本職じゃないしな〜と敬遠していました。
しかし、何か相談事を持っているメンティーさんにメッセージを送って、学びたいこと（困っていること）の詳細を聞いてみると、自分のこれまでの経験で対処できることが意外と多かった印象です。
自分も、その相談事を通して勉強させていただき、成長することができました。

# １年間でいくら稼いだの？

Mentaで１年間に稼いだ金額は以下の通りです。

![スクリーンショット 2023-12-03 2.58.46.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/838340/959b9c16-8d4a-cc20-500b-aecc293cee43.png)

売上からサービス手数料を引いた上記の利益が、私の手元に入ってくる金額です。

１２ヶ月で割ると、大体**１ヶ月あたり2万円**とそこまで多い金額ではありません。
もちろん、開発業務をガッツリ請け負った方が懐に入ってくる金額は何倍も良いと思いますが、実入りが多い分稼働時間も増えるので、人によっては本業との両立が難しいと思います。（私もその一人でした。。）

しかし、Mentaでの副業は自分で**柔軟に働く時間を決める**ことができ、**自分の体に必要以上の負担をかけず**に済みました。
副業が原因で、身体的または精神的に疲れて本業に支障が出てしまっては、本末転倒ですよね。
個人的には、Mentaで**ゆる〜く稼ぐ**のもありかなと思います。

# 最後に

以上が、自社サービス[(Menta)](https://menta.work/)で始めた副業の1年記念の振り返りです。

副業解禁になってから、周りで色んな人から副業で「〜〜を始めたよ」という話をたくさん聞くようになりました。
しかし、あまり副業の成果について話している人は、少なかったように思ったので今回の記事を書こうと思いました。
あと、自社サービスを使って副業してる人も意外といないのかなと思ってます。

---

### 一緒にMentaで教えてみませんか？

Mentaでは、プログラミング**以外**にも多種多様なカテゴリについて教えることができます。
最近では、**占い**、**フィットネス**、**ゲーム**といったカテゴリもあるので、ご自身の強みとマッチする領域がきっと見つかるはずです。

百聞は一見に如かずなので、まずは気軽に[Menta](https://menta.work/)に遊びにきて、色々覗いてみてください。

https://menta.work/

この記事を読んで、皆さんの副業の選択肢が少しでも広がれば嬉しいです。
また、皆さんがしてる副業についての記事もあればぜひ読みたいので、シェアいただければ幸いです🙌
10年使えるパソコンを作りたい(一般家庭編)

# 概要

昨年2022年10月に作った自作PCの構成を紹介します。


# 背景

妻の実家のパソコンの動きが遅くなり、調子が悪くなってしまいました。Windows 10のサポート期限が近づいていることもあったのでWindows 11に早く変えたかったのと、当時評判の良かったIntel Core i3を使ってみたかったので、自作PCを組むことにしました。


# 方針

- 私の使いたい部品を使いつつ、全体の値段はできる限り安く抑える。
- 10年快適に使えるパソコンを目指す。そのために少し性能の良い部品を選ぶ。
- 一般家庭で良く使われるWeb閲覧や動画試聴、オフィスソフトが快適に動くパソコンを作る。


# 構成

## CPU

Intel Core i3 12100

https://www.intel.co.jp/content/www/jp/ja/products/sku/134584/intel-core-i312100-processor-12m-cache-up-to-4-30-ghz/specifications.html

Core i3ながら数年前の高性能モデルを越える性能を持っており、コスパの良いCPUです。Core i3を使ってみたかったので選びました。今回の用途なら全く問題無く、快適です。グラフィックボードを組合せればパソコンゲームにも対応できる性能を持っています。

リテールクーラーを付属している点も嬉しいです。CPUクーラーの費用を抑えられます。今回の用途ならリテールクーラーで十分冷えます。動作音も気にならないです。


## マザーボード

GIGABYTE B660M DS3H DDR4 (MicroATX) ドスパラ限定モデル

https://www.dospara.co.jp/SBR1530/IC477760.html

価格を抑えるためにMicroATXです。開発はしないので拡張性は不要と考え、MicroATXでも問題無しと判断しました。

ミドルクラスチップセットB660で安い中で、将来の拡張性を考慮してUSB-Cが付いているモデルを選びました。メモリを4本刺せる点やUSB2.0ポートが付いている点も良いです。

今回は無線LAN不要だったため無線LAN無しで探しており、コストダウンに寄与しています。


## グラフィックボード

無し。その代わりに、グラフィック内蔵のCPUを選んでいます。

グラフィックボードの故障リスクを減らし、グラフィックボード故障時のトラブル対応の手間を省くことを狙っています。


## メモリ

Crucial DDR4 PC4-25600 8GB 2枚組

家庭用用途なら16GBで十分と判断しました。
DDR5が高かったのでDDR4です。定格3200MHzのメモリを選んでいます。


## SSD

KIOXIA EXCERIA G2 NVMe (500GB)

https://www.kioxia.com/ja-jp/personal/ssd/exceria-g2.html

家庭用用途なら500GBで足りると判断しました。KIOXIAを使ったことが無かったので選んでみました。問題無しです。


## 電源

玄人志向 KRPW-L5-400W/80+ (400W)

https://www.kuroutoshikou.com/product/detail/krpw-l5-400w-80-.html

安定性とコスト重視です。

プラグイン式ではありませんが、使わないケーブルの紛失を気にしなくて良いという利点があると思っています。


## ケース

Thermaltake Versa H17

https://jp.thermaltake.com/versa-h17.html

コスパ重視の定番ケースです。安いですが質感は悪くないと思います。マザボ用のスピーカーが付いているのが嬉しいです。


## ケースファン

Versa H17に添付のケースファンのみ。今回の用途なら十分です。


## OS

Microsoft Windows 11 HOME

10年サポートしてくれるのがベストですが、サポートが切れてしまったらLinuxなどを入れて使うことを目論んでいます。


# 値段

以上の合計で約7万円(OS込み・当時の価格)でした。


# 感想

以前のパソコンより快適になったので、1年以上経ちましたが現状問題無さそうです。

前回のパソコンは4～5年くらいで動きが遅くなってしまいました。今回のパソコンはメンテしながら使うことで長持ちして欲しいと思います。
python 公共交通機関のデータを基にした単回帰分析

# はじめに
昨今、AIの活用が叫ばれる世の中になりました。
ディープラーニングとか、ニューラルネットワークとか、色々あると思いますが、
そもそもAIを使わなくていい分析や予測というものが世の中には多々存在します。

逆に言えば、AIを使うか使わないかという判断は、あるやり方に従っていけば
おのずとわかるようになっています。

この記事は、AIを使わなくても済む分析の例をあえて紹介し、技術活用のリテラシーを
皆様方に高めていただくことを目的とします。
比較的低レイヤーな話も織り込みながら、AIの活用の最も基礎となるところを
説明したいと思います。

# 回帰モデルと機械学習モデル
皆様ご存知の通り、AIというのは何らかの規則に従って将来的な振る舞いを予測することに
使うことができます。

### モデルとは
データの予測や解析を行う、ある一定の規則のことを言います。

### データ分析のモデルを簡単にまとめる
大学で学ぶレベルの話ですみませんが、ざっくり言うと下記です。
- 単回帰分析モデル・・・学習・予測したいデータのための材料が１つしかない場合に使える。
- 重回帰分析モデル・・・学習・予測したいデータのための材料が複数個ある場合に使える。
- 機械学習モデル・・・重回帰分析データと比べて学習・予測の精度を高めたい場合に使える。

単回帰分析、重回帰分析モデルは、言ってしまえばただの計算式です。
これはAIでも何でもありません。

では、最初から機械学習モデルを使えばいいかというと、そうではないと思います。

### 回帰分析と機械学習の切り分け

一般的には、
- 学習・予測したいデータ
- 学習・予測の材料としたいデータ
の2つの相関係数を取って、相関が高ければ機械学習を使用する必要は薄いと言われます。

どの程度の相関係数がいいか、明確な基準はありません。
私が聞く限りでは0.7～0.8程度あれば機械学習モデルがそもそもいらないといわれます。

一方、クラスタリングなど、データの分類を行いたい場合は最初から機械学習モデルを
検討してもいいと思われます。その辺は使用目的に応じて検討した方がいいと思います。

# 単回帰分析の適用例の紹介

今回は、最も簡単である単回帰分析を適用した例を紹介します。

### 鉄道の車両数について


![DSC_7421.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/213945/4365b757-b465-a0fa-b28c-a226e47c8d47.jpeg)
富山県の富山地方鉄道の電車(3両編成)


ご存知のように、人の多い都会では電車の車両が8両～10両と長く、
人が少ない田舎では1～3両程度の電車を目にすることが多いと思います。

しかし、車両が短いからといって電車が混雑しているとは限りません。
むしろ、車両が長い都会の電車の方が混雑がひどく、地方の人間からは
「満員電車は嫌だ」と言われることも多いと思います。

では、鉄道会社は何を基準にしてやり繰りする車両の数を決めているのでしょうか？

### 輸送密度について

鉄道路線に客がどれくらいいるかという指標の1つとして「輸送密度」という基準があります。
これは、鉄道会社が路線に設定している距離長(km)に対して
1kmあたり1日にどれくらいの客が乗っているかというものです。

### 輸送密度と鉄道会社の車両数の関係を学習させる

いくつか、鉄道会社のオープンデータをとって学習させることにします。
機関車など、客を乗せない車両はカウントしませんでした

また、ただ単純に輸送密度を比較すると学習の精度が悪くなりそうだったので、

「各路線の輸送密度×営業キロ数」の重みづけのデータを入れることにしました。
![スクリーンショット 2023-09-07 000131.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/213945/216105a8-ad5d-8d14-47c4-e33f14269060.png)

実行結果は
決定係数：0.8062197244938027

となり、回帰モデルとしての精度はまあまあかなと思います。

### 回帰モデルの課題

上記の回帰係数を求めるプログラムに、入力変数としてあるデータを追加しました。
![DSC_3404.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/213945/859f0e16-31a1-792c-279f-86ab0b55de3b.jpeg)
昔友達に連れて行ってもらった鉄道があります。
新潟県と群馬県の県境を走る上越線という路線があります。
この路線は、利用客が非常に少なく、1日にたったの5往復か6往復しか電車が走っていません。
マニアの間では秘境として知られてるそうです。

調べてみると、この区間では1日あたり22両の電車を活用して客を乗せていることが分かり、
そのデータを先ほどのソースに付け加えて単回帰分析を再実行しました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/213945/a7e78eb2-44b2-22d0-654a-5251b7084cae.png)

すると
回帰係数：0.7831190021539549
となり、回帰式としての精度が落ちてしまいました。

調査したところ、この路線に限り別の路線と共同で車両をやり繰りしている関係で、
1日あたりの運行車両数がどうしても多くなってしまうようです。

細かい事は分かりませんが、
- JR線のように、多数のネットワークを持つ路線
- 地方の鉄道のように、わずかな路線長から成り立つ路線
では、回帰モデルを使い分けた方がいいのかもしれません。

# まとめ

- 電車の路線の車両数は、各路線の「輸送密度」というデータと何らかの関係がある
- 逆に言えば輸送密度が落ちることを予測して将来の車両数を減らす分析をすることができる
- ただし、JR線のように全国にネットワークがある会社と、地方の零細企業は比較対象にしない方がいいのかもしれない
【Drupal】フィールドの値を空にしたい。

以前、新機能のリリースに合わせて、デプロイ時に特定のフィールドの値を空にするという実装を行いました。
そこで、中々空にすることができずハマった経験があったので、備忘録として残します。

## やりたいこと
一度、やりたいことを整理します。
「記事コンテンツタイプの``fuga``フィールドの値を空にしたい」です。

## 実装
### 失敗例
まずは、失敗例から...
```php
function hoge() {
  foreach (\Drupal::entityTypeManager()->getStorage('node')->loadByProperties([
    'type' => 'article',
  ]) as $node) {
    $node->get('field_fuga')->delete();
  }
}
```

### 正解
```php
function hoge() {
  foreach (\Drupal::entityTypeManager()->getStorage('node')->loadByProperties([
      'type' => 'article',
  ]) as $node) {
    $node->set('field_fuga', NULL)->save();
  }
}
```
Coreソース内の``delete();``メソッドを追って関数内を見てみましたが、値を空にするようなプログラムはかかれていないようです。
この場合は、``set('{ フィールド名 }', NULL)``なんですね。
【Drupal】hook_update_N のリセット方法

新機能のリリース・バグ改修では、``hook_update_N``を実装することが多いですよね。
``hook_update_N``は、「DB更新時に実行を行うものとされ、実行後にモジュールのバージョン情報がデータベースに刻まれる」という仕様があります。

そのため、実装の単体テストやデバッグをするにあたって工夫されている方もいるかと思います。

工夫例として...
- Databaseのリストアを繰り返したり...
- 都度、別のモジュールを実装してスクリプトを検証したり...

ちょっとそこまでするのは馬鹿らしいですよね。

そこで今回は、一度走らせた番号をリセットしてくれる``Drush``コマンドを紹介しようと思います。

## リセット方法
```shell-session
drush php:eval "\Drupal::service('update.update_hook_registry')->setInstalledVersion('custom_module', 10002);"
```

上記のコマンドを実行すると、データベース内のモジュールのスキーマバージョンがリセットされます。

https://api.drupal.org/api/drupal/core%21lib%21Drupal%21Core%21Update%21UpdateHookRegistry.php/function/UpdateHookRegistry%3A%3AsetInstalledVersion/11.x


## 参考リンク
https://drupal.stackexchange.com/questions/179485/how-do-i-re-run-updates-change-module-schema-version

## ``hook_upadte_N`` について
``hook_update_N``は DataBaseの更新を行うものです。データベースの Contents や Config 等に変更をかけることが可能です。

https://www.drupal.org/docs/drupal-apis/update-api/introduction-to-update-api-for-drupal-8

## 関連
https://qiita.com/umekikazuya/items/421cf61a64b363cf9080
AWS Secrets Manager で値の一括取得が可能に - BatchGetSecretValue

# 内容

新しい API である **`BatchGetSecretValue`** で、複数のシークレットを同時に取得できるようになりました。

この機能により、一度に 1 つのシークレットを取得するために繰り返し呼び出したり、複数のシークレットを取得する際に部分的な失敗を考慮したりする必要がなくなり、全体的な効率が向上します。

https://aws.amazon.com/jp/about-aws/whats-new/2023/11/aws-secrets-manager-batch-retrieval-secrets/

https://docs.aws.amazon.com/ja_jp/secretsmanager/latest/apireference/API_BatchGetSecretValue.html


# やってみる

適当な シークレットを 2 つ準備。 
![スクリーンショット 2023-12-03 1.49.58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/280929/4abf9623-0d71-4d18-17be-14b074484ed0.png)

AWS CLI で実行

```
aws secretsmanager batch-get-secret-value --secret-id-list "secret001" "secret002"
```

結果

```json
{
    "SecretValues": [
        {
            "ARN": "arn:aws:secretsmanager:ap-northeast-1:１２３４５６７８９０１２:secret:secret002-MxP9hU",
            "Name": "secret002",
            "VersionId": "45d9265e-8bb9-4718-94fe-cdce3fd02540",
            "SecretString": "{\"user\":\"user002\",\"pass\":\"pass002\"}",
            "VersionStages": [
                "AWSCURRENT"
            ],
            "CreatedDate": "2023-12-03T01:48:31.571000+09:00"
        },
        {
            "ARN": "arn:aws:secretsmanager:ap-northeast-1:１２３４５６７８９０１２:secret:secret001-K7ddGd",
            "Name": "secret001",
            "VersionId": "0682d67a-210a-4efa-a396-ac5ed1942131",
            "SecretString": "{\"user\":\"user001\",\"pass\":\"pass001\"}",
            "VersionStages": [
                "AWSCURRENT"
            ],
            "CreatedDate": "2023-12-03T01:47:49.148000+09:00"
        }
    ],
    "Errors": []
}
```
Goで簡易WEBサーバを作成

# 記事概要
簡易WEBサーバを作成。

# スクリプト
```go
package main

import (
	"log"
	"net/http"
	"net/http/httputil"
	"net/url"
	"os"
)

func main() {
	port := "8080"  // デフォルトのポート番号
	ip := "0.0.0.0" // IP

	// コマンドライン引数からポート番号を取得
	if len(os.Args) > 1 {
		port = os.Args[1]
	}

	// / へのアクセスが来た時に dist フォルダ内のコンテンツを表示するハンドラを設定
	http.Handle("/", http.FileServer(http.Dir("./dist")))

	// /hoge へのアクセスが来た時にリダイレクトするハンドラを設定
	http.HandleFunc("/hoge", func(w http.ResponseWriter, r *http.Request) {
		http.Redirect(w, r, "http://localhost:3000", http.StatusFound)
	})

	// /piyo へのアクセスが来た時にリバースプロキシとして転送するハンドラを設定
	filesProxy := httputil.NewSingleHostReverseProxy(&url.URL{
		Scheme: "http",
		Host:   "localhost:5001",
	})
	http.Handle("/piyo", http.StripPrefix("/", filesProxy))

	addr := ip + ":" + port
	log.Print("サーバーを起動 => " + "http://" + addr)
	// サーバーを起動し、指定したIPアドレスとポート番号で待機
	err := http.ListenAndServe(addr, nil)
	if err != nil {
		log.Fatal("サーバーの起動に失敗しました: ", err)
	}
}
```

# 説明
結構忘れていたので、ChartGPTに手伝ってもらった。
1. distフォルダの下を見ている。
1. ```http://localhost/hoge```を```http://localhost:3000```にリダイレクト。
1. ```http://localhost/piyo```を```http://localhost:5001/piyo```にリバースプロキシ。
2100円でセンサモリモリのPico4MLを試してみた

[秋月電子通商](https://akizukidenshi.com/catalog/top.aspx)で2100円で販売されている[Pico4ML](https://akizukidenshi.com/catalog/g/gM-16714/)を試してみました。

パッケージには、Pico4MLとUSBケーブル、簡易マニュアルが同梱されています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/109992/c7259420-b794-33fc-4541-7150c1790a41.png)

2100円という価格にも関わらず、センサーやLCD、カメラが搭載されています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/109992/b36e2010-1192-aa7b-b45e-1b3ca6530514.png)
ピン配列は、Raspberry Pi Pico互換となっているので、拡張ボードなどは互換して使用できます。（表にはカメラ、裏にはLCDがあるので、拡張ボードを使う場合は、どちらかが使用不可になるかと）

## 動かしてみる
製造元である、ArduCAMのGithubからコンパイル済みのファームがいくつか配布されています。その中から[person_detection_int8](https://github.com/ArduCAM/pico-tflmicro/blob/main/bin/person_detection_int8.uf2)を動かしてみます。

Pico4MLをUSBでPCにつなぎ、BOOTボタンを押しながらRUNボタンを押します。そうするとPCがストレージとして認識するので、そこにダウンロードした、person_detection_int8.uf2をコピーします。

コピーが終わるとLCDにカメラ画像と数値が表示されます。この数値は、カメラに写ってるのが人物かどうかの確率です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/109992/a3c605d3-e3ad-c7bc-1254-79afcdb72271.png)

人物が映り込むと100%に近くなります。（素材は私が出てるYoutubeチャンネル）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/109992/7f7ef42f-1885-13a6-7139-191c19c87028.png)

[Github](https://github.com/ArduCAM/pico-tflmicro)には、プログラムやコンパイル方法なども配布されているので、開発する場合は、それらが参考になります。

ちなみにRP2040の開発環境は、Raspberry Pi上に以下のコマンドで簡単にインストールできます。
```
$ wget https://raw.githubusercontent.com/raspberrypi/pico-setup/master/pico_setup.sh
$ chmod +x pico_setup.sh
$ ./pico_setup.sh
$ sudo reboot
```

# 今後、やりたいこと
[以前に試したEdge Impulse](https://qiita.com/jksoft/items/2baff29650cab019b968)が[RP2040にも対応](https://docs.edgeimpulse.com/docs/development-platforms/officially-supported-mcu-targets/raspberry-pi-rp2040)していて、[Pico4MLも対応してそう](https://docs.edgeimpulse.com/docs/development-platforms/community-targets/arducam-pico4ml-tinyml-dev-kit)なので、今後試していきたいと思います。
あとは、いつもRaspberry Pi Picoの開発に使用しているArduino環境でもライブラリがあるので、そちらでも開発できるように準備したいと思います。
無関心な ViewModel

# はじめに
Android Advent Calendar 2023 3日目の記事です。

https://qiita.com/advent-calendar/2023/android

ViewModel について 1日目と2日目の記事の続きになります。

https://qiita.com/ykws/items/a418572adffc8192ef30

https://qiita.com/ykws/items/49d34da6177d235eb3f1

# ViewModel から Data Layer への関心をなくそう
Android Developers ガイドの下記の図で示されるように UI Layer である ViewModel から直接 Data Layer への関心をなくしたいです。 ViewModel から Data Layer へのアクセスは Domain Layer に任せます。

<img width="400" alt="UI layer cannot access data layer directly, it must go through the Domain layer" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/31787/85045bfa-c2e2-7dcc-6197-b388add6c59a.png">

https://developer.android.com/topic/architecture/domain-layer#data-access-restriction

Domain Layer は Optional として UI Layer から直接 Data Layer を参照する方針もあります。

<img width="500" alt="The UI layer's role in app architecture" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/31787/a7b23442-3d6a-9b6b-24cb-1c6ad1065626.png">

https://developer.android.com/topic/architecture/ui-layer

## Good

次のように ViewModel が Data Layer について無関心な状態として、その詳細を Domain Layer に任せたいです。

```kotlin
class LatestNewsViewModel(
    getLatestNewsWithAuthorsUseCase: GetLatestNewsWithAuthorsUseCase
) : ViewModel() {
```

UseCase が Data Layer に関心を持っている状態にします。

```kotlin
class GetLatestNewsWithAuthorsUseCase(
  private val newsRepository: NewsRepository,
  private val authorsRepository: AuthorsRepository
) { /* ... */ }
```

具体的な UseCase の書き方については [Call use cases in Kotlin](https://developer.android.com/topic/architecture/domain-layer#use-cases-kotlin) の部分で紹介されています。

## Bad

ViewModel が Data Layer からどうやって情報を取得するのかその詳細を知りすぎている状態です。

```kotlin
class LatestNewsViewModel(
    private val newsRepository: NewsRepository,
    private val authorsRepository: AuthorsRepository,
) : ViewModel() {
```

Domain Layer のサンプルとして紹介されている Now in Android App の `SearchViewModel` は、 UI Layer から Domain Layer と Data Layer へのアクセスが混在した実装になっています。

https://developer.android.com/topic/architecture/domain-layer#samples

```kotlin
class SearchViewModel @Inject constructor(
    getSearchContentsUseCase: GetSearchContentsUseCase,
    getSearchContentsCountUseCase: GetSearchContentsCountUseCase,
    recentSearchQueriesUseCase: GetRecentSearchQueriesUseCase,
    private val recentSearchRepository: RecentSearchRepository,
    private val savedStateHandle: SavedStateHandle,
    private val analyticsHelper: AnalyticsHelper,
) : ViewModel() {
```

https://github.com/android/nowinandroid/blob/eb54ec71e94d3c7e205d2291cd32e464c4691c92/feature/search/src/main/kotlin/com/google/samples/apps/nowinandroid/feature/search/SearchViewModel.kt#L42-L49

## おわりに

4日目は @ntsk さんの記事です。
Arduinoでピンをちゃんとインスタンスで定義する

## 前提

はるか昔に自作したIO-Kitというライブラリの布教です。

https://github.com/shirokuma89dev/IO-Kit

## 最近思うこと

digitalWrite()ってあんまよくないですよね。（思想強い）

何がよくないかというと、

- ピン自体を定義していない
- 記述が煩雑
- 入出力定義が曖昧

この三つ目は特に重要だと思ってて、ハイインピーダンス状態に保持しなければならないピンをLOWやHIGHにdigitalWriteしてしまったら普通に事故りかねないのでこれは結構重要です。

間違えてOUTPUTに設定していたピンでdigitalReadしてたから動かなかったー、じゃなくてdigitalReadできる構造にプログラムを作るべきじゃない（思想強い2回目）

## 簡単な思想

全てインスタンス作って定義しましょう！！というスタンスです。mbedに思想はかなり近いと思います。詳しい使い方はreadme見てもらえればと思いますが、概要だけ簡単に紹介します。 

とりあえずライブラリをインクルードします。PlatformIOの方はライブラリマネージャから簡単にインストールできます。

``` cpp
#include <IO-Kit.h>
```

出力はこのようにして使います。

``` cpp
#include <IO-Kit.h>

Output LED = 13;
Output LED_Arr[] = {10, 4};

void setup(){}

void loop(){
  LED = HIGH;
  delay(500);
  LED = LOW;
  LED_Arr[1] = LOW;
  delay(500);
}
```

これを使うと、Lチカがこのようにかけます。めっちゃ綺麗じゃないですか？

``` cpp
#include <IO-Kit.h>

Output LED = 13;

void setup(){}

void loop(){
  LED = !LED; //裏返す
  delay(500);
}
```

ちなみにInputも同じように使えます。

``` cpp
#include <IO-Kit.h>

Input SWITCH = 2;

void setup(){
    Serial.begin(9600);
}

void loop(){
    Serial.println(SWITCH);
}

```

## 内部実装

Outputのクラスはこんな感じになっています。operatorが鍵です。

bool　_pwmExpはSTM32だとPWMの仕様がちょっと異なるのでこのように付け足しています。

``` cpp
class Output {
 public:
  Output(int pin);

  float operator=(float val);
  int operator<<=(int val);

  byte raw(void);

  operator float();

 private:
  int _pinNumber;
  byte _pinStatus;

  void set(bool val);
  void setPWM(int val);

#ifdef _STM32_DEF_
  bool _pwmExp = false;
#endif
};
```

そしてこの内部はこのようになっています。ただのメンバ関数の説明は省きますが、代入演算子のオーバーロードって技を使って=という記号にこちらの関数を割り当てています。

``` cpp
float Output::operator=(float val) {
  val = constrain(val, 0.0, 1.0);
  if (val == 1.0 || val == 0.0) {
    this->set(bool(val));
  } else {
    this->setPWM(round(val * 255));
  }
  return val;
}
```

## 終わりに

みんな使ってください！！！
OpenSiv3Dでのリソースファイル（MP3）埋め込み時にファイル読み込み失敗した時の対処法


# はじめに
OpenSiv3Dは多くの開発者に愛用されているライブラリですが、実行ファイルにMP3ファイルを埋め込む際に特定の問題が発生することがありました。例えば、作者名や配布元のメタデータが含まれるMP3の音楽などです。
例：https://www.tam-music.com/
本記事では、この問題を解決するための方法として、`ffmpeg`を使用したMP3ファイルのメタデータ削除手順を紹介します。

## ffmpegの概要
`ffmpeg`は強力なオーディオ・ビデオ処理ツールで、ファイルの変換、ストリーミング、録画など多岐にわたる機能を提供します。このツールを使用することで、メディアファイルの形式を変更したり、特定のデータを取り除いたりすることが可能です。

# MP3ファイルのメタデータ削除コマンド
OpenSiv3Dでリソースファイルとして埋め込む前に、MP3ファイルからメタデータを削除するには、以下のffmpegコマンドを使用します。

```bash
ffmpeg -i original.mp3 -map_metadata -1 -c copy clean.mp3
```

## このコマンドの説明:
- `-i original.mp3`: 入力ファイル（この例では`original.mp3`）を指定します。
- `-map_metadata -1`: すべてのメタデータを削除します。
- `-c copy`: オーディオデータをそのままコピーし（再エンコードせずに）、出力ファイルに保存します。
- `clean.mp3`: メタデータを削除した新しいファイルの名前。


## 応用方法
このコマンドを応用する場合、以下の点を変更できます：
- 入力ファイル名（`original.mp3`）を変更して、異なるファイルに適用します。
- 出力ファイル名（`clean.mp3`）を変更して、生成されるファイルの名前を指定します。

# おまけ
この問題からインスパイアされて、PythonでMP3のメタデータを一括で消すだけのGUIアプリケーションをつくってみました。
https://qiita.com/hamukun8686/items/2e3014d83867122f9b1b

# まとめ
OpenSiv3Dでのリソースファイル埋め込み時に生じるMP3ファイルの問題を解決するため、`ffmpeg`を使用してメタデータを削除する方法を紹介しました。
Azure functionsのcURLデプロイ

VSコードが使用出来なかったり、特定のインターネット接続ができない環境下でAzure Functionsのデプロイする機会があったので、公式ドキュメントを基に実証してみました。

https://learn.microsoft.com/ja-jp/azure/azure-functions/deployment-zip-push

# 必要なもの
- Azure Functionsへの接続情報
- リポジトリのZIPフォルダ
- コマンドプロンプト

# デプロイ手順
1. 関数アプリの概要ページを選択して、「発行プロファイルの取得」を選択する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/769629/c81318f9-7e41-4bc1-ca11-04fa28018093.png)

2. publishMethod="MSDeploy"に該当するpublishUrl、userName、userPWDを取得する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/769629/83de0ff7-f043-7aac-82db-3d00cf69afff.png)

3. 下記のコマンドをコマンドプロンプトで実行し、userPWDを入力
<code>curl -X POST -u {userName} --data-binary @{リポジトリのZIPフォルダのパス}　https://{publishUrl}/api/zipdeploy</code>
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/769629/bb230e6e-2bca-dcf2-96d9-739f98b16295.png)

4. Azure ポータルでデプロイ先のFunctionsのリソースの「開発ツール＞高度なツール」を選択
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/769629/2ba1aa6a-58da-b04b-b7b6-d3b518a2036d.png)

5. DeploymentLogを確認してデプロイが成功していることを確認
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/769629/ca7adef6-fdd0-124d-d4f3-23dc5b06dba6.png)

# まとめ
コマンドプロンプトを使ってデプロイできる方法を紹介しました。
他にもAzure CLIを用いたり、PowerShellでデプロイがあるので端末や環境に適した方法でデプロイしてみてください。
 
またナレッジコミュニケーションでは「[Musubite](https://musubite-job.com/)」というエンジニア同士のカジュアルトークサービスを利用しています！この記事にあるような生成 AI 技術を使ったプロジェクトに携わるメンバーと直接話せるサービスですので興味がある方は是非利用を検討してください！
 
https://recruiting.musubite-job.com/features/company/knowledge-communication
 
今後もクラウド AI の最新情報を皆さんに届けていきたいと思います。お楽しみに！
Proxmox VE Training Courses について




:::note alert
Training Courses の受講はしていません！
受講を検討したけど諸々の理由で諦めたという記事です！
:::




## TL;DR

- Proxmox VE Training Courses の概要
- 諦めた理由
  - 値段が高い！
  - 時差がきつい！
  - アーリーアダプターのニーズに合っていない！
- いつ受けるのか？

## Proxmox VE Training Courses の概要


`Proxmox VE Training Courses `とは、`Proxmox Server Solutions GmbH (AT)`あるいは認定パートナーによるトレーニングです。
以下からアクセスできます。

https://www.proxmox.com/en/services/training


### 種類

値段は`Proxmox Server Solutions GmbH (AT)`、つまり本家大本のものを参考にしています。

| 名称 | 概要 | 時間 | 値段 |
|------|------|------|------|
| Proxmox VE Installation and Administration | シングル構成の管理<br>ネットワーク・ストレージ・仮想マシン・コンテナの管理<br>基本的な認証<br>GUIでの管理<br>バックアップ・リストア<br>ハンズオン | 14h (2.5 days) | 1450 € |
| Proxmox VE Advanced | クラスタ構成の管理<br>高度な認証<br>API<br>Ceph<br>トラブルシュート<br>パフォーマンス | 14h (2.5 days) | 1450 € |
| Proxmox VE Bundle | 上記２つのセット | 28h (5 days) | 2690 € |







## 諦めた理由

### 値段が高い！

12/2 時点の為替レートで429867JPYです。
[弊社のCOMMUNITYプラン](https://proxmox.classact.co.jp/proxmox_ve/#plan)だと**売値（≠利益）**で12CPU/年分です。
このトレーニングを受講しても売上に直結するわけではないので、このコストを広告などに使ったほうがいいかも…という判断。




### 時差がきつい！

現地はCET、こちらはらJSTです。

```
2:00 p.m. - 8:00 p.m. (CET) → 10:00 p.m. - 4:00 a.m. (次の日) (JST)
```
がっつり真夜中開催です。業務指示で受講させたら夜勤手当が発生してしまいます。
オマケに開催時間は`14h (2.5 days)、28h (5 days)`なので１週間は他の業務はできません！




### アーリーアダプターのニーズに合っていない！
[この記事](https://qiita.com/oishi-d/items/c57229ff59d1556fbb94#%E3%82%A2%E3%83%BC%E3%83%AA%E3%82%A2%E3%83%80%E3%83%97%E3%82%BF%E3%83%BC%E3%81%AE%E6%8A%80%E8%A1%93%E5%8A%9B%E3%81%AF%E9%AB%98%E3%81%99%E3%81%8E%E3%82%8B)に記載したのですが、現状のメイン顧客であるアーリーアダプターはそこまでProxmox**だけ**の知識を求めているわけでもないです。
コストパフォーマンスを考えると…


### じゃあいつ受講するのか？

事業が大成功したら祝賀旅行がてらオフライン開催の奴にいきますかね…


## 参考

https://www.proxmox.com/en/services/training
RSA暗号の問題を実装してみた

前回の続きで、早速問題(一部除く)を作ってみました。
前回の記事はこちらをご覧ください。

https://qiita.com/seiya1122_404/items/60c803199b75a7984eed

環境
Python 3.11.1
sympy 1.12
gmpy2 2.1.5

# 目次
- Low Public Exponent Attack
- wiener's attack(できなかった)
- 素因数分解で素数特定可能
- まとめ
- 参考文献

# Low Public Exponent Attack

```python
import sympy
import gmpy2
p = sympy.randprime(10 ** 99, 10 ** 100)
q = sympy.randprime(10 ** 99, 10 ** 100)
n = p*q
e = 3
l = (p-1)*(q-1)
d = gmpy2.invert(e,l)
message = b'Hello'
m = int.from_bytes(message, "big")
c = pow(m,e,n)
print('n:', n)
print('c:', c)
print('e:', e)
```

# wiener's attack(できなかった)
何度も実装してみたけどdが短くなるようにうまく行きませんでした、、、
何故かe大きくしても相対的にdが小さくならない・・・?

# 素因数分解で素数特定可能

計算量がO(N)の場合、10^8までは約1秒で求められることを利用したものです。

```python
import sympy
import gmpy2
p = sympy.randprime(10 ** 7, 10 ** 8)
q = sympy.randprime(10 ** 100, 10 ** 200)
n = p*q
e = 65537
l = (p-1)*(q-1)
d = gmpy2.invert(e,l)
message = b'Hello'
m = int.from_bytes(message, "big")
c = pow(m,e,n)
print('n:', n)
print('c:', c)
print('e:', e)
```

# まとめ
問題が解けるものがあっても作問ができるとは限らないとなると、
CTFの作問者の人って本当にすごい・・・

# 参考文献

https://atcoder.jp/contests/apg4b/tasks/APG4b_w?lang=ja

https://qiita.com/uneyamauneko/items/b88f26a9c8150705aec5

https://www.slideshare.net/sonickun/rsa-n-ssmjp

# IPFactory Advent Calender 2023

### 5日目 im_yappiさん

https://qiita.com/im_yappi/items/1b41e919c4d73e3b6c18

### 7日目 ERUTONEさん

https://qiita.com/ERUTONE/items/629815379369575e7a42
事務員がChatGPTを使ったアレコレについて書くよ

:::note info
この記事は[MIERUNE Advent Calendar 2023](https://qiita.com/advent-calendar/2023/mierune) 3日目の記事です！
昨日は[@Kanahiro](https://qiita.com/Kanahiro)さんによる[「PMTilesでサーバーレスなタイルサーバーをつくる」](https://qiita.com/Kanahiro/items/f540804c407d50da7de5) でした！
:::
非エンジニアによる、ちょっとした読み物としてご覧ください。

---
#### はじめに
- Qiitaへの初投稿になります。生暖かい目でご覧いただけると幸いです。
- 筆者は趣味でHTMLやらCSSやらPythonを触ったことはありますが、そのくらいのレベル感の事務員です。
---

#### ちょっとした自己紹介といきさつ
私は文系大学出身で、卒業後は某金融機関へ就職…という「ザ・文系」の人生を送ってきております。その後とある経緯から現在の会社に就職、所謂事務員として働いています。

元々PC関係のアレコレは好きで色々といじってはいたのですが、やはり独学では限界が…🥺

そんな最中、みなさんご存知のChatGPTが登場しました。そこで、日々感じていた
「これもっと楽に/いい感じに ならんかなぁ…」
というアレコレを進めたので、こちらで供養いたします。

---
#### その1 GAS書いてみた
仕事柄何かしらの集計をすることがあるのですが、会社で使用している各種サービスからcsv吐き出し→スプレッドシートへインポート→特定の列を消す→特定の列に特定の計算式を入れて……という作業を毎月**全て手動で**行っていました。つらい。
つらいけれど自力でスクリプトを書くほどの知識はありません。

ということでChatGPTの出番です。

![1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/304487/cad1a654-6da0-c0c4-c220-9a6a51d583e1.png)
まったくスクリプトを書けない私でもバリバリ作成されていきます。素敵！
<br>

(ちょっと社内秘になってしまうのでボカシを…)
コメントも自動で入れてくれるんですよね。ありがたい。
![2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/304487/f4fec39e-952d-6609-d936-1cb1d12fc899.png)

→毎月10分はかけていた処理がボタンポチーで終わるようになりました！

---
#### その2 Mermaidで組織図書いてみた
弊社ではNotionを利用しているのですが、会社の組織図はdraw.ioを使用して作成した画像をNotionに貼り付けるスタイルでした。綺麗な図は作れるのですが、いかんせん更新が非常にめんどい。

そこで良さげなツールを探して社内のSlackを漁ってみると、Mermaid記法なるものが共有されているではありませんか！
しかもNotionはMermaid記法に対応しているとのこと！

これは使うしか無い！…と思ったのも束の間、Mermaidさんがいうことを聞いてくれません。

※言うこと聞いてくれないイメージ図
![3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/304487/16b966b1-9ed7-cf10-6e2d-f1c4bcb3e3e0.png)
<br>

言うことを聞いてくれるように、こちらもChatGPTにお願いしてみます。ここ数ヶ月で画像も認識してくれるようになっていますね。
↓こちらはサンプルの図
![4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/304487/58a0c6cc-3142-0759-df43-6892e59f96d9.png)
<br>

こうなりました。(総支配人…)
```
graph TD
    総支配人-->取締役
    取締役-->CTO
    取締役-->CFO
    CTO-->技術チームA
    CTO-->技術チームB
    CFO-->管理部
```

```mermaid
graph TD
    総支配人-->取締役
    取締役-->CTO
    取締役-->CFO
    CTO-->技術チームA
    CTO-->技術チームB
    CFO-->管理部
```

ここまで出ればあとはちょっと修正して…
```
graph LR
    代表取締役-->取締役
    取締役-->CTO
    取締役-->CFO
    CTO-->技術チームA
    CTO-->技術チームB
    CFO-->管理部
```


完成！　ここまですぐに出してくれて非常に助かりました。
```mermaid
graph LR
    代表取締役-->取締役
    取締役-->CTO
    取締役-->CFO
    CTO-->技術チームA
    CTO-->技術チームB
    CFO-->管理部
```


---
#### おまけ1 テトリス作ってみた
ここまで出来ると遊びたくもなるのが人の性というもの。
まずはテトリスを作ってみました。chromeで動作しています。
![1.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/304487/492e3409-1ddf-562e-2813-cbd8ef7dc853.gif)


---
#### おまけ2 インベーダーゲーム作ってみた
ついでにインベーダー。こちらもchromeで動作しています。
(操作が下手くそなのは気にしないでください)
![2.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/304487/b15da142-309f-8b0d-69f0-f3c2ee362260.gif)

---
以上です！
日々の仕事の業務効率改善に向けて「こんなことできるんだなぁ」といった気付きの助けになってくれれば嬉しい限りです。

---
:::note info
明日は[@northprint](https://qiita.com/northprint)さんによる記事です！お楽しみに！！
:::
DAXのJOIN関連操作② ～NATURALINNERJOIN～

# DAXによるJOIN

DAXを利用したJOIN関連の関数をしらべていきます。

:::note
本記事は「Microsoft Power BI Advent Calendar 2023」、4日目の記事です。
https://qiita.com/advent-calendar/2023/powerbi
いいね！ 👍 よろしくお願いします！
:::

# JOIN系関数シリーズ

https://qiita.com/akihiro_suto/items/658cacb15cb4ffbf549d

https://qiita.com/akihiro_suto/items/cae5f45ad1089de7aa62

https://qiita.com/akihiro_suto/items/4bd6b0800da3a2501e89

## INNER JOIN(内部結合)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/80467/405252f5-40ad-0406-35b3-c5df9ae2032e.png)

Inner Joinは左右テーブルの共通部分だけ残ります。
DAXで内部結合を行うときは、`NATURALINNERJOIN`関数を使用します。

https://learn.microsoft.com/ja-jp/dax/naturalinnerjoin-function-dax

```内部結合.dax
NATURALINNERJOIN(<LeftTable>, <RightTable>)
```

SQLでJOINをする場合は結合するためのキーとなる列を指定しますが、**NATURALINNERJOIN関数ではまずリレーションシップの有無が重要です。** 

リレーションシップが構成されているテーブルであれば、結合キーの自動判別をしてくれます。

## 実践

LeftTable = 国名マスターと、RightTable = 販売トランザクション、

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/80467/9d7c44b7-adbb-d4d0-9438-d0fe62a8032d.png)


# **結合キーの判定**

ドキュメントには以下のように記載があります。

- テーブルは、2 つのテーブルの共通の列 (名前) で結合されます。 2 つのテーブルに共通の列名がない場合は、エラーが返されます

ただ、リレーションシップが構成されていてれば、列名が違っても、結合されます。

## リレーションシップが構成かつ、列名が違う

以下の結果をみてもわかる通り、列名が違っても判定してくれています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/80467/c934b973-9c24-7f72-a183-19e8f073306b.png)

## リレーションシップが未構成かつ、列名が一緒

列名が一緒でもリレーションシップが未構成の場合、結合はできません。

:::note warn
Query (4, 5) 共通結合列が見つかりません。結合関数 'NATURALINNERJOIN' には少なくとも 1 つの共通結合列が必要です。
:::

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/80467/5a4b9395-9a21-7d9c-6d44-98bf5a2d9527.png)

## TREATASを利用して結合

データリネージュが同一でないと結合がされないため、`TREATAS`関数を利用すると結合を行うことができます。

```Treatas.dax
EVALUATE
VAR country_name_TreatAs =
    TREATAS (
        '国名マスター',
        '販売トランザクション（リレーションシップなし）'[国ID],
        '国名マスター'[国名]
    )
VAR Result =
    NATURALLEFTOUTERJOIN (
        country_name_TreatAs,
        '販売トランザクション（リレーションシップなし）'
    )
RETURN
    Result
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/80467/1838868f-fbf7-bf58-b37e-9fa40d929d14.png)

# まとめ

明日はOUTERJOINを検証していきます。
vmware workstation player上の仮想マシンのGPU利用(ubuntu)

Windowsマシン上のvmware playerにインストールした仮想マシンおけるGPUの利用について確認しました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/201787/4691cfd1-cf19-82c0-227f-26fca7df98c8.png)


# １．GPUパススルーについて
GPUパススルーとは仮想マシンがGPUを占有することを指します。
残念ながら、vmware workstationではGPUパススルーによるホストGPUの占有はできないようです。


>VMware Workstation does not support GPU passthrough.

https://communities.vmware.com/t5/VMware-Workstation-Pro/VMware-Workstation-17-Pro-supports-use-of-host-GPU/td-p/2847355


# ２．3Dアクセラレーションについて
上記の通りGPUパススルーはできませんが、vmware workstationがホストGPU使用を抽象化して使用できるようにする3Dアクセラレーションはサポートされるようになっています。

https://docs.vmware.com/jp/VMware-Workstation-Pro/17/com.vmware.ws.using.doc/GUID-FF434E5C-2FEE-48C9-BEAF-943F0536301E.html

vmware workstationが抽象化したVGAは仮想マシンから確認が可能です。

```text:VGA
ubuntu@ubuntu22-04:~$ lspci
00:0f.0 VGA compatible controller: VMware SVGA II Adapter

ubuntu@ubuntu22-04:~$ lspci -s 00:0f.0 -v
00:0f.0 VGA compatible controller: VMware SVGA II Adapter (prog-if 00 [VGA controller])
        Subsystem: VMware SVGA II Adapter
        Flags: bus master, medium devsel, latency 64, IRQ 16
        I/O ports at 1070 [size=16]
        Memory at e8000000 (32-bit, prefetchable) [size=128M]
        Memory at fe000000 (32-bit, non-prefetchable) [size=8M]
        Expansion ROM at 000c0000 [virtual] [disabled] [size=128K]
        Capabilities: <access denied>
        Kernel driver in use: vmwgfx
        Kernel modules: vmwgfx

ubuntu@ubuntu22-04:~$
```


# ３．実計測
GLmark2を利用して計測を実施していきます。
準備・コマンド等は以下の記事を参照しています。
3Dアクセラレーションをoff/onして計測を実施しました。

```text:
$ glmark2 -s 320x240
$ glmark2 -s 800x600
$ glmark2 -s 1920x1080
$ glmark2 -s 2560x1440
$ glmark2 -s 3840x2160
$ glmark2 -s 7680x4320
```

https://qiita.com/Higemal/items/07206f382d6a073c8ca6


# ４．計測結果
以下の特性を確認することができました。
・3Dアクセラレーション有効時のほうが高性能
・3Dアクセラレーション無効時は解像度を上げるとスコアが低下
・3Dアクセラレーション有効時は解像度を上げてもスコアが落ちない
・逆に3Dアクセラレーション有効時は低解像度時はスコアが上がらない


解像度 | 3D ACC off | 3D ACC on
--- | --- | ---
320x240 | 1367 | 4563
800x600 | 720 | 4827
1920x1080 | 335 | 4419
2560x1440 | 260 | 4352
3840x2160 | 134 | 4083
7680x4320 | 37 | 3369

☟実数グラフ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/201787/4a5e419c-7ba7-99bc-eb9f-f44287fbff65.png)

☟対数グラフ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/201787/9b0decd4-c35a-d186-62fe-dfbbcc561b10.png)


☟ホストOS側のタスクマネージャ（3Dアクセラレーション有効：7680x4320の一部）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/201787/dd5682cb-7005-e8b4-9396-fd4053aef331.png)



# 最後に
GPUパススルーほどの性能は発揮できない可能性はあるものの、仮想マシンがGPUをある程度使用できることは確認ができました。ただし確実なパススルーや共有を実施する場合はvwmware ESXiを使用したほうが良いかと思います。
シュウォッチ的なものをmicro:bitで作ってみるための基礎(1)

古のシュウォッチ的なものをmicro:bitで作ってみたいのでまずは連射部分のプログラムからスタート

https://ja.wikipedia.org/wiki/%E3%82%B7%E3%83%A5%E3%82%A6%E3%82%A9%E3%83%83%E3%83%81


### プログラムについて
一度押すとカウントし、離すまでカウントしない(Flagが1のまま)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/71746/ab856566-7ecd-a5f7-e807-4964d0d8d332.png)


### (参考)プログラムへのリンク
https://makecode.microbit.org/S60258-13885-14342-89070

### イメージ
端子0とGND端子をスイッチを介して接続します
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/71746/da16582e-8029-3737-f040-435f24849643.png)
ESP32の書き込みで嵌った話

# ESP32の書き込みで嵌った話

家の押し入れで積み板になってたESP32を、デュアルショック4とマイコンのインターフェースに使いたくて引っ張り出して来たら、書き込みに嵌ったからそれの対処を記録しとく。

## 開発環境
|ボード|ＥＳＰ３２－ＷＲＯＯＭ－３２Ｅマイコンボード(K-16108)|
|---|---|
|USBtoシリアル変換モジュール|ＣＨ３４０Ｅ　ＵＳＢシリアル変換モジュール　Ｔｙｐｅ－Ｃ(K-14745)|
|IDE|Aruduino IDE 2.2.1|

## 嵌ったポイント
まずポート指定忘れた。（アホ
PICとSTMしか使ったことないから、Aruduinoなんか分かんない...
時間をとられたのが、ESP32をブートローダをFirmware Download mode（書き込み可状態）にする方法がわからなかったことだ。
どうやら、秋月が作ってるこのボードは自動ブートローダに対応していないみたいで、手動で書き込み可能状態にする必要があるみたい。

## 対処
bootピンとENピンがスイッチでロジックをローにできるようになってる。ボードの電源が入った状態で、以下のようなシーケンスを行うと書き込み可能状態になる。
前提として、bootは内部プルアップ、ENピンはボード上でプルアップがされている。
|シーケンス|boot|EN|
|---|---|---|
||||
|初期状態|1|1|
||||
|1|0|1|
|2|0|0|
|3|0|1|
|4|1|1|

のようにすることで書き込み可能状態とすることができる。
外部回路を追加して自動化できると思うけどめんどい。

# 参考文献
ESPRESSIF社公式より
[Boot Mode Selection](https://docs.espressif.com/projects/esptool/en/latest/esp32/advanced-topics/boot-mode-selection.html#boot-mode)
・"Manual Bootloader"の項に記載あり。また、"Automatic Bootloader"の項も、自動で書き込みできるはずのボードでできないときのトラブルシューティングになりそう。

[Troubleshooting](https://docs.espressif.com/projects/esptool/en/latest/esp32/troubleshooting.html)
・トラブルシューティングの"Bootloader Won't Respond"内にブートモードちゃんと設定してる？って聞いてる項がある。
[Unity]モバイル向け設定でBloomが光らない時

# 概要
Unityでは[実行環境ごとにクオリティを設定分けすることで処理負荷対策することができます。](https://qiita.com/kazuma_f/items/7c4cb13f093c0f848bf3)
モバイル機器だとデフォルトではBalancedになっていると思いますが、これをPerformantにするとBloomによる光エフェクトが表示されなくなります。光エフェクトはどうしても欲しい！という時の解決策を共有します。

# 最初に
Bloomを光らせるためにはMainCameraのRendering > Post Processingにチェックを入れて、Hierarchy上にGlobal Volumeを追加して、その中のBloomをONにする必要があります。
![スクリーンショット 2023-12-02 23.51.45.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/617265/3344d478-64e1-089c-46c8-9b9f7bd28c06.png)
![スクリーンショット 2023-12-02 23.52.42.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/617265/f52144a0-061c-23f7-6b51-cc6e801baf78.png)


# PerformantでもBloomを光らせる
Assets > Settings > URP-Performant.assetのQuality > HDRのチェックをつけるとBloomが光るようになります。

![スクリーンショット 2023-12-02 23.31.26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/617265/8d5f859b-358a-ba83-a443-4820f2360c87.png)

:::note info
Bloomは処理負荷が高めです。重たくなるようなら光らせないほうがいいかもしれないです！
:::
.service 自作して Python プログラムを systemd でデーモン化

## あらすじ

あるとき、FastAPI (Python) で WebApp を作りました。

https://github.com/aKuad/mozjpeg-webui

で、その WebApp を裏で常に稼働し続ける、みたいなのができないかなと考えました。

そこで気がついたのが systemd。よく Apache とか Samba を `systemctl` ってコマンドで起動したり停止したりするアレ。

そんなアレに自作のサービスを追加できないか、ということで試行錯誤したので、その日記をここに記すことにしました。

~~実際に作成してから半年近く経っての記事書きというのは内緒~~

## やりたいこと

* 特定の Python ソースを venv 上で動かしたい
  * Python ソースは `/opt/mozjpeg-webui/main.py` に設置
  * 仮想環境 venv も同ディレクトリに作成
* 稼働を `systemctl` で制御したい
* 自動起動も設定したい

## 下準備: Python 仮想環境構築・ソース配置

```sh
# すべてスーパーユーザ権限で
mkdir /opt/mozjpeg-webui

python3 -m venv /opt/mozjpeg-webui/.venv
/opt/mozjpeg-webui/bin/pip install -r /src-dir/requirements.txt

cp src-dir/* /opt/mozjpeg-webui/
```

Python 仮想環境というと、`source ./bin/activate` で仮想環境入り、というのをよく見かけると思います。ただ、少量のコマンド実行だったら同じ `bin` ディレクトリ内の `pip` を直接起動してやった方が早いので、そうしています。

## 完成品

とりあえずこんな形で動きました。

```/etc/systemd/system/mozjpeg-webui.systemd
[Unit]
Description=mozjpeg web application
After=network.target

[Service]
Type=simple
WorkingDirectory=/opt/mozjpeg-webui/
ExecStart=/opt/mozjpeg-webui/.venv/bin/python /opt/mozjpeg-webui/main.py

[Install]
WantedBy=multi-user.target
```

あとは作った `.service` を `/etc/systemd/system/` に置けば OK。

以下、各設定を適当に解説。(あまり正確じゃないかも)

### `After`

このサービスが起きてからこれ (自分) を起こす、という依存関係設定。

(しっかり理解できていませんが、) ネットワークが動いてからじゃないとダメそうな気がするので `After=network.target` としています。

### `WorkingDirecory`

どこをカレントとして `ExecStart=` のコマンドを実行するか設定。

WebApp サーバで、外部ファイル (HTML, CSS, JS とか) 読み込みを伴う上で、カレントが `main.py` の位置でないといけないです。最初、これにちょっとハマりました。

### `WantedBy`

OS 起動後、このターゲットに紐付いて起動、という設定。

これが無いと、自動起動設定 (enable/disable) が設定できません。

軽く調べると、多くのターゲットが `multi-user.target` に紐付いているとか。とりあえず、適当に「OS 起動後でユーザログイン無しでも起動」なら、これでいいのかも。

### 他

* `Description`: サービス一覧などに表示する説明
* `Type`: どういった動作のさせ方なのかの設定, 詳細省略
* `ExecStart`: サービス起動時に実行するコマンド

## あとがき

`ExecStart` とかは分かりやすいのですが、正直 `After` とか `WantedBy` とかが良く分かっていません。よく仕組みを理解する必要がありそうです。

でも、とりあえず適当に動かすなら上の通りでもよさそう･･･かも。

## 参考

https://qiita.com/ch7821/items/369090459769c603bb6b

https://qiita.com/ledmonster/items/5f2e1633d4124cb978fe
The Art of Social Engineering

ソーシャルエンジニアリング専門で書かれている本はこれまでにも何冊か見られますが、本書は2023年の新刊だけあって、AIを使ったソーシャルエンジニアリングについてにも言及されているところが他とは違うといったところでしょうか。

<a href="https://www.amazon.co.jp/Art-Social-Engineering-dynamics-cybersecurity-ebook/dp/B0CGXN92HD/">
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/8475/1e07ab69-afa4-0ef2-9f2b-bb280384d1bf.png" alt="The Art of Social Engineering書影" width="200"></a>

ソーシャルエンジニアリングに関する攻撃手法が、これでもかというくらい盛り込まれており、その対策も書かれているのですが、従来言われていること以上のことはありません。ざっくり言えばリテラシー向上させましょう、ということで、人間心理に対する攻撃なため、この分野がイタチごっこで特効薬的な防御手段ないのが難しいところです。

## ソーシャルエンジニアリングの心理学

ソーシャルエンジニアリング攻撃で使用される戦術は、以下6つの原則から成っている。

* 互恵性： 他人から何かもらったりしてもらうと、何か見返りを与えなきゃという気持ちが少なからず芽生える。
* コミットメントと一貫性: 何かを一度約束すると、約束やインセンティブが多少変化しても、その約束を守る可能性が高い。
* 社会的証明： 人の行動は、ある場所での他人の行動に影響を受ける。
* 権威: 権威のある人物（権威ある風に装っているものも含む）の命令には従う可能性が高い。
* 好意: 好意を持つ相手の言うことは聞き入れやすい。
* 希少性: マーケティングでよく使われるアレ
 
これらを上手く使って、標的を欺く。

## ソーシャルエンジニアリング攻撃の種類

大きな分類だと、以下のように整理されている。

* フィッシング
* ベイティング
* ダンプスターダイビング： 実際に企業等に侵入して、ゴミ箱などを漁り機密情報を入手する。
* 尾行
* 見返り: まず無料でサービス提供し、見返りを要求する（お金配りなどはこれ）
* もっともらしい口実
* 水飲み場攻撃

攻撃のチャネルは変化しているものの狙いは昔から変わらずで、やはり前述の心理的な特性をついて攻撃成立を目論んだものである。

## ソーシャルエンジニアリングにおけるAIの利用

攻撃手段としても、ディープフェイクやLLMを活用はこれからますます増えていくだろうと予測される。

* フィッシングメール文面の高度化: 現在では変な日本語文面で詐欺である
のが丸わかりだが、文面では区別がつかなくなる。
* ディープフェイク音声: 声を学習し、電話などで標的の知人の声で喋り相手を騙す。
* ソーシャルメディア操作： コンテンツの自動生成やインフルエンサーになりすます。Amazonなどの商品レビューは見分けがつかなくなっていく。

個人的には、ただでさえ電話だと、他人の声と息子の声が区別のつかない高齢者が多いのに、ディープフェイク音声がLLMで生成した応答をほぼリアルタイムでしゃべるようになると、かなり悪用されるのではないかと予想する。

これらのAIを活用したソーシャルエンジニアリング攻撃は新たな脅威ではあるものの、もちろん防御にもAIが活用されていくので、こちらも新たなイタチごっこになっていくことが想像される。

## まとめ

ソーシャルエンジニアリングは、結局は自衛によって回避するのが最終防御壁で、その役割が他のセキュリティ攻撃に比べて大きい。ニュースなどに目を通し、様々な攻撃手段についての知識を得ることがその対策であると、本書でも述べられている。
ソフトウェアアーキテクチャの基礎 22章読んだまとめ

## はじめに
ソフトウェアアーキテクチャの基礎 22章は「効果的なチームにする」です.
チームリーダーを始めてから2年ちょっと経ちました.
ソフトウェアアーキテクチャという文脈ですが,
効果的なチームを目指せるように, この書籍の内容を活かしていきたいと思います.
ポイントをまとめて, 思ったことを書ければと思います.

## 書籍

https://www.oreilly.co.jp//books/9784873119823/

## 効果的なチームにする

### チーム境界

* ソフトウェアアーキテクトの役割の1つは, 開発者がアーキテクチャを実装する際の制約をつくり伝えること
* 境界はきつくもできるし, ゆるくもできる
* きつすぎても, ゆるすぎてもフラストレーションを生む
* 効果的なソフトウェアアーキテクトは, 適切なレベルのガイダンスや制約を提供することで境界を適切な状態に保つ

> きつすぎても, ゆるすぎてもフラストレーションを生む

きつすぎてフラストレーションを生むのはイメージしやすいが,
ゆるすぎてもフラストレーションを生むのはなるほどと思った.
確かにアーキテクチャなど決める際に,
制約がないと意見がぶつかったりしやすくなるのかなとイメージした.
人数が増えると尚更多くなりそうと感じた.

### アーキテクトのパーソナリティ

* 3つの基本的なパーソナリティのタイプがある
    * コントロールフリークアーキテクト : きつい境界を生み出す
    * アームチェアアーキテクト : ゆるい境界を生み出す
    * 効果的なアーキテクト : チームに適切な制約と境界を生み出す
* 開発チームの効果的なリーダーになるには「技」が求められる。たとえば、チームと緊密に協力し合い、チームから敬意を得られていなくてはならない

本書にある通り, 
「開発者からアーキテクトに転身したばかりのときに起きやすい」
というのは理解できるので,
私も注意したい.

### どうやって管理するのか

効果的なソフトウェアアーキテクトがどの程度コントロールフリークであるべきで, どの程度アームチェアアーキテクトであるべきかを知るには主に5つの要因がある
* チームの親しさ
    * チームメンバーがお互いのことをよく知っている→コントロールの必要性は低
    * チームメンバーがお互いのことをよく知っていない→コントロールの必要性は高
* チームサイズ
    * チームが大きい→多くのコントロールが必要になる
    * チームが小さい→多くのコントロールは不要になる
* 全体的な経験
    * ジュニア開発者が多いチーム→多くのコントロールとメンタリングが必要となる
    * シニア開発者が多いチーム→多くのコントロールとメンタリングは不要となる
* プロジェクトの複雑さ
    * 非常に複雑なプロジェクト→コントロールが必要
    * 簡単なプロジェクト→コントロールがあまり必要ではない
* プロジェクトの期間
    * 期間が短い→コントロールは不要
    * 期間が長い→コントロールは必要

これらの要因を用いて, 
アーキテクトがどの程度チームをコントロールすべきか決定するために,
各要因を20ポイントの固定スケールで考えるとよい
※ +になるとコントロールフリークアーキテクト, -になるとアームチェアアーキテクト

私の所属チームと担当プロジェクトであててみる.

|要因  |値  |レーティング  |パーソナリティ  |
|---|---|---|---|
|チームの親しみやすさ  |お互いをよく知っている  |-20  |アームチェアアーキテクト  |
|チームのサイズ  |小さい(5名)  |-20  |アームチェアアーキテクト  |
|全体的な経験  |全員が経験者  |-20  |アームチェアアーキテクト  |
|プロジェクトの複雑さ  |そこそこ複雑  |+20  |コントロールフリーク  |
|プロジェクトの期間  |1年半くらい  |+20  |コントロールフリーク  |
|合計  |  |-20  |アームチェアアーキテクト  |

アームチェアアーキテクトになりそうかなと思ったが予想通りだった.
こうやって数値化して表現できるのは非常に良いと感じた.
今後もプロジェクトを始める際には行い,
フェーズが変わってきた際にも実施していきたい.

## チームの警告サイン

最も効果的な開発チームの規模を考える際には以下の3つの要素が関わってくるという考え方
* プロセスロス : プロジェクトに人を増やすほどプロジェクトにかかる時間が増える
* 多元的無知 : 内心では否定しているが同意してしまう現象
* 責任の分散 : チームの規模が大きくなるとコミュニケーションに悪影響を及ぼす

> プロセスロス : プロジェクトに人を増やすほどプロジェクトにかかる時間が増える

プロセスロスを無くして生産性を上げていく.
どこにプロセスロスがあるのか定期的に観察していく.
今はプロセスロスがなくても, 今後発生していくかもしれない.
反対はプロセスゲインというらしく,

下記に詳しく記載があった.
参考 : https://jinjibu.jp/keyword/detl/1151/

> 多元的無知 : 内心では否定しているが同意してしまう現象

これはめちゃくちゃありそうだなと感じた.
多元的無知の発生を検知して相手に確認するには正直経験が必要だと思うが,
自分自身が多元的無知に陥っていないか, 問いかけてみるのは良さそうと思った.

> 責任の分散 : チームの規模が大きくなるとコミュニケーションに悪影響を及ぼす

振り返りの際などで, 定期的に確認することが必要だなと感じた.
フェーズが変わった際やチームメンバーの入れ替えが生じた際には,
すごく重要な確認ポイントになるとも感じた.

## チェックリストの活用

* チェックリストは有効で, 対処されていることを網羅的に確認する優れた手段
* チームを効果的にするにはチェックリストをいつ活用し, いつ活用しないかを知ることが重要
* 何でもかんでもチェックリストにしすぎない
* プロセス内の必要なステップをすべて把握しながらできるだけ小さなチェックリストを作成すること

注意しながらチェックリストを作るのはもちろんだが,
チェックリスト自体のアップデートが大事だなと感じた.
作ってそのまま, となっているチェックリストは多いのではと感じている.

## ガイダンスの提供
* 設計指針を用いてガイダンスを提供することでチームを効果的にできる
* 技術的な根拠とビジネス上の根拠の両方を要求することが, ビジネス上の根拠を示す必要性を開発チームに認識させる強力なテクニック
* 開発チームが決定できることとできないことを図で説明するのは設計指針を伝えるもう1つの効果的なテクニック

どちらのテクニックも参考になる.
できることできないことを図で表すことで混乱も減らせるし,
納得した上で物事を進められると思った.

## まとめ
観点が増えたと感じました。
全体的に言えることとして,
何か初めるときに意識するのは勿論だが,
定期的な見直しをすることにより効果を持続&最大化できるんだなと思いました。
今回学んだことを活かしてチーム開発を良いものにしていけたらと思います。