OmniAICreator/Qiita-1.07M huggingface dataset:
エラーハンドリングをミスって大事故に

# はじめに
アドベントカレンダー初参加です！
とある企業でサーバーサイドエンジニアとして働いており、主にGoでAPIを実装しています。

今年に入って新規事業の開発を任され、色々やらかしを経験させていただきました。

その中でも一番のやらかしを自戒の念も込めて投稿したいと思います。

*特定を避けるために敢えて分かりづらく表現している箇所があります。その点ご了承くださいmm*

# 惨劇発覚前夜
とある会員制サイトのリリースを控えており、それに備えて色々準備を整えてました。
リリース当日はそれなりにアクセス急増が見込まれるので

- ALBの暖気申請
- フロントエンドサーバーのスケールアウト

等の対応を行いました。

今までも似たようなサイトをいくつかリリースしており、上記の対応でアクセスは捌けていたので今回も同様の対応で問題ないと思ってました。

リリース当日PM20:00 にサイトのURLを公開。

今までをはるかに上回るアクセスが来ましたが、特にサイトの表示につまることはなく、当日のリリース作業を終えることができました。

# 惨劇発覚
次の日、朝起きるとサポート用メアドに何件かメールが届いていました。
恐る恐る確認すると、重複してはいけないはずのユーザー情報が重複しているとの問い合わせが。。
すぐにマネージャーに報告し、原因究明に取り掛かりました。

# 惨劇はなぜおこってしまったのか
APIログを確認したところ、会員登録トランザクションでデッドロックエラーが数件吐かれてました。
DB（mysql）にて`SHOW ENGINE INNODB STATUS;`を実行したところ、会員登録トランザクションの以下のクエリ間でデッドロックが発生しているようでした。

1. 会員テーブルから会員情報を取得
2. 会員情報のステータスを修正し、UPDATE


ところが仮にデッドロックが発生したとしても、アプリケーション側でちゃんとエラーハンドリングされロールバックされれば、今回のような大きな障害には繋がりません。

今回はまさに上記の`1`の処理でエラーハンドリングを怠っていたために発生した障害でした。

簡単にコードで再現すると以下のような実装でした。

```go
func (r *repo) GetMember(ctx context.Context, id uint64) (member *Member, err error) {
	// ORMでクエリ構築(省略)

	// クエリ実行
	if _, err := db.LoadContext(ctx, member); err != nil {
		err = xerrors.Errorf(": %w", err)
	}
	return
}
```

Goでは関数の戻り値に名前をつけて、関数内で扱うことができます。
上記ではクエリ実行のエラーがnilでなかった場合、エラーをラップして関数の名前付き戻り値`err`を上書きし、最後にreturnするという意図の実装でした。
しかし、実際には、`err`がif文内で新たに宣言され、関数の名前付き戻り値とは別の変数として新しく宣言されてしまっています。

```go
// `:=`ではなく
if _, err := db.LoadContext(ctx, member); err != nil
// `=`が正解
if _, err = db.LoadContext(ctx, member); err != nil
```

この結果、クエリ実行時の変数`err`のスコープはif文内に限定され、エラーが握り潰されてしまいました。
そのため`1`の処理ではエラーが返されず、そのまま`2`の処理に進み、トランザクションがコミットされて不整合のあるデータが生まれてしまった、というオチです。

# 二度と惨劇を起こさないためにどうしたのか
主に以下のような対応を行いました。

- テーブル内で重複させたくないカラムには`UNIQUE KEY`を付与する
    - なぜこれを事前にやってなかったかは過去の自分に問いたいです
- エラーが発生した場合は、そのままreturnすることを基本とする
    - エラー判定のif文でreturnすることを徹底すれば、このようなミスが防げるのではという考えです
        - ただ書き方が冗長になる場合もあると思うので、あくまで意識として。。
        - エラーハンドリングのミスを機会的に防ぐために、Goの静的解析[`errcheck`](https://github.com/kisielk/errcheck)なども試してみましたが、今回のケースはアラートとして出してくれませんでした。。

```go
if _, err := db.LoadContext(ctx, member); err != nil {
    err = xerrors.Errorf(": %w", err)
    return
}
```
- ユーザー登録や決済など、クリティカルな処理は負荷テストを行うようにする
    - 今まで、同様の実装で何件かサイトのリリースを行いましたが、今回はそれまでを遥かに上回るアクセスが来たため、このようにバグとして明るみに出る結果となりました
    - まずはローカルでバグを再現する必要があると思い、Goを並列でテストする`t.Parallel`メソッドを使って、500件同時に会員登録を行うシナリオテストを実装しました
        - この負荷テストの詳細に関してはまた別の機会に紹介できればと思います
    - その結果ローカルで再現でき、バグフィックス後の確認も安全に行うことができました

# 終わりに
この一年色々やらかして、関係者の皆様には申し訳なさでいっぱいです。
それでも今の環境で応援していただけているのは感謝しかありません。
今後もサービスと共に成長できるように精進します。

P.S.
名前付き戻り値って便利な反面、少しスコープが分かりづらいなと思いました。
だからと言って、コード規約として全面禁止にするというのも踏み込めず、他社さんではどのように扱っているのか気になっております。
名前付き戻り値や今回のエラーハンドリングの扱い、その他諸々に関してアドバイスいただけますと大変嬉しいです。。！
[Power BI  Tips]レポートデザインのアイデア

# 元ネタ
https://youtu.be/k9LGRfREuIk

# このレポートデザイン
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/80467/ef17a155-9c3d-cd02-fb58-b5ae863d7230.png)

## やろうと思ったら

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/80467/c9ba15cf-0935-4c9b-c902-d29db6d189dd.png)

図形をたくみに組み合わせて作る・・のかなと思ったあなた！

# PowerPointで作るんですって！

パワーポイントならこのくらいの図形組み合わせはサクサクできますよね。
通常の画面比率が１６：９なので、Power BIもデフォルトならぴったりです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/80467/af4cf09a-71c8-70c6-9609-d30d9fc7d97a.png)

## 作成したら画像形式で書き出し

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/80467/d5ea763b-f2a3-5eaa-61d7-936ab3613ca0.png)

何も設定せずに書き出したら、１２８０×７２０px で書き出されました。

## Power BI Desktop の背景の設定

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/80467/42de5b72-b368-cd00-12ec-38aabee5c8f4.png)

ここで先程書き出した画像ファイルを読み込み、サイズ調整や透過をイメージに合うように調整します。

# 完成！

あとはボタンとして使うアイコンを並べたり、タイトルをヘッダースペースに配置したりします。
Power BI の図形ツールは少しずつPowerPointライクになるのかなとは感じますが、
まだ画像の配置や色や効果の調整・操作性はPowerPointが楽ですね。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/80467/0cece3f6-8b6a-b748-ef1f-27e7f0edb62f.png)
PythonからMatlabを動かす話

# まえがき
公式の記事が正しいし、情報も多いです。
ただし詰まった時に同じ詰まり方をしている記事があまりなかったので、~~matlabに詳しくはないですが~~書きます。
わからない時は直接質問ください、一緒に考えます。

# 前提(自環境)
|名称|バージョン|
|:---:|:--|
|Ubuntu|18.04|
|matlab |R2020b|
|python|3.8|

# 1. APIインストール

