OmniAICreator/Qiita-1.07M huggingface dataset:
UserLAndのsshをパスワード無しで使えるようにする

# お知らせ

UserLAnd3.0からandroid端末からsshログインするのにパスワードが不要になりました。

# 概要

- UserLAndでsshを使うと必ずパスワードを要求される
- 同じ端末内でパスワードが必要なのは面倒すぎるので改善方法を考えてみた

# パッチ

- ソースコードの修正が必要そうだったのでパッチを作成

https://github.com/yas99en/UserLAnd/commit/48add3c75fa53a0fb7df19c40e69b23f21a270ec#diff-d09f5fd256f91bc472d526d63bda8538da0190b99488ddf5fea414823ae405e2

# バイナリ

前回の投稿でかいたctrl-space-workaround

https://qiita.com/yas99en/items/22d58deaf1ddaa38819a

も含めたバイナリを作成、以下からダウンロード可能

https://github.com/yas99en/UserLAnd/releases/tag/v.2.7.3-yas99en-1

# 使い方

- .sshの作成（無ければ）

```text
$ mkdir ~/.ssh
$ chmod 700 ~/.ssh
```

- 鍵の作成とauthorized_keysへの登録

```text
$ cd /data/data/tech.ula/files/home/
$ mkdir .ssh
$ chmod 700 .ssh
$ cd .ssh
$ dropbearkey -t rsa -f id_dropbear | grep "^ssh-rsa " > id_dropbear.pub
$ cat id_dropbear.pub >> ~/.ssh/authorized_keys
```
- これで次回、起動時からノーパスワードで入れる

# パッチに至るまでの話

- UserLAndではsshサーバー・クライアントの実装としてdropbearを採用している 
- dropbear: https://matt.ucc.asn.au/dropbear/dropbear.html
- バージョンは v2017.75
- ソースコードを読む限りは、drobbearのクライアント（dbclient）は getpwuidでホームディレクトリを特定して~/.ssh/id_dropbearを読んでいるが、実際には使われない
- 可能性としては、いくつか考えられるが理由はわからなかった
  - getpwuidが機能していない
  - 読み取ったホームディレクトリが/data/data/tech.ula/files/home/以外になっている
  - .sshやid_dropbearのオーナーが適切でない
  - UserLAndのdropbearに修正が加えられている
- パッチは単純に dbclient -i 秘密鍵ファイル としているだけ。
製造業　設備保全におけるIoT導入は難しいという話

#前提　私とIoTについて
　10年ほど製造業工場の設備保全として勤務。修理屋としていかに早く壊れた設備を直すか、再発させないようにするか、上司が納得する報告書を書くのかに苦心しながら勤務。要は、機械を使っている現場や上司に怒られないように働いていた。
　今年、IoT推進部署へ異動。「勉強してこい」と上司には言われたが、「IoT」については製造業の隣にはいるだろうけど、その中身については全くわかっていない状態。つまり、日々の業務に追われ、興味があり勉強しようと思ってもできない状態だった。これにはやる気がないだけだろうという意見もあると思うが、目の前で壊れている機械を無視して、将来役に立つかもしれないIoTの勉強をさせてくださいと、言うことはできるのだろうか。そんなことをするよりとにかく早く機械を動かしたほうが評価は上がるのだ。つまり今までは、IoTについて勉強する必要がなかった。

　今回、幸か不幸か、会社員にとって避けられない異動によって、半ば強制的にIoTを勉強する機会を得た。勉強すると意外とIoTの世界は面白く、奥深く、そして製造業にとって根が深いことを知った。その情報を整理し、わかりやすくまとめたい。
#目的
・自分の考えをまとめるメモ
#IoTとは何か？
実はこの概念について纏めることについても、難しさを感じている。今やgoogleの検索画面で「IoT」とたたけば、「Internet of Things（モノのインターネット）」のことだよ、と数秒で出てくる。なるほど、そうか。じゃあそれは一体、どういうことなんだ？
インターネットのホームページは、懇切丁寧に解説してくれる。なるべく簡単に説明しましょう。フムフムなるほど、私は理解した気になる。インターネット経由でモノ同士が繋がることなんだ。へえ、こんなこともできるんだ。事例も含めれば、さらに理解を深めることができる。
その時は気づいていなかったが、調べれば調べるほど、そして職場の現状を知るほど、IoTはただのツールに過ぎないことがわかる。
IoT＝即座に職場の何かが改善する　わけではない。決して。今まで修理で使ってきた工具が、カタチの見えにくいソフトウェアとして導入できますよ、ということだと感じている。その工具の種類はとんでもなく多く、得ることのできる恩恵もでかいが、当然その分壁もある。
#導入の難しさ
なるほど、「IoT」の概要についてはわかった、と私は思う。それを上司に説明すると、上司はわかった、という顔をする。そして次に上司は言う。__じゃあ、導入して。__
実はここで既に難題が一つある。それは導入する場所の「ニーズ」の把握だ。
言いかえれば「困りごと」、「ウィークポイント」、「改善点」様々な概念があると思うが、重要なことはその導入する場所にとって「必要」かどうかだと思っている。
人から聞いた話や、過去の話、そして実体験として、その職場において__必要ない物は定着しない__。要するに何か改善をやって、その時は何かしらの評価を得たとしても、その後定着せず結局意味なく終わることは多い。それは保全における所謂「改善活動」で、山ほど見てきた。

・取り付けられたセンサーの値、見ても記録も何もしていないため意味がない
・定期的に行うはずの作業、やらなくてもバレないし、やる必要ない。やらないことで責任を問われることもない
・改善された形状の部品、その部品が壊れたら誰も知らないため改善前の部品が取り付けられる

IoTも導入する際、最も大事にしなければならないのはこのニーズ、必要性だ。その場所で何が一番困っているのか（問題点）を正確に把握し、それに対しIoTを効果的に導入する必要がある。
#じゃあ何に困っているのか
それがわかれば苦労しないし、聞く人物によってその内容は当然異なる。立場によっても違うし、データから得られる事象も切り口が多すぎて特定できない。例えば修理ひとつとっても、件数を重視するのか、時間を重視するのか、間隔を重視するのか。では正常な状態は？　基準は？　どの問題が一番問題なのか、その評価方法は？
製造業には様々な指標が存在するが、実は最初にやっていることはその指標の把握からである。IoTとは結局、問題解決のための一つの方法に過ぎず、普段製造業の工場で行われていることの延長線上にあるに過ぎない。
#今後
まだこの異動は始まったばかりである。が、さすがにアウトプットを出せなさ過ぎて焦っているところもある。すでに異動から3ヵ月は経過しているが、この問題点と取り組む内容を決めるのでいっぱいいっぱいだった。
通常、上司か自分に何か明確な「やりたいこと」があればこういった問題は発生しないだろう。これまでの自分の問題提起意識のなさを反省している。

ゆえに、この「Qiita」という環境において、この記事をアウトプットらしきものにしてお茶を濁したい
AtCoder Beginner Contest 205


##[A - kcal](https://atcoder.jp/contests/abc205/tasks/abc205_a)

O(1)

```C++:C++
#include <bits/stdc++.h>
 
#define rep(i,n) for(int i=0; i<(n); ++i)
#define fixed_setprecision(n) fixed << setprecision((n))
#define execution_time(ti) printf("Execution Time: %.4lf sec\n", 1.0 * (clock() - ti) / CLOCKS_PER_SEC);
#define pai 3.1415926535897932384
#define NUM_MAX 2e18
#define NUM_MIN -1e9
 
using namespace std;
using ll = long long;
using P = pair<int,int>;
template<class T> inline bool chmax(T& a, T b){ if(a<b){ a=b; return 1; } return 0; }
template<class T> inline bool chmin(T& a, T b){ if(a>b){ a=b; return 1; } return 0; }

int main() {
    double A, B;
    cin >> A >> B;

    cout << (B / 100.0) * A << endl;

    return 0;
}
```

##[B - Permutation Check](https://atcoder.jp/contests/abc205/tasks/abc205_b)

O(N)

```C++:C++
#include <bits/stdc++.h>
 
#define rep(i,n) for(int i=0; i<(n); ++i)
#define fixed_setprecision(n) fixed << setprecision((n))
#define execution_time(ti) printf("Execution Time: %.4lf sec\n", 1.0 * (clock() - ti) / CLOCKS_PER_SEC);
#define pai 3.1415926535897932384
#define NUM_MAX 2e18
#define NUM_MIN -1e9
 
using namespace std;
using ll = long long;
using P = pair<int,int>;
template<class T> inline bool chmax(T& a, T b){ if(a<b){ a=b; return 1; } return 0; }
template<class T> inline bool chmin(T& a, T b){ if(a>b){ a=b; return 1; } return 0; }

int main() {
    int N;
    cin >> N;

    vector<int> A(N);
    rep(i, N) cin >> A[i];

    sort(A.begin(), A.end());

    int res=1;
    rep(i, N){
        if(A[i] != i+1){
            res=0;
            break;
        }
    }

    if(res) cout << "Yes" << endl;
    else cout << "No" << endl;

    return 0;
}
```

##[C - POW](https://atcoder.jp/contests/abc205/tasks/abc205_c)

O(1)

