OmniAICreator/Qiita-1.07M huggingface dataset:
VCI初心者100本ノック【survey】

途中ですけど時間が時間なのでupします。
記事書きながら迷走していて時間がなくなりました。継続して更新する所存

#はじめに
VCIって素晴らしい。好きに持ち込んで出せるし、いろんなことをさせられる。
最近udonとかなんとか話が出始めましたが、これを一年近く前に運用開始しているんだから素晴らしい。でも、、、

**めちゃめちゃ敷居が高い！！！**
しかも今VCI作ってる人って、だいたいスキルのある人が多いし、
そんな人と同じレベルを求められても、、、、ぶっちゃけ困ります。
そもそも、どこを調べたらいいのかすらよくわからない。それでいてどんどんバージョンアップするので説明が何を指しているのかリアルタイムで追ってない人はさっぱりわからない。
やってみようにも実例を探すのも一苦労で、、、、（注1）

でもね、始めて見れば案外そこまで難しくない。
**あれ？色々出来て簡単って最高かな？**
VCIの最大の欠点はとっつきにくいことだと思うんです。
せっかく素晴らしいものなのにそのせいで作る人が少ないのはもったいない！ということで私がこういう物があればよかった（いいのに）というものをまとめようという試みです。

##作るもの
基本的に周りの記事の寄せ集めです。題目にあるようにsurveyっぽいものです。その上で、こんなサンプル欲しかったんだけど、、、というものを自分で追加していこうと思います。

##筆者のスペック
- 仕事はモデリングとかゲームとは全然関係ない
- もちろんunityやblenderなんかと関わりも経験も一切ない
- さらに、仕事も大学も非情報系、経験無し
- 3Dモデリングもやったことない
- luaなんてやったことない
- そもそもwindowsパソコンを家でいじり始めたのが今年の6月から
- VCIは20個くらいは作ってる。取り込み数も10を超えるものも

こんなクソ雑魚でもできるんだぞ！！

