OmniAICreator/Qiita-1.07M huggingface dataset:
MATLAB/Simulinkでパワーエレクトロニクス機器の高調波解析を行う

こんにちは。Blitz1127です。
前回、[3相全波整流回路](https://qiita.com/BLITZ1127/items/903beaed7894b9d80e25)を解析しましたが、今回は高調波について議論していきたいと思います。

# 高調波の概要
高調波とは、基本周波数の整数倍の周波数成分のことです。信号解析をしたことがある人ならば、信号をフーリエ変換などで時間成分を周波数成分に変換したことがあるかと思います。電気業界では、交流50/60Hzを基本成分として、その整数倍を議論しています。

本記事は、フーリエ変換でただお遊びしたという話ではなく、パワーエレクトロニクス業界では問題になりやすいということをシミュレーションしたいと思います。

# 高調波の発生害とその発生原因
　まずは高調波がどのような害をもたらすか説明します。図1は高調波による波形ひずみを示した図になります。青破線は単相交流回路の波形を示します。朱色破線は30％の3次高調波の波形を示します。黄色実践は高調波が重畳した時の波形を示します。高調波により、波形がひずんでいることがわかるかと思います。このように波形がひずんだ結果、高調波発生機器の周辺機器が異常動作をすることがあります。例えば、工場の電源系統において、モータ駆動用インバータが大量の高調波を発生させた結果、周囲のコンデンサに大電流が流れ込み過熱したり、工場構内の変圧器が異常な振動をすることがあります。
　高調波の発生原因は、パワーエレクトロニクス機器になります。例えば、3相全波整流回路では、1周期の間に6回スイッチングをするので、6次高調波付近が発生します。偶数次数はフーリエ変換と偶関数の特性から0になります。そのため、5次と7次の高調波含有量が増えます。
　このように、パワーエレクトロニクスの分野では、半導体素子を高速でスイッチングするがゆえに、高調波問題が発生してしまいます。

![Harmonics.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3035813/fa6f292c-c5b5-2d1f-a485-43a5be4ee7b7.png)

図1　高調波による波形ひずみ（基本波＋30%の3次高調波）

# MATLABで3相全波整流回路を解析
　それでは、パワーエレクトロニクス機器により高調波が本当に発生しているか調べてみましょう。回路としては、図2のような3相全波整流回路を活用します。回路パラメータは表1のとおりです。
　高調波は、パワーエレクトロニクス機器から交流側に流れ込むので、パワーエレクトロニクス機器の前段の波形を取得します。ブロックとしては「Three-Phase V-I Measurement」を活用します。


![Harmonics_circuit.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3035813/b866fc02-cc84-fe04-0567-533ecb172f12.png)
図2　MATLABのシミュレーション回路

表1　回路パラメータ

|回路素子|パラメータ|
|-|-|
|電源|6.6kVrms<50Hz> |
|ダイオード|オン抵抗 1mΩ <br>電圧降下 0.8V  <br>スナバ抵抗 500Ω <br>スナバコンデンサ 250nF|
|インダクタ|1mH|
|コンデンサ|1uF|
|抵抗|1kΩ|

# 3相全波整流回路の解析結果
　図3は交流系統側の電流波形です。正弦波の波形とは大きく異なった波形になっていると思います。これが高調波による影響です。

![Source_current.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3035813/b9e1a1d6-8c92-2283-0e18-966caa5e1d27.png)
図3　電源電流波形

　次にこの波形を解析します。MATLAB/Simulinkでは「Powergui」ブロックで様々な解析を行えるようになっています。ここでは「Powergui」ブロック内の「FFT Analysis」を選択することで、高調波解析を行うことができます。高調波解析するにあたり、注意点が二つあります。一つは、「Scope」ブロックの計算結果を「時間付き構造体」でワークスペースに出力すること。もう一つは、「モデル設定」です。これは、「単一のシミュレーション出力」のチェックを外しましょう（この設定に気が付かず、数日調べまくっていました…。）。
　図4はFFTをした波形になります。FFTするには、ある程度の時間を確保する必要がありますので、0.01sからの1サイクルでFFTをかけました。（Rだけの回路なので、すぐに定常状態に至っていると思いますが、スナバにより定常状態に至っていないかもしれません…。）
　結果、基本波電流が98.5Apeakであり、5次高調波が22.6%、7次高調波が11.3%…となり、THDが30.7%含まれていることがわかりました。予想通り5次,7次の高調波が流出していること、以降6n±1次の高調波が流出していることがわかりました。

![FFT_result.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3035813/ffc15af7-af2b-1b08-bdcf-4f4bfd8a6fbb.png)
図4 電源電流のFFT波形

# まとめ
今回はパワーエレクトロニクス機器で高調波が発生することを説明し、MATLAB/Simulinkでは一例として3相全波整流回路を取り上げ、高調波が発生することを確認しました。3相全波整流回路では、THD30%と非常に高い高調波を漏らしており、このままでは、高調波トラブルを引き起こしてしまいます。
これから、高調波の対策方法の解析などを行いたいと思います。
【docker✖️django】コンテナに入れ！2005, "Unknown MySQL server host...と2003, "Can't connect to MySQL server on...の解決方法！

# 概要
* DBマイグレーションを実施したら`Unknown MySQL server host`とか`pymysql.err.OperationalError:`といったエラーが発生したので、その解決方法を残しておく。

## 環境
* Mac
    * 機種ID：MacBookPro18,3
    * macOS：Monterey
    * チップ：　Apple M1 Pro
    * メモリ：　16GB

## 前提
* 会社で使っているdjangoプログラムを自分のローカル環境で触ることになった。djangoを覚えるためにも、DBのマイグレーションまで実施したい。
* `docker-compose.yml`の定義は以下の通り
    * serviceはdjango
    * web serverはnginx
    * databaseはmysql
* `settings.py`のDATABASESには`‘HOST’: “mysql”`と記載があり、`docker-compose.yml`のDB名`mysql`と一致してある

# エラー内容

* `python3 manage.py makemigrations`の結果

```
/opt/homebrew/lib/python3.10/site-packages/django/core/xxxxxx/commands/makemigrations.py:143: RuntimeWarning: Got an error checking a consistent migration history performed for database connection 'default': (2005, "Unknown MySQL server host 'mysql' (8)")
 warnings.warn(
No changes detected
```

* `python3 manage.py migrate`の結果

```
pymysql.err.OperationalError: (2003, "Can't connect to MySQL server on 'mysql' ([Errno 8] nodename nor servname provided, or not known)")
```

# 原因の追求
* エラー文章を頼りに色々調べたが、どちらも“mysql”に関係があることと考えられる
* dockerに関係があるかと思い、以下実施したが、関係なし
    * `docker compose down`や`docker compose up -d`、`docker-compose down -v`を実施
    * PCを再起動

* 試しにsettings.pyのHOSTの`mysql`をlocalhostのアドレス 127.0.0.1 と記入してマイグレーションを実施してみたが、以下エラーメッセージとなる。内容は変わっているが、今回とは関係なさそう。


```
django.db.utils.OperationalError: (1045, "Access denied for user 'root'@'localhost' (using password: YES)")

```

* 上記対応中に以下エラーが発生したので、`pip install cryptography`を実施したら、以下エラーは発生しなくなった
    * 参考：[【Python 】pymysqlで「RuntimeError: cryptography is required for sha256_password...」の解消方法！](https://akizora.tech/pymysql-cryptography-required-4236)

```
RuntimeError: cryptography is required for sha256_password or caching_sha2_password
```


* docker-compose.ymlの編集についてもいくつか記事があったが、変わらず。
    * [【MySQL】Unknown MySQL server host 'db' (-2)の対処法【Docker】](https://qiita.com/SyoInoue/items/2ed5b3017c517920ec09)
    * [Dockerで作成したMySQLに接続できなかった時の解決方法](https://qiita.com/a1k4r/items/0c39ada24639795d6a75)
    * [Host xxx is not allowed to connect to this MySQL server の対応](https://zenn.dev/ryo_kawamata/articles/mysql-connect-error)

* その後もいろいろ調べたのですが、全然わからぬ。。。
    * 翌日、とうとう先輩に相談...!!

# 解決方法
* あっさり解決しました。さすが先輩！
* 今回、dockerを利用しているので、DBマイグレーションする時もDockerのコンテナに入らないといけない。つまり、以下コマンドを実行する
    * コンテナ名は、docker-compose.ymlで定義したサービス名

```terminal
docker exec -it [コンテナ名] bash
```


* プロンプトが変わったことが確認できます。
* bashに入ってから、manage.pyがあるディレクトリで、`python3 manage.py migrate`を行うと、、

```bash
Operations to perform:
  Apply all migrations: 
#####################
                ... OK
```

* できたぁー！！！！！

* `docker compose up -d`でコンテナを起動しているので問題ないと勘違いしていました。なるほど、コンテナに入ってbashでコンテナ環境とホストOS（カーネル等）をつないであげないといけなかったんですね。
【SwiftUI】レトロスタイルを実装してみた

# はじめに
[こちら](https://appmaster.io/ja/blog/2022nian-nomobairuapuriuidezainnoaideatotsupu10)のサイトを見ていたら90年代のスタイルがイケてたのでSwiftUIで再現してみました。
![appmaster](https://user-images.githubusercontent.com/84154073/209798974-add7bf62-234a-46b3-a215-4852594bec61.png)

# サンプルアプリ
![Simulator Screen Recording - iPhone 14 Pro - 2022-12-28 at 19 37 47](https://user-images.githubusercontent.com/84154073/209799326-ffa20435-8047-41e1-9735-0ec843263049.gif)

# 実装
```swift:ContentView
import SwiftUI

struct ContentView: View {
    @State var text: String = ""
    var body: some View {
        VStack(spacing: 30) {
            Button {
                print()
            } label: {
                Text(text)
                    .font(.system(size: 30, weight: .black, design: .rounded))
                    .frame(maxWidth: .infinity, minHeight: 200)
                    .padding()
            }
            .buttonStyle(.retro(borderLineWidth: 10))

            LazyVGrid(columns: Array(repeating: .init(.flexible(), spacing: 30), count: 4), spacing: 20) {
                ForEach(0..<20, id: \.self) { index in
                    Button {
                        text += index.description
                    } label: {
                        Text("\(index)")
                            .font(.system(size: 30, weight: .black, design: .rounded))
                            .frame(width: 60, height: 60)
                    }
                    .buttonStyle(.retro(borderLineWidth: 5))
                }
            }

            Button {
                text = ""
            } label: {
                Text("Clear")
                    .font(.system(size: 30, weight: .black, design: .rounded))
                    .frame(maxWidth: .infinity, minHeight: 20)
                    .padding()
            }
            .buttonStyle(.retro(borderLineWidth: 5))
        }
        .padding(.horizontal, 30)
    }
}
```

```swift:RetroButtonStyle
struct RetroButtonStyle: ButtonStyle {
    let borderLineWidth: CGFloat
    func makeBody(configuration: Configuration) -> some View {
        configuration.label
            .background(.white, in: RoundedRectangle(cornerRadius: 10))
            .compositingGroup()
            .shadow(color: .black, radius: 0, x: borderLineWidth, y: borderLineWidth)
            .overlay(.black, in: RoundedRectangle(cornerRadius: 10).stroke(style: .init(lineWidth: borderLineWidth)))
            .scaleEffect(configuration.isPressed ? 1 : 0.99)
    }
}

extension ButtonStyle where Self == RetroButtonStyle {
    static func retro(borderLineWidth: CGFloat) -> RetroButtonStyle {
        .init(borderLineWidth: borderLineWidth)
    }
}
```

# おわり
デザインは奥が深いですね
ゼンリーのデザイン好きだったのに無くなるの悲しい。。。
Qiita Night IoT × 不動産業界のPMFを考える

２０２２年１２月１６日の Qiita Night～プロダクトマネジメント～に登壇しました！
本記事はその際の登壇資料を記事化したものです。

## はじめに
登壇自体初めての経験だったので、非常に緊張しました。
何をテーマに持ってくれば良いのか非常に迷いましたが、自分がProductManagerとして活動してきた中で普段考えていることをテーマに選ぶことにしました。

## こんなヒトに読んでほしい
- PdMを目指している方
- PdMになりたての方

- PdMって何をするヒトなんだろう・・・、ビジネスサイドとの調整ばかり・・・、と悩まれている方々

## Product Managerとは

「これ」といった正解があるわけではない、と考えています。
それは、プロダクトの成熟度、組織の規模によって担う役割は変わり得るはず、と思うためです。

正解がないからこそ、やりがいがあるしおもしろい、と個人的には思います。

でも、その中にも「共通項」はあるはずなので、それを深堀りしてみます。
→ 迷ったときは、言葉の定義から入ってみるべし！

## Product Managerの言葉の定義

Product を Manage するヒト
> Product：製品、結果、成果
> Manage：「（馬）をてなづけるが語源」なんとかする。どうにかしてする。

引用元：英和辞典・和英辞典 weblio

→ 製品、結果、成果を最終的に何とかするヒト と言い換えることができるのではないでしょうか。

## もう少し具体的に・・・

- プロダクト
    - 有形・無形を問わず何かを成し遂げる価値あるモノ
    - 価値 ＝ 誰かを幸せにすること
    - 例）抱えていた課題の解決、より豊かな暮らし

- それを何とかする
    - 実現する、達成する

つまり、Product Managerとは以下のように言い換えることができると思います。

- 課題を解決したり、より豊かな暮らしを届けるような
- 価値あるプロダクトを実現するヒト、達成するヒト

有名な著書「INSPIRED 熱狂させる製品を生み出すプロダクトマネジメント」でも以下のように記載されています。
> *機能を実装することではなく、問題を解決することである*
> 引用：INSPIRED 熱狂させる製品を生み出すプロダクトマネジメント

Product Managerは **”顧客の課題にフォーカスしてプロダクトを見つめる必要がある”**

前置きが長くなりましたが、IoTプロダクトが不動産業界のPMFを目指すための私なりの考えをご紹介します。
大事なことは「**顧客の課題にフォーカスして考える**」ということです。

## IoT x 不動産業界のPMFを考える

### 1. ソリューションではなく、顧客のコア課題にフォーカスする

プロダクトを作る際、顧客の声は非常に重要です。
しかし、顧客の言うとおりのソリューションが必ずしも正しいとは限りません。
また、我々ははじめに思いついたソリューションを素晴らしいものと思い込む傾向にあります。

- 事例１）顧客から XXX の機能がほしい と言われた。そのとおりに作ったら、全く利用されなかった。
- 事例２）一番初めに思いついた機能は素晴らしく思えた。スケジュール通りリリースしたが、全く利用されなかった。

このような悲しい事態を防ぐために、我々はソリューションではなく、顧客が抱える「コア課題」にフォーカスする必要があります。
顧客のコア課題にフォーカスするためには、顧客の要求ではなく、その背景にフォーカスしましょう。

**顧客は彼ら自身のことに関してはスペシャリストですが、ソリューションを構築するスペシャリストではないからです。**

言いかえると・・・
**顧客は彼ら自身（BtoBであれば、顧客の業界・業務）のスペシャリストなので、顧客の要求の ”背景” に真摯に耳を傾けること** が重要です。

それが顧客が真に求める「コア課題」の定義につながるはずです。

### 2. 顧客の声（課題）に耳を傾ける

顧客の言うとおりのソリューションが正しいとは限りません。
しかし、コア課題を定義するために顧客の声に耳を傾けることは重要です。

顧客への耳の傾け方には２つあると思います
1. **顧客からの直接の声に耳を傾ける**
1. **顧客からの目に見えない声に耳を傾ける（データを活用して、マーケットで発生している事象を認知する）**


私の所属する株式会社ビットキーのソリューションのひとつに「スマートロックをモバイルアプリで操作できる」というものがあります。
実際の声は以下のようなものがあります。

1. **顧客からの直接の声に耳を傾ける**
    例）直接ご連絡いただいた問合せ内容
    家に近づくと自動でスマートロックが自動で解錠されるが
	車に乗っている場合、降車している間にオートロックで施錠されてしまう
1. **顧客からの目に見えない声に耳を傾ける**
    例）冬場になると特定の事象が発生しやすい傾向にある

直接いただくお問合せ以外にも、データを活用すると課題が見えてくることがあります。
しかし、顧客の要求どおりにプロダクトを作ると、失敗します。塩梅が大事です。

### 3. プロダクトの特性を理解する

ここでは、プロダクトの特性のひとつである「変更容易性」についてお話します。
ビットキーのプロダクトのスマートロックを例にとってご説明します。

スマートロックの機構は大きく分けて、３つに分類されます

- Hardware（スマートロックの本体）
- Firmware（スマートロックを操作する組み込みソフトウェア）
- Software（Webやモバイルアプリなどスマートロックを操作するインターフェーズ）

#### それぞれの特性

- Hardware（スマートロックの本体）
    - 市場にアップデートを届ける速度は非常にゆっくり
- Firmware（スマートロックを操作する組み込みソフトウェア）
    - 市場にアップデートを届ける速度はHardwareよりは速いが・・・
- Software（Webやモバイルアプリなどスマートロックを操作するインターフェーズ）
    - 市場にアップデートを届ける速度はほぼ即時

#### そこから導かれること

- 例えば、市場で重大なインシデントが発生し即時解決が求められる場合は、Softwareで解決してあげるのがよい！
- FirmwareはSoftwareの変更を受けて柔軟に操作できるようなインターフェースが求められる！
- Hardware起因の問題は改修が非常に難しいため、必要なログが残せる等、初期段階での設計が非常に重要！


### まとめ

1. ソリューションではなく、顧客の課題にフォーカスする
    顧客の言うとおりではなく、「何に困っているか？」に意識を向ける

2. 顧客の声に耳を傾ける
    データを活用すると、見えてくる示唆や課題があります

3. プロダクトの特性を理解する
    特性を理解することで、プロダクトの方向性が見えてくることがあります
paizaラーニング「指定された数字までの出力 Python3編」

https://paiza.jp/works/mondai/double_roop_problems/double_roop_problems__print_column_new
#### 私の解答
```Python3
n = int(input())
for i in range(1,n):
    print(i, end=" ")
print(n)
```
#### 解答例
```Python3
n = int(input())
for i in range(1, n + 1):
    if i != n:
        print(i, end=" ")
    else:
        print(i)
```
BGPのAS番号が重複したら経路広報されなくなった

 # 前置き

この記事はネットワークエンジニア2年目のぺーぺーがこんな動作するんだ！という発見をまとめた記事です。
ご指摘あればバンバンお願いします…
P.S.アドベントカレンダーに意気揚々と登録したものの、業務繁忙で記事が書けず、挙句に当日39度の熱を出し当日出せませんでした…
ごめんなサイ

 # 用語集
 * IPアドレス：ネットワークにおける住所みたいなもの。192.168.0.1みたいな表記
 * 経路：特定のIPアドレスへたどり着くまでの道のり
 * BGP(ボーダーゲートウェイプロトコル)：「BGP使っているIPアドレス同士が**フルメッシュな感じでお互いのIPアドレスへの行き方を教え合う**」仕組み
 * 広報：BGPなどのプロトコルで経路を教え広めること
 * AS：組織のネットワークごとに持っている番号のこと。~~社用携帯の070-1111-****の1111までみたいなもの？~~
 * BGPテーブル：BGPで広報されてきた情報をまとめた行き方リストみたいなやつ


 # 概要
BGPというプロトコルを使ってネットワークを構築してたら、構築範囲外に同じAS番号のルータがいて、正常に経路が広報されなかった
`なんでいたのかはお察しください。`

 # 説明
ネットワークエンジニアの皆様はご存じかと思いますが、ネットワークではパラメタの被りNGなものがいくつかあります。
例えば：IPアドレス、AS番号etc...といってもパッと出るのはこのくらいだった。ルータIDとかもそうかも
今回はそのうちのAS番号が被ってしまい、正常ではない動作をしてしまいました。

![図1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2992714/358e6aaf-9ef1-c976-707c-c0aad4492e56.png)

両端のルータでAS1111から広報されている経路がBGPテーブルに載らなくなりました。

BGPの属性（パラメタというか情報）として、AS Pathというものがあります。
経路がどこから広報されてきたかのルートを示すもので、通ってきたASの番号がズラズラ～ッと並びます。
例えば）1111 2222 3333 ......　i
この時、自分のAS番号がASPath内に含まれていた場合、「あ！自分が広報してる経路じゃん！ループしないように破棄しよ！」と判断して
自分のBGPテーブルに載せないようにしてるんですね。

その結果ルータが本来受けているであろう経路は全て破棄されてしまい、「いやそんな経路知らんけど？」となってしまったわけです。

![図2.1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2992714/42a3e6e7-2cd8-a620-dec1-6045a672e8b1.png)

 # 解決方法
同じネットワーク内に同じAS番号が存在しなければいいです。
要はルータ1か3をAS1111でなくせばいいんですが、今回は事情がありその対策はとれませんでした。
そこで考えた方法が、AS1111同士の間どこかでBGPのやり取りをできないようにすること。
例えば）ルータ2とルータ3の間でBGPを使わず、スタティックルーティングする

![図3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2992714/3f0540e6-ffa8-2765-a5f0-c86469accbca.png)

こうすることでAS1111から経路を広報されることはなくなり、無事経路を受け取れるようになりました。

 # 思ったこと
実際に検証とか何故受け取れないかとか考えるのは新鮮でした。
BGPについては触れる機会が多いほうですが、2年目として学んだ知識を元に仕組みの理解ができるようになっている、と
ちょっとだけ感動した記憶があります。
引き続きネットワークの勉強続けたいなと思う所存です。

今考えたらRIB見ればすぐ分かったんじゃね？って思ったけど、まあいいか。
そもそも破棄される経路はRIBに載ってるのだろうか

 # まとめ
BGPのAS番号重複には気を付けよう！！！！！！！
次記事書くときはきっと実機のログも入れてるんだろうな～～～

私はクリスマスも正月も自宅に監禁されることになりましたが、おとなしくクラナド全話見てギャン泣きしようと思います。
皆様も良いお年を。
AppStore のアプリ審査通知をノーコードで Slack に通知しよう！

AppStore の審査通知って地味に見逃しますよね...
まあ、App Store Connect のアプリを入れれば通知してくれますが、できれば Slack で通知してチーム全員で見たいもの。
というわけで、サクッとアプリ審査通知を Slack に投げましょう！

# フロー

Slack チャンネルにはメールアドレスを設定でき、そのメアドに送られてきたメールをチャンネルに投稿してくれます。
これを利用して、App Store Connect からのメールを転送するだけです。

# 実装
## 1. Slack チャンネルにメールアドレスを設定

チャンネル情報を開いてインテグレーションタブを押し、「このチャンネルにメールを送信する」を押します。
すると、メアドが生成できるので控えておきましょう。

<img width="400" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/516428/685d929f-8786-5370-f267-08c08646d00a.png">

## 2. App Store Connect からのメールを転送

App Store Connect ってタイトルに入ってるものをさっきのメアドに転送すれば OK です。

Gmail を使っている場合は以下のようにできます。

1. [設定 -> メール転送とPOP/IMAP](https://mail.google.com/mail/#settings/fwdandpop) を開き、「転送先アドレス」を追加を押して先ほどの Slack チャンネルのメアドを登録します
1. [設定 -> フィルタとブロック中のアドレス](https://mail.google.com/mail/#settings/filters) を開き、「新しいフィルタの作成」を押します
1. from に `App Store Connect` と入力し、「フィルタを作成」を押します
1. 「転送する」を選んで、アドレスを設定し、「フィルタを作成」を押します

以上です！
【JavaScript】ハッシュを使いたい。でも順番は変えたく無い。その気持ち、わかります。

# JSのハッシュがクソな理由(あくまで筆者の主観です)
以下の結果は何が出力されるでしょうか?
```javascript
let hash = {
  76: {'name':'太郎A', 'age':'23'},
  55: {'name':'太郎B', 'age':'26'},
  82: {'name':'太郎C', 'age':'46'}
};
console.log(hash);
```
大抵の人（筆者を含む)が以下のような結果を期待するのでは無いでしょうか?
```javascript
{
  76: {'name':'太郎A', 'age':'23'},
  55: {'name':'太郎B', 'age':'26'},
  82: {'name':'太郎C', 'age':'46'}
}
```
しかし、実際には以下のようになります。
```javascript
{
  55: {'name':'太郎B', 'age':'26'},
  76: {'name':'太郎A', 'age':'23'},
  82: {'name':'太郎C', 'age':'46'}
}
```
**いやいや、順番変わってるやん。**
私は年齢で昇順にデータを持ちたいのです。
~~どうやらJavaScriptではハッシュがkeyによって昇順ソートされるみたいです。~~
~~その代わりキーでデータを取得するのが早そうです。~~
JavaScriptではハッシュの順序は保証されないらしいです。
キーで昇順になっていましたが、それは実行環境に依存するみたいです。
# とりあえずハッシュをやめて配列を使ってみる
順番が変わってしまうため以下のようにデータを持ってみます。
```javascript
let arr = [
  {'id':76, 'name':'太郎A', 'age':'23'},
  {'id':55, 'name':'太郎B', 'age':'26'},
  {'id':82, 'name':'太郎C', 'age':'46'}
];
console.log(arr);
```
もちろん想定通りソートされずにデータが取得できます。
しかし、データにアクセスするためにデータを線形検索しないといけなくなります。
```javascript:idが55のデータを取得(配列利用時)
let targetId = 55;
for(let v of arr) {
  if (targetId === v['id']) {
    console.log(`${v['name']}さん、こんにちは。`);
    break;
  }
}
```
ちなみにハッシュの場合は以下のように簡単にデータにアクセスできます。
```javascript:idが55のデータを取得(ハッシュ利用時)
let targetId = 55;
console.log(`${hash[targetId]}さん、こんにちは。`);
```
こう見るとハッシュはデータのアクセスに便利だなぁ、と思います。
# ハッシュと配列のいいとこ取りをしたい
順番は変えずにハッシュのようにデータを取得したい!!!
そんな風に思った時、ハッシュ型の値って参照渡しになっているような気がしたのを思い出しました。
ざっくり言うと以下のような性質です。
```javascript
let hashA = {'hoge':'ほげ'};
let hashB = hashA;
hashB['hoge'] = 'ホゲ';
console.log(hashA['hoge'])
// 出力結果: ホゲ
```
この性質を利用し、以下のように設定することでいいとこ取りを実現できました。
```javascript
let arr = [
  {'id':76, 'name':'太郎A', 'age':'23'},
  {'id':55, 'name':'太郎B', 'age':'26'},
  {'id':82, 'name':'太郎C', 'age':'46'}
];
let hash = {};
for(let v of arr) {
  hash[v['id']] = v;
}
```
上記のように配列とハッシュの両方でデータを持ってやることで
順番を考慮したデータ表示等で利用する場合は配列を、
データを取得して書き換え等を行いたい場合はハッシュを利用することで比較的スマートに記述することができます。
もちろんどちらかの変数でデータの書き換えを行った場合、もう片方にも反映されています。
# 最後に
JavaScriptでハッシュの並び順が変わることにとても驚きました。
今回私が示したやり方なんかよりもっといいものがあると思います。
もしよければあなたのやり方も共有していただけると幸いです。
一読いただきありがとうございました。

# 追記
## もっといいものがあった!!　そう、それはMap
この記事のコメントにあったようにMapは私がやりたかったことそのものでした。
Mapはキー・バリューでデータを保持でき、データをセットした順番も覚えてくれているとのことです。
さっそく今回のケースに合わせて例を書いていきます。
```javascript:Mapを利用した例
let map = new Map();
map.set(76, {'name':'太郎A', 'age':'23'});
map.set(55, {'name':'太郎B', 'age':'26'});
map.set(82, {'name':'太郎C', 'age':'46'});
for (let [k, v] of map) {
  console.log(`${v['name']}さん、こんにちは。`);
}
// 出力結果:
//  太郎Aさん、こんにちは。
//  太郎Bさん、こんにちは。
//  太郎Cさん、こんにちは。
```
JavaScriptのハッシュは全然クソじゃなかったです。
[Python]Python3の開発・実行環境構築[Mac]

### 前書き

年末ですね。仕事もほぼ納まったことですし、何か書きましょう。
ということで重い腰を上げて書いていきます。

### 準備

ターミナルを起動しましょう。

Homebrewがインストールされていない場合は、以下のサイトからコマンドをコピー＆ペーストしてインストールを行なってください。
https://brew.sh/index_ja
```
$ /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
```

### やるぞ

Python3の実行環境を構築します。今回はpyenvを使用します。インストールしましょう。
pyenvは実行プロジェクト（ディレクトリ）毎に実行するPythonのバージョンを指定できて便利です。
```
$ brew install pyenv
```

pyenvでインストールできるPythonのバージョンを確認します。

```
$ pyenv install -l
  ~省略~
  3.10.7
  3.10.8
  3.10.9
  3.11.0
  3.11-dev
  3.11.1
  3.12.0a3
  3.12-dev
  ~省略~
```

リストの中から使用するバージョンを指定して、Pythonのインストールを行いましょう。
```
$ pyenv install 3.11.1
```

インストール済みのPythonのバージョンは以下のコマンドで確認できます。
```
$ pyenv versions
* system (set by /Users/name/.pyenv/version)
  3.11.1
```

プロジェクト用のディレクトリを作成し、移動します。
```
$ mkdir demo-python-web-scraping
$ cd demo-python-web-scraping/
```

このディレクトリ内で使用するPythonのバージョンを指定します。
```
$ pyenv local 3.11.1 
```

指定されたバージョンの確認
```
$ python --version
  system
* 3.11.1 (set by /Users/name/path/demo-python-web-scraping/.python-version)
```

`$ python --version`コマンドが実行できない場合は、おそらくPythonコマンドのpathが通っていません。
以下のURLを参考にpathを通しましょう。
https://github.com/pyenv/pyenv#set-up-your-shell-environment-for-pyenv

>For Zsh
>If you wish to get Pyenv in noninteractive login shells as well, also add the commands to ~/.zprofile or ~/.zlogin.

```~/.zprofile
export PYENV_ROOT="$HOME/.pyenv"
command -v pyenv >/dev/null || export PATH="$PYENV_ROOT/bin:$PATH"
eval "$(pyenv init -)"
```

```
$ source ~/.zprofile
```

`$ python --version`の結果が返ってくるようになっていればOK。
これで環境構築完了です。

### Hello World

テスト用のファイルを作成してみましょう。
```
$ touch hello.py
```
おなじみのやつ
```hello.py
print('Hello World')
```

実行してみます。
```
$ python hello.py 
Hello World
```

無事Hello Worldできました。
OSGeo4Wをアップグレードした記録（アンインストールと再インストール）（2022年12月）


# はじめに
自宅PCで、QGIS（OSGeo4Wのパッケージとしてあるもの）をアップグレードしました。
もともとQGISの古いバージョンがOSGeo4Wのパッケージの一部としてインストールされていたので、少し手間がかかりました。メモしておきます。

（経緯）
* もともと、OSGeo4Wの一部として、QGIS3.8.2がインストールされていた。
* Windows用のQGISインストーラー（QGIS-OSGeo4W-3.28.2-1.msi）をダウンロードしてきて実行しても、QGISの更新がうまくいかず、古いバージョンのQGISが動いていた。

そこで、OSGeo4Wを入れなおすことにしました。

# わたしの環境
* Windows 10


# 方法
## 既存の OSGeo4W をアンインストール
OSGeo4WのFAQにアンインストールについて説明があった（[こちら](https://trac.osgeo.org/osgeo4w/wiki/FAQ#IsthereawayofuninstallingpackagesorallofOSGeo4W)）。これによれば、スタートメニューと、OS4GeoWのファイルツリー（一般的にはCドライブの直下）を削除すればよいらしいです。

> Individual package can be uninstalled via the Advanced install path. In the package listing click on the "New" column until the value changes to "Uninstall". Currently packages do not clean up desktop or start menu icons when uninstalling, this may be done manually.
> Currently there is no installer option to uninstall OSGeo4W completely. However, when all OSGeo4W applications, shells and services (like apache) are shutdown it is possible to just delete the whole OSGeo4W file tree (usually C:\OSGeo4W).

また、5年ほど前の記事ですが、私と同じようなことをされている方の記事もありました（[こちら](https://qiita.com/Yunie564/items/bcf95485d7e269ab11e5)）。（経験を共有くださりありがとうございます。）

ということで、まずはファイルツリーを削除。以下のようなファイルがありましたが、フォルダごと消しました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/679143/d38c4ea2-e5c8-7422-5ee7-08283c3c0bd3.png)

次にスタートメニューのOSGeo4Wも消しておきます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/679143/a3c83119-97b0-fb5f-655d-21284441a677.png)

再インストールするのでシステム環境変数はいじらないでおきます。

## OSGeo4W をインストール
[OSGeo4W](https://trac.osgeo.org/osgeo4w/)のページにある[Quick Start](https://trac.osgeo.org/osgeo4w/#QuickStartforOSGeo4WUsers)の手順をフォローしていきます。

1. OSGeo4W network installer をダウンロード
1. インストーラーを実行する
1. Express Installを選んで進む。パッケージはQGISとGDALにしておきました。（最近GRASSは全然使う機会がないので・・・）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/679143/c38ed00d-a722-18ef-5443-319a46dc450f.png)

するとインストールが無事に完了し、以下のようにプログラムのメニューに追加されました。（QGISはOSGeo4Wの下にあります。それが嫌な場合はスタートメニューのフォルダにショートカットをコピーしてもよいと思います。）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/679143/7eb53678-c01e-b603-bed1-da636cb3dbad.png)


# 結果の確認
無事にQGISがスタートしました。バージョンも最新です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/679143/0e2e4065-a93f-0608-25cc-a1f93108a84c.png)

なお、たまたま『インストール済みフォント』の一覧がでていきました。後で使うのでメモしておきます。

インストール済みフォント Open Sans Condensed Light, Open Sans Condensed, Open Sans Condensed Medium, Open Sans Condensed SemiBold, Open Sans Condensed ExtraBold, Open Sans SemiCondensed Light, Open Sans SemiCondensed, Open Sans SemiCondensed Medium, Open Sans SemiCondensed SemiBold, Open Sans SemiCondensed ExtraBold, Open Sans Light, Open Sans, Open Sans Medium, Open Sans SemiBold, Open Sans ExtraBold


# 参考にしたページ

https://trac.osgeo.org/osgeo4w/

https://trac.osgeo.org/osgeo4w/wiki/FAQ#IsthereawayofuninstallingpackagesorallofOSGeo4W

https://qiita.com/Yunie564/items/bcf95485d7e269ab11e5
Windows: 特定のIPアドレスやドメインだけVPN経由にするスクリプト

ビデオ通話しながら検証したりペア作業をすることはよくありますが、サーバや開発環境につ繋ぐためVPN接続する必要があり、ビデオ通話はVPN使わない通信でサーバなどはVPN経由と分けたいです。

そこでこちらの記事を参考にして、ルーティングを指定しています。

https://qiita.com/mindwood/items/5c56769a7fc40cafe7e3

ルーティングではドメインを指定できないためURLのような条件ではDNSからIPアドレスを引いてきています。
ドメインのIPアドレスが固定ならいいのですがIPアドレスが変わるものがあるため、たびたびルーティングの再設定を強いられることがあります。
手で更新していましたが、対象のドメインが複数あり手間なのでスクリプトで自動化しました。

# 手順

## 事前準備
1. VPN設定
上でリンクを貼っている記事などを参考に、VPN接続設定をし、すべての宛先でVPNを使わないようにします。

2. VPN接続時のダイアログ非表示設定
コマンドで操作したいので接続ダイアログを表示しないようにします。

以下のファイルを開き、該当のVPN接続でPreviewUserPwを1から0に変更します。
`C:\Users\{ユーザー名}\AppData\Roaming\Microsoft\Network\Connections\Pbk\rasphone.pbk`
```diff_powershell:rasphone.pbk
[VPN接続名]
Encoding=1
PBVersion=6
Type=2
...
- PreviewUserPw=1
+ PreviewUserPw=0
...
```


## 接続スクリプトファイル
PowerShellでスクリプトを書き、batファイルでクリック起動できるようにしました。

```connect-vpn.ps1
$VpnName = "XXXXXX"     # TODO: VPN接続名

###############################
# 登録済みIPアドレスをリセット
###############################
$DestinationList = (Get-VpnConnection $VpnName).Routes | Select DestinationPrefix
foreach ($Destination in $DestinationList){
     Remove-VpnConnectionRoute $VpnName -DestinationPrefix  $Destination.DestinationPrefix
}

###############################
# VPN経由にするIPアドレスを設定
###############################
$StaticIpList = @(
	"999.999.999.999/32"	# TODO: 任意のIPアドレス
	"999.999.999.0/24"
)
foreach ($StaticIp in $StaticIpList){
     Add-VpnConnectionRoute $VpnName -DestinationPrefix  $StaticIp
}

###############################
# VPN経由にするドメインを設定
###############################
$DomainList = @(
    "qiita.com"    # TODO: 任意のドメイン
    "google.com"
)
# ドメインのIPアドレスを特定して、VPNに登録する
foreach ($Domain in $DomainList){
    $DnsList = Resolve-DnsName -Name $Domain -Server 1.1.1.1 -Type A

    foreach ($Dns in $DnsList){
        $DnsIP = $Dns | Select IPAddress
        if([string]::IsNullOrEmpty($DnsIP.IPAddress)) { continue }
        Add-VpnConnectionRoute $VpnName -DestinationPrefix "$($DnsIP.IPAddress)/32"
    }
}

###############################
# VPN再接続
###############################
# VPN切断
rasphone -h $VpnName

# VPN接続
rasphone -d $VpnName
```

ps1ファイルはクリック起動できないので、batファイルから呼び出す形にします。
```connect-vpn.bat
@echo off
powershell -NoProfile -ExecutionPolicy Unrestricted .\connect-vpn.ps1
exit
```

ドメインのIPアドレスが変わる頻度が高い場合は定期的に更新するような処理にした方がいいかもしれません。
再接続せずにルーティングを反映する方法が分からないので、今のところは必要な時にこのbatを叩いています。
日商簿記3級に合格しました

2022年12月、師走の忙しい時期ではありますが、日商簿記3級のCBT試験を受験し、初回で合格しました。
この記事では、ITエンジニア（特に社内SE）が日商簿記を取得するメリット・および3級の勉強法について記述しています。
また、筆者はCBT試験（テストセンターで受験するもの）を受験しております。従来の年3回実施の紙での試験については、割愛します。

## バックグラウンド

- アラサー社内SE
- メイン業務はRailsやJavaScriptを使ってWebアプリケーションを書くことと、社内ネットワーク整備やクラウドサービス（AWS, Azure, MS365などなど…）のお守り
- 某国立大文学部卒（センター8割くらい）、教育系修士修了
- 日商簿記は社会人なりたての2018年、2019年にそれぞれ2級を受けて撃沈。

## メリット

- ITエンジニアの資格といえば、ベンダ系だったりIPAの基本情報・応用情報・高度試験だったり、あるいはTOEICのような英語の資格試験が思い浮かびます。その中でも、日商簿記はあまり受験するITエンジニアがいない印象があります。社内SEという文脈で考える日商簿記は3級でもおすすめです。
- おすすめの理由としては、企業の経済活動におけるお金の動きのイメージが掴めるというものがあります。PLやBSを抵抗なく読めるというのは、おそらく会社員だったら大きな恩恵を得ることができます。自分の会社のお財布事情がどんな感じなのか、というのが分かるようになります。簿記を学ぶと、「簿記も知らないで会社員になろうだなんて、なんて怖いことを…」と思うようになるかもしれません。
- さらには、プライベートでも投資（最近新NISAの概要が公開されましたね）を行う際に、日商簿記の知識があると、投資判断に役立ちます。
- また、これは万人にはお勧めしませんが、筆者は就職1年目から自分の家計のバランスシートを家計簿とは別に四半期ごとにつけており、家計の正確な把握に役立っています。
- 社内SE、特になんでもやらされる中小企業の社内SEですと、総務・経理と社内SEの領域が被ってくることが多いです。また、固定資産管理をしている方ですと、減価償却の概念（固定資産累計額はいくらで、償却期間はいくらで、だから残価はいくらで…）みたいなことがスッと分かりやすくなります。これだけでも日商簿記を学ぶメリットであると言えます。

## 勉強法

- 勉強開始は受験日のちょうど30日前、勉強時間は合計で30時間程度だと思います。1日多くても2時間、全く勉強しない日もちらほらありました（が、おすすめしません）。
- 勉強時間は何時間以上が良いというのはなく、人によってはもっと短くても受かると思います。まったくの初学者は30時間だときついかもしれません。

1. テキストを読む
『[スッキリわかる 日商簿記3級 第13版 テキスト&問題集](https://www.amazon.co.jp/dp/4300100012)』を購入し、2回通読しました。
大体の書店では、これ以外にもパブロフくんとか大原とかCPAとかいろいろな参考書があると思いますが、どれを選んでも大差ないです。ただし、**CBT試験を受験する際、従来の試験と大幅に形式が変わっているので、ブックオフなどの古本屋で中古品を買い求めるのは危険**です。ここだけがテキスト選びの注意ポイントです。
テキストは2回も通読すれば十分です。巻末の問題は、ほとんどやらなくてOKです。

1. 仕訳の練習
断言しますが**日商簿記3級は仕訳ゲーム**です。仕訳が十分にできれば、合格点は余裕でクリアできます。
逆に書くと仕訳ができないと手も足も出ません。
おすすめはスマホアプリの仕訳が勉強できる無料アプリです。具体的なアプリ名を上げることは避けます。テキストを読みながら、ちまちまスキマ時間や通勤時間にすすめましょう。テキストの巻末問題をやらなくて良い理由の一つはここにあります。

1. 問題をひたすら解きまくって復習
『[スッキリうかる 日商簿記3級 本試験予想問題集 2022年度版](https://www.amazon.co.jp/dp/4300100047)』を進めます。これをひたすら前日まで回します。
最初は100点中30点とか40点とかしか取れなくてビビりますが、私もそんなものでした。
復習が非常に大事で、具体的にはもう一度仕訳を書き直してみる、第3問なら答えを書き写すだけではなく、もう一枚解答用紙を用意して実際に書き入れて、締め切りまで行う、といったところです。
そのため、巻末についている冊子に直接書き込むのではなく、PDFをダウンロードしてA4のコピー用紙に印刷して、そちらに書き込んでください。
テキストの巻末問題をやらなくて良いもう一つの理由はここにあります。つまり、**テキストの問題を解く暇があったら、早く問題集に移って実際の問題に慣れてください**、ということです。
これを何回か繰り返していくと、気がつくと合格点に達するようになっています。なかなか点数が伸びない場合は仕訳力が圧倒的に不足していますから、「仕訳の練習」で間違えたところを繰り返してください。
問題集もパブロフくんとか大原とかCPAとか色々なものがありますが、**ネット試験・ネット模試**が付録でついているものを選んでください。
というのも、紙での試験とCBT試験は書き方がだいぶ違います。CBT試験はテンキーの「0」を連打する必要があり、ぶっつけ本番で挑むには少々リスキーです。せっかく無料で付録としてついているのですから、1回くらいはやってみたほうが良いと思います。もっとも、ITエンジニアならキーボードやマウス操作で苦戦する、ということは無いでしょうけど…。
また、ネット試験・ネット模試をやる際には、**A4のコピー用紙2枚とボールペン2本**を使って問題を解いていくと良いでしょう。これと電卓だけがCBT試験では使える道具です。本番と条件を揃えることは大きなメリットがあります。

## 当日

- 当日は受験票に書かれた受験時刻の30分前には会場入りしてください。試験の日に限って忘れ物をしたり公共交通機関が止まったりお腹が急に痛くなったりするものです。
- 受験時刻の30分前から受験ができます。
- 持ち込める電卓だと「00」のキーがあるので、たとえば7,000,000円（700万円）を計算したいときに「7」「00」×3回で4回の打鍵で済みますが、テンキーだと「0」しか無いので7回テンキーを叩く必要があります。**桁数を間違えないように注意！**
- 制限時間は60分で、もういいと思ったら受験終了です。その場で結果が返ってきます。

## 結果

- 82/100点で合格でした。第1問と第3問のみで合格点に達していました。（第2問がびっくりするくらいできませんでした）
- 後半に会社の繁忙期とイベントラッシュにぶち当たってしまい、何日も全く勉強ができない日ができてしまいました。繁忙期に試験を受けるのはおすすめしません。

## 今後の予定

- 日商簿記2級もCBTで受験しようと思います。年3回開催される紙での会場試験はしばらく難化の傾向が続きそうです。PCの使い方に習熟しているITエンジニアはCBT試験が導入されて結構有利になったと思います。
⑨でもわかる!Ubuntuをラズパイにインストールする方法!

どうもmikigohです。
この記事では⑨でもわかる用にラズパイにUbuntuをインストールする方法を3行で解説します。
あ、ちなみにこの3行ってのはPCの全画面で表示する場合のことを話しています。

**本題**
ラズパイにUbuntuをインストールする方法は、
・Raspberry Pi ImagerをPCにインストール
・SDをぶちこみ入れたいバージョンを選ぶ
・SDに書き込みラズパイにぶちこみ完成!

わかりましたでしょうか?
現在は⑨にとってもインストールしやすい環境になっています。
あ、わかんないとこがでた場合はググりましょう。
【TypeScript】Github に Push する前に自動で typecheck したい場合はhuskyが便利

# 背景
こんにちは，mayukorinです．普段チーム開発をしているのですが，開発をよりスムーズに行うために typecheck でエラーが起きていたらマージできないようにすることにしました．大人の事情で Github Actions が使えずどうしようか悩んでいたところ、チームのメンバーが「__husky__ を使えば，同じことができるかもしれないよ」と教えてくれました．試してみると結構簡単にできたので紹介したいと思います．

# huskyとは
huskyとは，commit や push を行う前に，指定したコマンドを実行できるJavaScriptパッケージです（説明が雑ですみません）．Githubは[こちら](https://github.com/typicode/husky)から，ドキュメントは[こちら](https://typicode.github.io/husky/#/?id=features)からアクセスできます．

# huskyでpushする前にtypecheckする方法
早速，huskyでpushする前にtypecheckする方法を紹介していきます．なお，今回はパッケージマネージャーとして yarn（バージョン1）を使っています．

## 1. husky のinstall
まず，husky を install します．
```
yarn add --dev husky
```
## 2. huskyでGit hooks を利用できるようにする．
次に，husky で Git hooks を利用できるようにします．
```
yarn -s run husky install
```

Git hooks については， [gitのドキュメント](https://git-scm.com/docs/githooks)に以下のように書かれています．

> Hooks are programs you can place in a hooks directory to trigger actions at certain points in git’s execution. Hooks that don’t have the executable bit set are ignored.

和訳すると，「Git hooks とは，hooksディレクトリに置くことで、gitの実行中のある時点で動作を開始させることができるプログラム」らしいです上のコマンドを実行すると，.huskyディレクトリが作成されます．

## 3. push する前に自動でtypecheckするように huskyを設定する．

最後に，push する前に自動でtypecheckするように huskyを設定します．今回私は typecheckを`yarn run tsc`で行っているので、以下コマンドを実行しました．

```
 yarn -s run husky add .husky/pre-push "yarn run tsc"
```

`husky add .husky/pre-push "push時に実行したいコマンド"` でコマンドを実行すれば大丈夫そうです．他にもcommit前に実行したい場合は，`.husky/pre-push` のところを`.husky/pre-commit` にすればよいです．

## 動作確認
試しに，typecheck error がある状態でpushしようとすると，pushできなくなります．
```
$ git push origin auto-typecheck-enable:auto-typecheck-enable
yarn run v1.22.10
$ .....node_modules/.bin/tsc
...
Found 16 errors in 8 files.

Errors  Files
...
error Command failed with exit code 2.
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.
husky - pre-push hook exited with code 2 (error)
error: failed to push some refs to '....git'
```

typecheck error がない場合は，このように push できます．
```
mayukorinrin@DESKTOP-Mayuko:~/STECH$ git push origin auto-typecheck-enable:auto-typecheck-enable
yarn run v1.22.10
$ ....node_modules/.bin/tsc
Done in 11.29s.
Counting objects: 15, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (15/15), done.
Writing objects: 100% (15/15), 1.66 KiB | 850.00 KiB/s, done.
Total 15 (delta 10), reused 0 (delta 0)
remote: Resolving deltas: 100% (10/10), completed with 6 local objects.
remote: 
remote: Create a pull request for 'auto-typecheck-enable' on GitHub by visiting:
remote:      ..../pull/new/auto-typecheck-enable
remote: 
To .....git
 * [new branch]      auto-typecheck-enable -> auto-typecheck-enable
```

# おわりに
husky ぜひ使ってみてください！

# 番外編
ちなみに` yarn -s run husky add .husky/pre-push "yarn run tsc"`を実行すると以下のようなファイルが作られます．
先頭の`#!`で始まる`#!/usr/bin/env sh` は，shebang (シェバン）と呼ばれるもので，「実行時にそのプログラムで実行するよ」ということを示しているらしいです．今回は，シェルで実行するよということを示しているみたいです．
```pre-push
#!/usr/bin/env sh
. "$(dirname -- "$0")/_/husky.sh"

yarn run tsc
```
AWS OrganizationsでメンバーアカウントにAWSアカウント名を取得させる

## やりたいこと
AWS Organizationsを運用している際、メンバーアカウント内の動的処理で自身の「AWSアカウント名」を取得したい。
（ユースケース：各アカウント内からアラートメールを送信する際に、メール件名にアカウント名を追加するときなど）

## 対応方法
アカウント名を動的取得するには基本的に`organizations:DescribeAccount`のアクションが必要となります。
ただし、こちらはOrganizationsの管理アカウントでしか利用できませんでした。

そのため

* 別途DynamoDBやS3にアカウント情報を定期保存するなど別の保存領域を使って取得する
* メンバーアカウント毎のIAMロールを管理アカウントに用意して、AssumeRoleしてもらう

などあまり美しくない方法しかなかったのですが、「Organizations の委任管理者機能」のポリシー調整でシンプルに実現出来ました。
「Organizations の委任管理者機能」については以下クラスメソッドさんの記事が分かりやすいのでご参照ください。

https://dev.classmethod.jp/articles/update-aws-organizations-delegated-policies/


Organizations の委任管理者機能に以下のポリシーを設定する事で各メンバーアカウントから`organizations:DescribeAccount`のアクションが可能になります。


※[管理アカウントID][Organization ID]は要変更
```json
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "Statement",
      "Effect": "Allow",
      "Principal": "*",
      "Action": "organizations:DescribeAccount",
      "Resource": "arn:aws:organizations::[管理アカウントID]:account/[Organization ID]/${aws:PrincipalAccount}"
    }
  ]
}
```

## ポイント
[グローバル条件コンテキストキー](https://docs.aws.amazon.com/ja_jp/IAM/latest/UserGuide/reference_policies_condition-keys.html)である`${aws:PrincipalAccount}`を使う事で、Organizations内のアカウント増に合わせてポリシーを調整する必要が無くなりました。
自動補完でinputの背景色が変わらないようにする方法

# はじめに
パスワードのinputを黒で実装していたら、Chromeの自動補完で白に変わるという不具合が発生、大変苦しんだので備忘録として残します。


## 背景色が変わる原因
自動補完後、下記のようなスタイルが適用されていました。
```scss
input:-internal-autofill-selected {
    appearance: menulist-button;
    background-image: none !important;
    background-color: -internal-light-dark(rgb(232, 240, 254), rgba(70, 90, 126, 0.4)) !important;
    color: fieldtext !important;
}
```

## 対処方法
シンプルに自動補完後のスタイルを上書きする形で落ち着きました。

```scss
  input:-webkit-autofill {
    box-shadow: 0 0 0 1000px rgb(0, 0, 0) inset !important; // background-colorでは変わらないため、box-shadowを指定。
    -webkit-text-fill-color: #fff !important;
  }

  // 自動補完後のカーソルが黒になるので、合わせて変更。
  input:-webkit-autofill:focus {
    caret-color: #fff !important;
  }

```

### サンプル
<p class="codepen" data-height="400" data-default-tab="css,result" data-slug-hash="MWBKVqJ" data-user="h-matcha" style="height: 300px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;">
  <span>See the Pen <a href="https://codepen.io/h-matcha/pen/MWBKVqJ">
  input-autofill-color-sample</a> by h-matcha (<a href="https://codepen.io/h-matcha">@h-matcha</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>


### おまけ
ググった結果では下記のような`transition`を指定する方法がよく出てきていました。
自分の場合は、残念ながら上手く効きませんでしたがメモとして残しておきます。
```scss
input:-webkit-autofill,
input:-webkit-autofill:hover,
input:-webkit-autofill:focus,
input:-webkit-autofill:active {
    transition: background-color 5000s ease-in-out 0s;
}
```
フロントエンドの責務と会社員の責務

# はじめに

エンジニアを始めてはや 4 年（いろいろ無駄な時間も過ごしたので実質 2 年）経ち、
現在フルリモートフルフレックスの会社でフロントエンドエンジニアとして従事しています。

そんな中で、自分が関わるプロダクトを進めていく上で改めてフロントエンドが持つ責務と会社員の責務（社会人としての責任のような当然のところは置いておいて）について考える機会があったので、
今回はそちらについて自分なりに思ったことを書いていこうと思った次第です。


# 各スコープごとの目標と社会貢献

いきなり責務から横道にずれますが、職務に関係なく、どの会社に所属していても
- 会社としての目標
- 所属している部署としての目標
- 個人の目標

上記のような目標に関して目にする方はおそらく多いのではないかなと思います。
これらはそれぞれスコープに違いはあれど、これらは最終的に**社会への貢献**というところに行き着くと思います。
上記の目標達成は、**会社として利益を出すため**という直接的な結果へのアプローチに繋がっているとは思いますが、
"会社として利益を出す"という行為は"社会への影響力を持つ"ということであり、すなわち**社会への貢献**なのかなと思います。

そして上記の目標を達成するために必要な、個々人が持つべきものが**責務**ではないのかなと私は思いました。


# それぞれの責務

## 会社員isRPG

前述した目標で説明した内容について、"会社としての目標"や"所属している部署としての目標"は基本的に経営者やステークホルダー、
マネージャーなどが決めている内容にはなりますが、"個人の目標"は当然個々人が決めているものになります。

すごく噛み砕くと、一連のプロセスはRPGゲームのようなもので、
1. 会社に入る
2. 目標を設定する
3. 目標達成のために頑張る
4. 目標を達成する
5. 業務をする
6. 会社に貢献する
7. 社会に貢献する　

といった流れは

1. 冒険の旅に出る
2. ボスを倒そうとする
3. 装備を集める
4. 強くなる
5. ボスに挑む
6. ボスを倒す
7. 世界を救う

みたいな感じなんじゃないのかなと。

つまり個人目標の内容が何であれ、達成までの内容はあくまで装備アイテムの1つであって、最終的な目的は会社に寄与し、**会社への貢献≒社会への貢献**をすることではないかと自分は考えます。

例えば、新しいフレームワークやツールのインプットをする、ということが目標の一部になっていた場合、インプットした知識はその知識を以ってどうプロダクトに影響を与えることができたか（実業務に於いて効果を発揮できたか）になるわけです。
つまり、やや乱暴かもしれませんが"目標"と"会社への貢献≒社会への貢献"をつなぐ為に必要な手段が"責務"となるのではないでしょうか。

前置きが長くなりましたが、こちらを踏まえた上で"責務"についてお話しできればと思います。


## フロントエンドとしての責務

上記のようにRPGで例えた場合、"フロントエンドエンジニア"というロールはそのままですが"ジョブ"ですよね。
F○ライクですが、白魔道士だったら周りの人を癒すのが生業だし、竜騎士だったら周りの敵を槍で倒すのが生業なわけです。
これがフロントエンドだったら、フロントエンドの設計や構築を行うのが生業ですよね。
全部挙げるとキリがないですが、環境がモダンでもレガシーでもだいたい共通しているのは

- UI設計
- アニメーションの作成
- APIとの連携
- コードレビュー
- 導線の設計
- テスト

人によって多少異なりますが、このあたりなのかなと思います。
ただ本当にこれだけしかできないと、**ただ作業ができる人**になりますよね。
RPGだったら一人でレベル上げして装備強くしてソロでボスを倒したり、なんてことできると思いますが、RPGでもすごくハードですし、当然会社員をやっているとそうはいかないわけです。
そこで必要になってくるのが、**会社員としての責務**になります。


## 会社員としての責務

また同じようにRPGで例えた場合、"会社員"というロールは"冒険者"という少しマクロなスコープになります。
冒険者は冒険をするのが生業ですが、ボスを倒すにはパーティを組まなきゃしんどいですよね。
パーティを組むにはパーティメンバーにしたい人と話をしなきゃいけないし、パーティを組んだ後はパーティメンバーと連携をとらないとボスには勝てません。
同じように、会社員は

- 他部署のメンバーと合意形成する
- 進捗状況を伝える
- 問題点を共有する
- 相手のことをリスペクトする

などが必要になってくると思います。
フリーで仕事をする場合、ものによってはエージェントを通したりすることでコミュニケーションは最低限で済んだりすると思いますが、
その場合はRPGで言うところのギルドから仕事を斡旋してもらうようなものなのかなと思います。


# 結局言いたいこと

会社員として会社に所属するからには、前述した通り**職種の責務**と**会社員の責務**の両方を果たさなければ、うまく会社に貢献することはできませんし、
いい影響も与えられないと、個人的には思っています。
今までエンジニアってこんなに色々なことやらなきゃいけないの？なんて思っていたこともありましたが、自分の職種がやらなければいけないことと、会社員としてやらなければいけないことを精査することで、会社に、社会に貢献するために何が必要か、何をすべきかはかなりクリアに見えてくると思います。
上記を意識して普段の仕事に取り組むと、より会社に良い影響を与えられる人材になるのではないのかなと思いました。
Firestore、Storageへのアクセスが可視化できるChrome拡張Firebase access viewerのご紹介

# はじめに
Firebase開発してるとこんなことありませんか？

- 無限ループで課金地獄が怖い
- FirestoreやStorageへのread/writeの流れを確認したい

ということでFirestore/Storageへのアクセスを可視化できるChrome拡張Firebase access viewerを作成しました！

https://chrome.google.com/webstore/detail/firebase-access-viewer/bjdhoepihkomdndgccgojepkhhhbhjle

# 使い方

1. Firebase access viewerをインストールする
2. Firebase access viewerを固定する（オプションだけどおすすめ）
3. ChromeでFirebaseプロジェクトのWebアプリを開く
4. Webアプリを開いたタブでChromeのDeveloper Toolsを開く

# 何ができる？

- WebアプリがFirestore/StorageにアクセスしたタイミングでFirebase access viewerのアイコンがチカッと光ります

    ↓こんな感じ（アクセスしまくったらチカチカし続けるので無限ループに気づけます！）
    ![CleanShot 2022-12-28 at 16.45.24@2x.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2989440/6598736d-9804-fa46-f509-403169c5b47d.png)

    - アクセスしまくったらチカチカし続けるので無限ループに気づけます！
    - 思ったよりもチカチカしたらリファクタしないとなという気分にしてくれます！

- Firestore/Storageへのアクセス履歴（最近100件）が確認できます

    ![CleanShot 2022-12-28 at 16.26.52@2x.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2989440/d380fe04-e4c1-02b9-0a09-da4e4bcfd3eb.png)

    Clearボタンで履歴をクリアできるので、事前にクリアしといてページ開いたときのアクセスの流れを確認するみたいなことが出来ます。

- Firestore/Storageへのアクセス詳細が確認できます

    履歴をクリックするとクリックしたアクセスの詳細が確認できます。

    ![CleanShot 2022-12-28 at 16.28.21@2x.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2989440/272cbb8e-9293-201b-28c1-0d80c047f6fb.png)

# 最後に

結構前にこっそり作ってたのですが、先日、実際の開発でめちゃくちゃ役に立ったので、今年最後の記事ってことで紹介記事を投稿することにしました。

Firebaserのみなさま、Firebase access viewer使っていい感じにFirebase開発楽しんで下さい！よいFirebaseライフを :thumbsup:
Windowsでレジストリの追加or更新をコマンド（bat）で実行

# やり方

『管理者権限で開いたコマンドプロンプトで実行』などの **管理者権限が必要** 。

```bat:サンプルコード
reg add "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon" /v "AutoAdminLogon" /t "REG_SZ" /d "1" /f
```

## サンプルコードの詳細

```reg``` レジストリ操作コマンド。
```add "レジストリーフォルダーパス"``` 無ければ追加、存在したら更新。（パスの末尾に\は不要）
```/v "項目の名前"``` 『value』の『v』。
```/t "項目の種類"``` 『type』の『t』。
```/d "項目の値"``` 『data』の『d』。
```/f``` 確認を挟まずに強制的に処理。『force』の『f』。

# 参考サイトさん

https://oozappase.com/windows/regcommand/

# バージョン

Windows 10 Pro 21H2 OSビルド 19045.2364
Use Google Drive in Windows explorer

# 設定手順

1.[PC版Google Drive (EN)](https://www.google.com/intl/en/drive/download/)、[PC版Google Drive (JA)](https://support.google.com/drive/answer/7329379#zippy=)をダウンロードしインストールする。

2.インストール後、自動で立ち上がるウィンドウに従ってGoogleアカウントにログインする。

3.Windowsのエクスプローラーを開き、PCをクリックしてGoogle Driveが(G:)や(H:)としてアクセスできるか確認する。

# 複数のGoogleアカウントにアクセスする(最大4つのアカウントまで)
設定手順で1つのGoogleアカウントのGoogle Driveにアクセス出来たことが前提です。


1.Windowsの`タスクバーの上矢印記号(^)`をクリックし、隠れているインジケーターを表示する。

2.その中の`Google Driveのアイコン`をクリックし、左上のGoogleアカウントの`プロフィールアイコン`から`別のアカウントを追加`を選択し、設定手順の2から同じように設定する。

---
<font color="yellowgreen">**QiitaLink**</font>
<font color="black">**Designed by RENOX**</font>
教えてください……

![image_2022_12_28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3084040/33ca3e1e-583f-cbd2-2e8a-75913a9cb073.png)
この赤線部分がなんで？
ってなりました、教えて頂けないでしょうか？
ExcelのデータをC#で取得する

ExcelのデータをC#で取得する。

**使用ライブラリ**：
ClosedXML

#### ClosedXMLの入手方法
ClosedXMLライブラリを用いることで、Excelデータを簡単にC#で取得することができるようになる。
NuGetパッケージマネージャーから、使用するプロジェクトにインストールするだけでOK。

**NuGetパッケージマネージャーの開き方**
・上部メニューバー → ツール → NuGetパッケージマネージャー▶ →ソリューションのNuGetパッケージの管理
参照からClosedXMLを検索して、インストールを行う。

#### usingの記述
ライブラリを使用するためのusing記述
```c#
using ClosedXML.Excel;
```

## ExcelのデータをC#で取得する

#### Excelファイルに接続する
```c#
var wb = new XLWorkbook(@"C:\Users\○○○○.xlsx", XLEventTracking.Disabled);
```
XLEventTracking.Disabledをつけることによって、セル挿入・削除追跡をオフにすることができる(らしい)。つけなくても〇

#### シートを選択する
```c#
var ws = wb.Worksheet("シート名");
//下のコードを使えば、左から〇番目のシートという指定ができる
var ws = wb.Worksheet(1);
```
#### 値を取得する
値を取得するためには、セルの座標を取得する必要がある。

⒈ セルの座標を取得
```c#
//(行番号、列番号)
//行が数字部分、列がアルファベット部分にあたる。
var cell = ws.Cell(1, 1);
```
※この時点ではセルの値ではなく、"A1"という座標そのものが取得されている

⒉ ワークシートのセルから値を取得
```c#
var value = cell.Value;
```
(cell).Valueプロパティを参照することによって、セルの値が取得される。




<br>
<br>

参照：
https://docs.sakai-sc.co.jp/article/programing/closedxml.html
Next.js 13 から next/link の Linkコンポーネント が 常に aタグをレンダリングするようになったので共有します

## 目的

Next.js 12 と 13 で Linkコンポーネントの実装方法が変化したよ、のお知らせ

## 使用技術

- "next": "13.0.5",
- "react": "18.2.0",
- "react-dom": "18.2.0",

## Next.js 12 までの Linkコンポーネント

Next.js 12までは`aタグ`を常にネストしないといけなかった

```tsx
import Link from 'next/link'

// Next.js 12まではaタグを常にネストしないといけなかった
<Link href="/about">
  <a>About</a>
</Link>
```

## Next.js 13 の Linkコンポーネント

Next.js 13以降は `aタグ` をネストしなくて良くなった

```tsx
import Link from 'next/link'

<Link href="/about">
  About
</Link>
```

なので、[Next.jsのLinkコンポーネントにpassHref属性を付与するのはどんな時なのか調べてみた](https://zenn.dev/k_kazukiiiiii/articles/1058a988f3fa5a)でまとめたようなLinkコンポーネントの実装方法はNext13の場合は必要なくなりますね。そもそもLinkコンポーネントの子供にaタグをネストするケースがなくなるので。

## Next.js12から13に変更する時の注意点

たとえば、Next.js13で開発しているプロジェクトがあるとします。

そこであなたは Next.js12までの  
Linkコンポーネントの書き方でコンポーネント実装を行いました。

そうすると `Hydration Error` と `validateDOMNesting Error` が出現することになります。

| Hydration Error |
| --- |
| ![Hydration Error](https://storage.googleapis.com/zenn-user-upload/f2cee0de7f24-20221228.png) |

| validateDOMNesting Error |
| --- |
| ![validateDOMNesting Error](https://storage.googleapis.com/zenn-user-upload/d94f68c9c1df-20221228.png) |

↑のようなエラーが出現する理由は「aタグの子供にaタグをネストする書き方はダメだよ。それはHTMLのタグの入れ子構造のルールに反しているから」なので、Next.js13のLinkコンポーネントの書き方に変更したら2つのエラーを同時に解決することができます！

## さいごに

Next.js12 から Next.js13 にバージョンアップするときに  
Linkコンポーネントを多用しているプロジェクトだったら  
このエラーを解決するのめっちゃ大変じゃん、と思いましたね。笑

## 参考文献

[Next.js Blog | next/link](https://nextjs.org/blog/next-13#nextlink)
QGIS・バッチ処理で出力ファイル名を式で指定する

「マスクレイヤで切り抜く」を例に説明します。

## 1.バッチ処理を開き、切り抜きたいファイルを指定

ツールボックスから「マスクレイヤで切り抜く」を選択し、下らへんにある「バッチ処理を実行」を押すとこのウィンドウが出てきます。
![スクリーンショット 2022-12-28 15.41.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2950165/7c4c5dbf-946d-ec6f-fa6e-bb6ecd36c408.png)

この写真では、あるディレクトリの中の全ファイルを追加しています。

## 2.式による計算...　を開く

いろいろなパラメータを設定した後、一番右の「出力ファイル」の「オートフィル」から「式による計算...」を選択します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2950165/e2359b83-b9b0-5512-fb5f-ad1f3a40e89a.png)

## 3.関数 replace を使用

documentation(https://docs.qgis.org/3.16/ja/docs/user_manual/working_with_vector/functions_list.html#replace )を引用します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2950165/ce429510-af02-8fd3-d4cd-abea1d2005b8.png)

ここで重要なのは、入力文字列を**INPUT**ではなく**@INPUT**と指定することです。
使用可能な文字列にINPUTとあリますが、間違えないようにしてください。
また、存在しないファイル名を指定して実行してもファイルを新しく作成してくれることはないのでそれも注意です。

式ビルダでdocumentationに沿ってファイル名を設定し、「OK」を押すとバッチ処理が実行されます。
旧 Xojo( Web1.0 ) で 右クリックメニュー を使う

Xojo で ContextualMenu を使うやり方。こちらも初見殺しだったので備忘録。
Xojo 2019 r3.1/3.2 の Web1.0 上の操作で過去のAPI。ここらへんのレガシーなノウハウや調べる手段は徐々に失われているみたい。かといって Xojo 2020 以降の Web2.0 系はまだ実用レベルではないようなので、自衛でメモ。

# 方法

ListBox を作り、Shown アクションハンドラを追加する。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/e21e64e4-c94e-2b63-c04e-df17c9b870df.png)
```
Var menu As New WebMenuitem
menu.Append(New WebMenuItem("編集"))
menu.Append(New WebMenuItem("削除"))
menu.Append(New WebMenuItem("キャンセル"))
Me.ContextualMenu = menu
dim hitItem as WebMenuItem
```

ContextualMenuAction アクションハンドラを追加する。
```
Select Case Item.Text
Case "編集"
  If Me.ListIndex < 0 Then
    MessageBox("リストから選択してください")
  Else
    // ...
  End If
Case "削除"
  If Me.ListIndex < 0 Then
    MessageBox("リストから選択してください")
  Else
    Me.RemoveRow(Me.ListIndex)
  End If
End Select
```


# 実行結果

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/93debe0f-8b31-112a-33d5-5dc9c6bd5c98.png)

右クリックでメニューが表示されます。Ye-151を削除します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/727b3699-bfcf-51f2-df18-17835ec17621.png)

削除されました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/c11489da-ee04-2410-89ed-578ec4cbb8af.png)

このやりかたはメニューの表示や非表示などの処理は必要ありません。

# 発展形

このサンプルでは編集処理はコメントアウトしています。編集するには入力UIが必要であるが、入力ウィンドウをポップアップするとすると以下あたりを使って作成することになります。
「旧 Xojo( Web1.0 ) で WebContainer を使う」
https://qiita.com/nanbuwks/items/02da6e3e41ab74c2dc2e

# 関連投稿

See also:

「Xojo 2019 → 2020 Webアプリの相違点」
https://qiita.com/nanbuwks/items/57ccf07ee9fffec145d3


<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>

<br>

# おまけ

Ye-151 を削除したのは、無茶な計画で実機作成に至らなかったからです。
Ye-150 シリーズは自動迎撃を行う高高度超音速戦闘機ですが、そのバリエーションの Ye-151 は、TKB-495 またはマカロフ TKB-539 砲を装備していました。しかしながら、マッハ 3 に迫る高速飛行中に、砲システムは機能しないはずです。
驚愕することに、この砲システムは驚異のメカニズムを備えていたそうです。

> 傾斜台の回転リングに取り付けられた。マウントは±30°傾けることができ、取り付けリングは360°回転することができ、取り付けリングの中心線の周りの60°の円錐形の範囲を攻撃可能であった。
( https://ja.wikipedia.org/wiki/Ye-150_(%E8%88%AA%E7%A9%BA%E6%A9%9F) )


単に機体軸に並行して取り付けた機銃であればわかりますが、60°の円錐形の範囲を攻撃可能ということは機種のマッハコーンに収納してたのではないか? 発射煙でストール必至では?

攻撃範囲が 60°の円錐形というのも理解が追いつきません。XB-70 や SR-71 などの脅威を排除するためにはこのようなものは必要ないはずです。劣悪な運動性能を補うためのドッグファイトに備えるとしても、レーダー連動でなければならないはずでそれを収めるためのマッハコーンは砲システムでふさがっています。

高高度から前線支援まで万事こなすマルチロールファイターを目指したのでしょうか。Mig-23 に対する Mig-27 のように、地上攻撃用の別バージョンなのでしょうか? しかしどうやらそうではなさそうで、高速高高度迎撃システムであるウラガン-5システムの武装オプションとして、 空対空ミサイル や 無誘導ロケット に加えて傾斜回転式台座の30 mm機関砲 x 2 が含まれていたそうです。警告射撃のために使うつもりだったのでしょうか?

案の定、実機製造はされなかったということで、今回のリストから削除対象になりました。
【データの漏れの確認/BigQuery】手作業やコピペでリスト化したデータに漏れが無いか確認する方法

# 今回の課題
PCの特定のディレクトリ内で、削除したいファイルが複数あったため、
削除したいファイルを手動・コピペでリスト化し、そのリストをBigQueryでテーブル化した。

手動・コピペでリスト化したため、BigQueryでテーブル化した削除リストのファイル名に間違いが無いか確認を行いたかった。

## 確認した方法
下記のクエリのように、左側はマスタデータ、右側は手作業でリスト化したデータとして、左外部結合した際に、右側のテーブルにNULLが無ければ、
左側のテーブルは右側のテーブルのファイル名を全て所持しているということが分かる。

※左側のテーブルが右側のテーブルのファイル名を全て所持している=ファイル名が全て一致している。
　つまり、ファイル名に誤りが無い。ということが分かる。
```SQL
with master as (
    select
        delete.file_name as delete_file_name -- 削除するファイルを手動でリスト化した際のファイル名
        , list.file_name as all_file_name -- 正しいファイル名のカラム
    from
        `削除したいファイルをリストアップしたテーブル` as delete -- 削除するファイルを手動でリスト化したデータのテーブル

        left join `正しいファイル名が格納されているテーブル` as list -- joinした側のsh_jumpplus_jpg_filesのfile_nameカラムにnullが無いか探す。
        on delete.file_name = list.file_name
)
select
    delete_file_name
    , all_file_name
from
    master
where
    all_file_name is null -- joinした側のsh_jumpplus_jpg_filesのfile_nameカラムにnullが無いか探す。
```

以上です。
コーシーシュワルツの不等式ってなんぞや

# コーシーシュワルツの不等式
コーシーシュワルツの不等式の不等式は以下の様に定義されている。
今回はなぜ、この不等式が成立するのか分からなかったので、メモとして証明をしていく。

・コーシーシュワルツの不等式
<!-- formula -->
```math
   \biggl(\sum_{i=1}^{n}a_i^2\biggl)\biggl(\sum_{i=1}^{n}b_i^2\biggl)\;\geq\;\biggl(\sum_{i=1}^{n}a_ib_i\biggl)^2

```
<!-- formula -->

等号成立条件
・$a_i = kb_i(i=1,2,3...n)$の時
・$a_i = 0$の時（いずれかが０の時）


# 証明

まず土台となるのは以下の数式
<!-- formula -->
```math
\begin{align}
0\:\leq\:\sum_{i=1}^{n}(a_ix - b_i)^2 &= \sum_{i=1}^{n}(a_i^2x^2 - 2a_ib_ix + b_i^2)\\
&=\biggl(\sum_{i=1}^{n}a_i^2\biggl)x^2 - 2\biggl(\sum_{i=1}^{n}a_ib_i\biggl)x + \biggl(\sum_{i=1}^{n}b_i^2\biggl)\;...(1)
\end{align}
```
<!-- formula -->

ここでポイントは　$0\leq\sum_{i=1}^{n}(a_ix - b_i)^2$　で右辺が２乗なのでこの不等式が成り立っている。

(1)の式が2次方程式になっているので、判別式:$D = b^2 - 4ac$を用いて以下が成り立つ。

<!-- formula -->
```math
\begin{align}
D = 4\biggl(\sum_{i=1}^{n}a_ib_i\biggl)^2 - 4\biggl(\sum_{i=1}^{n}a_i^2\biggl)\biggl(\sum_{i=1}^{n}b_i^2\biggl)\:\leq\: 0
\end{align}
```
<!-- formula -->

ここまで来ればあとは左辺に移行し、両辺４で割れば、コーシーシュワルツの不等式が出現する。
<!-- formula -->
```math
\begin{align}
4\biggl(\sum_{i=1}^{n}a_ib_i\biggl)^2 - 4\biggl(\sum_{i=1}^{n}a_i^2\biggl)\biggl(\sum_{i=1}^{n}b_i^2\biggl)\:\leq\: 0\\
\\
4\biggl(\sum_{i=1}^{n}a_ib_i\biggl)^2\:\leq\:4\biggl(\sum_{i=1}^{n}a_i^2\biggl)\biggl(\sum_{i=1}^{n}b_i^2\biggl)\\
\\
\biggl(\sum_{i=1}^{n}a_ib_i\biggl)^2\:\leq\:\biggl(\sum_{i=1}^{n}a_i^2\biggl)\biggl(\sum_{i=1}^{n}b_i^2\biggl)
\end{align}
```
<!-- formula -->

終わり
Tree Felling Boksburg

ABOUT US
Whether you need us to cut trees, remove stumps or trim palms, we’re more than happy to accommodate you. We’ve been cutting down trees for 7 years and are proud of the customer service we provide.

We’re happy to give you a FREE quotation and can get one to you within 24 hours – no matter what size the job is. We pride ourselves on being competitively priced and providing high quality workmanship.

We take care of everything, from rubbish removal after each job to cleaning up afterwards, so all you need is to call and we’ll do the rest!

Tree Felling and Removal
Stump Removal
Palm Tree Removal
Tree Trimming and Pruning
Emergency Tree Removal