[[1]Python 用の MATLAB エンジン API のインストール](https://jp.mathworks.com/help/matlab/matlab_external/install-the-matlab-engine-for-python.html)を見ながらやっていきます。
この内容そのままなので今回は割愛します。

ただしmatlabエンジンのビルドができたら、lsとかで本当にあるかは確認してください
(公式にもありますが、```matlabroot/extern/engines/python/build/lib/matlab/```に```_init_.py```がいるってのが今回の肝です)。

# 2. pythonからmatlabを呼び出す

[1](#1.APIインストール)の補足に書いた通り、公式そのままpath通さないで```import matlab```ってするとモジュールが見つからないと怒られてしまいます。

以下のようなコードを記述することでこれを回避します。

```py:test.py
import sys
# matlabAPIのパスを追加
sys.path.append('matlabroot/extern/engines/python/build/lib/')
# APIのインポート
import matlab.engine

# matlabのファイル確認
print(matlab.__file__)
```

```text:出力
matlabroot/extern/engines/python/build/lib/matlab/__init__.py
```
このコードでmatlabのファイルとバージョンを確認しています。

自分は```pip install matlab```ができてしまったせいでこのファイルがcondaを指すようになってました。

一度```pip install matlab```してしまった人は```pip remove matlab```をしてからpythonコードを走らせてみてください。

# 3. matlabで書かれたコードを呼び出してpythonから実行する

呼び出し側のpythonコードと同じ階層にmatlabのユーザースクリプトを置きます。

以下のような階層ができれば正解です。
実行場所はカレントディレクトリで行ってください。外から実行するとmatlab engineが.mファイルを探せなくてエラーを吐きました。

```bash
.
│──test.py
└──triarea.m
```

スクリプトは[[2]Python からのユーザー スクリプトと関数の呼び出し](https://jp.mathworks.com/help/matlab/matlab_external/call-user-script-and-function-from-python.html)
の公式リファレンスままで、以下のように書きました。

```matlab:triarea.m
function a = triarea(b,h)
a = 0.5*(b.* h);
```

```py:test.py
# パス追加用にsysをインポート
import sys
# matlabAPIのパスを追加
sys.path.append('matlabroot/extern/engines/python/build/lib/')
# モジュールをインポート
import matlab.engine

# matlabエンジンをスタート
eng = matlab.engine.start_matlab()
# 自分のスクリプトに引数を渡して戻り値を変数に格納
res = eng.triarea(1.0, 5.0)
# 結果を出力
print(res)
eng.quit()
```

```text:出力
2.5
```

> エンジンの実行中に Python を終了すると、Python はエンジンとその MATLAB プロセスを自動的に停止します。
[[3]Python 用 MATLAB エンジンの起動と停止](https://jp.mathworks.com/help/matlab/matlab_external/start-the-matlab-engine-for-python.html)

と、あるようにpythonスクリプトが終了するとmatlabプロセスも終了しますが心配なのでeng.quit()としました。

# まとめ

同じようにして```eng.matlab関数()```としてあげれば、matlabにしかない組み込み関数とかも動かせます。

詳しくは[[4]Python からの MATLAB 関数の呼び出し](https://jp.mathworks.com/help/matlab/matlab_external/call-matlab-functions-from-python.html)の公式リファレンスが読みやすいかと思います。

ぜひやってみてください。

~~(祈願) 卒論うまく書けますように~~

# 参考文献

[1][Python 用の MATLAB エンジン API のインストール](https://jp.mathworks.com/help/matlab/matlab_external/install-the-matlab-engine-for-python.html)
[2][Python からのユーザー スクリプトと関数の呼び出し](https://jp.mathworks.com/help/matlab/matlab_external/call-user-script-and-function-from-python.html)
[3][Python 用 MATLAB エンジンの起動と停止](https://jp.mathworks.com/help/matlab/matlab_external/start-the-matlab-engine-for-python.html)
[4][Python からの MATLAB 関数の呼び出し](https://jp.mathworks.com/help/matlab/matlab_external/call-matlab-functions-from-python.html)
sassがコンパイルしない事でハマった話。


解決までかなり時間がかかったので自分用に記録として書きます。
あと、同じように詰まっている方のお役に立てられればいいなと思います。

やりたかった事
sassでコーディングしてWordPress化する

ハマった事
sassがコンパイルしなくなった

事象
・sass:watchは動いている為、一見コンパイルはされているように見えるが.scssファイルを書き換えるも、サイトの表記は変わらない
・コンパイルにはgulpfile.jpを使用の為、gulpfileを何度も書き換えた

エラー文：Error: "&" may only used at the beginning of a compound selector.
意味：「＆」は、複合セレクターの先頭でのみ使用できます。

解決した方法
sassファイルに&が２つ連結していたのが原因だった
⇨＆を一つ消したことで解決した
【Amplify】クラウド上にだけあるenvをローカルにプルする

### 一言で

Amplify Console上の操作で新規環境を追加したときは、`amplify pull --envName $envName`でソース側に情報を反映できる。

### 以下詳細
いつものようにAmplifyでアプリを新規作成し、フロントとバックを紐づけようとしていた時のこと。
要件は
+ フロント：本番とステージングの2環境
+ バック：本番とステージングと開発の3環境

今回は`staging`を追加することになった。
で、普通ならCLI経由で「amplify env add」するところを、ふとクラウドコンソール上で「新しい環境を作成」の文字が目に入り、試しに使ってみた。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/551800/77bba9e3-c991-5241-91d7-af08f2ebbbc1.png)

後はいつもと同じく画面に従ってポチポチボタンを押していき、無事デプロイ完了。
めでたしめでたし…とはならず、いつもなら`amplify env add`したとき勝手にローカルのソースにも環境情報が追加されるのだが、今回はクラウド上で操作が完結しているため、その手順がない。
つまりこのままローカルで`amplify env list`してもさっき追加したstaging環境は表示されないし、`amplify env checkout staging`しようとしても「そんな環境はないよ」と怒られてしまう。
困って公式のコマンド一覧を眺めてみたりググったりしたが、どうも有効な手段が見当たらない。

## 解決策

最終的に`amplify pull --envName staging`を実行することで、無事環境情報を引っ張ってこれました。
やってみたら上手くいった式の解決なので、他にスタンダードな方法もあるかもしれません。
それかgit fetch的な、クラウドからごっそり環境の情報を持ってくる手段ってあるんでしょうか。公式ドキュメント見逃してるだけかもしれませんが…

以上です。
STM32F303K8とI2Cを使ってI2Cスレーブから値を受信する。



x まだ試していない テスト確認済み2021/12/14


目的
I2Cスレーブのテスト 一発大成功
//tempval = 0;で止めてたのは、ご愛敬


参考



https://os.mbed.com/users/okini3939/notebook/i2cslave_jp/



![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/4c7a9917-0930-9277-cbb1-b13a986b5fa6.png)



```c++



//I2C_Slave_ReadA_303_1

#include "mbed.h"

//GPIOの初期化
DigitalOut myled(PB_3);//LED1

//シリアルの初期化
Serial pc(SERIAL_TX, SERIAL_RX); //nucleo 303

//I2Cの初期化
I2CSlave slave(I2C_SDA, I2C_SCL); //nucleo 303

//メイン関数
int main()
{

    char buf[10]; //I2Cバッファー

    //I2Cスレーブのアドレスの設定
    slave.address(0x80);

    //無限ループ
    while(1) {

        //I2Cの状態の読み出し(ポーリング)
        int i = slave.receive();

        //ステータスの表示
        pc.printf("I2C Status: %x\r\n", i);

        if (i == I2CSlave::ReadAddressed) {

            //バッファーをフリップフロップする。(シーソーする)
            if( buf[0] == 0 ) {buf[0] = 1;}else{buf[0] = 0;}

            //I2Cマスターに送信する
            slave.write(buf,1);

            //I2Cスレーブの送信データの表示
            pc.printf("\tRead A: %d\r\n", buf[0]);

        }//if

        //LEDの点滅
        myled = 1;
        wait_ms(100);
        myled = 0;
        wait_ms(100);

    }//while

}//main



```


I2Cマスター STM32L010F4P6


```c++



//I2C_M_Read_1

#include "mbed.h"

//I2C i2c(I2C_SDA, I2C_SCL); //767
//I2C i2c(dp5, dp27); //1114
I2C i2c(PA_10, PA_9); //010


//Serial pc(USBTX, USBRX); // tx, rx
//Serial pc(SERIAL_TX, SERIAL_RX); //767
RawSerial pc(PA_2, PA_3); //010

//#define S5851A 0x48
#define ADDR        (0x80)   //  address

int main() {

    char data_read[8]; //バッファー





    //無限ループ
    while(1){



        //dataの読み込み
        // Read temperature register
        i2c.read(ADDR, data_read,1,false);

        //温度の保存
        // Calculate temperature value in Celcius
        int tempval =  data_read[0]; //dataの転記

        //tempval = 0;

        //画面に表示
        pc.printf("Read : %x\r\n",tempval);

        //1秒待つ
        wait_ms(1000);

    }//while

}//main

//容量削減
void error(const char* format, ...){}



```
Python3 エンジニア認定基礎試験     絶対に合格する!(2021/8月合格)

# Python3 エンジニア認定基礎試験について
- 始めに
  - Python3 エンジニア認定基礎試験とは
  - 動機
  - 試験概要
- 試験勉強
  - 受験勉強開始前の知識レベル
  - 学習期間
  - 参考資料
  - 学習方法
- 試験当日
  - 準備
  - 試験
- その後
- 参考文献

# 始めに

## Python 3 エンジニア認定基礎試験とは 
Pythonの文法基礎を問う試験です。 
後述で紹介しますが、オライリー・ジャパン『Pythonチュートリアル 第4版』から各章数問ずつ出題されます。

## 動機
業務でPythonを使用するため、基本的な知識を身に着けたいと思い受験しました。

## 試験概要
- 問題数: 40問
- 出題形式: 選択形式
- 試験方法: コンピューター上で実施するCBT（Computer Based Testing）形式
- 試験時間: 60分 (回答完了次第、退出することができます)
- 合否水準: 70%
- 受験料: 11,000円 (学生 5,500円)

# 試験勉強

## 受験勉強開始前の知識レベル
Pythonについて少し理解をしていましたが、あやふやなところも散見されているレベル感でした。

## 学習期間
学習時間は1か月弱になります。

## 参考資料
- テキスト：[Pythonチュートリアル 第4版](https://aoten.jp/store/detail.html?no=a1800i_k210201)
- 無料テキスト: [Python チュートリアル](https://docs.python.org/ja/3/tutorial/)
- 無料問題集
  - [認定模擬問題（DIVE INTO EXAM)](https://diver.diveintocode.jp/dive_into_exam/lp)
  - [認定模擬問題（PRIME STUDY)](https://study.prime-strategy.co.jp/)  

## 学習方法
- まずは上記のテキストを1周行います(テキストを買っても良いですが、無料テキストでも十分だと思います)
- 次に、上記で紹介した無料問題集を解きます。

# 試験当日
## 準備
- 予約したテスト会場に向かいます。(時間に余裕を持っていきましょう<重要>)

## 試験
- 受付の際に、身分証明書を提出します。
- 注意事項を読んだうえで「スタート」をクリックし、試験を始めます。
- 時間には余裕がありますので、しっかり見直しをしましょう。
- 試験終了後、結果はすぐにわかります。 

# その他
## 再受験について 
同一科目に対して2回目の受験については制限がありませんが、3回目以降の受験は前回の試験日から7日間（24時間×7=168時間）は受験できません。

# 参考文献
- [オデッセイ コミュニケーションズのCBT](https://cbt.odyssey-com.co.jp/pythonic-exam.html)
Android Bazaar and Conference Diverse の案内

日本Androidの会が年2回主催する大きなAndroid系開発者イベントに『ABC：Android Bazaar and Conference』について簡単に記載したく思います。
ABCは2010年から年2回定期的に開催され続けてきたAndroidに関するカンファレンスとバザールを主としたイベントです。
今はさまざまなITイベントが開催されるようになり技術・知識共有が簡単になりましたが自身の振り返りも兼ねてせっかくの機会ですので記載しておきたく思います。

# 勝手に主なイベント回を紹介します。

* 記念すべき第1回は東大で開催されました。そして次の第2回も東大で開催され、当時は入場制限がかかるほどの長蛇でした。

http://www.android-group.jp/index.php?%A5%A4%A5%D9%A5%F3%A5%C8%2FAndroid%20Bazaar%20and%20Conference%202010%20Spring

http://www.android-group.jp/abc2011w/

* 第3回は早稲田大学でした。

第3回は3.11の後という事もあり、『頑張れ日本、頑張れAndroid!!』をテーマにエンジニアの方々の目に見えない活躍の発表の場にもなりました。

http://www.android-group.jp/abc2011s/

* 開催5周年時は秋葉原UDXにて開催

http://www.android-group.jp/conference/abc2014s/

# 2017年からはABCは東京からABCDとして地方へ進出

今まで首都圏開催だったABCですが2017年からは、ABCDと名称を少し変更し金沢・香川・浜松でそれぞれ開催されてきました。

https://sites.google.com/android-group.jp/abcd2019h/

https://japan-android-group.connpass.com/event/192378/

そして先日開催されたのが、なんと離島の伊豆大島（Izu / Oshima）からの配信です。新型コロナウィルス感染拡大に伴ってリモート開催を余儀なくされてしまっていますがこれが逆に地方からの発信に追い風となっています。

https://abc.android-group.jp/abcd2021w/

Androidだけじゃなく、「地方創生、働き方改革、DX、ワーケーション」といったテーマにもABCDが調度時代マッチしています。

まだ動画公開しているので見逃した方は是非チェックしてみてください。

（過去のイベントリンクは以下にまとめられています）
https://abc.android-group.jp/
C#でカノジョをつくる（13日目）

お疲れ様です。たなしょです。
今日はカノジョの原型となるモデルを作成しました。
ようやく第一歩ですね。
##完成したもの
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/268048/efb11bf1-50a7-b47d-4522-b3a00ddb34df.png)
まだ「おはよう」などのあいさつを返すことはできませんが、一方向のコミュニケーションは取れます。
画像は[illustAC](https://www.ac-illust.com/main/detail.php?id=22347665&word=%E3%83%9E%E3%83%95%E3%83%A9%E3%83%BC%E3%81%A8%E3%83%9B%E3%83%83%E3%83%88%E9%A3%B2%E6%96%99%EF%BC%88%E9%9D%92%E3%83%BB%E3%83%A1%E3%82%AC%E3%83%8D%E3%81%AA%E3%81%97%EF%BC%89&searchId=1575395150#)さんから拝借しました。（かわいい！）

##カノジョのなかみ

```c#
/// <summary>
/// RandomResponderまたはRepeatResponderを
/// ランダムに選択して応答メッセージを返す
/// </summary>
/// <param name="input">ユーザ-の発信</param>
/// <returns>応答メッセージ</returns>
public string Dialogue(string input) { 
    Random rnd = new Random();
    int num = rnd.Next(0, 10);
    if (num < 6)
    {
        _responder = _res_random;
    }
    else
    {
        _responder = _res_repeat;
    }
    return _responder.Response(input);
}
```
このDialogueメソッドがカノジョの心臓部分です。
Random関数でランダムな数値(0~9)を生成します。
6より小さい場合ランダムなことを返して、6以上なら入力した文字と同じ文字を出力します。（オウム返しな受け答え）

## ランダムな受け答えのなかみ

```c#
class RandomResponder : Responder
{
    private string[] _responses =
    {
        "めっちゃいい天気!",
        "確かにそうだね",
        "10円拾った",
        "じゃあこれ知ってる？",
        "それねー",
        "それかわいい♪"
    };

    /*~中略~*/

    // Response method
    public override string Response(string input)
    {
        Random rnd = new();
        return _responses[rnd.Next(0, _responses.Length)];
    }
}
```
0~5までの要素に書く文字列を格納しています。
Responseメソッドが呼ばれるとランダムで0~5までの数値を生成して配列の中身を参照しています。

## オウム返しのなかみ

```c#
class RepeatResponder : Responder
{
    /* 中略 */
    
    // Response Method
    public override string Response(string input)
    {
        return String.Format("{0}ってなに？", input);
    }
}
```
オウム返しなので単純に引数をもってきて「ってなに？」の文字列と合わせて、
合成した文字列を返却しているだけです。

## 「話す」を押したときのうごき

```c#
private void button1_Click(object sender, EventArgs e)
{
    string value = textBox1.Text;
    if (string.IsNullOrEmpty(value))
    {
        label1.Text = "なに？";
    }
    else
    {
        string response = _chan.Dialogue(value);
        label1.Text = response;
        PutLog("> " + value);
        PutLog(Prompt() + response);
        textBox1.Clear();
    }
}
```

テキストボックスに何も入力せず「話す」ボタンを押すと「なに？」が表示されます。
テキストボックスに何か入力されている状態で「話す」ボタンを押すと、Dialogueメソッド呼ばれて受け答えの処理が実行されます。
そして左端のプロンプトに会話内容を出力します。

## 最後に
今日はカノジョの原型を作成しました。
まだ一方向のコミュニケーションしか取れませんが、これからある程度会話のキャッチボールができるように改良していきたいです。
R Markdownで定型レポート楽々作成

## 色々なテーブルを並べたレポートを大量生産したい

R Advent Calendar 2021 15日目の記事です。

<https://qiita.com/advent-calendar/2021/rlang>

今年の春ぐらいから半年ほどかけて、R用Dockerイメージとしてよく使われる`rocker/rstudio`や`rocker/tidyverse`などをビルドしている[`rocker-org/rocker-versioned2`リポジトリ](https://github.com/rocker-org/rocker-versioned2)のビルドシステム改修作業を行っていました（[Japan.R 2021](https://japanr.connpass.com/event/230381/)のショートセッションで話しました）。

その作業の一環で、ビルドされたDockerイメージの情報をレポートとして記録するよう機能を作ろうというという話になり、R Markdownでやってみたら簡単だったので簡単に紹介します。

このような実際に動いている実例があると理解しやすくなると思いますので、参考にしてみてください。
（このリポジトリでイメージの更新のある度に動いて、毎回100以上のMarkdownファイルを生成しリポジトリ付属wikiに登録しています）

なおill-identifiedさん(@s_katagiri)の最近訳された、R Markdown Cookbookに非常にお世話になりました。「こんなことやりたいけどできるのかな？」と思ったらこの本の中を探して見ることをオススメします。

R Markdown クックブック：<https://gedevan-aleksizde.github.io/rmarkdown-cookbook/>

R Markdown Cookbook 原著（英語）：<https://bookdown.org/yihui/rmarkdown-cookbook/>

## 実例

↓のテンプレートから

<https://github.com/rocker-org/rocker-versioned2/blob/d0df52bdd47336f5bdf9bb85e88b42c58b96a55a/build/reports/template.Rmd>

↓みたいなレポートや

<https://github.com/rocker-org/rocker-versioned2/wiki/r-ver_7967f4e91da7>

↓みたいなレポートが出力されました。（GitHub Actionsによる自動生成）

<https://github.com/rocker-org/rocker-versioned2/wiki/ml-verse-cuda11_6e34075afb48>

### 読み込む外部ファイルのパスを外部から指定する

yamlヘッダーの`params.<parameter_name>`で変数を設定し、`rmarkdown::render(params = list(<parameter_name> = parameter))`という感じで外部から変数の中身を設定できます。
変数の中身は`params$parameter`という感じで取り出せます。

以下の例ではタイトルを`image_name`という変数で指定し、それ以外に5つのファイルのパスを変数で指定するようになっています。

```yml:ymlヘッダー
title: "`r params$image_name`"
params:
  image_name: ""
  inspect_file: ""
  imagetotls_inspect_file: ""
  apt_file: ""
  r_file: ""
  pip_file: ""
```

レポート内では、以下のように`params`からファイルのパスを読み込んで加工してテーブルを出力しています。
`inspect_file`には`docker instpect image <imagename>`コマンドで出力させた、Dockerイメージの情報の書き込まれたjsonファイルを指定するので、これでDockerイメージの情報をレポート内に読み込めるわけです。

```R:R
df_inspect <- jsonlite::read_json(params$inspect_file)
```

クックブックではここに書かれています。
<https://gedevan-aleksizde.github.io/rmarkdown-cookbook/parameterized-reports.html>

### ルートディレクトリをプロジェクトのルートディレクトリに合わせる

RMarkdownファイルを実行するとき、デフォルトではルートディレクトリはRMarkdownファイルのある場所に設定されます。
これだと外部ファイルを読み込む際の相対パス指定がややこしかったりするので、`{rprojroot}`パッケージの関数を使ってプロジェクトのルートディレクトリをルートディレクトリに変更してやると便利かもしれません。

以下のようになチャンクを書いてやると、knitするとき（`rmarkdown::render()`を実行しRMarkdownファイルから最終的なレポートを出力させるとき）のルートディレクトリを変更してやれます。

````Rmd:Rmd
    ```{r, include=FALSE}
    knitr::opts_knit$set(root.dir = rprojroot::find_root_file(criterion = rprojroot::is_git_root))
    ```
````

（Qiitaではバッククオート4つで囲ってもバッククオート3つのコードブロックをコードとして認識させられないのでスペース4つで認識させています。上記ブロック左側のスペースはそのためのものなので無視してください）

これはknitするときに使用される設定なので、RStudioでRMarkdownファイルを編集中にチャンクを実行して内容を確認するとき用には別途Global Optionsで設定が必要です。
![globaloptions.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/675583/54c900c3-b0c0-3e50-6637-cd4102174bfd.png)
vscode-Rの場合はそもそもRMarkdown用にルートディレクトリを変更するような機能は持っていないため気にする必要はありません。（と言うかこの設定をやらないと書きづらい）

ワーキングディレクトリについてはクックブックのこのあたりに書かれています。`{rprojroot}`パッケージについては触れられていないので、別途`{rprojroot}`パッケージのドキュメントを確認してみて下さい。
<https://gedevan-aleksizde.github.io/rmarkdown-cookbook/working-directory.html>
Shopify のサブスク(定期購入) アプリ Bold Subscription を利用する



[Shopify Advent Calendar 2021](https://qiita.com/advent-calendar/2021/shopify) 13日目の記事です。

Shopify で定期購入(サブスクリプション)を扱いたいときに利用できる Shopify アプリである [Bold Subscription (ボールド サブスクリプション)](https://apps.shopify.com/bold-subscriptions?locale=ja)を紹介します。

Shopify 自体ではサブスク(定期)購入機能は提供していないため、定期購入を扱いたい場合にはサブスク用の Shopify アプリを導入する必要があります。サブスク用のアプリはいくつかありますが、ここでは Bold Subscription (以下では Bold と略します)について紹介します。

### Shopify 自体にも Subscription API はあるけど

Shopify 自体に [Subscription API](https://shopify.dev/apps/subscriptions/getting-started#subscription-apis) というものが2021年頭にリリースされました。しかし、これはサブスク用アプリを開発する開発者向けのAPIです。通常のアプリでは実質利用できないと思った方がいいです。
Subscription API については、[Shopify Subscription APIs を掘り下げて分かったこと](https://zenn.dev/kei178/articles/aadc0b3b6ea64e)
の記事がまとまっていますので気になる方はそちらをご覧ください。

当初、Bold 経由で作成したサブスク注文を、このAPI使えばサブスク情報を取得できるのかなと思ったけど、呼べなかった.

# Bold Subscription

[Bold Subscription](https://boldcommerce.com/subscriptions) は Bold Commerce 社が開発しているサブスク用のサービスです。そのひとつとして Shopify 用にShopify アプリとして提供しています。現在(2021年12月)は Bold V2 が最新版です。V1は独自にサブスク機能を開発していましたが、V2 では上述した Shopify Subscription API を利用してサブスク機能を開発しています。

## Bold Subscription の特徴

1. 金額: 49 USD/月
2. 60日間無料体験
- 管理画面のUIは英語
- 専用 API を提供している
- カートやチェックアウト画面は、Shopifyの通常の商品と同じものを使う。(よって単品と定期便を同じカートに入れて買うことができる)
- カートに1つでも定期便商品がある場合、ユーザーの支払い方法は Shopify payment(クレカ)のみ
- マイページにて定期便の設定変更ができる(配送頻度やサブスク停止など)
- サブスク用のクーポンの設定は、Shopifyのディスカウントページで行う。

※ 5つ目以降は、Bold というより Shopify Subscription API を利用しているアプリなら同じ挙動になると思う。

Bold の強みとしては、長年サブスク機能をグローバルに提供したきた知見と専用のAPIがあることかなと思っている。機能自体は他のサービスと比較してないですが、一般的なものは揃っています。


## Bold Subscription 主な使い方

すごいざっくりとした、ユーザーが購入するまでの流れです。

1. サブスクリプショングループを作成する。ここで、定期購入させたい商品の選択、購入頻度、割引を設定する。
1. 商品ページに1で作成したサブスクの購入ボタンをLiquid をカスタマイズして設置する。
1. ユーザーが商品ページから商品を購入する。


詳しい導入方法は、他の記事でスクショ付きで詳しく説明されているので、そちらを参考にしてください。

- [Shopify定期購入アプリBold Subscriptions V2の導入方法・日本語化・使い方ガイド【2021年版】](https://blog.nb-a.jp/2021/03/26/bold-subscriptions-v2/)
- [公式: Set up Bold Subscriptions V2](https://support.boldcommerce.com/hc/en-us/articles/360050100092-Setup-Bold-Subscriptions-V2)


## 試してみて気になったところ

Bold V2 を試してみていくつか気になった点を書いておきます。これは別にBoldに限らない気もするけど参考まで。

- 複数商品で1つの定期便を作ると、その単位でしか商品の解約や発送日を変えられない。当たり前なことだが、消費量に差が出るような商品の組み合わせだと、片方だけ発送日を変えたいみたいな要望があるが、それはできないので、そこを考慮しておく必要がある。
- 定期便であってもカートで数量は変えられる。もし、商品によっては一人1つまでしか定期購入されたくない場合は、カート側で何かしら制御する仕組みを作る必要がある。 

## Bold V2 の所感 (V1との違い)

現在、Bold V1 を使っている身からすると、2021年12月現在では、V1 に比べると V2 の機能は少し足りない感じはあります。例えば、V1では定期購入回数によって割引率を変えることはできません。ここら辺はおそらく後々追加されていくのではないかと思っています。


## まとめ

基本的な定期購入の機能は揃っているので、比較的簡単に定期購入を始められます。Shopify を使って定期購入を実現したい方は、60日無料なので、とりあえず試してみるといいと思います。
[Windows/WPF] バックグラウンドプロセスを作ってみる(.NET5版 別解)

もくじ

https://tera1707.com/entry/2022/02/06/144447

- **バックグラウンドアプリ関連記事**
    - [バックグラウンドプロセスを作ってみる](https://zenn.dev/tera1707/articles/b961d9810d45f9)
    - [バックグラウンドプロセスを作ってみる(.NET5版)](https://qiita.com/tera1707/items/4d2cc7c55a6df4c1aa62)
    - [バックグラウンドプロセスを作ってみる(.NET5版 別解)](https://qiita.com/tera1707/items/c48f13ea01c8615136cb)
    - [バックグラウンドプロセスを作ってみる(.NET8版 別解2)](https://tera1707.com/entry/2025/05/14/230730)

# やりたいこと

以前、.NET5でバックグラウンドプロセスを作ったが、もっと簡単かもしれない方法があったのでメモ。

# 手順

1. 「WPFアプリケーション」を選択する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/352601/41374a9e-02bb-b3e1-c7ac-428fe419262a.png)


1. ターゲットフレームワークで「.NET5.0」を選択する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/352601/aa48712f-edaa-1872-28cc-972e28968bc1.png)

1. App.xamlの先頭の<Window>にあるStartupUri="MainWindow.xaml"を削除
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/352601/4cb8ec63-4b5f-e32d-90d3-85a2a2ad5fa1.png)

1. App.xaml.cs にある「App」クラスに、`OnStartup()`メソッドのオーバーライドを追加する。
  (Appにカーソルを合わせて、ALT+Entを押し、出たメニューで「上書きの追加」を選択し、`OnStartup()`を選択する)

1. 起動後5秒でアプリを終了するには、下記のように書く。

``` App.xaml.cs
using System.Threading.Tasks;
using System.Windows;

namespace WpfApp10
{
    public partial class App : Application
    {
        protected override async void OnStartup(StartupEventArgs e)
        {
            await Task.Delay(5000);
            this.Shutdown();
        }
    }
}
```

※`App.xaml`で`StartupUri="MainWindow.xaml"`を消してないと、上のコードでTask.Delayしている間にウインドウが出てしまうので、必ず削除しておくこと。

# 前回のやり方との差

前回のやり方は下記。

https://qiita.com/tera1707/items/4d2cc7c55a6df4c1aa62

前回のやり方と今回のやり方で、特に動きに違いはないように見える。

どちらも、

- タスクマネージャーの
    - 「プロセス」タブには出てこない
    - 「詳細」タブには出てくる

同じ動きするのであれば、今回のやり方の方が、簡単かもしれない。
【Django】プロジェクト名と設定フォルダ名を別々の名前にする方法

## この記事について
プロジェクト名と設定フォルダ名を別々の名前にする方法を記します。
[Django公式tutorial](https://docs.djangoproject.com/ja/3.2/intro/tutorial01/)のディレクトリ構成では、プロジェクト名と設定フォルダ名が同じ名前になってしまいます。
開発をする際に分かりづらいため、プロジェクト名と設定フォルダ名を別々の名前にする方法を記します。


## 説明
[Django公式tutorial](https://docs.djangoproject.com/ja/3.2/intro/tutorial01/)を例に手順を記載します。

## 公式tutorialの方法
公式tutorialに沿ってプロジェクトを作成します。

```
$ django-admin startproject mysite
```

作成されたプロジェクトのフォルダ構成は以下のようになります。
プロジェクト名と設定フォルダ名が同じで分かりづらくなってしまいます。


```
mysite  #　プロジェクトフォルダ
    ├── mysite  #　設定フォルダ
    │   ├── __init__.py
    │   ├── asgi.py
    │   ├── settings.py
    │   ├── urls.py
    │   └── wsgi.py
    └── manage.py
```


## プロジェクト名と設定フォルダ名を別々の名前にする方法

①プロジェクトフォルダを作成する
②第一引数に任意の設定フォルダ名、第二引数にプロジェクト名を指定してstartprojectをする。

```
$ mkdir mysite
$ django-admin startproject config mysite
```
'config'という設定フォルダ名でプロジェクト作成ができました。
フォルダ構成は以下の様になります。
[Django公式/startproject](https://docs.djangoproject.com/ja/3.2/ref/django-admin/#:~:text=If%20the%20optional%20destination%20is%20provided%2C%20Django%20will%20use%20that%20existing%20directory%20as%20the%20project%20directory%2C%20and%20create%20manage.py%20and%20the%20project%20package%20within%20it.%20Use%20%27.%27%20to%20denote%20the%20current%20working%20directory.)

```
mysite  #　プロジェクトフォルダ
    ├── config  #　設定フォルダ
    │   ├── __init__.py
    │   ├── asgi.py
    │   ├── settings.py
    │   ├── urls.py
    │   └── wsgi.py
    └── manage.py
```

## まとめ
設定フォルダ名を指定してプロジェクトを作成するには以下の手順でstartprojectをします。

①プロジェクトフォルダを作成する

```
$ mkdir <プロジェクト名>
```
②第一引数に設定フォルダ名、第二引数に①で作成したプロジェクト名を指定してプロジェクトを作成する。

```
$ django-admin startproject <設定フォルダ名> <プロジェクト名>
```
モデルスペックにおける超基本的なテスト（Postモデルver.）

RSpecのモデルスペックではバリデーションやインスタンスメソッドをテストします。
今回はバリデーションの中でも基本的な`presence: true`を取り上げてテストしてみました。


# 1. Postモデルのバリデーション確認

今回Postモデルにはcontentカラムが存在すること（`presence: true`）がバリデーションによって制限されています。

```post.rb
class Post < ApplicationRecord
  validates :content, { presence: true }
end
```

# 2. モデルの要件を満たせば有効であることをテスト


itで始まる行の中に`post`というインスタンスをnewメソッドで作成します。この`post`のcontentカラムには「あああ」という文字列が入っています。
そして`be_valid`というマッチャを用いて、作成した`post`が有効であることをテストします。

```post_spec.rb
require 'rails_helper'

RSpec.describe Post, type: :model do
  
  it "投稿内容があれば有効な状態であること" do
    post = Post.new(
      content: "あああ"
    )
    expect(post).to be_valid
  end
end
```



`bundle exec rspec`してみるとテストにが成功することが分かります。


# 3. モデルの要件を満たさなければ無効であることをテスト

今度はバリデーションが上手く機能しているか確認してみましょう！
contentカラムには`presence: true`というバリデーションを付与しているので、contentカラムに何も含まれていないとpostインスタンスは無効になるはずです

```post_spec.rb
require 'rails_helper'

RSpec.describe Post, type: :model do
  
  it "投稿内容、ユーザーidがあれば有効な状態であること" do
    post = Post.new(
      content: "あああ"
    )
    expect(post).to be_valid
  end

  it "投稿内容が無ければ無効な状態であること" do
    post = Post.new(
      content: nil
    )
    post.valid?
    expect(post.errors[:content]).to include("can't be blank")
  end
end
```

今回はインスタンスが無効であると、content属性にエラ〜メッセージが付いてくるという特性を利用して、バリデーションが機能していることをテストしました。
Geomagic Touch を使う

### VisualStudio2019
#### プロジェクト作成設定
MFCアプリ
ダイアログベース
共有DLLでMFCを使用する
　スタティックライブラリ使用だと「hdu.lib(hduError.obj) : error LNK2038: 'RuntimeLibrary' の不一致が検出されました。」のエラーになる
サイズ変更=OFF
最小化ボックス
Windowsソケット

#### プロジェクト環境設定
構成プロパティ
　詳細
　　文字セット

```
マルチバイト文字セットを使用する
```

　C/C++
　　全般
　　　追加のインクルードディレクトリ

```
$(OH_SDK_BASE)\include;$(OH_SDK_BASE)\utilities\include;
```

　C/C++
　　コマンドライン
　　　追加のオプション

```
/source-charset:utf-8 /execution-charset:utf-8
```

　リンカー
　　全般
　　　追加のライブラリディレクトリ

```
$(OH_SDK_BASE)\lib\$(Platform)\$(Configuration);$(OH_SDK_BASE)\utilities\lib\$(Platform)\$(Configuration);$(OH_SDK_BASE)\lib\$(Platform);
```
　　入力
　　　追加の依存ファイル

```
hd.lib;hdu.lib;Winmm.lib;version.lib;
```
#### Releaseビルド
下記のHaptic Device DriversとOpenHaptics for Windows Developer Edition v3.5をインストールしたPCなら、ReleaseBuildしたアプリを実行可能
### HDAPIConsoleExamples
AnchoredSpringForce
指定位置から離れるに従い反力が増える
Calibration
わからん
CommandJointTorque
指定位置から離れるに従い反力が増え、その時の押力を取得する
CommandMotorDAC
３軸モータ用DACに直接指示する、６軸のエンコーダ値・XYZ位置を取得する
ErrorHandling
エラーで振動を起こすのだが、わからん
FrictionlessPlane
水平面を上下方向から探る
FrictionlessSphere
球体表面を探る
HelloHapticDevice
領域内では指定位置から離れるに従い反力が増える
PreventWarmMotors
モーター温度を取得する
QueryDevice
XYZ位置を取得する
ServoLoopDutyCycle
サーボ周期を取得する
ServoLoopRate
サーボ周期を取得する
Vibration
ペンに振動を起こす

### Haptic Device
Touch
https://ja.3dsystems.com/haptics-devices/touch
Document
https://ja.3dsystems.com/haptics-devices/touch/documents
3D Systems Touch User Guide(PDF)
Haptic Device Brochure (English)(PDF)
### Haptic Device Drivers
3DSYSTEMS Geomagic Sculpt
Touch Device Driver v2021.9.21:
for Ethernet Touch or Touch X, and USB Touch or Touch X devices
紹介ページ
https://support.3dsystems.com/s/article/Haptic-Device-Drivers?language=ja
ドライバ自体
https://s3.amazonaws.com/dl.3dsystems.com/binaries/Sensable/driver/Touch_Device_Driver_2021.9.21.exe

### How do I download and get Developer Support for OpenHaptics

https://support.3dsystems.com/s/article/How-do-I-download-and-get-Developer-Support-for-OpenHaptics?language=en_US

### OpenHaptics for Windows Developer Edition v3.5
紹介ページ
https://support.3dsystems.com/s/article/OpenHaptics-for-Windows-Developer-Edition-v35?language=ja
ファイル自体
https://s3.amazonaws.com/dl.3dsystems.com/binaries/Sensable/OH/3.5/OpenHaptics_Developer_Edition_v3.5.0.zip

### Pairing
Touch Smart Setup を起動
![setup1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/436333/f2c26b56-63f8-5a0c-879d-2cd859799c54.png)
後ろ側にあるボタンを押す
![setup2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/436333/6c8259a5-4436-4f72-ef91-a137bc1d2065.png)
「Save Configuration」ボタンをクリックする、アプリが自動で終了する
Firebase Realtime Databaseで配列のデータを削除する(Vue.js)

#経緯
とある案件でFirebase Realtime Databaseを使用していたのですが、登録や取得は問題なくできたんですが削除だけがどうしてもわからず教えていただきました。
忘れないようにメモします。

#環境
`Vue.js: 2.6.14`
`firebase: 8.10.0`

#前提
データはこんな感じの配列です

```
hogehoge-default-rtdb
  - items
    - 0
        - itemCode: "1"
        - itemName: "あいてむ1"
        - などなど
    - 1
        - itemCode: "2"
        - itemName: "あいてむ2"
    - 2
        - itemCode: "3"
        - itemName: "あいてむ3"
```

itemCodeは一意です



#やりかた

```
async deleteItem(itemCode) {
  let targetIndex = "";
  // indexの取得
  await firebase
    .database()
    .ref("items")　　// itemsを取得する
    .orderByChild("itemCode") // itemCodeを持つ要素を並び替え
    .equalTo(itemCode) // itemCodeがoderByChildのitemCodeと一致するものを検索する
    .once("value", (snapshot) => {
      targetIndex = Object.keys(snapshot.val())[0]; // 削除対象のindexを取得
    });

  //削除の実施
  await firebase
    .database()
    .ref("items")
    .child(targetIndex) // 取得した削除対象のindexで検索
    .set(null) // 対象のデータをnullにする
    .then(() => {
      alert("消せたよん")
    });
    
``` 

---

できれば1処理で終わらせたいけどとりあえずこんな感じでできました。
もしもっといい書き方をご存知の方いらっしゃいましたら教えてください。
python で標準出力をリアルタイムに取得するときにハマった件

Python で何か外部コマンド(ffmpeg, vlc,...)を実行するとき、標準モジュールである subprocess を使うのが一般的かと思います。この時、標準出力をPythonプログラム内でリアルタイムに取得したいときは subprocess.Popen で非同期で実行し、その結果をキューなどでメインプロセス側に渡せばOKかと思いますが、ここでハマったので自分の備忘録がてら記事にしたいと思います。

### 環境
Ubuntu:20.04
Python:3.8

### やりたいこと

あるPythonメインプロセスを実行させながら、外部コマンド(ffmpeg, vlc, ..)の標準出力される結果をリアルタイムでPythonメインプロセスで読み込みたい。

### 一般的な方法

コード例

```
import subprocess
import multiprocessing
import time

def sub(queue):
    """サブプロセスで実行する処理"""
    cmd = ['ffmpeg', '-i', 'input.mp4', 'output.mp4']
    proc = subprocess.Popen(cmd, stdout=subprocess.PIPE)

    while True:
        # 標準出力を取り出し
        start = time.time()
        line = proc.stdout.readline()
        elapsed_time = time.time() - start
        print("stdout parse fps: ", 1/elapsed_time)
        queue.put(line)

def main():
    # プロセス間でやり取りするキュー
    queue = multiprocessing.Queue()
    p = multiprocessing.Process(target=sub, args=(queue, ))
    # サブプロセスを実行
    p.start()

    while True:
        line = queue.get()
        # 以下、何か処理を記述

main()
```

### 問題

上のコードを実行すると、例えば自分の環境では以下のような出力になります。

```
stdout parse fps: 0.3043587...
stdout parse fps: 2087535.7856...
stdout parse fps: 2038475.8047...
stdout parse fps: 2083567.7802...
stdout parse fps: 2384956.6805...
stdout parse fps: 0.3043587...
....
```

標準出力を行ごとに取得しているのですが、一定間隔である行の取得に時間がかかってしまいます。

### 原因

調べても同じような問題で困っている人は少なかったのですが、挙動的に内部のどこか標準出力の結果がバッファリングされているような感じでした。しかし、subprocess.Popenの引数でbufsizeというオプションがあったため、この数を調整しても変化なし。
さらに調べてみると、linuxコマンドで stdbuf という標準出力のバッファリングの長さを指定できるコマンドがあることを知りました。実行したいコマンドの前に stdbuf を付けるようです。

### 結論
subprocess で以下のようにして実行する

```
# 標準出力を行バッファリングとする
stdbuf_cmd = ['stdbuf', '-oL']
cmd = ['ffmpeg', '-i', 'input.mp4', 'output.mp4']
proc = subprocess.Popen(stdbuf_cmd + cmd, stdout=subprocess.PIPE)
```
配属後半年で確立されてきたCatch-upのスタイルに関して

#はじめに#
今回、開発経験のない方にオススメの開発知識のCatch-up方法を本記事でお伝えできればと思います。
自分自身も新卒で入社後、開発未経験ながらも開発配属となり、配属当初はCatch-upにかなり苦労した経験があり、そんな境遇にある人が他にもいるのではないかと考え、本記事の執筆に至りました。

この方法が合う人/合わない人がいらっしゃると思いますが、少しでもみなさんが抱えている悩みの解消に繋がれば嬉しいです。

#自己紹介#
今年の4月に新卒で入社し、現在は主にソフトウェアを運用するための環境構築をしたり、障害が発生した際のサーバーの状態を把握するための監視をしたりする部署に所属しています。私が所属しているチームでは、クラウドサービスの管理から社内用ツールの開発など幅広い技術に触れる機会があります。

大学は社会学部で、開発とは全く縁のないことを学んでおり、プライベートでもPCに触れる機会が多くはなかったため、開発に配属後はゼロベースからのスタートでした。
そのため、配属後はCatch-upに苦労しましたが、最近ようやく自分のスタイルを確立して効率的に理解できるようになってきたので、自分が意識していることをお伝えできればと思います。

#配属された当初の学習方法#
配属された当初は右も左もわからない状態で、知らないワードが出てきては検索し、説明が理解できず途方に暮れることが多々ありました。(ネットサーフィンに1日を費やすこともありました。。。)
その当時の自分のCatch-upスタイルは、闇雲にわからないことを調べ、そこで出てきた内容を丸々理解するという方法を取っていました。
コーディングに関しても求める結果に対して、なぜそのような処理をするのか理解せず、ただ実装することに夢中になっていました。(例えばjavaの連想配列に関する処理を調べてそのままコードを真似て実装するなど)

このようなスタイルを続けていた結果、自分が理解したつもりでいる知識にあまり納得感がなく、実践的で使えない知識ばかりが増えてしまいました。

調べてインプットしているはずなのに、なぜかあまりスッキリしないな〜みたいな感覚を持っている方は他にもいるのではないでしょうか？
まさしく自分もその状態に陥っていました。

#実践してよかった学習方法#
上記の通り、配属された当初はインプットに時間は費やしているけど、うまく理解できていないことが多々ありました。
しかし、配属されたグループでの仕事に携わる機会が増えていく過程で、自分のCatch-upのスタイルが確立されていき、スッキリと理解できることが増えてきました。

以下で自分がCatch-upの際に意識・実践している3つのことに関して説明していきたいと思います。

<h3>1. 仮説を立てながら取り組む</h3>
調べて出てきた情報を闇雲にインプットするのではなく、得られた情報を元に自分で改めて「これってこういうことなのかな？」という仮説を立てて自分がぶつかった疑問を改めて考え直してみる。このプロセスを踏むことで納得感を持った知識理解に繋がり、その知識もより実践的なものになります。
仮説を立てて再考した結果、納得して理解ができていればそれは自分の知識として消化できていると判断できるし、納得感があまり持てなければうまく消化できておらず、もう少し調べてみたり、周りの人に質問して聞いてみる必要があると判断することができます。

自分自身もこの仮説を立てて何かに取り組むということを意識的に実践することで、自分のぶつかった疑問に対する解像度がグッと上がりました！

<h3>2. 自分がCatch-upしたことを言語化してアウトプットしてみる</h3>
自分が理解したことを自分の言葉で改めて言語化することには様々なメリットがあります。

<h5>・何が理解できているのか、自分自身だけでなく周囲に知ってもらうきっかけになる</h5>
自分の理解を言語化して説明することで、周りの人もどんなサポートやどんな経験が必要であるのかイメージできるようになり、新人へのアプローチがしやすくなると思います。また、言語化の過程で「こんなこともできるよ」「これはこういうことなんだよ」などと+αの気づきが得られることも結構あります。

自分が開発に配属された当初、わからないことばかりで「もっと教えて欲しい」「もっとコミットして欲しい」と思うことが正直ありました。
しかし、試行錯誤を重ねたことで、ただサポートしてもらうことを期待するのではなくて、自分自身で周りの人がサポートしやすい環境や教えてもらうきっかけを作るということが新人として重要であると思います。
<h5>・自分の理解にズレがないかをチェックできる</h5>
自分の理解が実際にあるべき理解とズレている場合、他者に対して言語化することで事実とのギャップを知り、正しい知識へと修正を図ることができます。前の段階である程度言語化できていれば、正しい知識を即座に定着させることができます。(自分の体感では、一番定着するのはこのパターンだと思います。)

<h5>・知識の定着度が上がり、より実践的になる</h5>
自分が学んだことを他者が理解できるように説明することは簡単なように見えて、確実に理解できていないと意外と難しいことです。
反対にそれができれば、その過程で理解が深まっており、なお且つ言語化というアウトプットができているためそ、の知識は実践的なものに自ずとなっています。

周りの上司・先輩にぶつけてみるのはもちろん、理解できていない仲間に自分の言葉で説明してみることもお互いにメリットがあって良いと思います。(Qiitaの記事を書いて説明してみることも言語化としてはいいのではないかと思います！)

<h3>3. 知識を活用するための実践の場を作る</h3>
自分が積み重ねた知識を積み重ねただけで満足するのではなく、ゼロから実践してみることはCatch-upの最終ステップとして重要です。
例えば、コーディングであれば自分が学んだことを生かして何かを実装してみるなどが知識を生かした実践にあたります。

実際に自分の知識を生かして何かを実践してみることで、自分が学んだつもりでいるものが自分の知識としてものになっているのか、それとも実践的な知識になっていないのかを改めて確認することができます。また、実践の過程で新たな知識を得るきっかけになることもあるので一石二鳥の方法です。
また実践を通して得られる、「できるようになってる！」「わかるぞ！」という感覚は自分自身の自信やモチベーションのアップにも繋がります。

#まとめ#
自分が開発に配属されてからの試行錯誤の結果、実践してよかったCatch-upの方法に関して述べてみました。
本記事に記載した以外にも様々なCatch-upのスタイルがあると思いますが、Catch-upとセットで何らかの形でアウトプットすることを意識すると理解の質がグッと上がると思います。

こんな記事なんかを書いていますが、自分自身も開発経験の少ない未熟なエンジニアです。
「こんなスタイルもオススメだよ！」などがあれば是非教えていただきたいです！

この記事を読んでいただいた方に何か少しでも気づきがあれば嬉しい限りです。
わからないことだらけで、悩むこともありますがコツコツ、一歩一歩の成長を楽しんで頑張りましょう！！
Azure Recovery Services コンテナー の削除手順

削除できずに困っている人がいたのでメモ。

1. Recovery Services コンテナー -> プロパティ -> セキュリティ設定 -> 論理削除を無効化する
2. "Azure Backup soft delete functionality has been disabled" というメールが届く(特にアクションは必要なし)
3. Recovery Services コンテナー ->　バックアップアイテム -> Azure Virtual Machine を選択 -> バックアップアイテム一覧から対象のVMを選択 -> 三点リーダーボタンから"バックアップの停止"を選択 -> "バックアップデータの削除"を選択 -> バックアイテムの名前や理由を入力して "バックアップの停止" を実行
4. 3.が終了したら Recovery Services コンテナー を削除する
(git) submodule かつ LFS を使用している repository を clone する

以下の様な関係の状況で後述コマンドを使用することで、
repository A , B のファイルの実体を全て取得できる事を確認できた。

git repository A 
git repository B : (A の submodule。LFSを利用)

`git lfs clone --recurse-submodules <git repository A>`

参考: https://github.com/git-lfs/git-lfs/issues/2254
WebStorm の設定確認事項


## nodenv 利用時の IDE からの npm script の実行
IDE から npm script の実行すると以下の様な package manager が以見つからない旨のエラーがでます。

```
Error running 'lint': Specify a valid package manager: cannot find a binary file inside '/Users/<user>/.anyenv/envs/nodenv' directory
```

以下の対応を行うと正常に npm script をキックできるようになります。

- `npm -g install @nodenv/jetbrains-npm`
- package manager のパスを `echo $(npm -g prefix)/lib/node_modules/@nodenv/jetbrains-npm` の出力結果に変更する
    - ![webstorm1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/110482/dc50a5a0-6419-50d5-caa2-038cdb6bb670.png)

以下のブログを参考にさせて頂きました :pray: 

https://android.gcreate.jp/intellij_with_nodenv/

## ESlint
プロジェクトの設定を勝手に読み込んで format してくれます。

> 自動構成では、WebStorm はプロジェクト node_modules フォルダーの ESLint パッケージと、現在のファイルが保存されているフォルダーの .eslintrc.* 構成ファイルを使用します。現在のファイルフォルダーに .eslintrc.* が見つからない場合、WebStorm はプロジェクトルートまでの親フォルダーで .eslintrc.* を検索します。

https://pleiades.io/help/webstorm/eslint.html#ws_js_eslint_automatic_configuration
ReactからRailsAPIにクッキーを送るときにはまった話

#概要
今日はReactからRailsAPIにクッキーを送信する際にはまったことがあるのでそのときにどう対処したかを簡単に説明します。フロントエンド側は簡単だったのですが、バックエンド側の方の記述に手間取ったのでメモしておきます。
cors (closs origin resourse sharing)のエラーがずっと出てしまっていました。API通信にはaxiosを使用しております。

#フロントエンド
（例）

```typescript
axios.post(
        'http://localhost:3001/users',
        answers,
        { withCredentials: true},
)
```

このようにしてaxiosの引数を一つ追加して、```{ withCredentials: true}```とするだけで良いです。
実際にCookieが送れてているかどうかはGoogleChromeの検証モードで確認できます。
[こちらの記事](https://qiita.com/ykkamm/items/258bac725f118826c295 "Qiita article")を読んでみてください。

#バックエンド
corsのエラーがこのままだと出てしまうので、バックエンド側の編集も必要になります。
cors.rbのresourseの部分に```credentials: true```の記述を追加してください。
（例）

```ruby
#略
allow do
      origins 'http://localhost:3000'
  
      resource '*',
        #略
        credentials: true（この行を追加してください）
end
#略
```

これを追加するとcorsのエラーが出ないようになりました。

#余談
個人的にかなり時間がかかった部分なので、記事にしてみました。
同じことで困っている人がいたら参考にしてみて欲しいです。
CompositionAPIに対応したライブラリ「VueUse」を使ってみる

Vue関連の便利なプラグインは数多ありますが、Vue.js3を学習しているときにCompositionAPIに対応したライブラリを見つけたので試してみました。
# VueUseとは
VueUseはCompositionAPIに対応したさまざまな関数を用意しているライブラリです。
アニメーションやステート管理など便利な機能を簡単に実装することができます。
CompositionAPIのライブラリですがVue2でも使うことができます。

# さっそく使ってみる

環境
npm : 7.15.1
node: v14.16.1
vue: 3.2.24
VueUse: 7.2.2

## インストール
**npm**

```
npm i @vueuse/core
```

**CDN**

```
<script src="https://unpkg.com/@vueuse/shared"></script>
<script src="https://unpkg.com/@vueuse/core"></script>
```

今回はnpm を使ってインストールしましたがCDNで手軽に使うこともできます。
インストールが完了したら使いたい関数を`import {〇〇} from '@vueuse/core'`でインポートすれば使えるようになります。
## useMouseで座標を取得する
```js:App.vue
<template>
  <img alt="Vue logo" src="./assets/logo.png" />
  <div style='text-align: center'>
    <UseMouse>
      x: {{ x }}
      y: {{ y }}
    </UseMouse>
  </div>
  
</template>

<script>
import { useMouse } from '@vueuse/core'

export default {
  name:'App',
  setup() {
    const { x, y, source } = useMouse()
    return { x, y, source}
  }  
}
</script>
```

1行の記述だけでマウスの座標を取得できました。

![ezgif.com-gif-maker.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/625911/9ccff06e-ebe5-9ff5-de02-61df1242f2d6.gif)

## syncRefでソースとターゲットを同期させる
```js:HelloWorld.vue
<template>
  <img alt="Vue logo" src="./assets/logo.png" />
  <div>
    <input v-model="source" placeholder="Source" type="text">
    <input v-model="target" placeholder="Target" type="text">
  </div>
</template>

<script>
import { ref } from 'vue' 
import { syncRef } from '@vueuse/core'

export default {
  name:'App',
  setup() {
    const source = ref('')
    const target = ref('')
  
    const stop = syncRef(source, target)

    source.value = 'hogehoge'
    console.log(target.value)
  
    return { source, target }
  }  
}
</script>
```

ターゲットのrefsをソースのrefsと同期させているのでソースの文字列を変えるとターゲットの文字列も変わりますが逆の場合は変わりません。
![ezgif.com-gif-maker (1).gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/625911/23ece94b-795b-e7c8-9ff4-765f4ddc6cdd.gif)

## useElementSizeで要素のサイズを取得する

```js:App.vue
<template>
  <img alt="Vue logo" src="./assets/logo.png" />
  <HelloWorld>
    Width: {{ width }}
    Height: {{ height }}
  </HelloWorld>
</template>
```

```js:HelloWorld.vue
<template>
  <div ref="el">
    Height: {{ height }}
    Width: {{ width }}
  </div>
</template>

<script>
import { ref } from 'vue'
import { useElementSize } from '@vueuse/core'

export default {
  setup() {
    const el = ref(null)
    const { width, height } = useElementSize(el)

    return {
      el,
      width,
      height,
    }
  }
}
</script>
```
 HTML要素のサイズをリアクティブに取得してくれます。

![ezgif.com-gif-maker (2).gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/625911/f60fbc84-0d34-f68d-22ce-48be8e927986.gif)


# おわりに
 VueUseは1行記述するだけで実装できてしまう機能も多く本当にお手軽に使えるライブラリだと思いました。CompositionAPIに基づくライブラリなのでまだリリースされてから日が浅いですが公式ドキュメントが充実していてデモを触ってみることもできるので見ているだけでも面白いです。
先日v.7.3.0がリリースされuseElementByPointなど新しい関数が追加され、使える機能が日に日に増えているのでこれからも追って見ていこうと思います！
【統計学】区間推定を行う上での勘所

# １. まえがき
区間推定（特に母平均）を行う上での勘所をメモとしてまとめようと思う。

# ２. 95%信頼区間の意味
$×$「推定した区間に95%の割合で母数が含まれる」
　→母数は定数なので、その推定区間に含まれるか含まれないかは、一意に決まる。
$〇$「母数の推定を100回行ったとき、95回はその推定区間に母数が含まれる」

# ３. 母平均の区間推定の注意点

母平均の区間推定を行うと、95%信頼区間は以下の不等式で表現できる、という表記をよく見る気がする（当社比）。

```math
\bar x - 1.96 \frac{\hat\sigma}{\sqrt n} \leq \mu \leq \bar x + 1.96 \frac{\hat\sigma}{\sqrt n}

```
ここで、$\mu$は母平均で、$\bar x$は標本平均であり、$n$はサンプルサイズである。そして、 $\hat\sigma$は母標準偏差の推定値であり、不偏分散平方根を代入する。

この評価式の成立ために、1つの仮定と1つの近似が要求されることを覚えておく必要がある。

## 　３.１. 仮定：標本平均の分布が正規分布に従う
母平均を上下から評価するのに、標本平均の分布が$N ( \mu , \frac{\sigma ^2}{n} ) $に従うことを利用している。このような分布が実現するためには、母集団が正規分布であるか、もしくは、サンプルサイズ$n$が中心極限定理が成立するぐらい大きい必要がある。

## 　３.２. 近似：母標準偏差は不偏分散の平方根
母標準偏差は、次式のように不偏分散の平方根として点推定して与える。

```math
u = \sqrt \frac{s^2}{n-1} \rightarrow \hat\sigma
```
※$u$が不偏分散の平方根で、$s^2$が偏差平方和である。




よく見る区間推定の評価式には、これらの仮定と近似があることを注意されたい。

## 　３.３. 補足（t分布について）
母集団分布が正規分布のとき、②の近似を行わずに$t$分布を用いて、母平均を評価する方法がある。
近似を無くすために素直に考えると、もし母標準偏差（もしくは母分散）の情報なしに、標本から計算できる値のみで母平均を評価できたらとは、思わないだろうか。

ここで、$t$分布に関する一つの命題を提示しよう。

「$N(\mu , \sigma ^2)$に従う正規母集団から、大きさ$n$の標本を無作為抽出し、標本平均$\bar X$、標本分散$U^2$をつくると（※確率変数は大文字にしている）、

```math
T=\frac{\bar X -\mu}{\sqrt{\frac{U^2}{n}}}
```
は自由度$n-1$の$t$分布 $(f_{n-1}(t))$に従う。
ただし、標本分散$U^2$は、

```math
U^2 = \frac { \Sigma \left( X_i - \bar X \right)^2 }{n-1}
```
不偏分散として定義する」

確率変数$T$の格好を見てもらえばわかるが、これは、標準化した標本平均$Z = (\bar X -\mu) / (\sqrt{\frac{\sigma^2}{n}})$の母分散を不偏分散に置き換えた形をしている。そのため、$T$の形は覚えやすいのではないのだろうか。

母平均と標本平均・分散の関係を示すこの命題を用いることで、母分散が未知のままで区間推定が可能になる。
そして、この区間推定に用いる$t$分布は、その性質として、$f_n(t) = f_n(-t)$という対称性を持ち、その形状が正規分布のような対称な山形になることが知られているので、正規分布をもとにした場合と全く同様の方法で、母平均の区間推定ができる。

95%信頼区間の幅は、自由度に依存するが、例えば $n=10$では、

```math
\bar x - 2.228 \sqrt \frac{得た不偏分散}{10} \leq \mu \leq \bar x + 2.228 \sqrt \frac{得た不偏分散}{10}

```
と計算される。

$t$分布の表はこちらを参考にしてほしい。
[20-2. t分布表 from 統計学の時間](https://bellcurve.jp/statistics/course/8970.html)

# ４. 最後に
統計学、変数の命名方法も難しいですよね。
間違い等ビシバシご指摘ください。
anyenv 経由で nodenv を導入した環境で新しい node.js を使う

# はじめに
https://qiita.com/ucan-lab/items/ce35bcaf2562054917a8

上記記事に体変お世話になりました。
(当記事では新しい node.js の利用にフォーカス)

また、公式docは[こちら](https://github.com/nodenv/nodenv)

# 前提
- any env 経由で nodenv が入っている
- `nodenv install -l` しても、欲しい最新の node.js のバージョンが出てこない

# 手順
- anyenv-update の plugin を入れてアップデート
    - `mkdir -p $(anyenv root)/plugins`
    - `git clone https://github.com/znz/anyenv-update.git $(anyenv root)/plugins/anyenv-update`
    - `anyenv update`
- `nodenv install -l` で新しい node.js のバージョンを確認する
- 対象のバージョンを install する
    - ex. `nodenv install 16.13.0`
- `nodenv versions` で install 結果を確認
- `nodenv global <バージョン>` で切り替える
    - ex.`nodenv global 16.13.0`
- `nodenv versions` で適用結果を確認
Unityのマウスイベント - 簡単ポップアップ

Unityのマウスイベントでクリック押しっぱなしの処理や、ドラッグアンドドロップの処理とかがいろいろ簡単にできますが、
特に自分がよくやるポップアップの実装を作ってみます
こんなの
![3984100000.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/689266/8dc73da3-e2f5-229d-c9b1-37892fd74f45.gif)
見出しだけのテキスト書いて長い説明はポップアップでとかやるといいと思います

準備
---
必要なものは、
・オブジェクトの領域内にマウスが入った・出たの判定
・ポップアップの表示非表示
これらの組み合わせで実装できそうです

まずは、オブジェクトの領域内にマウスが侵入したかどうかの判定をします

`PopUpTest`という名前でスクリプトを作りました
デフォルトのMonobehaviourのほかに、`IPointerEnterHandler`,` IPointerExitHandler`というのを継承させます
わからなくてもとりあえずその通り書いておいてください
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/689266/aacdff49-b45c-924b-9dcb-3fee0d47929f.png)
エラーが出ているので解消します
上の名前空間に、`using UnityEngine.EventSystems;`を追加しておきましょう
さらに、`IPointerEnterHandler`にカーソルを合わせると
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/689266/3885c364-4fb2-a151-e128-954705c9402b.png)
と出るので、<font color=blue>考えられる修正内容を表示する</font>をクリック 
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/689266/29e32244-c156-c188-c451-06e4ff99b798.png)
インターフェイスを実装します クリック
すると、勝手にコードを書いてくれてエラーもなくなります
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/689266/bb1a0b77-9770-d627-cb30-c4d322df91b6.png)
中の`throw new System.NotImplementedException();`は消してしまって、
もうひとつの` IPointerExitHandler`の方も同じようにインターフェイスを実装まで進めましょう

こんなようになれば大丈夫です
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/689266/ab3c6e9b-bcbe-b370-0e74-17aa8eedfdba.png)

---

この時点で、このPopUpTestスクリプトをButtonやImageなどのUIオブジェクトにアタッチすると、マウスの侵入判定ができています
が、わかりやすく確かめるためにテキストで表示させるようにしましょう
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/689266/233073d6-0918-a678-12de-6e11e90c6f08.png)

unityエディタの方ではImageと、その子にTextを設置
PopUpTestスクリプトはImageにアタッチし、インスペクターのTextにヒエラルキーのTextをアタッチ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/689266/0f74cf2c-0c85-b8f7-f134-0fee70ce87ea.png)
うまくいってるとこうなると思います
![39841000.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/689266/48edaafe-1835-af0f-2ade-e325509c3ba2.gif)

---
マウスの判定ができたので、あとはマウスが入ってきたときと出ていったときに、それぞれポップアップの表示非表示を書けば良いわけです
先にシーンの方を作ってみると、こんな感じでいいと思います
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/689266/803ec604-f2ef-5b90-0e5a-418afb3618f9.png)
中に入れるコードは、
PopUpのオブジェクトをGameObjectで宣言して、SetActiveで制御すれば良いと思います
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/689266/57a3fabe-1ee0-3dcf-4f12-638ee2e9ae5a.png)
これで完成です
(動いてるのは一番最初のgifと同じなので割愛)
「DeepL API 使い方」で検索したけど結局わからなかったあの日の僕へ

# 結局どう書けばいいんでしょうか

こう思ったことはないでしょうか。

使い方を調べてもなんか難しいことばかり出てきてよくわからない

ましてphpとかpythonとか言われましても。。

こっちはHTMLとCSSとJSしかできないんですが！！！

なんかもうコピペするだけで使えるやつください！

# これです

<p class="codepen" data-height="300" data-default-tab="html,result" data-slug-hash="JjrbaLx" data-user="rechili" 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/rechili/pen/JjrbaLx">
  DeepL API Code Sample</a> by rechili (<a href="https://codepen.io/rechili">@rechili</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>

あとは頑張れ！！

---

アライドアーキテクツでは月1回程度のペースでエンジニア採用を目的とした Meetup を行っています！
開催時期によって対象者が変わるのですが、今回の開催は2023年の4月入社になる方が対象です！（文理・学歴不問）
HTML&CSSしか書いたことないという方でも大歓迎です！

https://www.wantedly.com/projects/676498
[.NET5] 出力フォルダの中に「net5.0-windows」フォルダができないようにする

もくじ

https://tera1707.com/entry/2022/02/06/144447

# やりたいこと

ビルドしたときにコンフィグ名(Debug/Release等)のフォルダの下に「net5.0-windows」というフォルダができる。(.netFrameworkのときにはなかった)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/352601/247712ca-80ad-8474-abe0-0627c88e2ef0.png)

これを、.netFrameworkと同じように、「Debug」フォルダのすぐ下に出るようにしたい。

# やり方

下記の2行を、csprojフォルダに設定を追記する。

```
    <AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>
    <AppendRuntimeIdentifierToOutputPath>false</AppendRuntimeIdentifierToOutputPath>
```

全体としては、下記のようになる。

```
<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <OutputType>WinExe</OutputType>
    <TargetFramework>net5.0-windows</TargetFramework>
    <UseWPF>true</UseWPF>
	<EnableDefaultApplicationDefinition>false</EnableDefaultApplicationDefinition>
    <AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>★これ★
    <AppendRuntimeIdentifierToOutputPath>false</AppendRuntimeIdentifierToOutputPath>★これ★
    <Platforms>AnyCPU;x64</Platforms>
  </PropertyGroup>

  <ItemGroup>
    <ApplicationDefinition Remove="App.xaml" />
  </ItemGroup>

</Project>
```

下記のように「net5.0-windows」フォルダがなくなって、一段上がる感じになる。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/352601/5b10d22e-f37e-2077-8227-d37b209b6af4.png)


# 参考

MS公式

https://docs.microsoft.com/ja-jp/visualstudio/ide/how-to-change-the-build-output-directory?view=vs-2022

上記ページのコレ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/352601/4417f043-71e5-b412-af94-24efa9579811.png)


MS公式
csprojに設定できる内容一覧

https://docs.microsoft.com/ja-jp/dotnet/core/project-sdk/msbuild-props
MacOS で pyenv が PATH をちゃんと通してくれない時

# 環境

- macOS Big Sur 11.6
- Homebrew 3.3.7
- pyenv 2.2.2
- MacBook Air (M1, 2020)

# 現象

```shell
brew install pyenv
```

で `pyenv` を入れた後，

```shell
pyenv install miniforge3-4.9.2
```

とかで入れた `python` が起動できない

# 対策

実は https://github.com/pyenv/pyenv に記載されていることなのだが，

```shell
eval $(pyenv init --path)
```

という1行が，

```shell
eval $(pyenv init -)
```

の前に必要になったようだ．
こうすることで，`PATH` に `$HOME/.pyenv/shims` が追加され，正常に動作する．

わりと最近の記事を見ても，`--path` の行を入れてないものが多かったりするので注意．