```C++:C++
#include <bits/stdc++.h>
 
#define rep(i,n) for(int i=0; i<(n); ++i)
#define fixed_setprecision(n) fixed << setprecision((n))
#define execution_time(ti) printf("Execution Time: %.4lf sec\n", 1.0 * (clock() - ti) / CLOCKS_PER_SEC);
#define pai 3.1415926535897932384
#define NUM_MAX 2e18
#define NUM_MIN -1e9
 
using namespace std;
using ll = long long;
using P = pair<int,int>;
template<class T> inline bool chmax(T& a, T b){ if(a<b){ a=b; return 1; } return 0; }
template<class T> inline bool chmin(T& a, T b){ if(a>b){ a=b; return 1; } return 0; }

int main() {
    ll A, B, C;
    cin >> A >> B >> C;

    if(C%2==0){
        if(A*A<B*B) cout << "<" << endl;
        else if(A*A>B*B) cout << ">" << endl;
        else cout << "=" << endl; 
    }else{
        if(A<B) cout << "<" << endl;
        else if(A>B) cout << ">" << endl;
        else cout << "=" << endl; 
    }

    return 0;
}
```
streamlitでダウンロードリンクを作る

2021年4月現在、file_uploaderはあるのですがダウンロードボタンはないので自分で作る必要があります。

## DataFrameの場合

`df`というDataFrameをCSVにしてダウンロードさせます。

```py
import base64
csv = df.to_csv(index=False)  
b64 = base64.b64encode(csv.encode()).decode()
href = f'<a href="data:application/octet-stream;base64,{b64}" download="result.csv">download</a>'
st.markdown(f"ダウンロードする {href}", unsafe_allow_html=True)
```

## 汎用化した関数

```py
import os
import base64

def file_downloader(filename, file_label='File'):
    with open(filename, 'rb') as f:
        data = f.read()
    
b64 = base64.b64encode(csv.encode()).decode()
href = f'<a href="data:application/octet-stream;base64,{b64}" download="result.csv">download</a>'
st.markdown(f"ダウンロードする {href}", unsafe_allow_html=True)
```


