OmniAICreator/Qiita-1.07M huggingface dataset:
Swift ユニットテスト 5分で出来るとことんシンプルなテスト導入

初めてのQiita投稿です。
間違いあればコメントいただけると幸いです。
よろしくお願い致します。
 
**Xcode 13.1**

##プロジェクト作成

**Include Testsにチェックを入れてプロジェクトを作成します。**
[![Image from Gyazo](https://i.gyazo.com/6c89a1252bf1b1e8323b51ec15cc5eb1.png)](https://gyazo.com/6c89a1252bf1b1e8323b51ec15cc5eb1)

**UnitTest, UI　UnitTestのファイルがデフォルトで生成されます。**
[![Image from Gyazo](https://i.gyazo.com/1a263931707c721e511b43db35a8a9de.png)](https://gyazo.com/1a263931707c721e511b43db35a8a9de)


## ViewControllerにテスト対象のメソッドを追加


**下記メソッドをViewControllerへ追加します。**

```Swift
    func add(num1: Int, num2: Int) -> Int {
        return num1 + num2
    }
```

[![Image from Gyazo](https://i.gyazo.com/63f5ad3da6f67508e26c88b663d99092.png)](https://gyazo.com/63f5ad3da6f67508e26c88b663d99092)

##Tests.swift内にテストを追加

**下記テストを追加**

```Swift
    // testを行う場合は関数名の頭にtestと記述
    func testAdd() throws {

        // ViewControllerをインスタンス化　addメソッドに引数1と3を与えてresultにInt型の結果を代入する
        let result = ViewController().add(num1: 1, num2: 3)

        // XCTAssertEqualは引数2つが等しいかテストを行う　等しい場合テストが成功する
        XCTAssertEqual(result, 4)
    }
```

[![Image from Gyazo](https://i.gyazo.com/12956ca2e610c5ffbce25e3ba66a8e92.png)](https://gyazo.com/12956ca2e610c5ffbce25e3ba66a8e92)


##テストを行う

**赤枠のボタンを押下します。するとテストが走り、失敗なら警告、成功なら緑のマークが表示されます。**
**これでテストは完了です。私自身、食わず嫌いでテストを避けていましたがシンプルに実装することで簡単に出来ました。**

[![Image from Gyazo](https://i.gyazo.com/66b18b701ab2c1b158f74bcd693a9453.png)](https://gyazo.com/66b18b701ab2c1b158f74bcd693a9453)

## これから
**あえてテストを失敗させるためにメソッドの内部を変更したり、XCTAssertEqualの第2引数を変更してみたり、さまざまな箇所を変更して結果を確認してみましょう。XCTAssertEqual()以外にもいくつものテストがあるので調べながら試してみましょう。**

**既にあるプロジェクトへのテストの追加やUIテストなどありますが、とことんシンプルに説明できたのではないかと思います。**
**以上、最後までご覧いただきありがとうございました。**
素人が量子プログラミングを1年間やって感じたこと

# 素人が量子プログラミングを始めて1年がたった

Qiitaに初めて量子コンピュータのプログラミング記事を投稿したのが
`2020/12/17`
でした。そこから1年経ちました。
素人なりに、量子コンピュータが今どういう状況であるかを書いてみたいと思います。

なお、開始2ヶ月時点での記事は以下の通り。このときと感じ方は変わっているでしょうか？
[素人が量子プログラミングをやって感じたこと](https://qiita.com/notori48/items/c0293496d72446fb15af)

# 2ヶ月時点で感じたこと がどう変わったか

振り返ってみます。

- 量子プログラミングは、ひたすら面倒？　→SDKやAPIが増えてきたため、だいぶ緩和されました。特に量子機械学習は恩恵を感じます。  

- ライブラリを使うのにもある程度知識は必要？　→　これは変わりません。  
- 地獄のデバッグ？　→　これは変わりません。  
- 日本の量子コンピュータ技術者は圧倒的に少ない気がする？　→　これも変わりませんが、いたるところで量子コンピュータへの参入を聞きますので、だんだん増えてきていると思います。特に大手が「味見」でやってみるような話が多いかも。  
- プログラミング環境は整えやすい？　→　これは変わりません。  
- ちょっと勉強するだけでもリテラシーが上がっていく？　→　これも変わりません。ただ、最先端がぐいぐい進んでいくので全く追いつけないです。。  
- (今の）量子コンピュータでできること、できないこと　がちょっとわかる？　→これも変わりません。ただ、最先端がぐいぐい進んでいくので(ry  

# 新たに感じたこと

- 今の量子コンピュータ実機(NISQ)[^1]でビジネス問題を解くという夢は終わった

でかいこと言ってますが、これは間違いないと思ってます。NISQの実証実験が明らかにしたことは、エラー率を下げない限りただ大規模化（量子ビット数の増加）をしても計算が破綻してしまい意味をなさないということです。GoogleのシカモアQAOA論文をみてもそれは明らかでした。問題や量子ビットのトポロジーなど色々な要素が絡みますが、なんとか解が出るのはせいぜい10量子ビットとか20量子ビットの回路までであって、これでビジネス上の問題を解くというのは無理でしょうし、そもそも数十万円の古典コンピュータで十分にシミュレートできる範囲です。

- NISQ向けのアルゴリズムだけを切り出しても、容易には古典を超えられない

実機のエラー率が問題であれば、少なくともシミュレーションでは古典アルゴリズムを超える性能が出ると期待したくなります。しかし、これすらも多くの場合はうまくいきません。
私がぎりぎり観測できてる範囲は量子機械学習だけですが、2019とか2020の論文をみても、例えばクラスタリングや分類問題で、性能面で古典アルゴリズムにボロ負けしています[^2]。
量子の世界へ古典情報を埋め込むまではいいのですが、量子情報の世界を効率よく探索すること、まさに求解アルゴリズムをうまくやるということが極めて難しいです。
ただ適当にモデルを作って適当に最適化した程度では全然うまくいきません。
「とにかく量子はすごいから、古典のものを量子にすげ替えれば性能は同等以上になる」というのは全く正しく有りません。だからこそ、面白いとも言えます。
研究者人たちはこのアルゴリズム探索を頑張っているという認識です。

- 思いほか光量子やシリコンが台頭してきている

新しい方式がどんどん登場してきています。光量子（アナログ、GKP量子ビット）、シリコンなどなど。
超伝導とイオントラップが当面は二強かと思ったのですが、今後数年でもひっくり返る可能性あり、という感じです。

- 量子誤り訂正の進展が速い

量子誤り訂正(QEC)の実機実証がどんどん進んでいます。
最初は誤りの検出だけでしたが、今は誤りの検出→訂正までもできはじめています。
まだ17量子ビットで1論理量子ビット？を作るというレベル[^3]、作るだけで論理演算も出来ていない、サイクルを増やすとどんどん誤ってしまう、などなど課題は山積みですが、あくまで理論上の存在だったQECが実機で動いたというのは凄いニュースです。
これがスケールするか（＝大規模化するか）は別問題だと思いますが、期待したくなります。
ただ、QECには論理量子ビットの数十倍（以上？）の膨大な物理量子ビットを必要としますので、物理量子ビットが最低でも1,000量子ビットぐらいはないと意味ある問題は解けなさそうです。

- そうはいっても時間がかかるので、”量子ビジネス”は実用より人材育成や教育にシフトしている

そうはいっても量子コンピュータでまともな問題が解けるのはまだまだ先でしょう[^4]。早くて2030年、もっと先であろうと思います。
でもビジネスを展開する企業としては、それまで食費0円というわけにはいきません。
なので、自社の抱える専門部隊を「人材育成や教育」にまわしてお金を稼いでいるという印象です。
また、シミュレータを売ったり、環境を売ったりするケースも目立ちます。
ある程度は知識がないと、食い物にされますので、気をつけましょう。


# 量子コンピュータに参入すべきなのか？

実用がだいぶ先だとわかった上でやる　ことは必須かと思います。
私自身は、”本業”でご飯を食べながら、隙間時間に「無駄になってもいいや」という気持ちで勉強したり実装したりしています。
ただ、何もしないでいると、量子コンピュータがほんとうの意味で「実用化」されたとき、もはや容易に追いつけないほど先へ行ってしまっている可能性は高いと思います。

# まとめ

実用がどれぐらい難しいか、量子を乗りこなすのがどれほど職人技なのかがよくわかった一年でした。
量子コンピュータは”楽しんで”やるのがいいと思います。
とにかく色々な分野の人材が足りてないので、あなたの居場所もきっとあると思います。[^5]

[^1]: ゲート型のみを量子コンピュータと言っています。アニーリングのほうも、ゲートよりましでしょうが、バラ色という印象はありません。問題や用途によっては使えなくもないかな？ぐらいで・・・。

[^2]: そのくせ、計算時間は（量子を無理やり古典でシミュレーションするので）古典の100倍とか1000倍とかかかるので、評価だけで大変です。

[^3]: 表面符号で、d=3の符号だったかと思います。

[^4]: 初期の頃は、「量子コンピュータでビジネス問題を解きますよ（古典コンピュータより良いとは言っていない）」というのも多かったですが、最近は控えめになってきた気がします。

[^5]: Pythonごりごり書けますよ！という人も歓迎されるでしょうし、計算機強いですよ！という人も歓迎されるでしょうし、物理詳しいですよ！という人も歓迎されるでしょう。とにかく、色々なところが未整備なので、みんなでやっていかないと終わりません！
AWS入門編

AWS（Amazon Web Services）の勉強を始めました。超基本的な内容ですがまとめました。

#AWSを使うメリット

###1. Webシステムに必要な機能やサービスが一式揃う
AWSは提供しているサービスの種類がとても豊富。
それぞれ別の事業者から借りる必要のあったインフラを一括で借りられる。

###2. 定額制ではなく従量制
使う分だけを借りられるのでコスト削減に繋がる。

###3. 日本語と日本円に対応している
日本語によるドキュメントが豊富であること。またAWSを導入するにあたっての相談窓口を東京に配置しているので日本語で相談できる。またAWSの使用量は日本円で支払えます。


#AWSが提供するサービス

####Amazon EC2
OSを含む仮想環境をクラウドに構築できる。

####Amazon S3
データの保管場所（ストレージ）の機能を持つ。データ容量は最大5TBで障害やエラーに強い。

####Amazon Route 53
DNS（ドメインネームサービス）。ドメインからIPアドレスを割り当てる。

###Amazon RDS
代表的なDB（Amazon Aurora、PostgreSQL、MySQL、MariaDB、OracleDatabase、SQL server）をクラウドで利用できる。

###Amazon VPC
EC2同士の通信やRDSとのデータのやり取りなどに内部・外部問わずネットワークを構築してくれるもの。多くのAWSはVPCの利用が必須。


#参考
[図解即戦力 Amazon Web Servicesのしくみと技術がこれ1冊でしっかりわかる教科書](https://www.amazon.co.jp/dp/4297108895?psc=1&smid=AN1VRQENFRJN5&ref_=chk_typ_imgToDp)
Markdown記述

よく忘れるのでメモ

## テーブル
```
|a|b|c|
|:-:|:-:|:-:|
|1|2|3|
|4|5|6|
```
|a|b|c|
|:-:|:-:|:-:|
|1|2|3|
|4|5|6|

## ディレクトリ構造
```
app 
 ├─ file1
 ├─ file2
 └─ dir1
     └─ dir/file1
```


##　フォント
### 文字色
HMTLで指定する
``<font color="red"></font>`` => <font color="red">赤色</font>
### 上付き、下付き
HMTLで指定する
``x<sup>2</sup>`` => x<sup>2</sup>
``x<sub>2</sub>`` => x<sub>2</sub>
### 太字
``**Bold**`` => **Bold**
### 斜体
``*Italic*`` => *Italic*

### 改行
- ``<br>``タグを使う
- 文末に半角空白スペースを2つつける


##　参考資料
[Markdown記法 チートシート](https://qiita.com/Qiita/items/c686397e4a0f4f11683d)
[Qiitaのテーブルの書き方についてまとめた](https://qiita.com/zakuroishikuro/items/f33929eab9d55c5bd073)
[Qiitaのマークダウンで色をつける方法[140色]](https://qiita.com/twipg/items/d8043cd4681a2780c160)
Python(Django)でSNS系アプリ作ってみた

# 概要
PythonのFWのDjangoでSNS系のアプリを作成してみました

・ソースコード
https://github.com/heihei-wooooo/sns-python

# 内容
TwitterのようなSNSアプリ(Web版)です。
グループでユーザと投稿を管理する仕様で
投稿のシェアや「いいね」ができます

・ログイン機能
・グループとフレンドFriend
・投稿とシェア
・publicグループ
・「いいね」ボタン
ターミナルで音データのサンプリングレートを変換する

ターミナルを使用してサンプリングレート（標本化周期）を変更する。
Core Audioのフォーマット変換ユーティリティである`afconvert`を使用します。

使用前にcdコマンドで対象ファイルのあるディレクトリに移動してください。

```
//　afconvert␣対象ファイル名␣-d␣変更後データフォーマット@サンプリングレート␣生成ファイル名

$ afconvert test.wav -d LE16@96000 test_96k.wav
```
変換前
<img width="400" alt="スクリーンショット 2021-12-29 23.15.51.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2270393/f04915a4-7aab-856d-84a4-65f49915c422.png">
変換後
<img width="400" alt="スクリーンショット 2021-12-29 23.16.53.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2270393/6485ee31-8480-6a5f-f0af-e39eca85f91b.png">
ちなみにビット深度も変えれます。

```
$ afconvert test.wav -d LE24@96000 test_24bit.wav
```

もちろんデータ形式が変わるだけで音質が良くなったりはしませんのでご注意を。
（ハイレゾ未対応用に変換とかなら使えるかも）

#####afconvert公式
https://ss64.com/osx/afconvert.html
SREについて学ぶ - エラーバジェット編

## はじめに
サイトリライアビリティエンジニアリング（SRE）について学んだことをアウトプットしたいと思います。
今回は、エラーバジェット編です。

## エラーバジェットとは？
エラーバジェットとは、サービスの信頼性がどの程度損なわれても許容できるかを示す指標です。
例えば、サービスレベル目標（SLO）が「99.99%」のリクエスト応答率を維持することである場合、エラーバジェットは、エラー応答率を「0.01%」以下に抑えることになります。
開発チームと運用チームは、エラーバジェットの条件を満たしてシステムの信頼性を維持するという共通目標に向かってお互いに協力し合いながら働きます。

## なぜ必要なのか？
エラーバジェットの説明をみると当然の内容のように感じますが、なぜエラーバジェットという共通目標の設定が必要なのでしょうか？

これは、開発チームと運用チームの目標の違いから生じる行動の対立を避ける為になります。

- 開発チームの目標
新機能を出来るだけ迅速にリリースすることが目標になります。
なので、たくさんの新機能を迅速にリリースしたいと考えます。

- 運用チームの目標
システムを安定運用させることが目標になります。
なので、システム変更による問題発生を抑えるためにリリースはできるだけ少なくしたいと考えます。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/689353/be2c69e6-a813-ed96-8c7c-d6e62e33fb92.png" width=50%>
上記のような目標の違いから両チームの行動に対立が生じてしまうことになります。
この対立を避ける為にエラーバジェット（エラーの予算）という指標を設定します。

## どのように運用するのか？

エラーバジェットは、運用チームがエラー対処に充てることができる予算となります。
もし、システムの信頼性が損なわれてしまいエラーバジェットを使い果たしてしまった場合、
開発チームは新機能のリリースを中止し、信頼性を高めるための対策を優先させる運用とします。

このような運用を行うことで開発チームはエラーバジェットに余裕があるときは、新機能の開発に対する速度を優先してリスクを大きく取ることができます。

しかし、エラーバジェットが底をつきそうな状態ではどうでしょうか？
開発チームは、新機能のリリースを中止したくないと考える為、信頼性を高めるためのテスト作業の割合を増やす、リリースの速度を落とす等の対応を行うことが必要になります。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/689353/98fc986a-2580-704f-ce95-cbf57b96b0e2.png" width=60%>
エラーバジェットの最大のメリットは、両チームのイノベーションと信頼性の適切なバランスが取れるよう共通目標を持って協力し合うことができることです。

## さいごに
エラーバジェットは、開発チームと運用チームを対立関係から協力関係へ変えるためのとても良い仕組みだと思いました。
sftpコマンドを非対話形式で実行

# はじめに

SFTPコマンドは、基本は対話形式ですが、batch modeやヒアドキュメントを使えば、非対話形式で実行することもできます。セキュリティの都合上、システム間のファイル連携を、SFTPサーバ経由でする、といったことは、今でもよくある話です。今回は、一番面倒な、パスフレーズ付きの秘密鍵を使った、公開鍵認証方式でいきます。


また、今更な話題ですが、opensshの開発チームが、scpは古くて使いづらく、sftpかrsyncを使うのを推奨するというのを、2019年4月に出しています。

> The scp protocol is outdated, inflexible and not readily fixed. We
recommend the use of more modern protocols like sftp and rsync for
file transfer instead.


http://www.openssh.com/txt/release-8.0


この流れは続いてるらしく、scpからsftpへの置き換えを検討しているようです。

> A near-future release of OpenSSH will switch scp(1) from using the
legacy scp/rcp protocol to using SFTP by default.

http://www.openssh.com/txt/release-8.8

サーバ間のファイルのやりとりは、sftpかrsyncのどちらかに今後はなっていくと思われます。



# 事前準備

## パスフレーズつきの秘密鍵

いまどきは、ed25519で作成したいものです。

```terminal
$ ssh-keygen -t ed25519 
...
Enter passphrase (empty for no passphrase): 
Enter same passphrase again:
```

そうもいかない場合は、RSAの4096bitでいきましょう。

```terminal
ssh-keygen -t rsa -b 4096 
```

## パスフレーズを標準出力するシェルスクリプト

下記のようなものを作成しておきます。

```bash:askpass.sh
#!/usr/bin/env bash

echo "${鍵作成時に入力したパスフレーズ}"
```

もちろん、実行権限をつけます

```terminal
chmod +x askpass.sh
```

# ssh-agent + ssh-add + SSH_ASKPASS

* ssh-agentを起動
* ssh-addで、作成した秘密鍵を登録
* パスフレーズの入力は、SSH_ASKPASSに、パスフレーズを出力するスクリプトのパスを設定
* sftpコマンドが終わったら、ssh-agentを停止


```terminal
$ eval `ssh-agent`
$ DISPLAY=":0.0" SSH_ASKPASS=askpass.sh setsid ssh-add id_ed25519 </dev/null
$ sftp ${sftp_user}@${sftp_server}

sftp> 
...
sftp> quit

$ ssh-agent -k
```

これで、秘密鍵のパスフレーズ入力が、対話なしでできるようになりました。
あとは、sftpサーバ上で実行するコマンドの部分です。これはヒアドキュメントを使えばいいです。

sftpコマンドを使ったシェルスクリプトは、下記のようになります。


```bash:sample_sftp.sh
#!/usr/bin/env bash
set -euo pipfail

sftp_user=...
sftp_server=...

eval `ssh-agent`
DISPLAY=":0.0" SSH_ASKPASS=askpass.sh setsid ssh-add ~/.ssh/id_ed25519 </dev/null
sftp ${sftp_user}@${sftp_server} << EOF
put local_file /dst
put local_file2 /dst
get /from/remote_file
quit
EOF
```


# 参考

https://stackoverflow.com/questions/38354773/how-to-pass-an-ssh-key-passphrase-via-environment-variable

https://laboradian.com/how-to-use-ssh-agent/

https://qiita.com/kite_999/items/e77fb521fc39454244e7

https://www.ipswitch.com/jp/blog/is-scp-more-secure-than-sftp

https://www.comparitech.com/net-admin/sftp-vs-scp/

https://qiita.com/tomoyk/items/bf18eec969486b6fc3c4

https://qiita.com/sasaplus1/items/619283711399c55306b6

https://qiita.com/wadahiro/items/977e4f820b4451a2e5e0
Laravelで（1 WARNING in child compilations (Use 'stats.children: true' resp. '--stats-children' for more details) webpack compiled with 1 warning）というエラーが出た時

# さっそく本題へ
LaravelでUIに変更を加えたので、
npm run dev
を実行したらタイトル（または以下）のようなエラーが出た。

**1 WARNING in child compilations (Use 'stats.children: true' resp. '--stats-children' for more details)
webpack compiled with 1 warning**

なにこれれれれれれれれれれれれ！！！！！！！

調べたら気にしなくてもいいエラーのようですが、どうしても細かいことを気にする性格をしている者~~（毎回日本語が変で記事がわかりにくいなのも気にしてくれ）~~で、、、、、、

でも、安心してください！
解決策が見つかりました！

```言語:webpack.mix.js
mix.webpackConfig({
    stats: {
        children: true,
    },
});
```

上のソースコードを書き加えるだけでいいみたいです！
こうするとエラーの内容が消えるのですが、なんと

**Warning
  (598:3) autoprefixer: start value has mixed support, consider using flex-start instead**

上記のような、新たなエラーに変わりました！！！
どうしてだよおおおおおお

ま、これでとりあえずここまで来たら僕の悩みは解決しました。

これはつまり、僕のエラーの原因はどっかのファイル（ま、sassがコンパイルされた後のファイルつまりpublic/app.css）の598行目のどっかをflex-startにしてくれ！ってことです。

以上！解散！

## 参考サイト
https://laracasts.com/discuss/channels/elixir/mix-1-warning-in-child-compilations
自作アプリケーションのデプロイに役立つなにか


「`docker-compose`で開発して結局本番環境なし」みたいなことが続いたので流石にそれは卒業しようと思い、作って書いてみました。
モバイル系はあんまり参考にならないと思います。

# 目標

- 開発環境どまりをやめる

# 基礎の基礎

## 自作アプリケーションを動かすには

- （ビルド）
- インストール
    - 実行に必要なファイルの配置（assets等）

をする必要がある。

※ ビルド不要な場合はインストール（配置）のみ

## よくあるパターン

[tingtt/prometheus_sh_exporter](https://github.com/tingtt/prometheus_sh_exporter)
自分のリポジトリだけど、よく見るパターンを真似して作ってみました。

注目ポイントは[リリース](https://github.com/tingtt/prometheus_sh_exporter/releases)のページと[Makefile](https://github.com/tingtt/prometheus_sh_exporter/blob/main/Makefile)です。

Makefileではインストールの処理が書いてあり、使いたい人は、

- リリースページから使いたいOSやCPUアーキテクチャに当てはまるファイルをダウンロードし、解凍
- `make install`コマンドの実行

だけでインストールできます。
（windowsの場合はexeファイルを実行するだけ）

# 基礎

## Makefile

C言語だけの話ではない。
シェルスクリプト（コマンド）を書いておいて簡単に呼び出せるようにできる。

言語・フレームワークに関わらず

- lint（コードの質チェック）
- ビルド
- テスト
- インストール
- アンインストール

等のスクリプトが必要になってくると思います。
これらの処理を`Makefile`に書いておくことで、「実行する前にビルドが必要」などのコマンド同士の依存関係や複数のコマンドを実行しないといけない場合のコマンドの簡素化などができます。
（`Makefile`に書いた処理は`make`コマンドで呼び出せます。）

※ linuxの場合、systemdのサービスとしてインストールできるようにしておくと実用的かと

おすすめ記事：[Makefile ことはじめ](https://qiita.com/kasei-san/items/ad25df63260e86c5cc71)
あとはオープンソースのリポジトリのMakefileを覗いてみるのもいいですよ！
※ 複雑なものは絶望したので自分はそっと目をつむりました。

## Dockerfile（dockerの場合）

本番環境もコンテナを利用する場合（K8sなど）は`Makefile`は無しで、`Dockerfile`にビルドとインストールの処理を書くだけでも良いと思う。（得意な方で書きましょ）
その`Dockerfile`からイメージを作成し、DockerHubなどのレジストリに置いたり使ったり。

本番環境がコンテナではないが、テスト環境・開発環境用にdockerを使いたい場合は`Makefile`も用意して、`Dockerfile`内で`make`コマンドを実行するように作成すれば良いと思います。（本番環境では`make`コマンドでインストール）

# 自動化（簡単）

簡単です。（`Makefile`に必要な処理をたくさん書けば） :thinking:

GitHub ActionsやGitLab CI/CDで`make`コマンドを活用することで、`.github/workflow/*.yml`, `.gitlab-ci.yml`を書くのも楽になるよ！

自分の場合同じプロジェクトでGitHub Actions、GitLab CI/CDを両方同時に使うことが多いので`Makefile`を頑張って書いて`make`コマンドだけでいろいろできるようにしてます。

例に上げたリポジトリではGitHubのリリースに置くアーカイブの作成も`Makefile`に処理を書いています。
:arrow_forward:  ~~こんどこれについてもう１つ書くつもり~~
書きました。 [Goのリリースアセットの配置を自動化したい](https://qiita.com/tingtt/items/c775750ec0ea59d17d2d)
Pythonのsubprocessでkillが効かないときの対処法

# はじめに
Pythonの`subprocess.Popen`を使って，サブプロセスを起動・終了させようとしたが終了だけうまくいかなかった．
原因と対処法をメモしておく．

# 結論
この現象は，`subprocess.Popen`で`shell=True`を指定していた場合に発生する．

対処法は，`exec`コマンドを先頭にくっつけること．

```python
subprocess.Popen('exec 実行するコマンド', shell=True)
```

# 再現手順
以下のように，`起動する側(run.py)`と`起動される側(wait.py)`の2つのスクリプトを書くと簡単に再現できた．

```python:run.py
from subprocess import Popen
import time

p = Popen('python3 wait.py', shell=True)
time.sleep(5)
p.kill()
```

```python:wait.py
import time

for i in range(1000):
    print(i)
    time.sleep(1)
```

`python run.py`を実行すると，`run.py`の終了後も`wait.py`のプロセスが存在したままになった．
一方で，Popenによって生成されたシェルのプロセスは正常に終了していた．

# 原因
`subprocess.Popen`で`shell=True`を指定していたため，コマンドはPopenによって起動されたシェルの中で実行されていた．
`kill`コマンドによってシェルは正常に終了されるが，シェルによって起動されたコマンド（プロセス）は終了できていなかった．

# 対処法
上が原因であるとすれば，生成されたシェルと実行するコマンドが同じプロセスになればよい．
`exec`コマンドを使うことで，生成されたシェルのプロセスの中でコマンドを実行させるようにする．

これで，`.kill()`を実行すれば生成されたシェルとともに実行したコマンドも停止できるようになる（なった）．

対策後のコードはこんな感じ．

```python:run2.py
from subprocess import Popen
import time

p = Popen('exec python3 wait.py', shell=True)
time.sleep(5)
p.kill()
```

# さいごに
ここで紹介した方法以外にもプロセスグループを作るといった方法もあるらしい．（まだよくわかってない）
生成するプロセスの親子関係や，数が多い場合は考えるべきかもしれない．
【Mac】過去の遺産 Touch Barを無料で何とか活用してみた

##結果
デフォルトアプリを利用するだけで、こんな感じになりました。
![スクリーンショット 2021-12-29 22.23.24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1556811/d0c4855b-71f9-9eb0-ae16-3c332da25ab8.png)
##経緯
会社からPCリフレッシュの案内が届き、MacBook Air (2018)からMacBook Pro (2020)に変更しました。
届いたMacBookを確認すると、一昔前に噂になっていたTouch Barがついてることに気がつきました。
当初はあまり活用方法が思いつかず、やはり噂の悪評は本当だった…とがっかりしました。しかし、色々検索してみてこれなら使えそう！と思ったやり方があったのでまとめます。
##環境
PC：MacBook Pro (13-inch, 2020, Four Thunderbolt 3 ports) ※Intel版
OS：macOS Monterey 12.1
ブラウザ：Google Chrome
##活用方針
デフォルトアプリ「Automator」を活用して、以下のやりたいことを実現する！

* 何もインストールせず無料でTouch Barを活用
    * 「BetterTouchTool」を購入するのが一番早いと思いますが、お金もかかりますし、なにより勝手にインストールすると会社のセキュリティポリシーに違反しそうで断念しました。
* Chromeのブックマークを登録可能
* ブックマーク以外の機能も最低限表示可能
* アプリケーションも表示可能
* 上記を常時表示可能


## 方法
STEP1：クイックアクションを作成する ~ブックマーク編~
1.　Automaterアプリを開く （デフォルトのアプリ）
2.　ファイル→新規　→クイックアクションの順で選択
3.　「シェル」で検索して、「シェルスクリプトを実行」を選択→右にドラッグする
4.　上部の「ワークフローが受け取る現在の項目」を選択し「入力なし」を選択、※　アイコン/色の設定もこのページで出来ます。
5.　シェルスクリプトに「open {対象のurl}」を入力
6.　名前をつけて保存
7.終わり

STEP2：クイックアクションを作成する ~アプリケーション編~
1.　Automaterアプリを開く （デフォルトのアプリ）
2.　ファイル→新規　→クイックアクションの順で選択
3.　「アプリケーション」で検索して、「アプリケーションを起動」を選択→右にドラッグする
4.　上部の「ワークフローが受け取る現在の項目」を選択し「入力なし」を選択、※　アイコン/色の設定もこのページで出来ます。
5.　対象のアプリを選択　※ターミナルは「その他」の「ユーティリティ」にあります
6.　名前をつけて保存
7.終わり

STEP3：作成したクイックアクションをTouch Barに表示させる
1. システム環境設定→キーボードを選択
2. 「Touch Barに表示する項目」を「クイックアクション」にする
3. 「Control Stripを表示する」にチェックを入れる
4. 右下の「Control Stripをカスタマイズする」を選択する → お好みで設定する ※自分はミュートと明るさ設定だけ残しました
5. 終わり

これで常時ブックマークとアプリケーションをTouch Barに表示させ、なおかつ最低限の機能も右端に追加することができました。

なお、作成したクイックアクションは、Finder→移動→optionを押して「ライブラリ」を選択→「Services」を選択、で確認できます。
また、システム環境設定→機能拡張→Touch Barで、作成したクイックアクションのOn/Offや、表示順番の入れ替えができます。
作ったのにTouch Barに反映されていない場合は、まずはここのチェックボックスを確認してみてください。

ちなみに画像の右にある「高速検索」は、下記のQiita記事を参考に作成したクイックアクションです。
[Automatorのショートカット機能を使って爆速のGoogleコピペ検索を設定する](https://qiita.com/kazuooooo/items/eefd88a2a852a5daf08d)

## 最後に
色々大変でしたが、なんとか使えそうな感じに仕上がって良かったです。
Touch Bar自体は近未来感があって好きなので、新規のMacBookから廃止されてしまって残念です。
今後この機能は発展していかないと思いますが、しばらくはTouch Bar付きMacBookを利用すると思うので、仲良く付き合っていきたいです。

なお、こんなことしなくても便利かつ更に色々な機能を兼ね備えたTouch Bar専用アプリはありますので、お金やインストールに問題がなければそちらをご利用されることをおすすめします。

最後まで読んでいただきありがとうございました！
git hooksの始め方

## 本記事に書かれていること

- git hooksを使って、スクリプトを実行する設定方法
- git hooksのスクリプトをgitで管理する方法
- pythonやrubyでスクリプトを書く方法

hooksスクリプトで実際にやりそうなあれこれのサンプルコードとかはないです。

## git hooksでスクリプトを動かしてみる

まずはプロジェクト作成

```shell
$ mkdir hooks-sample
$ cd hooks-sample
$ git init
```

`git init`した際に、`.git/hooks`配下にhooksのサンプルファイルが作成されています。
サンプルファイル以外にも命名規則に従ったファイル名でスクリプトを作成しておけば認識してくれます。
pre-commit.sampleを書き換えてcommit前にメッセージが表示されるようにします。
また、hooksスクリプトで拡張子は使えないので、`.sample`はファイル名から削除しておきます。

```shell
$ cd .git/hooks
$ mv pre-commit.sample pre-commit
$ chmod a+x pre-commit
$ cd ../../
```

ファイルの中身を書き換えます。

```shell:pre-commit
#!/bin/sh
echo "pre-commit message"
```

適当にファイルを作成してコミットしてみる

```shell
$ touch some_file
$ git add -A
$ git commit -m "init"
pre-commit message
[master (root-commit) 2e9222d] init
 1 file changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 some_file
```

commitコマンドにトリガーされてcommit前にメッセージが表示されました。

## commitさせたくない場合

pre-commitであれば、commit前にlintチェックをしてエラーがあればcommitさせたくないなどあると思います。
スクリプト内で`exit 1`してあげればcommitを中断することができます。以下のようにpre-commitを修正します。

```shell
#!/bin/sh
echo "commitできません"
exit 1
```

メッセージを表示した後、コード1でexitしているのでcommitが中断されるはずです。

```shell
$ touch some_file2
$ git add -A
$ git commit -m "このcommitコマンドは中断されます。"
commitできません
$ git status
On branch master
Changes to be committed:
	new file:   some_file2
```

無事commitが中断されました。

## hooksスクリプトをgit管理したい

ここまで、hooksスクリプトは.git/hooks配下にありました。このディレクトリはgitの管理下にはないのでチームでhooksスクリプトを共有したい場合はこのままでは使えません。
hooksスクリプトを管理するディレクトリを作成し、そのパスをgit hooksのパスとして設定します。

```shell
$ mkdir .hooks
$ mv .git/hooks/pre-commit ./.hooks
$ git config core.hooksPath .hooks
```

これでhooksスクリプトをgit管理に入れて、チームで共有することができました。
git configは各環境で実行してもらう必要があります。READMEにでも書いておけば良いでしょう。

## hooksスクリプトでpythonが使いたい

そんな場合は、シバン行をpythonに変えてあげるだけです。
同様にrubyやperlも使えるみたいです。

```shell:pre-commit
#!/usr/bin/env python3
print("pre-commit")
```

## 終わり

以上、hooksスクリプト使い始めるまでの設定について書きました。
使う機会があれば、各hooksでできそうなこと、やったらよさそうなことについても書きたいと思います。
簡単に「IPv4アドレス」とは

##IPアドレスとは
IPアドレスは、`172.31.48.0`のような`8bit×4の整数値`のこと。
ドットで区切られた4つの数字は、0~255の計256種類の数字から取ることができる。

IPアドレスには、`IPv4`と`IPv6`という2つのバージョンがありますが、今回はIPv4についての記事になります。

###8bitとは
連続した8個のビットであり、`0~255の256種類`存在する。
簡単に言うと、`2の8乗=256`です！
ということは、`0.0.0.0 ~ 255.255.255.255`の範囲で選べるということになります。

##IPv4アドレスとは
IPv4アドレスは、`ネットワークアドレス`と`サブネットマスク`を用いてネットワークを表現している。

（例）`172.31.32.0/24`の場合、
ネットワークアドレス＝`172.31.32.0`
サブネットマスク＝`/24`

表記の意味はざっくりこんな感じ。

###サブネットマスクで選択範囲が変わる
上記で0~255までの数字を選択できると説明しましたが、どれでも選んでいいというわけではなく色々と制約があり、サブネットマスクによってネットワークアドレスの選択範囲が変わってきます。

（例）172.31.32.0/24の場合、
`末尾の0のみが可変できる数字`になります。

・何故か？
→`/24は172.31.32の桁まで`という意味で、`8bit+8bit+8bit=24`という考えになります。
[Blender]ペラい服の端を押し出して厚み感を持たせるスクリプト

#概要
1枚目が2枚目になる
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/299114/5bf4f6a8-c177-c541-8460-90f142fc8f6c.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/299114/6c880d5a-4081-e5b0-1e87-08070d9a58e3.png)

#使い方
袖パーツに使う事を想定
袖の端をループ選択して以下のスクリプトを実行


#解説
情報ウィンドウのコマンドをコピペしただけ
適当に値を弄って各自調整
挙動的は面を張る→距離0押し出し→スケールを弄る→内側へ押し出し→面を削除

```
import bpy

bpy.ops.mesh.edge_face_add()

bpy.ops.mesh.extrude_region_shrink_fatten(MESH_OT_extrude_region={"use_normal_flip":False, "use_dissolve_ortho_edges":False, "mirror":False}, TRANSFORM_OT_shrink_fatten={"value":0, "use_even_offset":False, "mirror":False, "use_proportional_edit":False, "proportional_edit_falloff":'SMOOTH', "proportional_size":1, "use_proportional_connected":False, "use_proportional_projected":False, "snap":False, "snap_target":'CLOSEST', "snap_point":(0, 0, 0), "snap_align":False, "snap_normal":(0, 0, 0), "release_confirm":False, "use_accurate":False})

# ここのvalueを0.99とかにすると厚み感を薄くできる
bpy.ops.transform.resize(value=(0.9, 0.9, 0.9), orient_type='NORMAL', orient_matrix=((1, 0, 0), (0, 1, 0), (0, 0, 1)), orient_matrix_type='GLOBAL', constraint_axis=(True, True, True), mirror=True, use_proportional_edit=False, proportional_edit_falloff='SMOOTH', proportional_size=1, use_proportional_connected=False, use_proportional_projected=False)

bpy.ops.mesh.extrude_region_shrink_fatten(MESH_OT_extrude_region={"use_normal_flip":False, "use_dissolve_ortho_edges":False, "mirror":False}, TRANSFORM_OT_shrink_fatten={"value":-0.09, "use_even_offset":False, "mirror":False, "use_proportional_edit":False, "proportional_edit_falloff":'SMOOTH', "proportional_size":1, "use_proportional_connected":False, "use_proportional_projected":False, "snap":False, "snap_target":'CLOSEST', "snap_point":(0, 0, 0), "snap_align":False, "snap_normal":(0, 0, 0), "release_confirm":False, "use_accurate":False})

bpy.ops.mesh.delete(type='FACE')

```

参考資料
[【Blender】コマンドを並べるだけで手作業を自動化する](https://note.com/info_/n/nfa9bd04239df)
Golangに入門してみた: Exercise: Loops and Functions

# Golangに入門してみた: Exercise: Loops and Functions

最近、転職活動をしているときにgRPCについての話があり、あまり詳しく知らなかったのでハンズオンしたいな、と思いどうせならgRPCの醍醐味である別言語間での通信を実現してみたいなと思い、現在使えるJavaScript, Python, Rubyに加え、流行のGolangを用いてAPI作ってみたいなと思い、Glangのtutorialをやってみました。

そこで、とりあえずGolangのfor文 + if文を使って平方根を求めるエクササイズがあったので、それをググりながら書いてみた。そこまで難しくないし、ヒントも出されているので、5分くらいで終わったのですが、その回答を載せます。答えは見てないので、非効率なプログラム書いているかもしれませんが、まぁいいでしょう。

## エクササイズ内容

こちらのページのエクササイズを行いました。
https://go-tour-jp.appspot.com/flowcontrol/8

![](https://storage.googleapis.com/zenn-user-upload/99d4cb256a76-20211228.png)

## 回答内容

```Go
package main
import (
	"fmt";
	"math"
)

func Sqrt(x float64) float64 {
	z := float64(1) // 初期値
	for i := 0; i < 100; i++ {
		prev_z := z
		z -= (z*z - x) / (2*z)
		
		if math.Abs(prev_z - z) < 0.0000001 {
			return z
		}
	} 
	return z
}

func main() {
	fmt.Println(Sqrt(2))
	fmt.Println(math.Sqrt(2))
}

出力：----------------------
1.4142135623730951
1.4142135623730951
```

math.Sqrt(2)と同様の答えになったので、良いでしょう。
>次に値が変化しなくなった (もしくはごくわずかな変化しかしなくなった) 場合にループを停止させます。 

この部分をどう再現するかがもっと別の書き方あるような気がしますが、もし他に「この書き方がいいよ！」というのがあれば教えてください。


## 感想

Golang初めて触ってみましたが、型指定とかあっていいですね。
Pythonは型指定ないので機械学習の実装しているときに、この変数のデータには何が入っているのだろう？と思うことがあるのでGlangで機械学習実装できたら嬉しいですね。

Pythonでも型指定みたいなことできるので、型が間違っていればエラーを出すようにすればいいのでしょうけども。

あと、３,4章くらいtutorialがあるので、それもやってしまおうと思います。
iPhone のカメラでエゴマと蕎麦の実をマハラノビス距離で識別

　iPhoneを使ってエゴマと蕎麦とそれ以外(ごみ)を識別してみました。
　前回記事[『iPhone で円形度を使ってエゴマと蕎麦の実を識別』](https://qiita.com/pic18f14k50/items/5434615031684a4cafc4)では円形度だけで識別したので、今回は円形度と面積でクラスの分布を反映してマハラノビス距離で識別します。
　※後半でげろしますが前回記事の補足の位置付けの記事です。

　識別結果の青がエゴマ、緑が蕎麦、赤がそれ以外です。

|学習用データの分布|入力画像での識別|
|:-:|:-:|
|<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/71605/22a72a1e-c341-5eed-2761-c9c7cd83136c.png" width=500px>|<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/71605/291a4d4f-5fc8-4edc-4b51-455c6fb58993.gif" width=300px>

　識別結果の下のグラフの楕円がマハラノビスの等距離線で左側がエゴマ、右側が蕎麦です。楕円の中心が平均値です。距離が３を超えると異常（ゴミ）と判定するようにしています。この例ではエゴマ・蕎麦・ゴミ（大小）を識別できています。

##### クラス辞書

| クラス | 円形度<br>平均$\mu_1$ | 円形度<br>標準偏差$\sigma_1$ | 面積<br>平均$\mu_2$ | 面積<br>標準偏差$\sigma_2$ |共分散<br>$\sigma_{12}$|
|:-:|:-:|:-:|:-:|:-:|:-:|:-:|
|エゴマ|0.858361|0.197776|0.000974214|0.000189814|0.000018802
|蕎麦|0.814706|0.0700254|0.00386794|0.000603650|0.000000648

コードはGithubに置いています。サンプルデータも入っています。

https://github.com/tamai999/CircleDetection

#### １.　マハラノビス距離

　エゴマや蕎麦を代表とする値（平均値など）との距離（ユークリッド距離）でパターン認識行う方法があります（距離が近ければそのクラスに属するという判定をする。プロトタイプ法と呼ぶ）。[『マハラノビス距離』](https://ja.wikipedia.org/wiki/マハラノビス距離)によるパターン認識では学習用データの分布の広がりに基づいた距離で識別を行います。

　この手法はパターン認識のほかに品質管理で異常値を見つけるのに利用します。分布の広がりを考慮することで、冒頭の識別結果のように平均値（楕円の中心）との距離が近くても蕎麦の場合は異常とせず、エゴマの場合は異常（ゴミ）と判別できる場合があります。

　マハラノビス距離の計算式は次のようになります。

```math
マハラノビス距離\;d = \sqrt{(\vec{\;x\;} - \vec{\;\mu\;})^\top \Sigma^{-1} (\vec{\;x\;} - \vec{\;\mu\;})}
```

<br>
　。。。ここでげろすると、参考URLの記事を読んだだけで説明できるような理解度がありません。とりあえずこちらの記事[『マハラノビス距離の意味を２次元の場合で理解する』](https://mathwords.net/mahalanobis)の数式をswiftで愚直に実装すれば冒頭の実行結果のようにそれなりの結果が得られることは確認した、という状態です（マハラノビス距離の存在は知っていて試してみたかった）。

#### ２.　最後に

参考になりそうな知見、ノウハウが皆無な記事ですが、
今回のプログラムは古い機種（iPhone6s）で実行しており、画像処理においてカメラ性能、処理能力面でこのような処理にこのくらいの機種は使えそう、という一つの目安になれば幸いです。

#### 参考URL

* [マハラノビス距離の意味を２次元の場合で理解する](https://mathwords.net/mahalanobis)
* [判別分析](http://www.cfme.chiba-u.jp/~haneishi/class/2009/20091216.pdf)
* [判別分析とパターン認識 (1) - マハラノビスの汎距離](http://racco.mikeneko.jp/Kougi/10s/AS/AS08pr.pdf)
* [マハラノビスの距離 入門](https://www.jstage.jst.go.jp/article/qes/9/1/9_13/_pdf)
ファイル名の括弧内の文字を抜き出す VBA マクロ

## はじめに

提出ファイルの集約といったタスクで、誰が提出したか把握するため、ファイル名に各自のID、あるいは名前等を入れるような命名規則にしたことはありますか？自分の仕事はそんなのばかりです。そんな地道な仕事をエクセルにお手伝いしてもらうため、ファイル名から名前を抜き出す関数を作ってみました。

## 使用例

例えば【】に自分の名前を入力して提出しなさい、というルールで進めた場合下記のようなファイルが来ると思うのですが、ここから下記のような抜き方ができるといいな、という関数です。

-【山田太郎】提出ファイル.xlsx　→ **山田太郎**　だけ抜き出す
-【Yamada Taro】提出ファイル.xlsx　→ **Yamada Taro** を抜く

またカッコには半角のカッコ記号の他、上記のような【「［等々...結構種類があり、記号が変更になるたびにプログラムを書き換えるのはスマートではありません。

## ソースコード

`getBraceInside` という名前で作っています。列挙型で括弧の形を定義しており、指定する括弧を変更すれば別の形でもプログラムの変更なしで対応できます。

```vb
Option Explicit

Private Const mtContextID As Integer = 10

Public Enum BracketType
    parenthesis = 1      ' () parentheses ASCII
    brace = 2            ' {} braces, Curly brackets
    bracket = 3          ' [] square brackets
    quote = 4            ' '' single quotes
    jp_brace = 5         ' 「」鍵括弧
    jp_bracket = 6       ' 【】
    wide_parenthesis = 7 ' （） full-width parenthesis
    wide_brace = 8       ' ｛｝ full-width braces, curly brackets
    wide_bracket = 9     ' ［］ full-width square brackets
    jp_double_bracket = 10 ' 『』 Japanese double hook brackets
End Enum

Public Function getBraceInside(str As String, _
        Optional paren_type As BracketType = jp_bracket) As String

    Dim pos_start As Integer, pos_end As Integer
    Dim strSTART As String, strEND As String
    getBraceInside = ""

    Select Case paren_type
        Case parenthesis
            strSTART = "(": strEND = ")"
        Case brace
            strSTART = "{": strEND = "}"
        Case bracket
            strSTART = "[": strEND = "]"
        Case quote
            strSTART = "'": strEND = "'"
        Case jp_brace
            strSTART = "「": strEND = "」"
        Case jp_bracket
            strSTART = "【": strEND = "】"
        Case wide_parenthesis
            strSTART = "（": strEND = "）"
        Case wide_brace
            strSTART = "｛": strEND = "｝"
        Case wide_bracket
            strSTART = "［": strEND = "］"
        Case jp_double_bracket
            strSTART = "『": strEND = "』"
        Case Else
            Err.Raise vbObjectError * myContextID + 515, Description:="unknwon parenthesis type"
    End Select

    pos_start = InStr(str, strSTART)
    pos_end = InStr(str, strEND)
    pos_end = pos_end - pos_start - 1

    getBraceInside = Mid(str, (pos_start + 1), pos_end)
    Debug.Print("String: " & getBraceInside & " distilled from: " & str)
End Function

```

おためしあれ。
【Flutter】グラデーションの使用方法

# 概要


Flutterでグラデーションを使用する方法

# Containerにグラデーションをかける


「Container」ウィジェットのBoxDecorationで設定する

```dart
class BodyGradientScreen extends StatelessWidget {
  const BodyGradientScreen({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Container(
      height: double.infinity,
      width: double.infinity,
      decoration: const BoxDecoration(
          gradient: LinearGradient(
        begin: FractionalOffset.topCenter,
        end: FractionalOffset.bottomCenter,
        colors: [
          Color(0xff6DD5FA),
          Color(0xff2980B9),
        ],
        stops: [
          0,
          1,
        ],
      )),
    );
  }
}
```

<img width="400" alt="グラデーション1" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2329811/7d1f6109-e5eb-cb81-bd77-00c50848e92e.png">


stopsの値を変えるとグラデーションの開始位置や終了位置を変更することができる

```dart
class BodyGradientScreen extends StatelessWidget {
  const BodyGradientScreen({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Container(
      height: double.infinity,
      width: double.infinity,
      decoration: const BoxDecoration(
          gradient: LinearGradient(
        begin: FractionalOffset.topCenter,
        end: FractionalOffset.bottomCenter,
        colors: [
          Color(0xff6DD5FA),
          Color(0xff2980B9),
        ],
        stops: [
          0.2,
          0.7,
        ],
      )),
    );
  }
}
```

<img width="400"　alt="グラデーション2" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2329811/b789f835-f79a-a11b-b749-2cef472dc453.png">
【Python3】プライベートなインスタンス変数にクラス外からアクセスできてしまう

Pythonのカプセル化について備忘録としてまとめます。

## 環境
* Ubuntu20.04
* Python 3.8.10

## 筆者の認識

- インスタンス変数の頭にアンダーバーを2つ着けるとプライベート変数として扱われ、クラスの外部から参照・再代入できなくなる。

```python:Hoge.py

Class Hoge(object):
  def __init__(self, hoge: str):
    # 外部からアクセスできなくする
    self__hoge = hoge


hoge = Hoge("fuga")
# エラーになるはず
hoge.__hoge = "foo"
# エラーになるはず
print(hoge.__hoge)
```

## 実際の挙動

```python:Hoge.py

class Hoge(object):
  def __init__(self, hoge: str):
    self__hoge = hoge


hoge = Hoge("fuga")

hoge.__hoge = "foo"

print(hoge.__hoge)
```

Hoge.pyをコマンドライン上で実行すると再代入・変数へのアクセスともにできてしまいます。

```bash
$ python3 Hoge.py 
foo
```


再代入せず、参照だけした場合、エラーになりました。(意図した挙動)
参照はできないが代入はできるというのが不可解です。再代入したら参照もできてしまうのもよくわかりません。

```python:Hoge2.py

class Hoge2(object):
  def __init__(self, hoge: str):
    self__hoge = hoge

hoge = Hoge("fuga")
print(hoge.__hoge)
```

```bash
$ python3 Hoge2.py 
Traceback (most recent call last):
  File "Hoge2.py", line 9, in <module>
    print(hoge.__hoge)
AttributeError: 'Hoge2' object has no attribute '__hoge'
```

## 検証

### 1. 本当に変数名の頭にアンダースコアを2つ付けるとプライベート変数になるのか

Pythonの公式ドキュメントには下記の記述がありました。

> “Private” instance variables that cannot be accessed except from inside an object don’t exist in Python. 

どうやら一般的な意味でのプライベート変数はPythonには無いようです。( ~~同じページに Python classes provide all the standard features of Object Oriented Programming なんて書いてるのは何なんだ~~)

なんで、**「変数名の頭にアンダースコアを2つつけると(厳密な意味での)プライベート変数になる」** というのは偽であると言えそうです。

Pythonのマングリング(アンダースコア2つから始まる変数の名前を置換する機能)によりこのような挙動になります。

例： Hogeクラスの ``` __hoge``` 変数は ``` _Hoge__hoge ``` という変数名になる

この機能は本来は継承元と継承先で変数名が重複しないようにするのが目的のようです。


```python:hoge3.py

class Hoge3(object):
  def __init__(self, hoge: str):
    self.__hoge = hoge


hoge = Hoge3("fuga")

hoge.__hoge = "foo"

print(vars(hoge))
```

上記のスクリプトを実行すると以下のような結果になります。

```bash
$ python3 hoge3.py 
{'_Hoge3__hoge': 'fuga', '__hoge': 'foo'}
```

挙動をまとめると

* Hogeクラス内で定義した ```__hoge```変数は実行前に ```_Hoge__hoge```という名前に置換される。
* 実行時には hogeクラスのオブジェクトには ``` __hoge```という変数は存在しないので参照できない。
* hogeクラスのオブジェクトが```__hoge```変数を持たないため、再代入できるように見えた。(実際は新しい属性がオブジェクトに追加された ※ hoge3.pyの実行結果より)

ということになります。
参照はできるのに再代入ができるように見えたのはマングリングが原因でした。

## 課題

Pythonのこの仕様には2つの問題があるように思われます。 

1. 本来の意味でインスタンス変数を隠蔽できていない(見かけ上は再代入できる)
1. オブジェクトに自由に属性を追加(おそらく削除も？)できてしまう


これらの課題の解消方法を今後調査・検討していきたいと思います。
UE4 RenderTargetでのメモリリークについてのメモ

# 概要
UnrealEngine にてRenderTargetのメモリリークについての調査と解決方法についてのメモです。

## 環境
Windows10
Visual Studio 2017
UnrealEngine 4.26

## 参考
以下を参考にさせて頂きました、ありがとうございます。
[VRAMリークの調査方法について](https://answers.unrealengine.com/questions/876307/view.html
)
[[UE4] メモリーリークをどう追跡して修正するか](https://qiita.com/donbutsu17/items/4634665264c94c794d63)
[[UE4] C++コードにゲームの初期化，終了，更新のタイミングで処理を追加する方法](https://historia.co.jp/archives/775/)


# RenderTargetメモリリークについて
`r.DumpRenderTargetPoolMemory` にて調査中に以下の値が徐々に増えていることに気づきました。

```terminal:出力結果
[2021.12.19-06.20.03:758][573]Pooled Render Targets:
[2021.12.19-06.20.03:766][573]53.282MB total, 12.095MB used, 28 render targets
```
使用終わりのレンダーターゲットが解放されていないということになります。

## 関連コード
"Engine\Source\Runtime\RenderCore\Private\RenderTargetPool.cpp"


# 対処コード
ゲーム開始時にレンダースレッドに `ENQUEUE_RENDER_COMMAND` マクロを使って未使用レンダーターゲットを解放するタスクを積みます。
以下参考コード。

```cpp:MyProject.cpp
#include "RenderTargetPool.h"

void FMyAppMainModule::StartupModule()
{
	// レンダースレッドにタスクを積む
	FWorldDelegates::OnPostWorldCreation.AddLambda([](UWorld* pWorld)
	{
#if !WITH_EDITOR
			ENQUEUE_RENDER_COMMAND(MyProjectWorldChanged)(
			[](FRHICommandListImmediate& RHICmdList)
			{
				// 未使用リソースを解放
				GRenderTargetPool.FreeUnusedResources();
			});
#endif
	});
}

```

これでレンダーターゲットが解放されるようになりました。


# まとめ
メモリリークはなかなか追跡が大変です。ツールを使うにも学習コストが。。
UE4 レベルブループリントのメモ

# 概要
UnrealEngine のレベルブループリントについてのメモ書きです。
C++での差し替え方法について。

## 環境
Windows10
Visual Studio 2017
UnrealEngine 4.26

## 参考
以下を参考にさせて頂きました、ありがとうございます。
[UE公式：Level ブループリント](https://docs.unrealengine.com/4.27/ja/ProgrammingAndScripting/Blueprints/UserGuide/Types/LevelBlueprint/)
[【UnrealC++】⑩レベルブループリント【UE4】](https://bigden.hatenablog.com/entry/2018/02/27/081236)

 
# C++ でのレベルブループリントの差し替え
## C++でのクラス用意
ALevelScriptActor を継承したクラスを用意します。
関連コード
`Engine/Source/Runtime/Engine/Classes/Engine/LevelScriptActor.h`

以下サンプル、イベント`MyEvent`を追加しています。

```cpp:MyLevelScript.h
#pragma once

#include "CoreMinimal.h"
#include "Engine/LevelScriptActor.h"
#include "MyLevelScript.generated.h"

UCLASS()
class MYPROJECT3_API AMyLevelScript : public ALevelScriptActor
{
	GENERATED_BODY()

public:
	AMyLevelScript();
	virtual ~AMyLevelScript()=default;
	
protected:
	virtual void BeginPlay() override;
	virtual void EndPlay(const EEndPlayReason::Type EndPlayReason) override;

public:
	// 追加するイベント
	UFUNCTION(BlueprintImplementableEvent)
	void MyEvent();

};
```

```cpp:MyScriptActor.cpp
#include "MyLevelScript.h"
#include "Engine.h"
#include "Engine/LevelScriptActor.h"

AMyLevelScript::AMyLevelScript()
{
}

void AMyLevelScript::BeginPlay()
{
	UE_LOG(LogTemp, Log, TEXT("AMyLevelScript::BeginPlay()"));

	Super::BeginPlay();

}

void AMyLevelScript::EndPlay(const EEndPlayReason::Type EndPlayReason)
{
	UE_LOG(LogTemp, Log, TEXT("AMyLevelScript::EndPlay()"));

	Super::EndPlay(EndPlayReason);
	
}
```


## レベルブループリントでの設定
クラス設定 -> クラスオプションで親ブループリントを差し替えます。

![LevelBP.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/303806/9876f50f-f323-d71e-ab33-31bbc8260d83.png)


## 追加したイベント呼び出し
追加したスクリプトを検索して実行します。
処理負荷的に毎回検索して実行はよろしくないです。レベル側で開始/終了時にどこかで管理するようにすべきかと思います。

```cpp:.cpp
// レベルスクリプト検索
TSubclassOf<AMyLevelScript> _FindClass;
_FindClass = AMyLevelScript::StaticClass();
TArray<AActor*> _ActorList;
UGameplayStatics::GetAllActorsOfClass(GetWorld(), _FindClass, _ActorList);

// 見つかったら実行		
if(_ActorList.Num() > 0){
	AMyLevelScript* _ActorScript = Cast<AMyLevelScript>(_ActorList[0]);
	if( _ActorScript ){
		// イベント実行
		_ActorScript->Restart();
	}
}

```


# まとめ
あまりレベルブループリントを使わなかったのですが、C++と紐づけるなら（個人的には）使いやすくなるかも。
Microsoft Forms API 現時点でのまとめ

# 背景
Power BI 用の Custom Connector を作ろうと改めて調べてみたら、二種類の API path 構成が確認されたので、まとめておく。

# API 一覧

現状二種類混在しているが、light を付けるのが古い API かな？
もう一つの odata 系と書いた方には Forms Pro 用のデータが含まれてそうでもあるし。

:::note warn
公式ドキュメントがないので、light の有無のどちらが今後の趨勢かは不明
:::

どちらも、endpoint は同一: https://forms.office.com/formapi

## metadata

以下で metadata 取得可能

https://forms.office.com/formapi/api/$metadata#forms

## light 系

|概要|api|補足|
|-|-|-|
|一覧取得|api/**light**/forms||
|テナント/ユーザー指定|api/{tenantID}/users/{userID}/**light**/forms|テナントとユーザーIDを個別には出来なさそう|
|formId で指定|api/**light**/forms<b>(</b>{form ID}<b>)</b>||
|指定した回答|api/**light**/forms<b>(</b>{form ID}<b>)</b>/responses|

## odata 系 おそらくこちらで公式公開されていくのでは？と。

|概要|api|補足|
|-|-|-|
|一覧取得|api/forms||
|formId で指定|api/forms/{form ID}||
|指定した質問|api/forms/{form ID}/questions||
|指定した回答|api/forms/{form ID}/responses||
|自分とシェアしてる一覧|api/sharedWithMeForms|
|テナント/ユーザー指定|api/{tenantID}/users/{userID}/forms|テナント省略は不可。/forms/以降はユーザーと共通|
|グループ一覧|api/{tenantID}/groups/|テナント省略は不可|
|テナント&グループ指定|api/{tenantID}/groups/{groupID}/forms|テナント省略は不可。/forms/以降はユーザーと共通|

# 取得結果比較

大まかな差としては

- path
- odata 系 での Encode 
- light 系には、questions API がない
- 取得結果に若干の差異あり

## formId で指定
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/120072/7e292ee9-7b32-db36-5501-ead781a4f5c2.png)


## 指定した回答
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/120072/dd93b170-7303-e8d7-3faf-3d90ab87473b.png)

## 指定した質問
odata 系にしか無し
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/120072/cbc51238-f9d7-5d6c-5b00-37bb5df568c7.png)



# 認証
利用するためには認証が必要です。
ブラウザでなら簡単に試せます。

## ブラウザで

以下にアクセスする。timeout は不明

https://forms.office.com

## コードで
以下でコード的な取得方法の説明有り

https://techcommunity.microsoft.com/t5/microsoft-forms/is-there-an-api-to-read-microsoft-forms-data/m-p/292045

![2021-12-29_16h09_42.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1645569/738b6bdb-6145-49a5-bcb6-422834c451d4.png)

## Power Automate で

SharePoint の Http コネクタで出来ちゃいます。[send-an-http-request-to-sharepoint](https://docs.microsoft.com/ja-jp/connectors/sharepointonline/#send-an-http-request-to-sharepoint)

詳細は以下で

https://qiita.com/baku2san/items/419aba7a5b1cc19ccbf5

## Power Query カスタムコネクタで
詳細は以下お勧め。

https://github.com/microsoft/DataConnectors/blob/master/docs/m-extensions.md

```powershell:カスタムコネクタでの認証設定例
// Data Source Kind description <https://github.com/microsoft/DataConnectors/blob/master/docs/m-extensions.md>
PQExtensionFormsAPI = [
    Authentication = [
        Aad = [
            AuthorizationUri = "https://login.microsoftonline.com/common/oauth2/authorize",
            Resource = "https://forms.office.com" // Azure AD resource value for your service - Guid or URL
        ]
    ],
    Label = Extension.LoadString("Forms API で Response 取得") // (optional Friendly display name for this extension in credential dialogs.         
    // , TestConnection    Gateway 経由でデータ更新する場合にはサポート必要
];
```

# あとがき
次回はようやく、カスタムコネクタ公開へ・・？


# keyword

How to use Microsoft Forms API
VBA で OneDrive / SharePoint のファイルにアクセス

## はじめに
SharePointやOneDriveのような、クラウドベースのネットワークで共有しているファイルにマクロでアクセスを試みると、ファイルにアクセスできずにエラーが発生します。

これはファイルパスがURL方式になっていることが原因なので、ファイルパスの形式変更を試みることでエラーを回避できます。

最近マクロを作るときには必ずセットでこの関数も実装する羽目になるので、同じ悩みを持っている方に関数をご紹介します。

## こんな時に使える

- VBA で OneDrive / SharePoint / Box 等オンラインストレージ上のファイルにアクセスする

### 期待される動き

例えば、下記例のような二種類の文字列のうち、URLになっている方だけを加工してくれる関数が便利ですよね。

```vb
Sub entrypoint()
   Debug.Print cnvNetPath2Local("C:\Users\NormalAccount\")
   Debug.Print cnvNetPath2Local("http://servername/c/directoryname/")
End Sub
```
出力はというと。

```sh
C:\Users\NormalAccount\
\\servername\c\directoryname\
```

フォルダ名、ファイル名を扱う際、この加工をしておくと扱いが非常に楽になりますよね。

## ソースコード

というわけで下記の通り。ここでは `cnvNetPath2Local` という名前を付けています。

```vb
' cnvNetPath2Local
' ------------------------------------------------------------------------
' ファイルが開けないネットワークドライブを通常のフォルダパスに(強引に)変換する。
' 本メソッドではsなしを扱う
' OneDrive形式 : http://servername/c/sample/
' 通常の形式 : \\servername\c\sample\
'
Public Function cnvNetPath2Local(path As String) As String
    If InStr(path, "http://") > 0 Then
        ' http:// で始まっている場合はスキーム定義部分を削除
        cnvNetPath2Local = Replace(path, "http:", "")
    Else
        ' 検出できない場合はそのままパスを返す
        cnvNetPath2Local = path
    End If
End Function
```

URL 形式の場合、スキーム文字列を削除するだけの動きです。

関数にするほどか？というレベルではありますが、地味に効いてきますのでよく使う関数群に入れておくことをお勧めします。

## 今後の課題

https:// も含めて回避できるようにするなどが課題ですが、https:// の共有フォルダに出会ってないので。必要性はわかりません。誰か知っていたら教えてください。
LogstashでWebhookにform-dataをPOSTする

# 概要

この記事では、Logstashでログを読み込み、その内容を https で multipart/form-data 形式でPOSTする方法を記載します。
また、主に開発用を想定し、それを Windows 上の Docker で Logstash を動作させる方法も記載します。

# 要約

簡単に言えば、以下のように config に記載すればできるはずです。

```
output {
  http {
    http_method => "post"
    url => "https://my-url/foo/bar"
    format => "message"
    content_type => "multipart/form-data; boundary=||^26Qx3v^||"
    message => "--||^26Qx3v^||
Content-Disposition: form-data; name=field1

A new log entry was found!
%{message}
--||^26Qx3v^||--"	
  }
}
```

改行コードは CRLF としてください。

# form-dataでのPOST

ドキュメントを探した限り、form-dataを扱うための仕組みは存在しませんでした。そのため、http output filterを使って生データをPOSTするしかないようです。
生データをPOSTするには、formatをmessageとし、content_typeにContent-Typeヘッダを指定します。ペイロードはmessageで指定します。content_typeで指定するboundaryは、当たり障りのない文字列を指定してください。
Logstashの config は、logstash.yml で指定した場合を除き ```\r\n``` のような指定ができませんので、configをCRLFの改行コードとし上記のような定義としています。

# Windows Docker 上で Logstash を利用

## コンテナの実行

Windows で Docker Desktop を使って Logstash を稼働させるには、以下のコマンドを実行します。

```
docker run --rm -it --name=ls -v /f/es/docker/:/usr/share/logstash/pipeline/ -v /f/es/log/:/mnt/log/ docker.elastic.co/logstash/logstash-oss:7.3.2
```

この例では、```F:\es\docker\logstash.conf``` で config を指定しています。また、```F:\es\log\``` を ```/mnt/log/``` にマウントしていますので、ここにログを配置してテストに使えます。

## config のリロード

開発時は config をいろいろ修正して試行錯誤することがあるかと思います。プロセスにSIGHUPを送れば、config の再読込を行うことができます。

```
docker exec -it ls /bin/kill -SIGHUP 1
```
Python + TypeScriptのmonorepoでpre-commitの設定

## はじめに

やろうとした時に他にやっている人がいないくて、
色々調べてもなかったので備忘録として。

## よくあるやつ
* `TypeScript`
 
[Run a TypeScript type check in your pre-commit hook using lint-staged + husky](https://dev.to/samueldjones/run-a-typescript-type-check-in-your-pre-commit-hook-using-lint-staged-husky-30id) にあるように `husky` と `lint-staged` の組み合わせを使う

```json
{
  "scripts": {
    "prepare": "husky install"
  },
  "lint-staged": {
    "**/*.{ts,tsx}": [
      "prettier --config .prettierrc --parser typescript --write",
      "git add"
    ],
  },
  "devDependencies": {
    "husky": "^7.0.4",
    "lint-staged": "^12.1.4",
    "prettier": "^2.5.1"
  }
}

```

* `Python`

[Python製のツールpre-commitでGitのpre-commit hookを楽々管理！！](https://dev.classmethod.jp/articles/python-git-pre-commit/) にあるように `pre-commit` を使う

```yaml
repos:
-   repo: https://github.com/psf/black
    rev: 21.12b0
    hooks:
      -   id: black
-   repo: https://gitlab.com/pycqa/flake8
    rev: 4.0.1
    hooks:
      -   id: flake8
          args: ['--extend-ignore=E203', '--max-line-length=88']
-   repo: https://github.com/pycqa/isort
    rev: 5.10.1
    hooks:
      -   id: isort
          args: ['--profile', 'black']

```

## 問題点

これらのツールは、 `git` の `pre-commit` フックを使っていて、且つこのフックには一つしか設定できないので、どちらかしか使えない。

最初に `pre-commit` を設定して「動いた！」ってなった後に、 `husky` を設定すると `husky` は動くけど `pre-commit` は動かなくなる。

## 解決策

`Python` の `pre-commit` に `TypeScript` の設定を追加する。

```yaml
repos:
-   repo: https://github.com/psf/black
    rev: 21.12b0
    hooks:
      -   id: black
          files: '^backend/.*\.py'
-   repo: https://gitlab.com/pycqa/flake8
    rev: 4.0.1
    hooks:
      -   id: flake8
          files: '^backend/.*\.py'
          args: ['--extend-ignore=E203', '--max-line-length=88']
-   repo: https://github.com/pycqa/isort
    rev: 5.10.1
    hooks:
      -   id: isort
          files: '^backend/.*\.py'
          args: ['--profile', 'black']
-   repo: https://github.com/pre-commit/mirrors-prettier
    rev: v2.5.1
    hooks:
      -   id: prettier
          files: '^frontend/.*\.(ts|tsx)'
          args: ['--parser', 'typescript', '--write']
```

`Typescript` の `husky` と `lint-staged` に `Python` を追加することもできるはずなのだけど、
なぜか上手く動かない。。。

```json
{
  "scripts": {
    "prepare": "husky install"
  },
  "lint-staged": {
    "**/*.{ts,tsx}": [
      "prettier --config .prettierrc --parser typescript --write",
      "git add"
    ],
    "**/*.py": [
      "pre-commit",
      "flake8 --extend-ignore=E203 --max-line-length=88",
      "isort --profile black",
      "git add"
    ]
  },
  "devDependencies": {
    "husky": "^7.0.4",
    "lint-staged": "^12.1.4",
    "prettier": "^2.5.1"
  }
}

```

あと、 `pre-commit` は設計思想として multi-language をあげているので
`pre-commit` に対応を追加するのがよさそう。
Gitとは？

#Gitについて
※とある未熟者エンジニアの備忘録です。

ソースコードの変更履歴を管理するバージョン管理

・バージョン管理とは？
例）
設計書(ver0.1)⇒設計書(ver0.2) 
全て上書きをするのではなく、ver0.1のある部分だけを修正や変更(差分更新)を加えたもの。そしてver0.1に戻すこともできる。

・Gitのメリット
誰がどこのコードを修正したのかが分かる
修正したコードを元のコードと合体できる
これまでのコードに戻せる

これらの事からチームでの開発で便利なツールと言える。
下記サイトよりインストール可。
https://git-scm.com/
朝活開発を約２カ月半行った結果

本日で今年の仕事納めなので、2021/10/18から続けていた朝活について共有しようかと思います。
（この記事も2021/12/29の朝活中に書いてます）

## 朝活のきっかけ

仕事で大きな区切りがあり、自分を見つめ直す機会がありました。
今後企業で働くにしろ個人で働くにしろスキルは磨き続けなければいけない、というある意味当たり前のことを再認識したのがきっかけです。

## 朝活を始める前に最初にやったこと

M1 macbook air（一番安いモデル）を買いました。家に届いたのが10/17でその翌日から朝活を開始してます

## 朝活概要

* 出勤前の１時間程度
* 会社近くのドトールコーヒーでやる
* 平日は基本的に毎日、休日/休暇は任意
* 仕事が終わって帰宅後GitHubにpush

## 結果

2021/10/18から2021/12/29までで合計49時間（49日間）朝活をすることができました。

その間、以下３つの内容にチャレンジしてます。

#### iOSアプリ

![RoutineTree.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2088399/5464e6c6-70fd-6e77-35a6-77a2ae2ee3be.png)

mac, iphoneユーザーなので、私の生活に役立つアプリを作ってストアに公開しようとトライしました。

過去もSwiftを趣味でいじってた期間はありましたが、真面目にストアに公開しようとしてたのは今回が初めてです。

現在は`In Review`中...

#### 自身のホームページ

https://syamaz.github.io/website/

GitHub pagesにBlazorで作った私自身のウェブサイトをホスティングしてます。

GitHub pagesを使ってみたかったのと、dotnetのBlazorWebAssemblyを触ってみたかったためトライ。

#### Webサービス（Vue, AWS使用）

現在挑戦中です。

iOS(モバイル)やって、ホームページ（静的Web）やったら次はWebアプリ/サービスかなということでやっています。

iOSアプリやBlazorホームページはdotnet開発という仕事での経験が何らかの形で活きていましたが、これはストレッチ目標感が強いです。

来年はしばらくこれをやってそうです。

## 今のところ朝活ってどうか

語り尽くされている話かもしれませんが...

* 早寝早起きが身につく。健康になりそう
  * 22時半就寝、5時起床
* 毎日コーヒー分（200~300円）のコストが発生
  * 元を取るために集中することになる
  * 自宅で継続できる自信があればそれでもいいかも（私は無かった）
* 年末になった今「継続できた達成感」が得られている
* 時間を無駄にしないために目標に対して真っ直ぐな開発ができる気がする
  * ホームページ作成も`Blazor`, `GitHub pages`だけに集中して不要な機能拡張やデザインへのこだわりを排除できた気がする。

私個人としてはいいことの方が多かったので来年も続けます。
意外と忘れる!! Pythonのフレームワークとは?

 
      
#概要
Pythonで利用できるフレームワークには、3つのタイプがあります。
・フルスタックフレームワーク(Full-Stack Framework)
・マイクロフレームワーク　　(Microframework)
・非同期フレームワーク　　　(Asynchronous Framework)

#フルスタックフレームワーク(Full-Stack Framework)とは
Web開発に必要なものがまとまっているフレームワークです。

データベースからのデータ取得処理、ログイン認証、各種フォームの作成など、Web開発に必要な機能がすべて揃っているフレームワークです。そのため小規模な開発だけでなく、大規模な開発にも使えて汎用性が高いのが特徴です。

機能が豊富な反面、覚えることが多く、学習コストが高くなりやすいです。

```
[代表的なフレームワーク]
・Django
・web2py
・Pylons
・CubicWeb
```

#マイクロフレームワーク(Microframework)とは
必要最低限の機能がまとめられているフレームワークです。

フルスタックフレームワークと比べると、機能が少なく軽量です。そしてシンプルなので自由度が高いという特徴があります。必要最低限の機能でシンプルな設計になっているため、覚えることが少なく初心者でも理解しやすいです。

マイクロフレームワークは、小規模な開発に向いています。

```
[代表的なフレームワーク]
・Flask
・Bottle
・CherryPys
・Dash
```

#非同期フレームワーク(Asynchronous Framework)とは
同時に複数接続処理が可能なフレームワークです。

非同期通信ができるため、データの送信者と受信者でタイミングを合わせないで処理できるのが特徴。レスポンスが早く効率的に作業できるので、人気があります。

```
[代表的なフレームワーク]
・Tornad
・Sanic
・Growler
・Aiohttp
```
#気になる雑学
一般的に使われる鉄板なフレームワークは、

```
[鉄板なフレームワーク達]
・Django
・Bottle
・Flask
・Tornado
・web2Py
```
#最後に
今回は、Pythonのフレームワークを紹介してきました!!
細かいフレームワーク達は興味のある物を個人で調べてみて欲しいです。
Elastic Beanstalkの.platform/hooksと.platform/confighooksの違い

Elastic Beanstalk(以下EB)のプラットフォームフックとして`.platform/hooks`と`.platform/confighooks`が用意されています。ドキュメントサンプルなどでは、両ディレクトリに同じスクリプトファイルを設置しており違いがよくわからなかったため、両者の違いについての学んだことを残しておきます

## プラットフォームフックとは？

- EBプラットフォームを拡張するために特別に設計された機能
  - プラットフォーム：オペレーティングシステム (OS)、ランタイム、ウェブサーバーなど
- アプリケーションのソースコードに設置することによって、カスタムスクリプトをインスタンスプロビジョニングのあらゆるタイミングで実行できる
    - カスタムスクリプト(フックファイル) : バイナリファイルなど`#!`で始まるスクリプトファイル (`#!/bin/bash` など)
- 設置したサブディレクトリによって実行するタイミングを指定できる
    - `.platform/hooks/prebuild`、`.platform/confighooks/postdeploy`など
    - タイミングの詳細は「[インスタンスデプロイワークフロー](https://docs.aws.amazon.com/ja_jp/elasticbeanstalk/latest/dg/platforms-linux-extend.html#platforms-linux-extend.workflow)」を参照
- Amazon Linux 2 より前のバージョンでは使用できない

## `.platform/hooks`と`.platform/confighooks`の違いは？
▼簡潔に言うと
**.platform/hooksはアプリケーションデプロイ時、.platform/confighooksは設定変更時**

### `.platform/hooks` : アプリケーションのデプロイプラットフォームフック
`eb deploy`などインスタンスの終了や再起動が必要な場合に発生する

### `.platform/confighooks` : 設定デプロイプラットフォームフック
AWS CLIやEBコンソールから設定を変更した時など、インスタンスの再作成せずに更新だけする設定変更を行った場合に発生する

## おまけ

### 両ディレクトリで同じスクリプトを使用したい場合はシンボリックリンクを貼る
.platform/hooksと.platform/confighooksで同じスクリプトを使用したい場合はシンボリックリンクを貼っても動作する

```bash
cd .platform/hooks/predeploy
ln -s /.platform/confighooks/predeploy/01_extension.sh 01_extension.sh
```

### 設定を更新したときのローリング設定
[アプリケーションデプロイと同じように](https://docs.aws.amazon.com/ja_jp/elasticbeanstalk/latest/dg/using-features.rolling-version-deploy.html)設定デプロイ時にもローリングを設定できる。何も設定しないで設定を更新するとアプリケーションサーバーの再起動などでダウンタイムが発生する可能性があるので、忘れずに設定を行う

▼設定方法
EBコンソールで対象の環境へ行き、ナビゲーションペインから設定 > ローリング更新とデプロイを選択。設定の更新セクションにてローリングデプロイ設定をする

## 参考
https://docs.aws.amazon.com/ja_jp/elasticbeanstalk/latest/dg/platforms-linux-extend.html#platforms-linux-extend.hooks

https://docs.aws.amazon.com/ja_jp/elasticbeanstalk/latest/dg/using-features.rollingupdates.html

https://qiita.com/yuyasat/items/4d93b4ad4f86a6e13d50