#お品書き
##VCI
0. 環境構築する
1. TSOにアップロードする
    2. [公式](https://virtualcast.jp/wiki/doku.php?id=seed:upload:vci)
2. cubeを表示する
3. materialを設定する
4. 拡縮できるようにする
5. 拡縮の等方化をする
6. 重力を設定する
7. 止まらなくする
8. emittionを設定する
9. 子オブジェクトを設定する
10. 座標をロックする
11. コライダーを抜く
12. コライダーを調整する
13. istriggerを設定する
14. 画像を入れる・テクスチャを貼る
15. 文字を表示する
16. unityでも日本語文字を表示する
17. 装着可能にする
18. コメントを読み取る
19. VCI作成の環境構築をする
20. パーティクルエフェクトを入れる
21. 他のソフトで作ったモデルを入れる
22. jointを設定する
23. 背景VCIを作る
24. VC内部で更新する
25. ノーマルマップを入れる
26. matcapを入れる
27. 透明にする
28. 透明cutoutする
29. 持てなくする
30. マテリアルについて理解する(unlit,standard,Mtoon)
31. 処理の重さについて理解する
32. 裏側にもテクスチャを貼る
1. 

##スクリプト

1. スクリプトの環境構築をする
    2. [公式](https://virtualcast.jp/wiki/doku.php?id=vscode:tutorial)
2. luaスクリプトを入れてハロワする
    3. [公式](https://youtu.be/n8uW_FgDFVU)
3. サンプルを読んで勉強する
    1. [公式サンプル](https://virtualcast.jp/wiki/doku.php?id=vci:sample)：割とたくさんあるようですが、書きかけみたいな記事も多いです。~~ここよりはマシです~~
3. マテリアルの色を変える
4. 処理の流れを理解する
5. 初期化処理を行う
6. update()
7. updateALL()
8. onGrab()
9. onUnGrab()
10. onUse()
11. onUnuse()
12. onTriggerEnter()
13. onTriggerExit()
14. onCollisionEnter()
15. onCollisionExit()
16. イベントの種類を理解する
17. 所有権を理解する
18. 所有者のみ処理をする
19. _ALLを理解する
20. クォータニオンを理解する
21. オブジェクトを動かす
22. 別のオブジェクトから操作する
23. デバッガを使う
    24. [公式](https://virtualcast.jp/wiki/doku.php?id=vscode:debugger)
24. テクスチャを変更する
25. UVスクロールを設定する
26. エフェクトを再生する
27. ぶつかったときの処理をする
28. モジュールを使う
29. 基本的な文法を確認する
30. コントローラーに触覚を伝える（振動する）
31. コメントを扱う
    1. [公式サンプル：コメントをすると落ちてくるタライ](https://virtualcast.jp/wiki/doku.php?id=vci:sample:message:tarai)
32. カメラを操作する
33. 位置を取得する
34. アニメーションを設定する

##エフェクト
1. 散らばるエフェクト
2. 軌跡が出るエフェクト
3. エフェクトの組み合わせ
4. モデルにエフェクトを適用する
5. エフェクトを入れ子にする

##その他
1. 情報源を確保する（twitter,wiki）
2. バグ報告をする
3. デバッグウィンドウを出す
4. 描画のレベルを調整する
5. VCIの歴史を把握する
6. やりながらデバッグする
    7. [公式](https://youtu.be/-RRrIJt5Txw)：動画です。


なんか作ってるうちにTIPSと混ざってきてる気がするなぁ、、もし充実してきたら分離して別に上げます。

注1:結構な頻度で人に聞くと、「昔はもっとひどかった」みたいなこと言われるんですが、すごいです、真似できないです。だから僕はすごくない人にもやってほしいです。
Wiiリモコンの応用例まとめ

# はじめに
[以前の記事](https://qiita.com/TwDaiki/items/a4ea7d4750ab6459e6cb)でWiiリモコンの楽しさに目覚めてしまい、wiiリモコンやwiiボードの応用例を調べました。
ゲーム操作のほかに、VR、AI、vvvvといった面白い応用例も見つかりました。

# Wiiリモコンの応用例

※WEB記事ベースで項目を列挙していて、似たものは省略しています
※個人的に面白そうなもの順に並べています
※具体的な実現方法が記載されていない参考記事もあります
※「使用するもの」のWiiリモコンやWiiボードは省略しています

#### プロジェクターの映像にペンでタッチ操作をする
  + 参考記事：https://qiita.com/yaju/items/814a556704dfacdce58b  
  + 使用するもの
      + Windows PC（Windows10）
      + 赤外線ペン（100均のマジックライトペンと赤外線LEDで自作する）

#### OculusのコントローラーとしてWiiボードやWiiリモコンを使用する
  + 参考記事：https://qiita.com/n_yositaka/items/51f5347806e622ea915c
  + 使用するもの
      + Mac PC
      + Oculus

#### Wiiボードをパソコンに接続して体重を計測する
  + 参考記事：https://forest.watch.impress.co.jp/article/2008/01/18/wbhealthmeter.html
  + 使用するもの
      + Windows PC（アプリはVista、XP対応となっている....）

#### Wiiリモコンをライトセーバーやマッサージ器にする
  + 参考記事1：https://forest.watch.impress.co.jp/article/2006/12/11/wiisaber.html
  + 使用するもの
      + Windows PC（アプリはXPで動作確認済みとのこと）
  + 参考記事2：http://www.kako.com/neta/2006-019/2006-019.html
  + 使用するもの
      + Windows PC

#### トレーニングデータを収集する際にWiiリモコンでAIカーを操作する
  + 参考記事：https://qiita.com/takeru@github/items/604697225d3214ff0e8b
  + 使用するもの
      + M5StickC
      + M5StickV
      + BeetleC
      + タミヤのボールキャスター
      + ダイソーのスマホ用広角レンズ

#### vvvvを使ってwiiリモコンでダンスパフォーマンスをする
  + 参考記事：[https://qiita.com/Junky_Inc/items/54194266920e1f48b03d...](https://qiita.com/Junky_Inc/items/54194266920e1f48b03d#%E7%94%9F%E3%81%8D%E3%81%A6%E3%81%8F%E4%B8%8A%E3%81%A7%E5%BF%85%E8%A6%81%E3%81%AF%E3%81%AA%E3%81%84%E3%81%93%E3%81%A8%E3%81%93%E3%81%9D%E5%BF%85%E8%A6%81%E3%81%A7%E3%81%82%E3%82%8B)
  + vvvvのwiiリモコン用プラグイン  
https://discourse.vvvv.org/t/wiimote-plugin/3034
  + ビジュアルプログラミング言語「vvvv」をはじめよう！（vvvvの参考記事）    
https://qiita.com/yhy_jp/items/4b4d8841842c17943ca1 

#### Wiiボードを使った幼児用移動ロボットの研究
  + 参考記事：https://naglly.com/archives/2010/08/wii-balance-chair.php

#### ドラクエ10のPC版でWiiリモコン＋ヌンチャク操作を実現する
  + 参考記事：https://qiita.com/eucalyhome/items/3bb0d5be1e8b498ca741
  + 使用するもの
      + Raspberry Pi Zero W(H)  
      　→USBゲームパッドのエミュレーションをさせるっぽい
      + Wiiリモコン用ヌンチャク

#### Wiiリモコンの十字キーでWiiリモコンのLチカをする
  + 参考記事：https://qiita.com/jp-96/items/ff3822ab81f7696172c0
  + 使用するもの
      + ESP32　※ESP-IDFを使用する

#### WiiリモコンでMacのプレゼンアプリ(Keynote)のスライドを操作する
  + 参考記事：https://qiita.com/gungnir_odin/items/995f1ba70fd4e2412a29
  + 使用するもの
      + Mac PC(MacOS X EI Capitan)

#### WiiリモコンでWindows7のゲーム(MacのVMware上で動作)を操作する
  + 参考記事：https://qiita.com/yyu/items/88da95a6c130fca60af7
  + 使用するもの
      + Mac PC

# 雑感

Wiiリモコンは内蔵ハードウェア機能の多さや拡張性にも関わらず、中古ショップでだいたい100円で売られています。
上記の例を参考にすれば、お財布に優しくいろいろ遊べそうです。

# おまけ
#### Wiiリモコンの赤外線センサを外して使用する
  + 参考記事：http://www.kako.com/neta/2007-001/2007-001.html

# 更新履歴
* 2019-12-22：新規作成 
* 2019-12-23：ライトセーバーやマッサージ器の例を追加＆一部の文章表現を見直し 
* 2020-01-05：おまけを追加
ガートナーのバイモーダル論での組織改革のガーディアンという役割

[ガートナーの提唱するバイモーダルIT](https://qiita.com/SoarTec-lab/items/f56b16f55ad6122a4970)という記事でガートナー社の提唱するバイモーダル論をざっくり書きました。

この記事では組織がバイモーダルを使い分けをしようとする、あるいは組織をモード1からモード2に移行しようとした場合の

* 起きる問題
* そこで必要な「ガーディアン」という役割の必要性と意味を書きます。
* 組織デザイン事例
* ガーディアンの素質

について自分の解釈を書こうと思います。

# 起きる問題
そもそも、システムの安定性を重視するモード1とビジネスの変化へのスピードを重視するモード2は、
考え方、開発手法、思想も全く異なるので、
組織の中で分断するとお互いに以下の様な対立関係を生むそうです。

> モード1 -> モード2
> 落ち着きなくチャラチャラした無責任で軽い存在だと煙たがりがち
> モード2 -> モード1
> を古臭く動きが遅い足手まといの恐竜の化石のように感じてしまいがち

# ガーディアンの役割
組織的には対立しがちなモード1, モード2はどちらも必要な思想なので以下のアプローチが必要になってきます。

* システム特性からどちらのモードが適切か判断しバイモーダルを使い分ける。
* 2つのチームの間に入り連携をサポートする事でシステムのQCDの最適化を図る

このアプローチを行う役が正に「ガーディアン」でありバイモーダル組織にとって必須の存在です。

# 組織デザイン事例
ガートナー社はモード1, モード2のチームを別会社にする事を推奨していました。
またタイトルは忘れましたが、バイモーダルの組織改革について書かれている書籍では以下の様に書かれていました。

* 給与体系、組織文化、制度などいわゆる働き方も全く異なるチームなので別会社にする
* エンジニア採用面では、優秀なエンジニアはモード1組織に興味を持たせる事が難しい為、破格の条件で採用するには、社内制度的に無理になるケースが多いのでモード2を別会社にする事で優秀なエンジニアを採用する

大手Sierでも古くから付き合いのある金融系などのモード1チームと、新規事業を専任とするモード2チームを全く部署で分けている会社がありました。

# ガーディアンの素質

* バイモーダルそれぞれの特性を理解している
* システム特性を判断できる
* それぞれの組織文化に敬意を持つ事ができる柔軟さを持っている
* モード2が理解できる最新技術に追従している

## 思ったこと
モード1文化もモード2文化も両方必要。
両方の特性を理解した上で使い分ける事が大事。
組織変革には調整力が必要。
【随時更新】[化学]物性（メモ）

個人的メモです。整理中。


#基本物理的特性
比重
比容積
溶解性
ガス透過性

#機械的性質
加工性、かたさ、弾性・粘性など

(外力の種類による分類)
（1）引張り特性、（2）圧縮特性、（3）曲げ特性、（4）せん断特性など

(外力のかかり方による分類)
（1）静的特性、（2）衝撃特性、（3）クリープ特性・応力緩和特性、（4）疲労特性など

#熱的性質
* 融点 Tm (melting point)

　　固体（結晶）　 → 液体

* ガラス転移温度 Tg (glass transition temperature)

* 結晶化温度(Crystallization temperature)

* 液晶転移温度

* 熱分解温度 Td (thermal degradatioin temperature)
 
熱重量分析にて、一般的には過熱により重量が5wt%減少する温度
熱重量分析(thermogravimetric analysis, TG)　高分子を窒素雰囲気下で加熱したときの重量変化を測定

* 熱伝導率
* 熱膨張率
* 耐熱性(heat resistance)
最も重要な特性の１つだが、定義がありまいで、時と場合のよってTmであったり、Tgであったりする。

熱変形温度(heat distortion temprature)
荷重たわみ温度(load deflection temprature)
 

#電気的的性質
誘電率
導電性

#光学的性質
透明性
屈折率


#化学的特性
耐薬品性、生体適合性

#成形加工性

#耐環境特性
文言縦書きレンダリングに挑戦

## はじめに

[前回](https://qiita.com/libru1/items/e0db075a535277f9fa99)

linuxっぽいデバイスエラー
/dev/stdoutや/dev/nullとか指定出来ないパスエラーに悩まされつまづいていました

## 実行
レンダリング処理はソースファイルを読み、縦書きにレンダリングし、svgファイルとして出力します。

/dev/stdout 標準出力が割り当てられないなら、実際のファイルを割り当てる方法があれば出力出来るかも。

ソースファイルをrenderでgrep しました。
functon renderで実装されているので引数で渡す方法を探します。

ソースはimportではなく、requireで、node_modulesフォルダも無いので頑張れば読めるかもしれません。

わからないなりに格闘。自前で呼ぶ関数を実装を試みました。

が、しかし、コマンドラインに渡す口がありそうです。

usageとにらめっこし、よく読んでみると、
outputオプションで行けそうです

```sh
node ./build/wenyan.js —render helloworld.wy —output ./renders/helloworld.svg
```

エラーが消えました。
rendersフォルダの中を見ると、ファイルが出来ました。
何故かファイル名がhelloworld.svg.000.svgで中身は一文字もありません。

文字はありませんが、古文書風の用紙、見ていて美しさにテンションあがります。

ソースの指定を見直し、再実行

```sh
node ./build/wenyan.js —render ./examples/helloworld.wy —output ./renders/helloworld.svg
```

な、なんとsvgのファイルサイズ増えました。
ドキドキしながらブラウザで表示してみると、縦書きのソースコード入りで表示出来ました。

ビルドエラー出てたけど、上手く行ってたのでしょうか。

念のため、ビルド前のwenyan.jsで実行してみると、…

同じファイルが作成されました。

今までの試行錯誤を思い、自分のレベルの低さに悲しくなりましたが、ソース出力は嬉しくてサンプルソース、片っ端から生成しました。

## おわりに

ファイル名が不思議な感じですが、生成された縦書きソースはうっとりです。

引き続き、仕組みを見ていきたいです。
Reactで投稿のIDを取得する

# はじめに

[いなたつアドカレ](https://qiita.com/advent-calendar/2019/allinatatsu)の二十二日目の記事です。

もうすぐ終わりですね。。。

今回はReactでURLから投稿などのIDを取得する方法の備忘録です。

## じっそー

```jsx:App.js
import React from 'react';
import { BrowserRouter as Router, Route } from 'react-router-dom'

function App() {
  return (
    <Router>

        <Route exact path='/:id' component={Hoge} />
    </Router>

  );
}


export default App;
```

`/:id`のURLでHogeのコンポーネントというRouteの定義ができました。

```js
const id = props.match.params.id
```
Hogeのコンポーネントで上のようにすることで、idを使用できます

このidを使ってAPiを叩くなりしましょ
v-modelの使い方と双方向データバインディング


# フォーム入力バインディング

フォーム（`input要素`, `select要素`, `textarea要素`など）の入力値 / 選択値を`vueインスタンス`の**data**を同期させる 「**双方向データバインディング**」を行うには`v-model`ディレクティブを使用する。

```index.html
<div id="app">
  <input v-model="message">
  <p>{{ message }}</p>
</div>
```

```vue.js

new Vue ({
  el: '#app',
  data: {
    message: ''
  }
})
```

`v-modelディレクティブ`は次の2つの処理を一つにまとめています。
（１） **データバインディングで、要素のvalue属性（値）を更新する**

```
v-bind:value="message"
```

（２） **イベントハンドリング（イベントが発生したときに呼び出される処理）で、受け取った値をデータに代入**

入力フォームにユーザが入力

↓ 　**inputイベント**が発生

```
this.message = event.target.value
```
で値を得られる。
messageプロパティの値が変更されます。

DOM要素へのデータバインディングと、要素から取得したデータをリアクティブデータに反映させるこの2つの処理を自動化した構文が**`v-model`**


# ラジオボタン

ラジオボタンのデフォルトの値の方は**文字列**

```index.html

<div>
    <span>性別:</span>
    <label>
      男性
      <input type="radio" value="male" v-model="form.sex">
    </label>
    <label>
      女性
      <input type="radio" value="female" v-model="form.sex">
    </label>
    <p>性別: {{ getRadioValue }}</p>
  </div>
```

```vue.js

data: {
  return {
    //省略
    form: {
      sex: '',

    },
  }
},
```

`value属性`の値がバインディングされるので female / male のどちらかが
`data`の中の`sex`プロパティへ代入されます。


# セレクトボックス

```index.html
<div>
  <select v-model="form.selected">
    <option disabled value="">--選択してください--</option>
    <option>A</option>
    <option>B</option>
    <option>C</option>
    <option>D</option>
  </select>
</div>
```

【 **単数選択** 】

```vue.js
data: {
  return {
    //省略
    form: {
      selected: ''
    },
  }
},
```

【 **複数選択** 】

```vue.js
data: {
  return {
    //省略
    form: {
      selected: []
    },
  }
},
```

#  チェックボックス

チェックボックスのデフォルト値の値の型は`Boolean`

```index.html

<div>
  <label>
    <input type="checkbox" v-model="form.checked">
    20際以上です
  </label>
</div>
```

```vue.js
data: {
  return {
    //省略
    form: {
      checked: true
    },
  }
},
```
【Laravel】boolean型へのキャスト

###boolean型（理論型）とは
phpのマニュアルによれば、「boolean は、真偽の値を表します。 この値は、TRUE または FALSE のどちらかになります。」とのこと。

つまりboolean型には「TRUE」と「FALSE」の2種類の値にしかならない。

###型をキャスト（変換）すると
boolean型へのキャストを行うと次の値は「**FALSE**」と判定される。

・boolean の FALSE
・integerの0
・floatの0.0
・空の文字列、および文字列の "0"
・要素の数がゼロである配列
・NULL
・空のタグから作成された SimpleXML オブジェクト

```php
var_dump((bool) false);    // bool(false)
var_dump((bool) 0);        // bool(false)
var_dump((bool) 0.0);      // bool(false)   
var_dump((bool) "");       // bool(false)
var_dump((bool) "0");      // bool(false)
var_dump((bool) []);       // bool(false)
var_dump((bool) NULL);     // bool(false)

```
これら以外の値はTRUEとなる

###判定処理への利用

DBテーブル内にその値があるかどうかの判定
例）指定したIDのユーザが存在するかどうか

```php:User.php
return (boolean) $this->where("id",$user->id)->first();
```
first()で取り出したデータはオブジェクト型のデータとなるが、存在しない場合NULL値となるためFALSEを返す。

これだったらis_null()やempty()でいいかも。
非同期処理の例外処理の書き方

promiseとasync awaitの例外処理の書き方を紹介します。

# promiseの場合
与えられた引数を２倍にして、コンソールに描画するメソッドを例にして説明します。
２倍にするメソッドとして、doubleメソッドを作ります。
doubleメソッドの引数に１０を与えて、console.logを実行すると２０が表示されます。

```react
const double = (number) => {
  return new Promise(resolve=>{
    resolve(number * 2)
  })
}

double(10)
  .then(num => console.log(num))
// 実行結果： 20
```

続けて、doubleメソッドの中で例外を発生させます。

```react
const double = (number) => {
  return new Promise(resolve=>{
    // 意図的に例外を発生
    throw new Error('エラーが発生しました')
    resolve(number * 2)
  })
}

double(10)
  .then(num => console.log(num))
// 何も表示されない
```

例外が発生した時に、受け取る処理を書かないと何も表示されません。
これでは、システム内でエラーが発生しても何も通知されないことになります。

では、例外処理を書いていきます。
promiseオブジェクトはcatchメソッドが使えるので、thenに続けてcatchを記述します。

```react
const double = (number) => {
  return new Promise(resolve=>{
    // 意図的に例外を発生
    throw new Error('エラーが発生しました')
    resolve(number * 2)
  })
}

double(10)
  .then(num => console.log(num))
  .catch(error => {
    // 例外が発生するとcatchに入る
    console.log(error.message)
  })
// 実行結果： エラーが発生しました
```

doubleメソッド内でエラーが発生した時にthenメソッドを飛ばしてcatchメソッドに処理が移行します。
catchメソッド内でerror.messageと記述すると、new Errorで設定した「エラーが発生しました」というメッセージを表示するとことができます。

ちなみに、thenとcatchがチェーンになっている場合、以下のような動きになります。

```react
const printA = () => {
  console.log('A')
}
const printB = () => {
  console.log('B')
}
const printC = () => {
  console.log('C')
}
const rejected(){
  console.log('reject')
}

// パターンA
Promise.resolve()
  .then(printA)
  .then(printB)
  .catch(rejected)
  .then(printC)

// 実行結果
// A
// B
// C

// パターンB
Promise.reject()
    .then(printA)
    .then(printB)
    .catch(rejected)
    .then(printC)

// 実行結果
// reject
// C
```

パターンA:
例外が発生しなかった場合、catchメソッドは実行されずに次のthenメソッドまで処理が移行します。

パターンB：
例外が発生した場合、catchメソッドまで処理が移行した後、thenメソッドが実行されます。


# async awaitの場合

promiseの時と同じく、与えられた引数を２倍にして、コンソールに描画するメソッドを例にして説明します。

```react
const double = async (number) => {
  return (number * 2)
}

const exec = async () => {
  const result = await double(10)
  console.log(result)
}

exec()
// 実行結果： 20
```

正常に結果が返り、２０と表示されました。
続いて、例外処理を書いていきます。
async awaitの場合はtry-catch文を使います。

```react
const double = async (number) => {
  throw new Error('エラーが発生しました')
  return (number * 2)
}

const exec = async () => {
  try {
    const result = await double(10)
    console.log(result)
  } catch (e) {
    console.log(e.message)
  }
}

exec()
// 実行結果： エラーが発生しました
```

例外が発生して、catch文に処理が移行したことを確認できました。

# まとめ
システムにエラーは付きもので、エラーが起きた時にcatchする機能がないとユーザには何も通知されずに利便性の悪いものになってしまいます。
なので、適切な場所に例外処理を記述することをお勧めします。

# おまけ

try-catch文の中で、promiseのcatchを書くとどうなるでしょう？
やってみましょう。

```react
const double = number => {
  return new Promise(resolve=>{
    // 意図的に例外を発生
    throw new Error('エラーが発生しました')
    resolve(number * 2)
  })
}

try {
  double(10)
    .then(num => console.log(num))
    .catch(error => {
      // promiseのcatch処理
      console.log('promiseのcatch処理')
  })
} catch {
  // try-catchのcatch処理
  console.log('try-catch文のcatch処理')
}
// 実行結果： promiseのcatch処理
```

結果より、try-catch文のcatchには入らずに、promiseのcatchの中の処理が実行されました。

# 参考
https://numb86-tech.hatenablog.com/entry/2017/01/02/152517
Django学習とWebDriverでのテスト [その１]

# 目的
Djangoの開発の学習として、Tutorialを実装します。
その際に自動テストも行い、Djangoの自動テストを行うためのseleniumの学習も行います。


# 環境構築
## docker環境構築
dockerの環境構築は完了している前提で作業します。
参照：[Docker上でDjango開発準備](https://qiita.com/tkhr68000/items/3fb672e2f588874ed9f5)

## selenium環境構築
最小限のselenium環境構築は完了している前提で作業します。
参照：[pythonでWebDriverを駆動](https://qiita.com/tkhr68000/items/5713c02baf88951ac953)

# チュートリアル１の自動テスト

## アプリ作成
以下のURLを参照にし、アプリを作成してみます。
[はじめての Django アプリ作成、その 1](https://docs.djangoproject.com/ja/3.0/intro/tutorial01/)
以下のURLにアクセスし、表示されることを確認します。
`http://127.0.0.1:8000/polls/`

## スクリプト作成
スクリプトを作成します。

``` test_01_polls.py
from selenium import webdriver

# EdgeDriver
driver = webdriver.Edge()
# URL
driver.get("http://localhost:8000/polls/")
# screenshot
driver.save_screenshot("01_polls.png")

```

## 実行
スクリプト実行してみます。

```
python .\test_01_polls.py
```

## 結果確認
うまく動作すれば、画面がキャプチャされて「01_polls.png」が作成されているはずです。
Using left join and name column in Model at Laravel Eloquent.

## Environment

```
Laravel Framework 6.5.2
```

## Example

```php
<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Facades\DB; // for giving alias to base table

class TableA extends Model
{

    protected $table='table_a';

    public static function getList()
    {
        return DB::table('table_a as a')
            ->leftJoin('table_b as b', 'b.id', '=', 'a.b_id')
            ->get([
                'a.id',
                'b.id as b_id',
                'a.created_at as created_at'
            ]);
    }
}
```

## Note

If each table have created_at and you don't narrow one created_at explicitly, you'll face an error like below

```
SQLSTATE[23000]: Integrity constraint violation: 1052 Column 'created_at' in order clause is ambiguous
```
小さくて早い？Svelteとは

この記事は[FIXER Advent Calendar 2019](https://adventar.org/calendars/4579) 22日目の記事で[cloud.config Tech Blog](https://tech-blog.cloud-config.jp/)にマルチポストされています。

# Svelte
昨今よく使われているVirtualDOMを使用したReactやVueのようなJaveScriptライブラリを見かけますが、Svelteはそれらと違い、.svelteという拡張子のファイルからhtml、css、JavaScriptを吐き出してくれるコンパイラとなっています。
  
## VirtualDOMを使用するフレームワークと比べて何がいいの？
VirtualDOMは変更を比較する際に、VirtualDOMの再構成をし前回との差分を見るという手順を踏む必要があります。それではどうしても無駄な比較が多くなってしまいます。しかし、Svelteはビルド時にアプリケーション内の変更される場所を認識するコンパイラなためVirtualDOMに比べて比較処理は少なくなります。
  
## 記法について
ReactやVueとの比較を書こうと思ったのですが公式にちょうど良い例があったので引用させていただきます。

***React***

```react:React
import React, { useState } from 'react';

export default () => {
  const [a, setA] = useState(1);
  const [b, setB] = useState(2);

  function handleChangeA(event) {
    setA(+event.target.value);
  }

  function handleChangeB(event) {
    setB(+event.target.value);
  }

  return (
    <div>
      <input type="number" value={a} onChange={handleChangeA}/>
      <input type="number" value={b} onChange={handleChangeB}/>

      <p>{a} + {b} = {a + b}</p>
    </div>
  );
};
```
<br/>***Vue***

```vue:Vue
<template>
  <div>
    <input type="number" v-model.number="a">
    <input type="number" v-model.number="b">

    <p>{{a}} + {{b}} = {{a + b}}</p>
  </div>
</template>

<script>
  export default {
    data: function() {
      return {
        a: 1,
        b: 2
      };
    }
  };
</script>
```
<br/>***Svelte***

```:Svelte
<script>
	let a = 1;
	let b = 2;
</script>

<input type="number" bind:value={a}>
<input type="number" bind:value={b}>

<p>{a} + {b} = {a + b}</p>
```
これらのコードは同じ動きをしますが、コード量を比較すると差が一目瞭然ですね。
  
## 個人的に好きなところ
- 上のコードでもわかるのですが、複数のコンポーネントを返すことができる点です。Reactのように`React.Flagment`で囲ったり、Vueのように`template`で加工必要もありません。毎回インデントの階層を増やして囲むのを面倒に思っていた自分からしたらとても嬉しい仕様です。
- もう一つは、ReduxやVuexのような状態管理が機能として実装されている点です。
新しくパッケージを追加する必要がなく

```:store.js
import { writable } from 'svelte/store';

export const text = writable("hello world");
```

これだけの記述で宣言する事ができます。  

storeの中身を操作したいときも

```:ChangeText.svelte
<script>
	import { text } from './store.js';

	function changeText() {
		text.update(() => "CLICK BUTTON!");
	}
</script>

<button on:click={changeText}>
	Click me
</button>
```
このようにupdateを呼び出して値を更新するだけです。 
あとはstoreの値を使いたいところで以下のように記述するのみです。

```:App.svelte
  let store_text
  text.subscribe(value => {
    store_text = value;
  });
```

公式のページに親切に各機能の書き方がわかりやすく見れるようになっていて、サンプルを元にしてその場で書き換えることができるためとても便利です。  
https://svelte.dev/examples#hello-world
- 上の例の種類を見ても分かる通り公式ページが便利でわかりやすくとっつきやすい点も好きでおすすめできる点です。[REPL](https://svelte.dev/repl)が実装されているため、わざわざ環境を整えずにコードの動作を確かめることができます。

## おわり
読んだことや書いたことがある人ならわかると思うのですが、個人的には[Riot.js](https://riot.js.org/ja/)や[Vue.js](https://jp.vuejs.org/index.html)に似た文法だと感じました。
個人的にどう発展していくか注目していきたいライブラリです。

今回、Svelteの紹介のみの記事になってしまったのですが、次はSvelteで何かを作って記事を書くことを自分への課題にして終わりとします。
Spring Fest 2019 スライド一覧

## 概要
Spring Fest 2019に参加してきました。
その際の、登壇スライドのまとめとなります。

---
## 基調講演 From Spring Boot 2.2 to Spring Boot 2.3 
- [From Spring Boot 2.2 to Spring Boot 2.3 ](https://www.slideshare.net/makingx/from-spring-boot-22-to-spring-boot-23-jsug)

## Spring Boot アプリの運用が楽になる？ Pivotal と Microsoft が共同開発した専用 PaaS「Azure Spring Cloud」のご紹介 !!
- [Azure Spring Cloud の環境構築方法のご紹介 \| 寺田　佳央 - Yoshio Terada](https://yoshio3.com/2019/12/20/how-to-configure-the-azure-spring-cloud/)

## Spring Boot爆速開発超絶技巧
- [Spring Boot爆速開発超絶技巧 #jsug #boot / Spring Boot & IntelliJ IDEA technique - Speaker Deck](https://speakerdeck.com/yusuke/spring-boot-and-intellij-idea-technique)

## 入社1年目のプログラミング初心者がSpringを学ぶための手引き 
- [入社1年目のプログラミング初心者がSpringを学ぶための手引き](https://www.slideshare.net/KouheiToki/1spring)

## LINE公式アカウントのチャットシステムにおけるSpringおよびWebFluxの活用事例
- [LINE公式アカウントのチャットシステムにおけるSpringおよびWebFluxの活用事例 / Examples of using Spring and WebFlux in the chat system for LINE official accounts - Speaker Deck](https://speakerdeck.com/line_developers/examples-of-using-spring-and-webflux-in-the-chat-system-for-line-official-accounts)


## 徹底解剖Spring MVCアーキテクチャー -DispatcherServletの中身を覗いてきました-
- [【Spring fest 2019】徹底解剖Spring MVCアーキテクチャー](https://www.slideshare.net/ssuser070fa9/spring-fest-2019spring-mvc)

## NissanConnectの舞台裏で動くSpring Boot／Spring Cloud 〜Microserviceの実運用の事例〜
- [Spring Boot and Spring Cloud Inside NissanConnect at SPRING FEST '19](https://www.slideshare.net/DaisukeMorishita1/spring-boot-and-spring-cloud-inside-nissanconnect-at-spring-fest-19)

## 無茶振りMicrometerの話
- [無茶振りMicrometerの話 - Google スライド](https://docs.google.com/presentation/d/1ChFvgyxoqlA2eX4bwse1VC9vcFpiFYtFSVV1YqbBzt4)

## システム間連携を担うSpring Integrationのエンタープライズ開発での活用
- [システム間連携を担うSpring Integrationのエンタープライズ開発での活用](https://www.slideshare.net/apkiban/spring-integration-207667949)

## RSocket徹底入門 ~Spring 5.2の目玉機能であるRSocket対応とは~
- [RSocket徹底入門 - Google スライド](https://docs.google.com/presentation/d/1ygSM85-RQ3NZjCg6RaZ52mGzxbWiItVwzlCpr1vaWBw/edit#slide=id.g75f375afa0_0_0)


## Quarkus による超音速な Spring アプリケーション開発
- [Quarkus による超音速な Spring アプリケーション開発](https://www.slideshare.net/ChihiroIto1/quarkus-spring)

## JSP/JSF から Spring Web + Thymeleaf への移行
- [Practical migration from JSP to Thymeleaf](https://www.slideshare.net/ssuser2e0217/practical-migration-from-jsp-to-thymeleaf)

## Spring Social でソーシャルログインを実装する
- [Spring Social でソーシャルログインを実装する](https://www.slideshare.net/rakutentech/spring-social-206911643)

## Springアプリケーションのテスト道具 使いどころ、使わないどころ
- [Springアプリケーションのテスト道具 使いどころ、使わないどころ / decide-to-use-test-tool-for-spring-application - Speaker Deck](https://speakerdeck.com/irof/decide-to-use-test-tool-for-spring-application)


## Spring with React for Enterprise Application
- [Spring with React for Enterprise Application - Speaker Deck](https://speakerdeck.com/sdaigo/spring-with-react-for-enterprise-application)
【Rails serve】Rails サーバーを起動できない場合

#rails server でサーバーが起動できない場合
以下のようなエラーが出る時、
``
Traceback (most recent call last):
	68: from bin/rails:4:in `<main>'
	67: from /Users/yu/.rbenv/versions/2.6.5/lib/ruby/gems/2.6.0/gems/activesupport-6.0.2.1/lib/active_support/dependencies.rb:325:in `require’
	66: from /Users/yu/.rbenv/versions/2.6.5/lib/ruby/gems/2.6.0/gems/activesupport-6.0.2.1/lib/active_support/dependencies.rb:291:in `load_dependency’
	65: from /Users/yu/.rbenv/versions/2.6.5/lib/ruby/gems/2.6.0/gems/activesupport-6.0.2.1/lib/active_support/dependencies.rb:325:in `block in require’
	64: from /Users/yu/.rbenv/versions/2.6.5/lib/ruby/gems/2.6.0/gems/bootsnap-1.4.5/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:30:in `require’
	63: from /Users/yu/.rbenv/versions/2.6.5/lib/ruby/gems/2.6.0/gems/bootsnap-1.4.5/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:21:in `require_with_bootsnap_lfi’
	62: from /Users/yu/.rbenv/versions/2.6.5/lib/ruby/gems/2.6.0/gems/bootsnap-1.4.5/lib/bootsnap/load_path_cache/loaded_features_index.rb:92:in `register’
	61: from /Users/yu/.rbenv/versions/2.6.5/lib/ruby/gems/2.6.0/gems/bootsnap-1.4.5/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:22:in `block in require_with_bootsnap_lfi’
``

この後もエラー文が長々と続きますが、何やらWebpackerというパッケージがインストールできていないようなので
``rails webpacker:install``
と、アプリディレクションで入力して、再度Rails サーバーを起動すれば、エラー文が解消され、無事、Railsサーバーを起動することができました！！！✨

エラー文は最後までしっかり読みましょう！
何かしらのヒントがそこに必ずあります！👌

### 補足
webpackerというのは、2015年に登場した、CSS、Javascript、画像などをまとめるモジュールバンドラー（require で表現された依存関係を解決してゆき、 コンパイルする際にそれらを全て内包したファイルを作ってくれるのが一般的なモジュールバンドラー）で、Node.jsのモジュールの一つらしいです
参考：
Webpackerとは
https://www.sejuku.net/blog/68146

モジュールバンドラーとは
https://blog.mach3.jp/2016/10/01/module-bundler.html
【Amazon ElastiCache】 Rails設定

#AWS側の設定
参考
https://qiita.com/leomaro7/items/f031cfdd7d12d5d5ccc5
https://lab.sonicmoov.com/development/aws/elasticache/

#Rails側の設定

```config/environments/staging.rb
  config.session_store :redis_store, {
    servers: {
        host: '[プライマリエンドポイント]',
        port: 6379,
        db: 0,
        namespace: 'sessions'
    },
   expire_after: 60.minutes
  }
```


```config/initializers/sidekiq.rb
Sidekiq.configure_server do |config|
  case Rails.env
    when 'staging' then
      redis_conn = proc {
        Redis.new(host: 'プライマリエンドポイント', port: 6379, db: 2)
      }
      config.redis = ConnectionPool.new(size: 27, &redis_conn)
    else
      config.redis = { url: 'redis://127.0.0.1:6379' }
  end
end

Sidekiq.configure_client do |config|
  case Rails.env
    when 'staging' then
      redis_conn = proc {
        Redis.new(host: 'プライマリエンドポイント', port: 6379, db: 2)
      }
      config.redis = ConnectionPool.new(size: 27, &redis_conn)
    else
      config.redis = { url: 'redis://127.0.0.1:6379' }
  end
end
```
よく使う カラムレイアウトのマークアップ

めちゃめちゃよく使うので、今更ながらメモに残しとく😋

左右のmarginは、.listItem + .listItemで、
上下のmarginは、2段目から取るようにしています。
左に左に、上に上に、marginをつけます。

こんな感じ↓
![名称未設定ファイル (1).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/527850/1361f6d2-6bf4-9838-1ea7-e8b613a66349.png)



# PCで2カラム、SPで1カラム
![名称未設定ファイル (2).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/527850/6540d12c-d1e7-e039-7bdb-3374af43f5eb.png)

```index.html 
<ul class="col2List">
  <li class="col2ListItem"></li>
  <li class="col2ListItem"></li>
  <li class="col2ListItem"></li>
  <li class="col2ListItem"></li>
  <li class="col2ListItem"></li>
</ul>
```

```style.scss 
* {
  margin: 0;
  padding: 0;
}
.col2List {
  display: flex;
  flex-wrap: wrap;
  @media (max-width: 640px) {
    display: block;
  }
  .col2ListItem {
    width: 48%; // デザインにより変更
    @media (max-width: 640px) {
      width: 100%;
    }
  }
}
.col2ListItem + .col2ListItem {
  margin-left: 4%; // デザインにより変更
  @media (max-width: 640px) {
    margin-left: 0;
    margin-top: 7vw; // デザインにより変更
  }
}
@media (min-width: 641px) {
  .col2ListItem:nth-child(n + 3) {
    margin-top: 4.8%; // デザインにより変更
  }
  .col2ListItem:nth-child(2n + 1) {
    margin-left: 0;
  }
}
```
# PCで3カラム、SPで1カラム
![名称未設定ファイル.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/527850/4ba6f02d-73f7-2f0f-78af-bcc2de09ef62.png)


```index.html 
<ul class="col3List">
  <li class="col3ListItem"></li>
  <li class="col3ListItem"></li>
  <li class="col3ListItem"></li>
  <li class="col3ListItem"></li>
  <li class="col3ListItem"></li>
</ul>
```
```style.scss 
* {
  margin: 0;
  padding: 0;
}
.col3List {
  display: flex;
  flex-wrap: wrap;
  @media (max-width: 640px) {
    display: block;
  }
  .col3ListItem {
    width: 30%; // デザインにより変更
    @media (max-width: 640px) {
      width: 100%;
    }
  }
}
.col3ListItem + .col3ListItem {
  margin-left: 5%; // デザインにより変更
  @media (max-width: 640px) {
    margin-left: 0;
    margin-top: 7vw; // デザインにより変更
  }
}
@media (min-width: 641px) {
  .col3ListItem:nth-child(n + 4) {
    margin-top: 4.8%; // デザインにより変更
  }
  .col3ListItem:nth-child(3n + 1) {
    margin-left: 0;
  }
}

```

# PCで4カラム、SPで1カラム
![名称未設定ファイルのコピー.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/527850/3212b90b-3377-6865-09f7-99cf5812c8f3.png)

```index.html 
<ul class="col4List">
  <li class="col4ListItem"></li>
  <li class="col4ListItem"></li>
  <li class="col4ListItem"></li>
  <li class="col4ListItem"></li>
  <li class="col4ListItem"></li>
  <li class="col4ListItem"></li>
</ul>
```
```style.scss 
* {
  margin: 0;
  padding: 0;
}
.col4List {
  display: flex;
  flex-wrap: wrap;
  @media (max-width: 640px) {
    display: block;
  }
  .col4ListItem {
    width: 23%; // デザインにより変更
    @media (max-width: 640px) {
      width: 100%;
    }
  }
}
.col4ListItem + .col4ListItem {
  margin-left: 2.5%; // デザインにより変更
  @media (max-width: 640px) {
    margin-left: 0;
    margin-top: 7vw; // デザインにより変更
  }
}
@media (min-width: 641px) {
  .col4ListItem:nth-child(n + 5) {
    margin-top: 2.5%; // デザインにより変更
  }
  .col4ListItem:nth-child(4n + 1) {
    margin-left: 0;
  }
}

```
ROSで移動したワークスペースごとに自動でsetup.bashを読み込むための環境構築

# 概要

本記事では`direnv`の簡単な使い方と，導入方法について紹介します．

# 動機
ROSで複数のワークスペースを使い分けていると，ワークスペースごとに`source devel/setup.bash`をする必要があり地味に面倒なので，自動化できないかなあと調べていました．

# 環境

Ubuntu 16.04
他のバージョンでも多分できます．

# 方法

`direnv`なるものがあり，これをを使用すると，それぞれのワークスペースルートディレクトリに移動するだけで，setup.bash自動で読み込んでくれるらしい．

## direnv導入方法

とても参考になる記事([direnvを使おう](https://qiita.com/kompiro/items/5fc46089247a56243a62))を発見したので，基本的にはこの記事通りに設定すれば環境構築はできそうです．

### `go command not found`

[direnvを使おう](https://qiita.com/kompiro/items/5fc46089247a56243a62)を参考にインストールしようと「goコマンドが見つかりません」なるエラーが発生．

確かにGoは導入した記憶がないので，新しく入れる必要がありそうです．

# Go のインストール

ここでは，`direnv`で使用している`go`の最新版を`apt install`で導入するための方法を紹介します．


### 通常の`apt-repository`では`go`の最新版が手に入らない可能性がある

今話題のGoは`apt install`で簡単にインストールすることができます． **しかし，apt-repositoryにあるバージョンに注意しなければなりません**．

筆者の環境で何も考えずに下記のようにgoをインストールした場合．．．

```
$ sudo apt update
$ sudo apt install golang-go
```

インストールされたのは`go 1.6`. 2019年12月現在の最新版は`go 1.13`のため，かなり古いバージョンがインストールされてしまっています．
`direnv`では，最低でも`go 1.8`以降のバージョンが必要なため，これでは`direnv`を使用することができません．

### `golang-go`の最新版をインストールするために`apt-repository`を更新

そこで，最新バージョンを手に入れるために，[ここ](https://github.com/golang/go/wiki/Ubuntu)を参考に `apt-repository`を更新し，再度インストールします．

```
$ sudo add-apt-repository ppa:longsleep/golang-backports
$ sudo apt-get update
$ sudo apt-get install golang-go
```

念の為，バージョンを確認してみると

```
$ go version
go version go1.13.4 linux/amd64
```

となり，無事最新版をインストールすることができました．

# direnvのインストール

ついでにdirenvのインストール方法も記載しておきます．

```
$ git clone https://github.com/direnv/direnv
$ cd direnv
$ sudo make install
```

~/.bashrcに下記を追記

```~/.bashrc
export EDITOR=vim  # 好きなエディタを指定できます．今回はvimを使用．
eval "$(direnv hook bash)"
```

## 使い方

例えば`/home/user/`以下に`catkin_ws`と`hoge_ws`があったとすると，それぞれのディレクトリにて，下記を実行します．


```
// ワークスペースに移動
$ cd ~/{ws_roos}

// .envrcの作成/編集
$ direnv edit .
```

作成した`.envrc`を下記のように編集．

```~/{ws_root}/.envrc
source deve/setup.bash
## outputが欲しい場合は下記を追加
# echo Auto sourcing source deve/setup.bash
```

これでワークスペースに移動するだけでsetup.bashを自動で読み込んでくれます．

# まとめ

「ROS 複数ワークスペース setup.bash 自動」で検索してもなかなか欲しい答えにたどり着けないものですね…

# 参考

- [direnvを使おう](https://qiita.com/kompiro/items/5fc46089247a56243a62)
- [Github golang/go](https://github.com/golang/go/wiki/Ubuntu)
ruby on railsをcircle ciでテストする


## CircleCiの設定ファイル

```.circleci/config.yml
# Ruby CircleCI 2.0 configuration file
#
# Check https://circleci.com/docs/2.0/language-ruby/ for more details
#
version: 2
jobs:
  build:
    docker:
      # specify the version you desire here 
      - image: circleci/ruby:2.6.5-node-browsers
        environment:
          BUNDLER_VERSION: 2.0.1
      # Specify service dependencies here if necessary
      # CircleCI maintains a library of pre-built images
      # documented at https://circleci.com/docs/2.0/circleci-images/
      # - image: circleci/postgres:9.4

    working_directory: ~/repo

    steps:
      - checkout

      - run:
          name: setup bundler
          command: |
            sudo gem update --system
            sudo gem uninstall bundler
            sudo rm /usr/local/bin/bundle
            sudo rm /usr/local/bin/bundler
            sudo gem install bundler
        # Download and cache dependencies
      - restore_cache:
          keys:
            - v1-dependencies-{{ checksum "Gemfile.lock" }}
            # fallback to using the latest cache if no exact match is found
            - v1-dependencies-

      - run:
          name: install dependencies
          command: |
            yarn install --check-files
            bundle install --jobs=4 --retry=3 --path vendor/bundle

      - save_cache:
          paths:
            - ./vendor/bundle
          key: v1-dependencies-{{ checksum "Gemfile.lock" }}

      # Database setup
      - run: bundle exec rake db:create
      - run: bundle exec rake db:schema:load

      # run tests!
      - run:
          name: run tests
          command: |
            mkdir /tmp/test-results
            TEST_FILES="$(circleci tests glob "spec/**/*_spec.rb" | \
              circleci tests split --split-by=timings)"

            sudo gem install bundler
            sudo gem install rspec
            sudo gem install rspec-core
            bundle exec rspec \
              --format progress \
              --format RspecJunitFormatter \
              --out /tmp/test-results/rspec.xml \
              --format progress \
              $TEST_FILES

      # collect reports
      - store_test_results:
          path: /tmp/test-results
      - store_artifacts:
          path: /tmp/test-results
          destination: test-results

```

## GemFileの設定

```Gemfile
group :development, :test do
  # Call 'byebug' anywhere in the code to stop execution and get a debugger console
  gem 'byebug', platforms: [:mri, :mingw, :x64_mingw]
  gem 'sqlite3', '~> 1.4'
  gem 'rspec'
  gem 'rspec-core'
  gem 'rspec_junit_formatter'
end

```

## bundle installする

```
bundle install --without production
```

## すべてコミットしてPUSH

```
git add .
git push origin master
```
macOSをCatalinaにしたらdotnet new出来なくなったのを解決した

初投稿です。

# 発生した環境
- macOS Mojave --> Catalinaにアップデートした
- ルートディレクトリに、`dotnet new`で使用するテンプレートを置いている
- dotnet CLIを使用している

# goal
`dotnet new`を実行して、exceptionが発生しなくなること

# 起きる条件
- macのルートディレクトリ配下に、`dotnet new --install`でインストール出来るテンプレートを置いてた
- macOSをCatalinaにアップデートする(今回はMojaveからアップデートした)
- アップデートの影響で、ルートディレクトリ配下に置いてたテンプレートが`Relocated Items`ディレクトリに移動させられると発生

# 起きるとどうなるか
- `dotnet new`や`dotnet new console`すると、下記のexceptionが発生するようになった
- `/HogeTemplate`ディレクトリにテンプレートを置いていた場合、下記のようなエラーメッセージになる

```
Could not find a part of the path '/MyDotnetTemplates/HogeTemplate'.
   at System.IO.Enumeration.FileSystemEnumerator`1.CreateDirectoryHandle(String path, Boolean ignoreNotFound)
   at System.IO.Enumeration.FileSystemEnumerator`1.Init()
   at System.IO.Enumeration.FileSystemEnumerator`1..ctor(String directory, Boolean isNormalized, EnumerationOptions options)
   at System.IO.Enumeration.FileSystemEnumerable`1..ctor(String directory, FindTransform transform, EnumerationOptions options, Boolean isNormalized)
   at System.IO.Enumeration.FileSystemEnumerableFactory.UserEntries(String directory, String expression, EnumerationOptions options)
   at System.IO.Directory.InternalEnumeratePaths(String path, String searchPattern, SearchTarget searchTarget, EnumerationOptions options)
   at System.IO.Directory.EnumerateFileSystemEntries(String path, String searchPattern, SearchOption searchOption)
   at Microsoft.TemplateEngine.Utils.PhysicalFileSystem.EnumerateFileSystemEntries(String directoryName, String pattern, SearchOption searchOption)
   at Microsoft.TemplateEngine.Edge.Settings.Scanner.DetermineDirectoriesToScan(String baseDir)
   at Microsoft.TemplateEngine.Edge.Settings.Scanner.Scan(String baseDir, Boolean allowDevInstall)
   at Microsoft.TemplateEngine.Edge.Settings.TemplateCache.Scan(String installDir, IReadOnlyList`1& mountPointIdsForNewInstalls, Boolean allowDevInstall)
   at Microsoft.TemplateEngine.Edge.Settings.SettingsLoader.RebuildCacheFromSettingsIfNotCurrent(Boolean forceRebuild)
   at Microsoft.TemplateEngine.Cli.New3Command.ExecuteAsync()
   at Microsoft.TemplateEngine.Cli.CommandParsing.NewCommandInputCli.<>c__DisplayClass19_0.<<OnExecute>b__0>d.MoveNext()
```

# なぜ起きるのか
- `dotnet new --install <directory>`を実行すると、使用している.NET SDKのバージョンに応じて、テンプレートが置いてあるディレクトリの絶対パスを`~/.templateengine/<sdk_version>`ディレクトリ以下の下記ファイルに書き込みにいく
  - en-US.templatecache.json
  - installUnitDescriptors.json
  - nugetTemplateSearchInfo.json
  - settings.json
  - templatecache.json
- `dotnet new`を実行すると、インストールされているテンプレートを上記の絶対パスで探しに行く
- macOSのアップデートでは上記ファイルの絶対パスが更新されないので、exceptionが発生した

# どうしたら起きなくなる？
- `.templateengine/<sdk_version>`ディレクトリ以下にある、対象テンプレートの情報を全消しする
Subversionをこのまま使い続けるべきなのか、

現在、職場にてSubversionのバージョン管理ツールであるtortoiseSVNを使用している。自分が使っているWindows10のpcが調子が悪いせいで、開発ではMacbook proを使用しているのだが macからの共有サーバーへのcommitがうまくいかない😩😖

社内の共有サーバーにリポジトリを作成しているため、macからのコミットができないみたいです。調べたところ共有サーバーを使用したやり方は、推奨されていないようだ。

どういうやり方ベストなのか分からないが、ひとまずmacからremoteでwindowsにつないで、共有したディレクトリ上で管理してやっていこうと思う。
Vim Plugin for GitHub Actions (YAML)

GitHub Actions (YAML) 用の Vim Plugin を作っています。
https://github.com/yasuhiroki/github-actions-yaml.vim

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/27201/ee80fa32-9c51-c42e-58ed-8df1b978d1b4.png)

# 機能

- `.github/workflows/*.yml` なファイルに機能するプラグイン
- syntax highlight
    - GitHub Actions 固有の文字列に新しく syntax highlight を定義しています
    - `matrix` と入力したつもりが `matrlx` と入力してしまった...という時に色で気づきやすくなります
- completion
    - `omnifunc` を追加したので、GitHub Actions 固有の文字列の入力に補完が効きます

# インストール方法

[dein.vim](https://github.com/Shougo/dein.vim) をご利用の方は↓でインストールできます。他のプラグインでも慣れた方法でインストールできるかと...。

```vim
call dein#add('yasuhiroki/github-actions-yaml.vim')
```

# うまく動かない場合は

このプラグインは filetype の yaml を継承しており [^1] 既存の YAML の syntax をベースに GitHub Actions 用の syntax を定義しています。
そのためYAMLファイルに対して何かカスタムしている場合は、このプラグインがうまく動かないかもしれません。少なくとも、 vim の標準の YAML syntax を使っていないとハイライトは機能しません。

[^1]: `filetype=yaml.gha `という設定をしています

# 裏話

過去に [circle.vim](https://github.com/yasuhiroki/circleci.vim) というプラグインを作っており、それとほぼ同じ（キーワードを差し替えただけ）だったりします。
Vue.jsのtemplateの中でURLとかの文字列をフィルターで置き換えする方法

タイトルからすごく直感的に分かりづらいタイトル！

#【本記事の目的】
vue.jsの中で、文字列の中の一部をフィルターで変更したい！
（phpでいうところのstr_replace）

#【前置き】（長いので飛ばしてもokです）

laravelでは画像データを投稿すると、デフォルトでpublicに保管されます。
それを実際に表示させるには画像をシンボリックリンクでstorage側で表示させる事を推奨されています。
参考：https://qiita.com/koru1893/items/1d2f522e20744b03e3ad

でもそれをlaravel経由のvue.jsで表示させようとするとうまくいかず。
**vue.jsの中でimgタグの参照urlをpublic→storage に置き換える**
という作業にハマったのでメモです。

**publicだと読み込めず、storageだと読み込める状態です。
![Sky_Light_Lover.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/287983/2cc6e755-7090-68e5-509e-c607be219a97.png)

なお、php（view）でそのデータを読み込むだけなら
[str_replace](https://www.php.net/manual/ja/function.str-replace.php)で画像のurlを変数にして置き換えて、imgタグの読み込み先として指定すれば行けます。

```php
//$image_urlがdbから持ってきたurl情報。urlの一部を置き換えるということ。
$image_url = str_replace('public/', 'storage/', $image_url);
```

phpのview内でやる方法で完了しているじゃん！て思うんですが、
vue.jsとか使って非同期でdb上のURL文字列を取ってくる場合、img参照用のURLをjsファイル内で（今回の場合vue.jsん中で）差し替える必要があります。

------------------------

#やっと本題
**カスタムフィルタを作りました！**
（※vue.jsのフィルタ機能は今は自作しないとダメぽい。vue.1系はフィルタのメソッドあったぽいです。なんで削除されたんだろう？）

filtersの中に、
「public」という文字列を「..storage」に置き換える
「replace」という処理を作りました。
（置き換え前、置き換え先のコードはもちろん任意です。）


```vue.js
<script>
    export default {
        props:['hoge'],
        data:function(){
            return{
             （略）
            }
        },
        mounted(){
          （略）
        },
        filters:{ //カスタムフィルタ。こんな感じ！
            replace:function(val){
                return val.replace("public", "../storage");   
            }
        },
       }
    }
</script>


```

replaceのフィルタは準備できました。
あとはtemplateの中で、フィルタします！
（※vue.jsの中では　{{ フィルタしたいデータ|フィルタの処理名 }} という書き方でフィルタリングできます。マスタッシュ！）

```vue.js
<template>
（略）
<img :src="image_url | replace('public','../storage')" alt="">
（略）
</template>
```

これで、urlのなかの一部を置き換えられます。
公開サイト側でソースをみると、下記のようになります。

####フィルタなしの結果

```
<img src="public/post_images/hoge.jpg">
```

####フィルタありの結果

```
<img src="../storage/post_images/hoge.jpg">
```

これできちんと画像が公開サイトで読み込めました。やった！



>参考：https://www.itsolutionstuff.com/post/how-to-replace-string-in-vue-jsexample.html
VB.net、C#　 DataAdapter.Updateのしくみを解説したサイト

VB.netやC#でのDataAdapter.Updateのしくみを解説したお勧めサイト


DataTableのRowStateの状態が
Added　→　InsertCommandプロパティ、
Modified　→　UpdateCommandプロパティ、
Deleted　→　DeleteCommandプロパティ、
に保存されているSQLコマンドが実行されるというわけですね。
http://okwakatta.net/code/ado09.html

こちらはVB中学校ってサイトでページの最後にDataAdapter.Updateの解説があります。
DataAdapter.Update(DataGridView.DataSource)って書き方もできるっぽいですね
http://rucio.o.oo7.jp/main/VBdotNet/Database/Database4.htm


try内でトランザクションを開始するステートを記述するんですね
処理が終わったらコミットステートメント
Chatch内でロールバックステートメント
Finally内でリソース開放
https://tmg0525.hatenadiary.jp/entry/2017/09/14/143406
https://hosopro.blogspot.com/2016/10/sqldataadapter-update-vb.html
https://www.atmarkit.co.jp/ait/articles/0401/24/news002_2.html
【StreamAPI】max(またはmin)で空Optionalが返るシチュエーション

# maxの返り値はOptional型
Streamのメソッドに[`max`](https://docs.oracle.com/javase/jp/8/docs/api/java/util/stream/Stream.html#max-java.util.Comparator-)(以下、`min`も同様)というものがある。一見、Streamの最大値をそのまま返すように見えるが、返り値の型は以下の例の通りOptionalである。

**コード**

```java

    List<Integer> integerList = Arrays.asList(1, 2, 3);
    Optional<Integer> maxIntegerOpt = integerList
            .stream()
            .max(Integer::compareTo);

    System.out.println("maxIntegerOpt = " + maxIntegerOpt);
```
**実行結果**

```
maxIntegerOpt = Optional[3]
```

ということは最大値が見つからない場合もあるということである。

## 色んな値のStreamで試してみた
「え、最大値が見つからないことってあるの？」と疑問に思ったので、色んな値のStreamで試してみた。
### 重複する値がある場合は見つかる
ははーん、きっと値が重複してたら最大値が一意に定まらないから最大値なしとなるんだな！
**コード**

```java
    List<Integer> integerList = Arrays.asList(1, 2, 3, 3);
    Optional<Integer> maxIntegerOpt = integerList
            .stream()
            .max(Integer::compareTo);

    System.out.println("maxIntegerOpt = " + maxIntegerOpt);
```

**実行結果**

```
maxIntegerOpt = Optional[3]
```

げぇー！重複してるのは一つの値としてまとめて判定している！地味にこれは新たな発見。

### Streamが空の場合は見つからない
正解はこちら。
**コード**

```java

    List<Integer> integerList = Collections.emptyList();
    Optional<Integer> maxIntegerOpt = integerList
            .stream()
            .max(Integer::compareTo);

    System.out.println("maxIntegerOpt = " + maxIntegerOpt);
```
**実行結果**

```
maxIntegerOpt = Optional.empty
```

まあ要素が無ければ最大値も調べようがないですよね。てか[公式](https://docs.oracle.com/javase/jp/8/docs/api/java/util/stream/Stream.html#max-java.util.Comparator-)に書いてました。マニュアル読めって話。

# Streamが空になるシチュエーション
※コメントを受けて追記しました。
空Streamに対して最大値を取りに行くシチュエーションある？と思っていましたが、間に`filter`などを噛ます場合は途中でStreamが空になります。
例えば以下のような、100以下の値で`filter`をかけて最大値を取りに行く場合は途中でStreamが空になり、空Optionalが返ります。

**コード**

```java

    List<Integer> integerList = Arrays.asList(101, 104);
    Optional<Integer> maxIntegerOpt = integerList
            .stream()
            .filter(integer -> integer <= 100)
            .max(Integer::compareTo)
```
この場合、結果が空Optionalということは`filter`に該当する要素がなかったということなので、結果を利用する側でその場合の処理を書く必要があります（そのためのOptional）。

# ~~空Optionalを返すのってどうよ？~~
~~要するに`max`はStreamが空でもエラーとせず、空Optionalを返してくれます。
しかし直感的にその動作がわかるでしょうか？最大値を調べようがなく、自分はてっきり何か例外が返ってくるものだと思っていましたので、空Optionalが返ってくることに違和感を感じていました。~~

※ご指摘いただき、`Optional`で返すことで、空Streamでも例外とならないことが明らかだと判断しました。
JSでブラウザがダークモードかを判定する

# はじめに
ブラウザにダークモードが搭載されるようになった！
CSSで、ダークモード時の Media Query が記述できる！
[Can I use... Support tables for HTML5, CSS3, etc](https://caniuse.com/#search=prefers-color-scheme)

→JSでは取得できないの...？？探してもあまり見つからないし....

いろいろ試行錯誤した結果、取得する方法を発見(?)したので、紹介しようと思います。

# 条件
 - **CSSで、Media Query "`prefers-color-scheme`" が記述できる**<br>
   2019.12.22現在、最新版Firefox, Chrome, Safari, Operaは使用できます。Edgeは残念ながら...<br>
   [Can I use... Support tables for HTML5, CSS3, etc](https://caniuse.com/#search=prefers-color-scheme)
 - **JSで、 `getComputedStyle` と `getPropertyValue` を使用できる**<br>
   モダンブラウザすべてに対応しています。<br>
   （ユーザーがJSを「実行しない」にしていなければ）取得できます。

# 考え方
 - JSでは現在、「直接の」判定はできない。
 - しかし、CSS変数は取得できる。
 - Media Query で、CSS変数の値を変えることが可能。

...ということは...？？

1. Media Query で CSS変数を定義
2. JSでCSS変数を取得し、値によって判定が可能

# 実装

今回記述したコードは、GitHubにあげておりますので、併せてごらんください。
[a01sa01to/DarkmodeGetter_js](https://github.com/a01sa01to/DarkmodeGetter_js/)

=====

**1\. CSS変数を定義**

```css
/* ライトモードの時、CSS変数 isDarkmode は存在しない */
html{ ... }

@media (prefers-color-scheme: dark){
  /* ダークモードの時 */
  html{
    --isDarkmode: True;
    ....
  }
}
```

[prefers-color-scheme - CSS: カスケーディングスタイルシート | MDN](https://developer.mozilla.org/ja/docs/Web/CSS/@media/prefers-color-scheme)

変数名や値などは、競合しないように適宜変えても構いません。

=====

**2\. CSS変数を取得**

```js
/* 1. <html> に変数を設定したので、まずは <html> を取得する */
const htmlTag = document.querySelector("html");
// -> <html lang=...> ..... </html>

/* 2. CSSプロパティの取得 */
const comStyle = getComputedStyle(htmlTag);
// -> CSSStyleDeclaration {0: ... }

/* 3. 変数の取得 */
const cssVariable = comStyle.getPropertyValue('--isDarkmode');
// -> "True"(ダークモード)・""（ライトモード）
// ライトモードは、変数を指定していないため、空の文字列が返される
```

もちろん、わざわざ上記のように書かずとも、1行で記述可能です。

```js
getComputedStyle(document.querySelector("html")).getPropertyValue('--isDarkmode');
```

1.でCSS変数を変更した場合は、こちらも変更する必要があります。

=====

**3\. 判定**

```js
/* 2 のコードの続き。"cssVariable" が定義されている前提 */
const isDarkmode = !!cssVariable;

// これでも同じ
const isDarkmode = Boolean(cssVariable);
```

ライトモードでは、`cssVariable == ""` なので、*Falsy* です。
そのため、 `isDarkmode` は `false` を返します。

ダークモードでは、 `cssVariable == "True"` → *Truthy* なので、 `true` を返します。

[Truthy - MDN Web Docs 用語集: ウェブ関連用語の定義 | MDN](https://developer.mozilla.org/ja/docs/Glossary/truthy)
[Falsy - MDN Web Docs 用語集: ウェブ関連用語の定義 | MDN](https://developer.mozilla.org/ja/docs/Glossary/falsy)

=====

以上により、ブラウザがダークモードかを取得することができました！


# もっと簡単な方法（2022/01/22追記）
もっと簡単な方法がありました。

```js
window.matchMedia('(prefers-color-scheme: dark)').matches
```

これにより、CSSのメディアクエリ `@media (prefers-color-scheme: dark)` に合致しているかどうかを判定できるため、
結果としてダークモードかどうかを判別することができるというわけです。

# 変更をリアルタイムに検知する方法（2022/01/22追記）
ライトモード・ダークモードの変更をリアルタイムに検知する方法を以下の記事にしました :smiley:
併せてご覧ください！

https://qiita.com/a01sa01to/items/41f919deadcd45ba613b
MacからEC2上のJupyter Notebookにポートフォワードでリモートアクセス

[『つくりながら学ぶ!PyTorchによる発展ディープラーニング』](https://www.amazon.co.jp/dp/4839970254/ref=cm_sw_r_tw_dp_U_x_9vY.DbDGGHSQ0)を読んでいます。
こちらの本ではWindowsを前提に、SSH接続設定はTera Termを使っているのですが、Macの場合だとちょっとだけ勝手が違います。


”EC2サーバーを作成し、初めて「Jupiter notebook --port 9999」を実行したときには1分ほど時間がかかって、図1.4.18のようなJupyter Notebookが立ち上がった状態になります。
 図1.4.18の「http: //localhost:9999/…」と続くURLをコピーして手元のPCのブラウザからアクセスすれば、EC2サーバーのAnaconda画面が表示されます。ですがその前にSSH転送の設定で手元のPCのport9999とEC2サーバーのport9999をつなぐ設定が必要です”(p.43)

ここですね。（ここまでのSSH接続は、「EC2 SSH Mac」 とかでググって出てきた方法でなんとかなった）
<img width="1920" alt="スクリーンショット 2019-12-22 17.10.45.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/158553/1993e605-9630-b67e-ea7c-202a989cce93.png">


ポートフォワードの設定をしてやります。
ターミナルで以下を打ちます。

```
ssh -i "<keyname_hogehoge.pemのPATH>"  -L 9999:localhost:9999 ubuntu@ec2-<ここはIPによって違う>.compute.amazonaws.com
```

例)

`ssh -i ./.ssh/amazon.pem  -L 9999:localhost:9999 ubuntu@100.100.100.100
`

<img width="980" alt="スクリーンショット 2019-12-22 17.16.41.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/158553/38c945fb-4be3-993d-1243-70c1d6c3fbd0.png">

MacのブラウザでURLに先ほど出てきた http://localhost:9999/?token=... を入れてやります。

<img width="1288" alt="スクリーンショット 2019-12-22 17.07.38.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/158553/7f64c922-4b66-7a32-e51d-4cc3191c348a.png">

やったぜ

参考
https://docs.aws.amazon.com/ja_jp/emr/latest/ManagementGuide/emr-ssh-tunnel-local.html