### 参考
[How to download file in streamlit](https://discuss.streamlit.io/t/how-to-download-file-in-streamlit/1806/17)
【Vue.js】vue-routerの動的URLでパラメータが変わった時、ライフサイクルフックは呼ばれないので注意

## はじめに
仕事で使う事になったので1からVue.jsについて学んだ。
ちゃんと覚えておかないとまずそうな事を備忘録として1つ1つ残しておく。

## vue-routerの動的URLでパラメータが変わった時、ライフサイクルフックは呼ばれないので注意
### vue-routerの動的URLとは
以下のように`/users/`に続く任意の文字列のURL（URLパスの`:id`の部分がそれ）である場合に、その時にあるコンポーネントを表示させるような設定の事。

```js:router.js
import Vue from 'vue';
import Router from 'vue-router';

import Home from './views/Home.vue';
import Users from './views/User.vue';

Vue.use(Router);

export default new Router({
    mode: 'history',
    routes: [
        { path: '/', component: Home },
        { path: '/users/:id', component: Users }
    ]
});
```

### vue-routerの動的URLでパラメータが変わった時、ライフサイクルフックは呼ばれないので注意
上記の[動的URL](#vue-routerの動的URLとは)を用いている時、Vue.jsが持つライフサイクルフックが呼び出されない。つまり、Vue.jsはコンポーネントそのもの（Vueインスタンス）は変化していないと認識する。

このような場合に、URLが切り替わったタイミング（パラメータが変わった時）に何かしらの処理を実行させたい場合には、`watch`を用いる。
![ezgif.com-gif-maker (28).gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1372684/b6fecd6f-e86b-cb9d-e846-c5b17701afed.gif)
動画のソースコードは以下。

```vue.Users.vue
<template>
  <div>
    <h3>Users</h3>
    <router-link to="/users/1">ユーザ１</router-link>
    <router-link to="/users/2">ユーザ２</router-link>
    <hr />
    <h1>User No. {{ $route.params.id }}</h1>
  </div>
</template>

<script>
export default {
  created() {
    console.log("created");
  },
  watch: {
    $route(to, from) {
      console.log("$routeのwatch");
      console.log(to);
      console.log(from);
    },
  },
};
</script>
```

ソースコード全体は以下。

https://github.com/yuta-katayama-23/intro-vuecli/commit/acc7728a68450e6804d6933606fe1ade239bd896

## Vue.jsの勉強メモ一覧記事へのリンク
Vue.jsについて勉強した際に書いた勉強メモ記事のリンクを集約した記事。

- https://qiita.com/yuta-katayama-23/items/dabefb59d16a83f1a1d4
データ活用を促進するスゴ素晴らしいOSS、Streamlitを紹介する。

# はじめに
OSSの[Streamlit](https://github.com/streamlit)が非常に有用でしたので紹介したいと思います。

# 何ができるか
[こちら](https://www.streamlit.io/)をご覧ください。
pythonを書くだけで、PowerBIやTableau、Grafanaでつくるようなダッシュボードをつくることができます。
作成物がコードなので、Gitでコード管理できるのも良いですね。

# どうやって作るか
素晴らしい時代になりました。
YoutubeにStreamlit公式の[解説動画](https://www.youtube.com/watch?v=B2iAodr0fOo)があります。
これを確認しながら、手を動かしましょう。
Streamlitの環境構築方法は、[こちら](https://qiita.com/hiyasichuka/items/68373957bd021435a4a0)を参考にしてみてください。


# おわりに

製造業の現場はパッケージやツールに合わせて業務を遂行するのが非常に苦手な印象を受けます。
したがって、高額で高機能なツール(SAP,Tableau,Salesforceなど)は、浸透させるハードルが高く、宝の持ち腐れになりがちです。
こういったOSSを活用し、必要最小限の機能でシンプルなモノをつくって業務改革を進めるのが良いかもしれません。
（OSSならではの難しさ、サポートの問題などはありますが）

以上です。
製造業のデータ分析で役に立つpandasを使った時系列データ集計加工

# はじめに

製造業の分野でデータ分析する際、製造プロセスデータ（例えば、温度や流量などの計装機器のデータ）を扱うことになろうかと思います。
そうした際、１分単位などの粒度の細かいデータは、レコード数が膨大で扱いづらいです。
そこで、pandasと呼ばれるpythonのライブラリを利用することで、簡単にデータ集計加工して、レコード数を削減することができます。

# サンプルコード

例えば以下のようなcsvファイルを扱う場合

```csvs:１分周期のプロセスデータ.csv
計測日時 ,温度 ,流量
2021/05/13 09:01:00 ,28.09 ,300
2021/05/13 09:02:00 ,29.02 ,200
2021/05/13 09:03:00 ,29.02 ,200
```

このようにpandasを活用することで、時間単位や期間指定、平均値や最大最小値の算出ができます。

```python
import pandas as pd
FREQ_HOUR='8h' # 集計時間
FILE_PATH = './１分周期のプロセスデータ.csv' # csvファイルパス
df = pd.read_csv(FILE_PATH, index_col=0, parse_dates=True) # csv読み込み インデックス指定とインデックス列をdatetime型変換
df = df['2021-05-01':'2021-05-15'] # 期間指定
df_mean = df.groupby(pd.Grouper(freq=FREQ_HOUR)).mean() # 平均値
df_max = df.groupby(pd.Grouper(freq=FREQ_HOUR)).max() # 最大値
df_min = df.groupby(pd.Grouper(freq=FREQ_HOUR)).min() # 最小値
```


以上です。
画像のレスポンシブ対応まとめ

## jQueryで切り替える
### メリット
* どのブラウザでも機能する

### デメリット
* レスポンシブ対象の画像ファイル名の語尾を統一する必要がある。（sample01-pc.jpg,sample02-pc.jpgなど）
* PC,スマホの２種類以上のブレイクポイントで切り替える場合、jQueryの条件分岐と画像が増える。（管理が面倒）
### 対応方法

```index.html
<img src="./sample01_pc.jpg" alt="レスポンシブ対象" class="reseponsive_image">
<img src="./sample02.jpg" alt="レスポンシブ非対象">
<img src="./sample03_pc.jpg" alt="レスポンシブ対象" class="reseponsive_image">
```

```index.js
// レスポンシブ対応する画像（共通のクラス名にする）
var $img = $('.reseponsive_image');
var sp = '_sp.';
var pc = '_pc.';
var spWidth = 600; //ブレイクポイント指定
 
function imageSwitch() {
    var windowWidth = parseInt($(window).width());
    $img.each(function () {
        var $this = $(this);
        if (windowWidth >= spWidth) {
            $this.attr('src', $this.attr('src').replace(sp, pc));
        } else {
            $this.attr('src', $this.attr('src').replace(pc, sp));
        }
    });
}
imageSwitch();
 
// リサイズの実行タイミング設定
var delayStart;
var delayTime = 200;
$(window).on('resize', function () {
clearTimeout(delayStart);
delayStart = setTimeout(function () {
imageSwitch();
}, delayTime);
});
```

## HTMLで切り替える
### メリット
#### 解像度だけに合わせて、画像の切り替えの可能が可能
例えばiPhoneX（スクリーン幅375px）でもピクセル比が2なので、ブラウザはその2倍の750wで指定した画像を表示する。（375wで指定した画像は表示されない）

#### もちろんウィンドウサイズに合わせて、画像の切り替えが可能。
メディアクエリで指定しているため、ブラウザの解像度を考慮せず、必ず指定された画像が表示される。
そのためブラウザの解像度によって画像が切り替わることがないので、異なる画像を切り替えるためにpictureタグを利用する。

### デメリット
#### ブラウザ対応が必要
[Picturefill] (http://scottjehl.github.io/picturefill/)で対応する。ファイルを読み込むだけで対応されるので、簡単。

```index.html
<script src="https://cdnjs.cloudflare.com/ajax/libs/picturefill/3.0.3/picturefill.js"></script>
```


### 方法

#### Retina対応をする
```index.html
<img src="img/sample.jpg"
     srcset="img/sample.jpg 1x,
             img/sample@2x.jpg 2x"
>
```

* 画像は「sample.jpg」と「sample@2x.jpg」の2枚を用意する。
* 1xと2xは解像度を表している。（Retinaディスプレイのとき、2xに指定した画像が表示される）

### 方法

#### ウィンドウサイズに合わせて画像を切り替える
```index.html
<picture>
  <source media="(min-width: 600px)" srcset="sample_pc.jpg 1x, sample_pc@2x.jpg 2x">
  <source media="(max-width: 599px)" srcset="sample_sp.jpg 1x, sample_sp@2x.jpg 2x">
  <img src="sample_pc.jpg">
</picture>
```
* 画像は「sample_pc.jpg」と「sample_pc@2x.jpg」と「sample_sp.jpg」と「sample_sp@2x.jpg」の4枚を用意する。（Retina対応しなくても大丈夫な場合は「sample_pc.jpg」と「sample_sp.jpg」の2枚だけでもOK）
* mediaで指定したピクセルで画面が切り替わる。
エラーコード0xc000000e

今回、自分はSATA SSDからM.2 SSDに換装するに当たってまるごとデータをクローンした。
クローン後、何回かUEFIのBoot Option Prioritiesがリセットかなんかされてしまって、OSが入ったM.2 SSDがBoot Option #1に選択されていなかったので手動で設定し、windowsを起動し普通に使えていた。
クローン後、2、3日経った後、windowsを起動したところ「0xc000000e」が発生した。

## エラーを直すために行ったこと

### Boot Option Priorities再設定
- もう一度Boot Option #1にM.2 SSDを設定してみたが、エラーは解消されなかった。

### USBからwindows起動
- USBでWindows起動ドライブ作成
- USBをPCに挿しPC起動
- 起動の際、F11キーを押しBoot Managerを表示し接続したUSBを選択


### スタートアップ修復
- スタートアップ修復を2、3回行うも修復されなかった。

### ブート領域復旧
- スタートアップ修復失敗画面から詳細オプションに進み、コマンドプロンプトを開く。

#### コマンドプロンプトでコマンド実行
- bootrec /rebuildbcd
- 「インストールをブート一覧に追加しますか。」と聞かれ、「y」を実行する。
- ファイルが見つかりませんと表示される。
- 「Windowsのインストールとして認識された合計数」の下に表示されているWindowsフォルダのパスを確認し、「bcdboot 「Windowsフォルダのパス」/l ja-jp」を実行する。

#### 注意点
- 以上を行うとWindows OSから回復パーティションが認識出来なくなっているので再認識させなくてはならない。

### Windows回復パーティションを再認識
- コマンドプロンプトを管理者モードで開く
- reagentc /infoを実行し、Windows REが無効になっているのを確認する。
- reagentc /enable実行し、Windows REを有効にする。
- reagentc /infoを実行し、Windows REが有効になっているのを確認する。

## その他
- Windows起動ドライブを作成する際フォーマットを間違っていて、PCにUSBを接続してもUSBからブートできなかったので注意してほしい。
【Rails】Basic認証の導入

# 目的
Railsで作成したアプリに`Basic認証`を導入する。

# 開発環境
macOS: *Big Sur*
Rubyバージョン: *2.6.5*
Railsバージョン: *6.0.0*

# 前提

- アプリ`test-app`が作成されている。
[【Rails】簡単な投稿アプリの作成](https://qiita.com/oak1331/items/18a4f3a3386aab0fa354)

# 手順

1. [はじめに](#はじめに)
1. [Basic認証の準備](#basic認証の準備)
1. [Basic認証の導入](#basic認証の導入)

# はじめに

今回は`Basic認証`を導入していきます。
`Basic認証`とは、HTTP通信の規格に備え付けられている、ユーザー認証の仕組みのことです。
サーバーとの通信が可能なユーザーとパスワードをあらかじめ設定しておき、それに一致したユーザーのみが、Webアプリケーションを利用できるようにします。

# Basic認証の準備

まずBasic認証の準備として、ユーザーとパスワードを設定します。

```:ターミナル
% vim ~/.zshrc
```

`「iキー」`を押して、インサートモードに移行し、zshの内部に、以下の記述を追加します。
今回、ユーザーは「admin」、パスワードは「2222」とします。

```ruby:ターミナル
export BASIC_AUTH_USER='admin'
export BASIC_AUTH_PASSWORD='2222'
```

記述を追加したら`「escキー」`、 `「:wq」`を入力後、、`「Enterキー」`を押して終了します。
最後に、`「sourceコマンド」`を実行します。

```:ターミナル
% source ~/.zshrc
```

これで、`BASIC_AUTH_USER`と`BASIC_AUTH_PASSWORD`という名前で、それぞれユーザー名とパスワードを定義できました!
続いて、この環境変数をRailsアプリ側で読み込むようにします！

# Basic認証の導入

続いて`authenticate_or_request_with_http_basicメソッド`を利用して、`Basic認証`を導入します。
`authenticate_or_request_with_http_basicメソッド`とは`Basic認証`を実装するために使用する、Railsのメソッドです。
ブロックを開き、ブロック内部で`username`と`password`を設定することで`Basic認証`を利用できます。

```ruby:app/controllers/application_controller.rb
class ApplicationController < ActionController::Base
  before_action :basic_auth


  private

  def basic_auth
    authenticate_or_request_with_http_basic do |username, password|
      username == ENV["BASIC_AUTH_USER"] && password == ENV["BASIC_AUTH_PASSWORD"]
    end
  end
end
```

これで`Basic認証`が導入でき、どのページにアクセスしても`Basic認証`が要求されるようになりました!
実際に確認してみて正常に動作すれば完了です！

# 最後に

以上で、`Basic認証`の導入は完了です。
では。
Linux OSの管理ツール Cockpit仮想マシン　前編

[前回](https://qiita.com/fy406/items/aab6d55ee76495b94813)の続きです。
今回はCockpitで仮想マシンを管理する方法を紹介します。

#準備
まずは必要なパッケージをインストールします。

```
yum install virt virt-install cockpit-machines
※cockpitの仮想マシンはvirtベースですので、virtもインストールします
```

続いて以下のコマンドを実行し、仮想化支援機能の状態確認を行います。
「成功」が表示されていれば問題なしで、「成功」以外が表示されていればその項目に対して対処する必要があります。

```
virt-host-validate
```

仮想化支援機能を使用できるようになりましたら、以下サービス起動と有効化を実行します。

```
systemctl status cockpit.socket
systemctl start cockpit.socket
systemctl status cockpit.socket
systemctl enable cockpit.socket
```

サービス起動まで完了しましたら、次はOSイメージをホストへコピーします。
コピー先は任意のディレクトリで大丈夫です。
例：/var/iso/

単に仮想マシンを動かすだけなら上記で準備完了ですが、ネットワークへ接続する場合はもう少し作業が必要です。
なお、ネットワーク周りの設定は失敗しますとSSHで作業している場合はネットワークが切断されてしまう可能性がありますのでご注意ください。
まず、ネットワークの設定ファイルをコピーします。
物理NIC名は使用しているマシンによって異なるので、`ls`コマンドで`network-scripts`ディレクトリ内を確認する必要があります。

```
cp /etc/sysconfig/network-scripts/ifcfg-<物理NIC名> /etc/sysconfig/network-scripts/ifcfg-br0
```

次にホストマシンに搭載されているNICのMACアドレスを確認します。

```
ip add
※link/etherの後ろにMACアドレスが表示されています
```

続いて`/etc/sysconfig/network-scripts/ifcfg-br0`ファイルを編集します。

```
[編集内容]
※以下の内容を書き換え
TYPE=Bridge
NAME=br0
DEVICE=br0
※以下の行を削除
UUID=""
```

続いて`/etc/sysconfig/network-scripts/ifcfg-<物理NIC名>`ファイルを編集します。
万一に備えて設定ファイルをバックアップしておくとよいです。

```
[編集内容]
※以下の内容を追記
HWADDR="<先程確認したMACアドレス>"
BRIDGE="br0"
```

上記設定完了後、`systemctl restart network`コマンドでサービス再起動します。
ssh接続が切断されなければ正常に完了しています。

以上でCockpitで仮想マシンを管理する準備は完了です。
ブラウザにてCockpitへログインして左ペインに「仮想マシン」の項目が存在していれば完了です。
次回に続きます。
単一トランザクション内で、複数レコード追加時のEntityExistsException: a different object with the same identifier を回避する

####使用技術
・SpringBoot（Javaフレームワーク）
・JPA（ORマッパー）
・MySQL（DB）

####やりたいこと
・単一トランザクション内で、単一テーブル（=テーブルAとする）に複数行を登録する
・テーブルAの主キーは自動連番（auto increment）

####エラー
>javax.persistence.EntityExistsException:
 A different object with the same identifier value was already associated with the session : [モデル名]
org.springframework.dao.DataIntegrityViolationException: A different object with the same identifier value was already associated with the session : 

要約すると、「主キーが重複してまっせ」ということですね。
複数レコードを一気に登録しようとしたとき、同じ主キーを自動連番してしまうことにより発生しているようです。


####ソース（改善前、エラーが出る）
改善箇所は後ほど記載します。

```Entity.Java
@Entity //エンティティクラスのアノテーション
@Getter //Getterの自動生成のアノテーション
@Setter //Setterの自動生成のアノテーション
@Table(name = "Entity") //テーブル名の指定
public class Entity {

  @Id //idであることをアノテーションで明示する
  @Column(name = "entity_id") //DB上のカラム名を指定する
  private int id;

  @Column(name = "detail")
  private String detail;
}
```

```EntityRepository.Java
@Repository
public interface EntityRepository extends JpaRepository<Entity, Long> {
}
```

```EntityService.Java

  @Autowired
  private TransactionRepository transactionRepository;

  @Transactional
  public void someMethod() {
  
    //Entityテーブルに複数のレコードを追加
    List<Entity> entitys = new ArrayList<Entity>();

    Entity entity1 = new Entity();
    entity1.setDetail("適当な文字列-1");
    entitys.add(entity1);

    Entity entity2 = new Entity();
    entity2.setDetail("適当な文字列-2");
    entitys.add(entity2);

    entityRepository.saveAll(entitys);
}
```

####ソース（改善後）

モデルクラスの主キーに下記を追加します。

```
@GeneratedValue(strategy = GenerationType.IDENTITY)
```

クラス全体ではこうなります。

```Entity.Java
@Entity //エンティティクラスのアノテーション
@Getter //Getterの自動生成のアノテーション
@Setter //Setterの自動生成のアノテーション
@Table(name = "Entity") //テーブル名の指定
public class Entity {

  @Id //idであることをアノテーションで明示する
  @GeneratedValue(strategy = GenerationType.IDENTITY)
  @Column(name = "entity_id") //DB上のカラム名を指定する
  private int id;

  @Column(name = "detail")
  private String detail;
}
```
[WIP]3Dモデルをコードで書くなら、OpenSCAD+BOSL2がおすすめ(初心者の意見です^^;)

# 経緯

3Dプリンタを買って、自分で3Dモデルを作りたいと思ったけど、CADソフトの操作性が難しいのと、3Dモデルをイメージするのが難しくて、挫折したので、コードで3Dモデルをつくるアプローチに変更^^;
しかし、OpenSCADだけだと、オブジェクト間の位置関係の指定がもっと難しかったので、偶然見つけたBOSL2を使ってみた結果、非常に良かったので。

# OpenSCAD

3Dモデルをコードでかける言語+ソフトウェア。

* https://openscad.org
* https://github.com/openscad/openscad
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/78540/f05ad998-e202-2373-9bdf-ecdd531841a5.png)

# BOSL2

OpenSCAD用拡張ライブラリ
* https://github.com/revarbat/BOSL2
* Wiki: https://github.com/revarbat/BOSL2/wiki
* Cheatsheet: https://github.com/revarbat/BOSL2/wiki/CheatSheet
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/78540/05a7f725-0242-f343-8258-2f32b33fbf47.png)



# なぜ、OpenSCAD+BOSL2か？

OpenSCADについても、BOSL2についても、3Dモデルについても、初心者なので間違っているかもしれません。その際はご容赦＆ご指摘ください。

## OpenSCADが使いにくいところ(個人的意見です！！)

* 部品群が(デフォルトだと)あまりない
* 座標の指定が空間をイメージできない初心者には難しい

## BOSL2がいいところ

* ネジなどのいろんなオブジェクトが揃っている
* ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/78540/0bdbec98-1e40-9c8b-87a5-1429c636f581.png)
* 位置指定方法が豊富
 * あるオブジェクトに対して、相対的に位置を指定できる
* 面取り処理がminkowski()関数のように難しくない
* もっと色々あると思いますが…


# あるオブジェクトに対する、相対位置関係を指定してオブジェクトを位置決めする

[attachments.scad](https://github.com/revarbat/BOSL2/wiki/attachments.scad)

* ある立方体の上に立方体を配置

* ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/78540/4d2e2797-5ee7-1624-81d4-786fc370d0aa.png)

```
include <BOSL2/std.scad>
cuboid([10,15,20]) {
   attach(TOP) cuboid([5,7,10]);
}
```

* ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/78540/8b85cb17-d5a2-7775-3fe9-7442da048497.png)

```
include <BOSL2/std.scad>

cuboid([10,15,20]) {
    attach(TOP) cuboid([5,7,10],anchor=RIGHT);
}
```

# BOSL2使うならこれやっとけ！！

* ネジとか蟻継ぎのようなダボ？みたいなかみ合わせの部品を使う場合は、キャリブレーションオブジェクトを印刷して、かみ合わせ用の変数$slopを[決定](https://github.com/revarbat/BOSL2/wiki/constants.scad#constant-slop)する
 * キャリブレーションは以下のモデルを3Dプリントして、決定する
 * ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/78540/fc426210-bc10-5a34-37b4-8ada59c1d964.png)
 * (ちなみに、私のPrusa i3 MK3S+でPETGを印刷すると0.00でちょっときつめ、0.05でゆるめだったので、$slop=0.03にしています。PLAだと未設定(0.00?)でぴったりでした。)
Python関数-ファイル操作

Pythonに触り初めて約一年、毎回同じことを調べてしまっていてプログラマーとしての成長が皆無なので、それらを記録、暗記して仕事効率を上げる
調べてみて、これ前にも調べたなってなったらここに記録。
あくまで自分用だが、初心者の人は自分と似たようなこと調べてるんじゃないかな?


##基本となるライブラリ
import os
import glob


##パスの操作(フォルダ検索など)
####フォルダ内のファイルの全てのパス検索(glob.glob())
フォルダ内のパスを一括で検索

用法:glob.glob("folder_path\\*")

```python
path_list = glob.glob(r"D:\Documents\tool\test_folder\*")
```

<details><summary>結果</summary><div>
```
[
'D:\\Documents\\tool\\test_folder\\1.txt', 'D:\\Documents\\tool\\test_folder\\2.txt', 'D:\\Documents\\tool\\test_folder\\3.txt', 'D:\\Documents\\tool\\test_folder\\4.txt'
]
```
</div></details>



####パスの結合(os.path.join())
パス同士を結合する。あるフォルダの下に、特定の名前のファイルを作るときとか便利。
stringどうしを+で繋げてもいいが、こっちだと"\"を付けるかどうかを考慮しなくていい?

用法:os.path.join(PathA,PathB,PathC,・・・)

```python
path = os.path.join(r"D:\Documents\tool\test_folder","5.txt")
```

<details><summary>結果</summary><div>
```
D:\Documents\tool\test_folder\5.txt
```
</div></details>



####パスからファイル名だけを取り出す(拡張子付き)(os.path.basename())
言わずもがな

用法:os.path.basename(file_path)

```python
name = os.path.basename(r"D:\Documents\tool\test_folder\hello.txt")
```

<details><summary>結果</summary><div>
```
hello.txt
```
</div></details>



####pathの分割 : ファイル名とそれ以外を分解(os.path.split())
パスをファイル名とそれ以外で分解

用法:os.path.split(file_path)

```python
sp = os.path.split(r"D:\Documents\tool\test_folder\hello.txt")
```

<details><summary>結果</summary><div>
```
('D:\\Documents\\tool\\test_folder', 'hello.txt')
```
</div></details>



####pathの分割 : 拡張子とそれ以外で分解(os.path.splitext())
パスを拡張子とそれ以外で分解。os.path.split()と似ているが、こっちはsplitextなので、text部分と拡張子部分を分けるって覚える?

用法:os.path.splitext(file_path)

```python
sp = os.path.splitext(r"D:\Documents\tool\test_folder\hello.txt")
```

<details><summary>結果</summary><div>
```
('D:\\Documents\\tool\\test_folder\\hello', '.txt')
```
</div></details>



####pathの分割 : 指定文字("\\"とか)で分割(string.split())
osではなく、stringとしての処理。
Pythonを段階的に学んできたわけではないので、こういう基本的な処理が抜けてて恥ずかしくなる。

用法:"path".split("分割する文字")
```python
pathA = r"D:\Documents\tool\test_folder\hello.txt"
sp = pathA.split("\\")
```

<details><summary>結果</summary><div>
```
['D:', 'Documents', 'tool', 'test_folder', 'hello.txt']
```
</div></details>

あとはindexで指定すればいい。sp[0]とかsp[-1とか]



####ディレクトリが存在してるかどうかの検索(os.path.isdir())
指定したpathのフォルダが存在しているかをbool型で返してくれる。
後述のos.mkdir()とかでフォルダを作りたい時に、既にそのフォルダがあるとエラーになってしまう。そこで、これを使って先にフォルダがあるか無いかをチェックする。

用法:os.path.isdir(folder_path)

```python
isflg = os.path.isdir(r"D:\Documents\tool\test_folder")
```

<details><summary>結果</summary><div>
```
True (フォルダが存在する場合) 
```
</div></details>



####ディレクトリの作成(os.mkdir())
指定したpathのディレクトリを作成。既に存在している場合は作成できずにエラーが出るので前述のos.path.isdir()と組み合わせる。
結果とかを一つのフォルダにまとめたりする時に頻出。

用法:os.mkdir(folder_path)


```python
#os.path.isdir()と組み合わせる例。Falseの場合はディレクトリは作られない
pathB = r"D:\Documents\tool\test_folder\test"
isflg = os.path.isdir(pathB)
if isflg == False:
    os.mkdir(pathB)
```

<details><summary>結果</summary><div>
```
フォルダが作成される or 作成されずに続行
```
</div></details>


###とりあえずここまで!　検索するたびにここに追記！
エンジニアのためのツイートランキングサイトを作成した


##注意

このサイト、及びこの記事はこちらの記事の模倣で出来上がっています。

https://qiita.com/jabba/items/1a49e860a09a613b09d4


相違点としては
__向こうが"qiita"  の"本"     による"商品"のランキングサイトである__のに対して
__こちらは"twitter"の"ツイート"による"情報"のランキングサイトである__
という点が相違点です。


#お金の話

お金が稼げているかどうかは正直まだわかりません。(アクセスがまだ十分な量でないため)


#集客の話

どのように広めるのか
1、qiitaで広める(エンジニアの情報が欲しいユーザーが集まっているため)
2、twitterで広める(駆け出しエンジニアがターゲット)





#サイトURL
サイト名：テック・ツイ・ランク

http://techtweetrank.short-tips.info/index.html


#ターゲット
ターゲット：エンジニアリングについてより濃い情報を得たいエンジニア





#使用言語
使用言語（バックエンド）:Python
使用言語（フロント）：Javascript

#参考文献

参考文献：こちらの記事を参考にしました。

https://qiita.com/jabba/items/1a49e860a09a613b09d4
WPFのImageのSourceがNullの場合の対策

#はじめに

WPFを使っていて、xamlで以下のようなコーディングをした際のことです

```C#
    <Image Source="{Binding ImageFilePath}"
           Width="100"
           Height="100"/>
```

.NetFramework4.8のときは、このImageFilePathがnullや空文字でもすぐに表示されたのですが、.NET5に変更した際に、エラーが起きて、表示がとても遅くなってしまいました。

エラーの内はこんな感じですね

> 例外がスローされました: 'System.NotSupportedException' (System.ComponentModel.TypeConverter.dll の中)
例外がスローされました: 'System.NotSupportedException' (PresentationCore.dll の中)
System.Windows.Data Error: 23 : Cannot convert '<null>' from type '<null>' to type 'System.Windows.Media.ImageSource'

#対策
対策といえばググりましょうということで、いろいろと調べましたが、[UWPのImageのSourceにnullや空文字をx:Bindしたときの対処方法(対処できない)](https://blog.okazuki.jp/entry/2015/10/19/081557)という記事で、TargetNullValueを設定すればよさそうということがわかりました。
さらに調べて、TargetNullValue={x:Null} とすることで対策できました。

```C#
    <Image Source="{Binding ImageFilePath, TargetNullValue={x:Null}}"
           Width="100"
           Height="100"/>
```

以上、できてしまえば簡単ですが、忘れてしまいそうだったので、備忘録もかねて記事とさせていただきました。
input:hiddenを少し便利にする

# 最近input:hiddenを使う機会があったので良い方法がないか模索

## 注意

初投稿なので至らないところがあると思いますが、過不足がありましたらコメントをお願い致します。
コードを使う場合は、ご自由に採用・改変してご利用ください。
ご利用に対するあらゆる影響に関して責任は持てません。

## 目標

input:hiddenを少し扱いやすくする。
複数の要素がある場合は、input:hiddenのnameをkeyとするハッシュオブジェクトを返す。
要素名を指定した場合は、input:hidden[name="name"]のjQueryオブジェクトを返す。

## 環境

- Ubuntu 20.4
- HTML5
- CSS3
- javascript
- jQuery 3.6.0
- npm 7.17.0
- Pug

## 試したこと

### hiddenを手軽に扱う小さいモジュールを書く

```javascript
(function( $ ) {
	$.fn.hiddens = function(name) {
		var $hiddens = this.children("input:hidden");

		var hids = new Object();
		if(name) {
			hids = $(this.children('input:hidden[name="' + name + '"]')[0]);
		} else {
			for(let i=0; i<$hiddens.length; i++) {
				let h = $hiddens[i];
				hids[h.name] = $(h);
			}
		}
		return hids;
	};
})( jQuery );
```

### 使い方

```html
<!-- 略 -->

<form id="test">
  <input type="hidden" name="spaceA" value="A" />
  <input type="hidden" name="spaceB" value="B" />
</form>

<!-- 略 -->
```

```javascript
// ex1 : 指定なし => ハッシュ(key=name, value=jQueryオブジェクト)
var hids = $('form#test').hiddens();
var hidA = hids['spaceA'];
var hidB = hids['spaceB'];
console.log("tag info: ", hidA.attr("type"), hidA.attr("name"), hidA.attr("value")); // tag info: hidden spaceA A
console.log("hidden A: ", hidA.val()); // hidden A: A
console.log("hidden B: ", hidB.val()); // hidden B: B

// ex2 : 要素を指定 => jQueryオブジェクト
var hid = $('form#test').hiddens("spaceA");
console.log("tag info: ", hid.attr("type"), hid.attr("name"), hid.attr("value")); // tag info: hidden, spaceA A
console.log("hidden A: ", hid.val()); // hidden A: A
hid.val("hiddens");
console.log("update A: ", hid.val()); // update A: hiddens
```

## 結論

個別に扱う場合は、少し扱いやすくなった気がする（個人の感想です）。
idでも指定できると良いが要改良。
複数の要素にアクセスしたい場合は、従来通り。

```javascript
$('form#id:hidden[name^="prefix"]').each(function() { /* 処理 */ });
```
python with句が便利な事例 / with が使える class の使い方

python の with って何に使うのかずっとわからなかった。やっと意味がわかったのでメモ。

# with って便利なの？

この神記事にすべてがありました

> [[Python] with構文で使用できるクラスを実装する](https://qiita.com/tchnkmr/items/c6b6480d236a51b91c17)

database 接続 / file開く など、何かしら connection close などの後始末が必要なときは with が最高に便利です！　 

## 何がいいの？

コードがシンプルになります

## コードがきれいになる例

残念な例

```py
try:
    obj = SomeClass()
    obj.do_something()
finally:
    obj.close()
```

５行あります。

Cool な例

```py
with SomeClass() as obj:
    obj.do_something()
```

以上！ ２行で終わりました！ ちゃんとclose()処理はされてますよ :)



# with で使える class とは

最初にいっとくと、関数では with ができません。必ず class にしましょう。

## 関数 → class への変換方法

```py
# 関数の宣言
def some(arg1):
   return do_something(arg1)

# 関数使い方
some('arg1')

# classの宣言
class SomeClass:
    def __init__(self, arg1):
        do_something(arg1)

# class 使い方
SomeClass('arg1')
```

## with で使える class の作り方 

↑ の例のように、普通に class 作るだけだとwithで使えません。
`__enter__ または __exit__` がないぞ、的なエラーが出ます。


```py
class W:
    def __init__(self):
        print('init')

with W() as w:
    print(w)
```

result 

```rb
AttributeError: __enter__
```

これは with句で呼び出されたclassは、暗黙的に `__enter__() __exit__()`  を呼び出されるからです。エラーを消すには、この関数を作ってあげればよいです。



# withで使わない場合
```py
class W:
    def __init__(self):
        print('init')
    def __enter__(self):
        print('enter')
        return self
    def __exit__(self, exception_type, exception_value, traceback):
        print('exit')

w = W()
print('===')
```

result

```rb
init
===
```

# withで使う場合

```py
class W:
    def __init__(self):
        print('init')
    def __enter__(self):
        print('enter')
        return self
    def __exit__(self, exception_type, exception_value, traceback):
        print('exit')

with W() as w:
    print(w)

print('===')
```


result

```rb
init
enter
<__main__.W object at 0x10347bfd0>
exit
===
```

# 悩んだエラー TypeError: `__exit__()`

`__exit__()`の引数をちゃんとしないと、エラー

> TypeError: `__exit__()` takes 1 positional argument but 4 were given

```py
# wrong
    def __exit__(self):

# right    
    def __exit__(self, exception_type, exception_value, traceback):
```



# with class をインスタンスで返す関数の場合

問題なく動く

```py
class W:
    def __init__(self):
        print('init')
    def __enter__(self):
        print('enter')
        return self
    def __exit__(self, exception_type, exception_value, traceback):
        print('exit')

def func():
    return W()

with func() as w:
    print(w)
```



result

```rb
init
enter
<__main__.W object at 0x10bddbfd0>
exit
```

# with class を class のままで返す関数の場合
無茶苦茶だけど動く

```py
class W:
    def __init__(self):
        print('init')
    def __enter__(self):
        print('enter')
        return self
    def __exit__(self, exception_type, exception_value, traceback):
        print('exit')

def get_class():
    return W

with get_class()() as w:      #<--- ()() ってひどい.顔文字か。
    print(w)
```

result

```rb
init
enter
<__main__.W object at 0x10bdc0fd0>
exit
```




# summary

`__enter__, __exit__` は with で使ったときだ **だけ** 呼び出される

`__exit__()` は必ず４つ引数を受け取る
Windows上のTouchDesignerでCPlusPlus OPを使用する手順

# CPlusPlus OP でできる事
自前のC++のソースコードをコンパイルして作成したプラグインを，TouchDesigner上で使用できるようになる．
事前にVisual Studioでコンパイルして作成したDLLファイルを，CPlusPlus OP (TOP/SOP/CHOP/DAT) からパスを指定することで読み込み．実行．
CUDA toolkitをインストールしておけば，同一ソースコードからCUDAを用いたGPUによる計算も可能．
サンプルコード上で仮想の関数が与えられているので，コード作成時にはそれをオーバーライドして使用することを想定．

# CPlusPlus OP の実行手順
ここでは`C:\Program Files\Derivative\TouchDesigner\Samples\CPlusPlus\DAT`フォルダ中にあるCPlusPlusDATExampleを実行しながら説明する．

## Visual Studio のインストール
以下のURLから最新のVisual Studio Communityをインストールする．
https://visualstudio.microsoft.com/ja/vs/community/
インストーラー中で，C++によるデスクトップ開発にチェックを入れておく．
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/267183/e27180ac-8c5e-34cf-7161-bd7f66de03fe.png)

## C++ から DLL ファイルを作成する
TouchDesignerのインストールディレクトリにサンプルコードが保存されている（筆者環境では`C:\Program Files\Derivative\TouchDesigner\Samples\CPlusPlus`）．
いくつかのサンプルがフォルダに分かれて配置されているが，今回はDATフォルダを実行して説明する．
DATフォルダ以下にあるCPlusPlusDATExample.slnを起動してVisual Studioを立ち上げる．

右側にあるソリューションエクスプローラーで，ソースコードを確認できる．

- CPlusPlus_Common.h: CPlusPlus OP共通で使用するクラスのヘッダファイル．編集しない．
- CPlusPlusDATEample.cpp: 作成するクラスCPlusPlusDATExampleのソースファイル
- CPlusPlusDATExample.h: 作成するクラスCPlusPlusDATExampleのヘッダファイル
- DAt_CPlusPlusBase.h: TouchDesignerが提供しているベースとなるクラスDAT_CPlusPlusBaseのヘッダファイル．編集しない．

CPlusPlusDATEampleクラスのexecute()関数がTouchDesignerの各フレームで実行される．
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/267183/41c8bb0c-bbbb-c485-c0b4-1a24950ac2a4.png)
ビルド >> ソリューションのビルド　を実行すると，コンパイルが行われDebugフォルダの中にCPlusPlusDATExample.dllというDLLファイルが作成される．

## CPlusPlus OP で DLLファイルを読み込み
TouchDesignerを起動して CPlasPlas DATを作成．
Plugin Pathに上で作成したDLLファイルのパスを指定する．
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/267183/b706d360-69d0-b6b7-03e3-6ff89d3fb387.png)
上手くいけば画像のようにCPlusPlus DAT内に文字列が表示される．

# デバッグの設定
Visual Studioでのデバッグ時に，TouchDesignerを自動で起動してブレークポイントに対応させることができる．
Visual Studioで　プロジェクト >> CPlusPlusDATExampleのプロパティ　を開く．
コマンドにTouchDesigner.exeのパスを記載．（筆者環境では`C:\Program Files\Derivative\TouchDesigner\bin\TouchDesigner.exe`）
コマンド引数に実行するtoeファイルのパスを記載．（筆者環境では，`C:\Program Files\Derivative\TouchDesigner\Samples\CPlusPlus\DAT`にCPlusPlus_debugger.toeを配置し，`$(ProjectDir)\CPlusPlus_debugger.toe`と指定した）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/267183/6b6f76d5-bd1f-bffe-26cd-fd45af0fe156.png)
設定を適用してプロパティページを閉じる．
設定が上手くいっている場合には，　デバッグ >> デバッグの開始　を実行するとTouchDesignerが自動で起動し，任意のブレークポイントで停止しデバッグが可能となる．

参考：
- Write a CPlusPlus Plugin, https://docs.derivative.ca/Write_a_CPlusPlus_Plugin
-  TouchDesigner/CustomOperatorSamples, https://github.com/TouchDesigner/CustomOperatorSamples
vscodeでplaywrightを始める

サクッとテストコードを準備するための環境構築

## vscodeの拡張機能をインストール

* [Playwright Snippets](https://marketplace.visualstudio.com/items?itemName=nitayneeman.playwright-snippets)  
Snippetsです。
同じ名前で[forkしたやつ](https://marketplace.visualstudio.com/items?itemName=sonjaq.playwright-snippets)もあるけど、違いがわからなかったのでfork元を利用しています。
* [Playwright Test Runner](https://marketplace.visualstudio.com/items?itemName=sakamoto66.vscode-playwright-test-runner)  
部分的にテストしたいときに使います。


## プロジェクト新規作成

```bash
mkdir e2etest
cd e2etest
npm init -y
```

## playwrightインストール

```bash
npm i -D playwright
npm i -D @playwright/test
```

## テスト用のディレクトリ作成

```bash
mkdir tests
```

## 作成したプロジェクトからvscodeを立ち上げなおす

```bash
code .
```

この時点でディレクトリはこんな感じになっていると思います。

* e2etest/
 * node_modules/
 * tests/
 * package-lock.json
 * package.json

## テストコード作成

- tests/helloworld.spec.js

``` javascript
const { test, expect } = require('@playwright/test');

test('basic test', async ({ page }) => {
  await page.goto('https://playwright.dev/');
  const name = await page.innerText('.navbar__title');
  expect(name).toBe('Playwright');
});
```
コマンドラインから```playwright test```と実行する以下の結果が出れば成功です。

```bash
> playwright test

Running 1 test using 1 worker

  ✓ tests\helloworld.spec.js:3:1 › [chromium] basic test (10s)


  1 passed (11s)
```


## テスト実行(F5)できるようにlaunch.jsonを設定

コマンドラインから実行が面倒なのでlaunch.jsonを設定します。
部分実行はPlaywright Test Runnerでできるので、launch.jsonでは、全テストを実行するように設定します。
モードは二つ

* Run Test - headless  
ヘッドレスで実行します
* Run Test - headed  
ブラウザを表示して実行します

```json
{
    "version": "0.2.0",
    "configurations": [
        {
            "type": "pwa-node",
            "request": "launch",
            "name": "Run Test - headless",
            "program": "node_modules/playwright/lib/cli/cli.js",
            "args":["test"]
        },
        {
            "type": "pwa-node",
            "request": "launch",
            "name": "Run Test - headed",
            "program": "node_modules/playwright/lib/cli/cli.js",
            "args":["test", "--headed"]
        }
    ]
}
```

## ソース管理対象外を設定しておく

テスト実行だけする分には、必要ないけど後々gitで管理すると思うのであらかじめ作成しておきます。

* .gitignore

```
node_modules/
```
テンプレートエラーの対処について

# Missing テンプレートエラーに対しての対処

### いきなり下記の様なエラーメッセージが出ました

ActionView::MissingTemplate in Items#index
Showing /Users/user名/projects/furima-35496/app/views/items/index.html.erb where line #1 raised:

Missing partial shared/_header with {:locale=>[:en], :formats=>[:html], :variants=>[], :handlers=>[:raw, :erb, :html, :builder, :ruby, :jbuilder]}. Searched in:
  * "/Users/user名/projects/furima-35496/app/views"
  * "/Users/user名/.rbenv/versions/2.6.5/lib/ruby/gems/2.6.0/gems/actiontext-6.0.4/app/views"
  * "/Users/user名/.rbenv/versions/2.6.5/lib/ruby/gems/2.6.0/gems/actionmailbox-6.0.4/app/views"

views-items-index.html.erbの冒頭の文に何か問題があるのか？
```ruby
<%= render "shared/header" %>
```

参考記事「https://qiita.com/pontarou194/items/47e130e9c7e08225f109」
erbファイルに部分テンプレートを書く際は、基本 <%= render 'ファイル名' %> でよかったはず・・・・
→階層を確認し、devise/・・・と階層を付け加えることで解決したとの事。

![エラー画像1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1727249/d2c95e14-30c0-0885-3e74-ec7154ab64dc.png)

viewファイルの階層を見てみると、上記の様になぜかsharedが「layouts」の階層の中に入ってしまっているため、sharedをviewsの直下に変更してあげる。

![エラー画像2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1727249/15e2f76b-7134-9da8-e12b-2ab785167cb8.png)


templateエラーはこれで解決しました。
(が、次のエラーが出てしまった・・・)
iOS のストアレビューを取得する Bitrise ステップを作った

# 概要

iOS のストアレビューを取得する Bitrise ステップを作りました。

https://github.com/hmiyado/bitrise-step-ios-store-review

Bitrise は追加コスト無しでいくらでも定期実行タスクを設定できます。
ストアレビューの取得は定期実行タスクとしては価値があり、そこまで難しくもないので作ってみました。

# 技術

## Bitrise の独自ステップの作成

Bitrise の独自ステップの作り方はほぼ公式ドキュメントを見ればわかります。

https://devcenter.bitrise.io/jp/contributors/create-your-own-step/

独自ステップは Go か Bash で作成することができます。
今回はストアレビューをXMLとして取得してパースするのに多少の構造化されたコードを書きたかったので Go を使いました。

Go は初めてでしたが、 [公式のステップリポジトリ](https://github.com/bitrise-io/bitrise-steplib) には多くの参考になるコードがあります。
参考にすると書きやすいです。

## iOS のストアレビューの取得

App Store の XML を取得する URL を利用しました。

```golang
appUrl := "https://itunes.apple.com/jp/rss/customerreviews/page=1/id=" + appId + "/sortby=mostrecent/xml?urlDesc=/customerreviews/id=" + appId + "/sortBy=mostRecent/json"
```

公式な API ではないので、予告なく変更される可能性はあります。

## Go で XML をパースする

Go は標準ライブラリ（`"encoding/xml"`）で XML を簡単にパースすることができました。
XMLの階層構造を直感的に取り扱えたり、不要な要素は struct で列挙しなくてもよかったりします。
Bash で書くよりもわかりやすくなったと感じます。

例えば、以下のような XML と struct を対応させることができます。

```xml
<entry>
  <title>タイトル</title>
  <content>コンテンツ1</content>
  <content>コンテンツ2</content>
  <author>
    <name>レビュワー名</name>
  </author>
</entry>
```

```golang
type Entry struct {
	XMLNAME xml.Name `xml:"entry"`
	Title string `xml:"title"`
	Content []Content `xml:"content"` 
	Author string `xml:"author>name"`
}
```


# 作ったステップの使い方

## 独自ステップを利用する

独自に作成したステップを利用するには、 bitrise.yml に以下のような記載をする必要があります。

```yml
    steps:
    - git::https://github.com/hmiyado/bitrise-step-ios-store-review.git@main:
```

これさえ書けば、ステップで利用するパラメータなどはWebのGUI上でも設定できるようになります。
普段GUIでワークフローを管理しているという方でも、一手間で独自ステップを利用できます。

## 今回作成したステップの運用方法

今回は Bitrise の定期実行機能を利用することを前提に、DB等を持たない設計にしました。
Bitrise 側で1日ごとにストアレビューを確認するように設定したら、過去1日間のレビューを Slack に投稿します。

私が関わっているプロダクトでも1日ごとのレビュー取得設定を行いました。

# 感想

Bitrise はワークフローの同時並列数に対する課金です。
これを有効活用するためには空いている時間でいかに仕事をしてもらうか、というのが大事です。
今回はその一環でストアレビューを取得するようにしてみました。

そのうち、 Android のストアレビュー取得にもチャレンジしてみたいです。
Imagemagickを使ってサブディレクトリを含む特定フォルダ直下の画像を一括リサイズした

タイトルの通りです。

# TL;DR
Windows環境でのやつです。
Imagemagickをインストールし、コマンドプロンプトを開き、こんなコマンドを叩きましょう。解像度は今回横幅1200pxを最大に指定していますが、そこはお好みで。

```shell
for /r %a in (*) do magick mogrify -resize "1200x>" %a
```

# 経緯
私が開発に関わったとあるWebサイトにおいて、ユーザーからアップロードされた一部画像の解像度が高解像度すぎてしまい、結果としてサーバーのリソースを圧迫していたりページの表示速度を遅くしていることが判明しました。

ということで、画像のダウンサンプリングをおこなってもシステムに影響が出ないことを確認のうえ、アップロードされている画像のうち一定以上の解像度のものをリサイズすることに。
そのためにいろいろ調べたというアレです。

# 環境
OS: Windows 10 Pro 64bit
CPU: Ryzen 3400G
RAM: 16GB

世の開発者の皆さんはだいたい開発環境にMacかLinux使ってると思うのですが、私はカーネルいじるの大好きおじさんことWindows信奉者のため。
Mac/Linuxの情報はけっこう世の中に溢れてたので、そちらの方はGoogleへどうぞ。

# やったこと
まず、コマンドラインで画像をゴリゴリいじることができる超便利ツール・Imagemagickをインストールします。

https://imagemagick.org/script/download.php
↑
こちらからWindows用のものを落としてきてください。

これでおそらくコマンドプロンプトからmagickコマンドが使えるようになってるはず。なっていなかったら適宜パスを通してください。

あとは、コマンドプロンプトを開いてcdコマンドで画像がたくさん入っているディレクトリまで移動し、

```shell
for /r %a in (*) do magick mogrify -resize "1200x>" %a
```

これを叩きましょう。
`for /r %a in (*) do`で、サブディレクトリを含むすべての配下ファイルのパスを変数%aに代入しつつループを回せます。
で、あとは`magick mogrify -resize "1200x>" %a`として、%aに入ってきた画像ファイルが横幅1200pxを超えていた場合、リサイズを走らせることができます。

# おわりに
こんなことをしなくても済むように、開発時点で設計はしっかりやりましょう。

# 参考文献
https://base64.work/so/windows/869189
https://imagemagick.biz/archives/93
PythonでCSVを扱う

# ファイルの読み込みと集計
csvを読み込んで、Worldwide Grossを集計します

```marvel.csv
Year,Title,Production Studio,Worldwide Gross
2008,Iron Man,Marvel Studios,585174222
2008,The Incredible Hulk,Marvel Studios,264770996
2008,Punisher: War Zone,Marvel Studios,54700105
2009,X-Men Origins: Wolverine,20th Century Fox,373062864
2010,Iron Man 2,Marvel Studios,623933331
2011,Thor,Marvel Studios,449326618
2011,X-Men: First Class,20th Century Fox,352616690
```

```read_csv.py 
import sys,csv

if len(sys.argv)!=2:
  sys.stderr.write("Usage: {} FILENAME\n".format(sys.argv[0])) 
  exit()

file=sys.argv[1] 
fh=open(file,'rb')
lines = fh.readlines()[1:] 
fh.close()

count=0 
for line in lines:
    line = line.rstrip("\n") 
    row = line.split(',') 
    print(row)
    count += int(row[3])

print("Total:{}".format(count))
```

出力

```bash
~ python read_csv.py marvel.csv
['2008', 'Iron Man', 'Marvel Studios', '585174222']
['2008', 'The Incredible Hulk', 'Marvel Studios', '264770996']
['2008', 'Punisher: War Zone', 'Marvel Studios', '54700105']
['2009', 'X-Men Origins: Wolverine', '20th Century Fox', '373062864']
['2010', 'Iron Man 2', 'Marvel Studios', '623933331']
['2011', 'Thor', 'Marvel Studios', '449326618']
['2011', 'X-Men: First Class', '20th Century Fox', '352616690']
Total:2703584826
```

# csvからDictionaryに変換
DictReaderクラスを使うと便利に変換できます

```csv_to_dictionary.py
import sys,csv

if len(sys.argv)!=2:
    sys.stderr.write("Usage: {} FILENAME\n".format(sys.argv[0])) 
    exit()

file=sys.argv[1]
count=0

with open(file) as fh: 
    rd = csv.DictReader(fh, delimiter=',')
    for row in rd: 
        print(row)
```

出力

```bash
~ python csv_to_dictionary.py marvel.csv
{'Title': 'Iron Man', 'Production Studio': 'Marvel Studios', 'Worldwide Gross': '585174222', 'Year': '2008'}
{'Title': 'The Incredible Hulk', 'Production Studio': 'Marvel Studios', 'Worldwide Gross': '264770996', 'Year': '2008'}
{'Title': 'Punisher: War Zone', 'Production Studio': 'Marvel Studios', 'Worldwide Gross': '54700105', 'Year': '2008'}
{'Title': 'X-Men Origins: Wolverine', 'Production Studio': '20th Century Fox', 'Worldwide Gross': '373062864', 'Year': '2009'}
{'Title': 'Iron Man 2', 'Production Studio': 'Marvel Studios', 'Worldwide Gross': '623933331', 'Year': '2010'}
{'Title': 'Thor', 'Production Studio': 'Marvel Studios', 'Worldwide Gross': '449326618', 'Year': '2011'}
{'Title': 'X-Men: First Class', 'Production Studio': '20th Century Fox', 'Worldwide Gross': '352616690', 'Year': '2011'}
```
Pandas で「本気出せば何とかなるけど、もっとスマートな解決方法ないかな」と思ったときに見る記事

# この記事について

PythonのPandasでデータを扱っている中で、少しの事なんだけど自分の思った通りにデータ操作できず、
小さな事で可読性の低い大量のコードを書いたり、考えこんでしまう時間を必要以上にかけてしまうことってありますよね。
（SQL だったらこんな風にすれば良いのになあ～みたいな）

ネットで検索したいと思っても<b>「何てキーワード検索していけばよいのかわからない・・・」</b>と言語化できない

そんな <b>もどかしい</b> ときに使える、小技集をまとめようと思って記事にしてみました。

<b>もどかしい</b>瞬間に遭遇し、スマートに解決できた、そんなアハ体験をどんどん備忘録的に追記していける記事に出来ればと思ってます。

## データ変換編
### ① 型変換したいけど例外エラーが出て”もどかしい”

例えば、Object型の日付型をdatetime型に変換したいけど、日付型に変換できない文字列が混在しているとき`pd.to_datetime()`の`errors="coerce"`オプションを上手く使えば良い！
数値型の場合は、`pd.to_numeric()`でも同様

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/658983/c0013214-8f72-f9fc-5b1d-38d2145ea3a7.png)


```python
import pandas as pd

data = {
    "date" : ["2021-01-01", "2021-02-01", "2021-03-01", "不明", "2021-05-01"],
    "sales": [10, 20, 30, 40, 50]
}

df = pd.DataFrame(data)
df[~pd.to_datetime(df["date"], errors="coerce").isna()]

>
         date  sales
0  2021-01-01     10
1  2021-02-01     20
2  2021-03-01     30
4  2021-05-01     50
```

# 募集中

Pandasを使っている最中に感じた <b>もどかしい経験</b> 募集中です
Rubyで１～１００を各々4乗して足すプログラムを書いてみた

1の4乗+2の4乗 ... 100の4乗 の合計を出力するプログラムを書きたい。

```ruby
  def calculate
    # 1の4乗 + 2の４乗+ ・・・ 100の４乗の合計を出力
    num = 1
    sum = 0
    while num <= 100
      sum = num**4 + sum
      num += 1
    end
    puts sum
  end
```

1**4は1の4乗の計算式らしい


# 処理の流れ

## 一回目の処理
sum = num**4 + sumは
sum = 1の四乗 + 0
となる。
ruby では右辺が左辺に代入されるので、
1がsumに代入される。
      num += 1
は
num = num + 1の省略記法
 で
1の四乗から2の四乗にしていく。

## 二回目の処理
sum = 2**4+ 1となる
sum = 17となる。
      num += 1は
2の四乗から3の四乗にしたいのでこう書いてる。


 while num <= 100
こう書いてる通り、この処理を100まで続ける



1の4乗+2の4乗 ... 100の4乗 の和を求める数学の計算式は分かりませんが、プログラミング言語初心者の自分でも、
1の4乗+2の4乗 ... 100の4乗 の和を求めるプログラムは書けるのです。
プログラミング面白いなって思いました。
【PHP】静的メソッドと動的メソッド

#静的・動的の意味
静的：変化がないことで、英語では`static`と表します。
動的：変化するもののことで、英語では`dynamic`と表します。

<font color="MediumVioletRed">
つまり、静的メソッドでは引数以外のものによって値が変化しないメソッドで
動的メソッドでは引数以外にもインスタンスによって値が変化し得るメソッドのことを言います。
</font>

※静的メソッドはインスタンスの影響受けないので、`static`でメソッドを定義した場合は`$this->プロパティ名`といった書き方をするとエラーになります。
<font color="Red">$thisはクラス(インスタンス)を指すため</font>

#具体的な例
テストの点数を計算する`Test`という名前のクラスを作成しました。
`$math,$english`という変数で数学と英語の得点を使って計算するものとします。

この場合`score`が静的メソッドになります。
テストの合計点は欠席日数にかかわらず変化しないためです。
一方、`total_score`は欠席日数によって減点されるので動的メソッドになります。

```php
<?php

class Test
{
    // 欠席日数
    public $absence;

    public function __construct($absence)
    {
        $this->absence = $absence;
    }

    // 静的メソッド
    public static function score($math, $english)
    {
        //単純な合計得点
        return $math + $english;
    }

    // 動的メソッド
    public function totalScore($math, $english)
    {
        //欠席日数によって得点を変化
        // 欠席日数が5日以上だったら、30点減点にする
        if ($this->absence >= 5) {
            return ($math + $english) - 30;
        }
        //欠席日数が5日未満なら、減点なし
        return $math + $english;
    }
}

// $absence=10, $math = 80, $english = 60の場合
 $my_test = new Test(10);  //コンストラクタに引数を設定した場合、newするときにも必ず引数を指定する
 echo $my_test->score(80, 60);  //出力結果 140
 echo '<br>';
 echo $my_test->totalScore(80, 60); //出力結果110
```

#参考サイト
https://fresh-engineer.hatenablog.com/entry/2018/08/23/031829
Intersection Observerでスクロール率による表示を実現する

Infinity loadingなどで使う、ページを90%まで読み込んだ時に処理を実行する方法について、Intersection Observerを使って実現が意外に難しかった。
あまり自信ないやり方なので、もっといいやり方あったら教えて欲しいです。

# 従来のやり方
```JS
document.addEventListener('scroll', function() {
    const scrollRate = window.pageYOffset / (document.documentElement.scrollHeight + document.documentElement.clientHeight);
    if (scrollRate > 90) {
        /* 何らかの処理 */
    }
});
```

このようにscrollイベントを監視して、scrollが行われるたびに現在のスクロール率を再計算する方法です。
このやり方だと、scrollするたびに判定処理が走るため、ページの動きが重くなりやすいです。


# Intersection Obverver
scrollの課題を解決するために、最近のブラウザだと [`Intersection Ovserver`](https://developer.mozilla.org/ja/docs/Web/API/Intersection_Observer_API) が定義されているのですが、これで元々やりたかったページ全体の９０%スクロールしたら表示するという方法が意外と難しかった。

Intersection Observerは名前が示す通り、交差する要素を指定するために、以下の３つの要素を指定します。

``` JS
const observer = new IntersectionObserver(() => {
    /* 何らかの処理 */
}, {
    root: null,
    rootMargin: "0px",
    threshold: 0.9,
});
const target = document.querySelector('body');
observer.observe(target);
```

- root & rootMargin 
    - 監視をする視点側
- target
    - 監視される対象
- threshold
    - 交差度合い

bodyを指定した場合、viewportのデフォルトである画面上には、常にbody全体が指定されるため、この場合の `交差率` は常に一定になって、0.9には届きません。

## スクロール率90%を実現する
結論から言うと、以下のようにviewportをずらすことで解決できます。

``` JS
root: null,
rootMargin: "-100% 0px 100% 0px",
threshold: 1.0 - 0.9,
```

このように設定すると、ブラウザの表示領域の下の領域にまだどれくらいの要素が残っているかが計測できるため、残りが 0.1 = 0.9スクロールしている、ということが計算できます。

bodyの大きさによっては、viewportをの大きさを変えたりなど、更なる調整をしないとうまく動かないケースもあるかもしれないです。


# Intersection Observerでスクロール率を計算する方法
viewportをブラウザの表示領域の下部にずらすことで実現できました。
ただ、あまり直感的な使い方ではなく、フッターなどをtargetに指定したほうが素直ですので、できるならその通り実装することをお勧めします。
VScodeで、楽々「import Class〜」したい→「PHP Namespace Resolver」拡張機能を使う。

今回は、「PHP Namespace Resolver」を紹介します。

import したいクラスって書くのが面倒です。

しかし、VScodeの便利な拡張機能「PHP Namespace Resolver」を使うと、

Control+option+i

でクラスの候補が出現し、選択すると、自動でimportしてくれます。

https://marketplace.visualstudio.com/items?itemName=MehediDracula.php-namespace-resolver
git init するときのデフォルトブランチ名をmainに設定する方法

# やり方

`git config --global init.defaultBranch main`

これで `git init` したときのデフォルトブランチ名が `main` に設定されます

# 詳細

ほぼ1年前ですがgitのバージョン2.28からinit時のデフォルトブランチ名に関する設定が可能になっています
詳細は以下記事を参照ください

https://github.blog/2020-07-27-highlights-from-git-2-28/

# ちなみに

これまた随分前の話ですがGitHubは2020年10月にリポジトリのデフォルトブランチをmainに変更することを発表しています。

https://github.blog/changelog/2020-10-01-the-default-branch-for-newly-created-repositories-is-now-main/

久々に `git init` したら下記のようなヒントメッセージが表示され、デフォルトブランチの変更に誘導されました
こういう親切なCLIはありがたいですね。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/136820/456f6e93-0df4-6aeb-0e17-9902506a7f8d.png)
【Ruby on Rails】超便利！request.refererを活用して元のページにリダイレクトする方法

####My Profile
プログラミング学習歴2ヶ月目のアカウントです！
プログラミングスクールで学んだ内容や自分が躓いた箇所等のアウトプットの為に発信しています。
また、プログラミング初学者の方にわかりやすく、簡潔にまとめて情報共有できればと考えています。
もし、投稿した記事の中に誤り等ございましたら、コメント欄でご教授いただけると幸いです。　



#対象者

・いいね機能を実装したい方
・フォロー機能を実装したい方

#手順目次
1.redirectの場所にrequest.refererをつける

#実際の手順と実例
###1.redirectの場所にrequest.refererをつける

いいねを押したもしくは消したとき同じ画面に戻る方法は下記の通りです。
実例ではフォロー、フォローを外す機能を参考にしています。

```
class RelationshipsController < ApplicationController

  def create
    @user = User.find(params[:follow_id])
    @following = current_user.follow(@user)
    @following.save
    redirect_to request.referer
  end

  def destroy
    @user = User.find(params[:follow_id])
    following = current_user.unfollow(@user)
    following.destroy
    redirect_to request.referer
  end

end
```


上記のリダイレクト先に注目です！
**redirect_to request.referer**を使うと簡単に同じページに遷移できて便利です！！！