OmniAICreator/Qiita-1.07M huggingface dataset:
Visual Studio CodeでPythonのモジュールが読み込めなくなった時に試すこと

##解決法
「Code → Preferences → Settings」を選択します。もしくは、「command + ,」というショートカットキーでもOKです。
![スクリーンショット 2020-11-13 17.54.22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/548334/01e81bec-923c-fb5e-2122-06a951189359.png)

右上にある小さなアイコンをクリックして開きます。
![スクリーンショット 2020-11-13 17.56.09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/548334/e971ea8e-8e08-c4be-21d5-d43bf40a740b.png)

settings.jsonというファイルが開かれます。Visual Studio Codeのパスの読み込み先を編集できるので、ここに「python.pythonPath〜」を設定して下さい。パス自体はお手元の環境次第かと思いますので、それを設定して下さい。
はじめからここにpythonのパスがある場合は上書き、無い方は新しく書き込んでしまって良いと思います。
念のため、元に戻せるようにしておいて下さい。
![スクリーンショット 2020-11-13 17.59.00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/548334/3b179876-7eb6-fdae-d507-bfd5be5e0376.png)


##おまけ
ついでにpythonがどのパスを読み込んでいるのか確認する方法をご紹介します。
百聞は一見に如かずということでまずはスクリーンショットをご覧ください。パッと見て「なるほどー」となる方は早速試してみて下さい。
ちょっと怖いという方には簡単な説明をします。
![スクリーンショット 2020-11-13 18.20.50.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/548334/a917617c-5701-6dea-21d0-3bef33ada5d6.png)

まずはホームディレクトリでpythonを起動します。
（元々Macにあるpython2系と区別するため、私はpython3というコマンドで起動しています。皆さんも環境に合わせたコマンドをお使いください）

pythonが起動すると「>>>」というのが出ますので、これでpythonと対話できます。
「import sys」と打ってEnterを押します。（何も起こりませんがそれで大丈夫です。）
「import pprint」と打ってEnterを押します。（何も起こりませんがそれで大丈夫です。）
「pprint.pprint(sys.path)」と打ってEnterを押します。
ここでpythonがパスを教えてくれます。
上から順に読み込んでいるので、この中でモジュールがある場所のパスをコピーしてvscodeのsettings.jsonにペーストして下さい。
「control + D」でpythonとの対話を終了できます。

もしも想定していたパスが無い、というようなことがあればパスを通す作業が必要になりますので、それは別途調べてみて下さい。
また、それぞれのコマンドについても詳しいことは割愛させていただきます。

個人的にはpprintを使うというのがポイントです。ただパスを聞くと横にズラズラと書かれて吐き出されるのでとてもよみづらい…というのを解決する一工夫です。


##経緯
ある日突然、それまで使えていたモジュールがimportエラーになっていました。具体的なエラー内容は忘れてしまったのですが、たぶん「そんな名前のモジュール無いよ」という感じだったと思います。
それまで使えていたのにそんなはずは無かろう…という気持ちでしたが、ふと、anyenvを入れたことを思い出し、パスの読み込み先が変わったのでは無いかと推測しました。
まずはローカルの環境変数（python2系と3系のパスの読み込み先、優先順位、pipでインストールしたモジュールの格納場所を調べたりetc）を色々と血眼になっていじっていたのですが、最終的に上記の方法で解決しました。
まさかエディタ側を調整するとは思わなかった…まだまだ修行が足りませんね。
ちなみに、色々とパスをいじっているうちにどんなコマンドさえターミナルで反応しないという危機的状況も経験しましたが、こちらは割とすぐ解決しました。
（インターネット上のあらゆる情報提供者に感謝します！）

ただ、まだ少し疑問に思っていることがありまして…
いくつかimportしているうちの1つだけ（具体的にはjaconv）急に使えなくなったのは何故なのかということです。
同じファイルで別のモジュールは使えているにもかかわらず何故これだけエラーになってしまったのか…
そしてこの解決策は最善なのか…という点が気になります。
もし原因など判明したら追記します。
navigation(v5)コンポーネントの型推定のメモ


```
import { StackNavigationProp } from '@react-navigation/stack';

type 好きな名前 = StackNavigationProp<
  画面の名前1,
  画面の名前2,
  画面の名前3,
>;

type Props = {
  navigation: 好きな名前
};

const 関数名: React.FC<Props> = (props) => {

    ・・・・　いろんなコード　・・・・・

     props.navigation.navigate('画面の名前')

　　 ・・・・　いろんなコード　・・・・・

}
```
Flutterの湯婆婆にサロゲートペア文字を理解させたら可愛くなった💗

#はじめに
[Flutterで湯婆婆を実装してみる](https://qiita.com/simontanz/items/50c06aaaac3aa9c896db)の続編です。

@everylittleさんの[C#婆婆](https://qiita.com/everylittle/items/d4df566a9c5f4bb58d5f)などで言及されている通り、サロゲートペア文字を処理しないと「𠮷」田さんは契約させてもらえません。

それはうちのFu婆婆も例外ではありません。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/249961/baaee61b-34af-f755-4c84-2ad967b7f0e0.png)


# サロゲートペア文字とは
Unicodeでは通常2バイトで1文字を表すところ、4バイトで表すものがあります。
それをサロゲートペアといって、上位2バイトを「上位サロゲート」、下位2バイトを「下位サロゲート」と呼んだりします。
サロゲートペア文字に関しては[この辺の記事](https://codezine.jp/article/detail/1592)を読んでおけばわかると思います。

#どうして文字化けしたの？
文字列操作するときに2つで1つの文字の半分だけとってきて表示したためです。

#どうすればいいの？
ゴリゴリと対応するならば、入力した名前のから抽出した1文字の文字コードが

* 上位サロゲート（0xD800～0xDBFF）：後方の1文字を追加
* 下位サロゲート（0xDC00～0xDFFF）：前方の1文字を追加

みたいな処理をすればよいです。

# 実装例
``` dart
 bool _isHighSurrogate(int charCode) {
    return (0xD800 <= charCode && 0xDBFF >= charCode);
  }

  bool _isLowSurrogate(int charCode) {
    return (0xDC00 <= charCode && 0xDFFF >= charCode);
  }

  String _zeitaku(String name) {
    if (name == null && name.isEmpty) {
      return "";
    }

    final rand = Random();
    int index = rand.nextInt(name.length);

    String newName = name.substring(index, index + 1);

    // 文字コードが上位サロゲート文字なら下位を追加、下位サロゲート文字なら上位を追加
    if (_isHighSurrogate(newName.codeUnitAt(0))) {
      newName = name.substring(index, index + 2);
    } else if (_isLowSurrogate(newName.codeUnitAt(0))) {
      newName = name.substring(index - 1, index + 1);
    }

    return newName;
  }
```

# もう少し簡単に実現
上記でも実現できますが、Dartの場合[Characters](https://api.flutter.dev/flutter/characters/Characters-class.html)クラスを使えばもっと簡単に実現できそうです。
Charactersクラスではサロゲートペアをきちんと1文字とカウントしてくれるみたいですね。

``` dart
  String _zeitaku(String name) {
    if (name == null && name.isEmpty) {
      return "";
    }

    var characters = Characters(name);

    final rand = Random();
    int index = rand.nextInt(characters.length);

    return characters.characterAt(index).string;
  }
```
[GitHub](https://github.com/kohta1992/flutter-baba)
#結果
https://flutter-baba.web.app/#/
良かったね！𠮷田さん！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/249961/df2eb3ae-19d7-7706-40ee-6a8ac3545c1c.png)
# 副作用
ちなみにサロゲートペア文字を理解したFu婆婆は絵文字にも対応できる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/249961/6c5c9a62-9587-881a-82bf-8f7c6da2d2b6.png)
高性能で可愛いババアになりました。
#おわりに
今回、サロゲートペア文字の対応をさせてみました。
ゴリゴリ書く版とCharactersクラスを使う版の両方を記載しましたが、
他の言語で対応しなければいけなかったりすることを考えるとゴリゴリ書く版も知っておいていいと思います。
Liveshareを使ってリモートでペアプロしたメンバーの変化

## はじめに

様々なプロジェクトでコードを書いていると可読性が高くメンテナンスもしやすいコードも
あればたまに見た瞬間に~~ふざけんな~~いけていない、いわゆるスパゲティコードもありますよね。
そんな~~ふざけた~~スパゲティコードのせいでバグの調査や動作確認に時間がかかってしまうことも
あるのが嫌なのでリファクタリングをすることに決めました。
決めましたけど自分はプロジェクト上PGでないし、あまり1人でやるのもチームとして
健全でないため、~~実験~~育成も含めてペアプロをしてみました。
※スパゲティコードがわからない人はググってみよう。

## 環境
* 開発言語：Go言語
* IDE：VSCode
* 共有ツール：LiveShare
* コミュニケーションツール：GoogleMeet

## そもそもペアプロとは

ドライバーとナビゲータの2人で一つの成果を作り上げていく開発手法。

* ドライバー
  * 手を動かす人
  * 成果物の責任を持つ人
* ナビゲータ
  * ドライバーに作業指示をする人
  * 成果物の大局を決める人
  * 成果物の責任を持つ人
 
細かくは以下の参考元を見てください。

### 参考元 

* [ペアプロについて話されているpodcast](https://fukabori.fm/episode/13)
* [ペアプログラミングして気がついた新人プログラマの成長を阻害する悪習](https://qiita.com/hirokidaichi/items/27c757d92b6915e8ecf7)
* [ペアプログラミングして気がついた新人プログラマの成長を加速する３つの習慣](https://qiita.com/KakkiiiiKyg/items/2d0920416a0e0187810d)
* [ペアプロ懐疑派だった僕が、実務でペアプロ導入して180度考えが変わった話](https://qiita.com/YudaiTsukamoto/items/06b426f4dbee268d5035) 

## やりたかったこと

* バグがよく発生する関数があるけど一つの関数で意味を持ちすぎなので適切に関数を分割したい。
* それをプルリクベースでやり取りすると時間がかかるし、検討意図とかも共有していきたい。（途中経過の共有）
* プロジェクトの暗黙知の共有
* 自分が普段考えていることの共有（知見共有）

## 裏でやりたかったこと

* ペアプロの良さの普及
* 強いチームを作るためのチームビルディングの一環
  * 属人化の防止
  * 色々な知見の吸収
	* 弱点の補完
	* 得意分野の強化

## やってみた結果
ドライバーの人が初めてペアプロしたということもあり、ペアプロの良さやメリットを
伝えることができたので良かったです。

* よかった点
  * 意思疎通しながらできるのでよかった
  * ベテランの考えを聞きながらできるのはよかった
  * レビューされながらコードを書くので時間短縮には繋がる
* 悪い点
  * 環境の準備がしっかりできていなかった
  * リファクタじゃなくて作り込みとか単純なコードは向かなさそう

## 最後に

今回はプロジェクトの合間を見つけての１回目の変化でしたが、
ペアプロでやりたかったことは少しはできました。
ただ、１回だけでなく継続的にやっていってこそ裏でやりたかった強いチームビルドに
繋がっていきます。
「属人化の防止」、「弱点の補完・得意分野の強化」はパートナーを組み換えて
ペアプロを実践することで効果を発揮し、チーム全体の底上げになりますので
やらず嫌いではなくやってみて損はないです。
正直最初失敗することもあるでしょうけど、失敗したら失敗したでしっかりと振り返りをしたら
得られるものは多いので気楽に挑戦って大事です。
【入門者向け】Canvas入門講座#8 円を塗りつぶそう【JavaScript】

#問題8
中心が(200, 200)、半径100の円を塗りつぶしなさい。
塗りつぶす色はマゼンタ色(#ff00ff)であること。
なお、以下のHTMLを使うこと。

```html
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="utf-8">
<title>問題8</title>
<script src="https://code.jquery.com/jquery-3.5.1.min.js"></script>
<script>
$(() => {
    // ここにプログラムを書く
});
</script>
</head>
<body>
<canvas id="my-canvas" width="500" height="300"></canvas>
</body>
</html>
```

#答え

```html
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="utf-8">
<title>問題8</title>
<script src="https://code.jquery.com/jquery-3.5.1.min.js"></script>
<script>
$(() => {
    // コンテキストを取得
    const ctx = $('#my-canvas')[0].getContext('2d');

    // 塗りつぶしの色をマゼンタ色にする
    ctx.fillStyle = '#ff00ff';

    ctx.beginPath();        // 現在のパスをリセットする
    ctx.arc(200, 200, 100, 0, Math.PI*2, true);	// 円を描画する
    ctx.closePath();        // パスを閉じる
    ctx.fill();           // 現在のパスを塗りつぶす
});
</script>
</head>
<body>
<canvas id="my-canvas" width="500" height="300"></canvas>
</body>
</html>
```

円が塗りつぶせました！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/163605/ea6c0cc1-290b-1c4b-2dbe-891b384f5c31.png)

#解説
コンテキストを取得します。これは問題1と同じです。

```js
// コンテキストを取得
const ctx = $('#my-canvas')[0].getContext('2d');
```

次に塗りつぶしの色を指定します。
塗りつぶしの色はfillStyleで指定します。

```js
// 塗りつぶしの色をマゼンタ色にする
ctx.fillStyle = '#ff00ff';
```

後はパスを作成し、最後にfillを呼びます。
円弧の描画arcメソッドについては問題7の解説をご覧ください。

```js
ctx.beginPath();        // 現在のパスをリセットする
ctx.arc(200, 200, 100, 0, Math.PI*2, true);	// 円を描画する
ctx.closePath();        // パスを閉じる
ctx.fill();           // 現在のパスを塗りつぶす
```
RMD-X8をM5 Stackで動かす(3)

前回は角度の読み込みとモーターの位置制御ができるようになりました．今回は，読み込んだ角度をもとにフィードバック制御を行ってみましょう．
サンプルプログラムは https://github.com/t-kamimura/RMDx8_m5stack にあります．該当するプログラム名はそれぞれの詳細説明の中にあります．

# PD制御

ここでは，最も簡単なフィードバック制御の一つである，**PD制御**を行います．

モーターをある目標角度$\theta_d$に持っていきたいとき，モーターが出すトルク$\tau$を
$$
\tau = -K_P (\theta - \theta_d) - K_D\dot{\theta}
$$
とします．ここで，$\theta$はモーターの現在角度，$\dot{\theta}$はモーターの現在角速度です．$K_P$，$K_D$はそれぞれ**比例ゲイン**，**微分ゲイン**と呼ばれます．
比例項$K_P (\theta - \theta_d)$は，現在の角度が離れているほど大きなトルクを生成します．仮想的にバネ力が働いているように動作します．これによって目標値に速やかに向かうことができます．
ただし，比例項だけでは目標値を通り過ぎてしまう（**オーバーシュート**）ので，粘性摩擦を表す微分項$K_D\dot{\theta}$を導入し，速やかに収束するようにしています．

ただし，RMD-X8はトルクセンサーを内蔵していないため，トルク制御を表す上記の制御則をそのまま実装することはできません．そこで，モーターが出すトルクはモーターに流れている電流値にほぼ比例するという性質を利用し，
$$
I = - K_P (\theta - \theta_d) - K_D\dot{\theta}
$$
という制御を考えます．RMD-X8には電流センサーが内蔵されているため，この制御則は実装可能です．

# 電流制御プロトコル

RMD-X8で電流制御を行うときは，以下のコマンドを送信します．

|  指令  |  data[0]  |  data[1]  |  data[2]   |  data[3]  | data[4]  | data[5]  |  data[6]  |  data[7] |
| ---- | ---- | ---- | ---- | ---- | ---- | ---- | ---- | ---- |
|Current control	| 0xA1	|0x00	|0x00	|0x00	|current value low byte	|current value high byte	|0x00	|0x00|

電流指令は`int16_t`型で作成します．指令値は-2000 ~ 2000の間で設定され，電流値としては-32 A ~ 32 Aに相当します．
ただし，RMD-X8の定格電流は4.9 Aなので，安全に駆動できる指令値は-300～300くらいの範囲になります．

CANで送るときは，16ビット(=2バイト)で表された電流指令値を2つのバイトに分割します．

```c
int32_t tgt_cur = 100;  //任意の値
cmd_buf[0] = 0xA1;
cmd_buf[1] = 0x00;
cmd_buf[2] = 0x00;
cmd_buf[3] = 0x00;
cmd_buf[4] = tgt_cur & 0xFF;
cmd_buf[5] = (tgt_cur >> 8) & 0xFF;
cmd_buf[6] = 0x00;
cmd_buf[7] = 0x00;
```

# PD制御の実装

電流制御によるPD制御のサンプルプログラムは`RMD_CurrentTest`です．

## 角度と角速度の読み取り
まず，前回説明した角度読み取り指令を使って現在の角度を取得します．このとき，角速度も計算しておきます．

```c
// read multi turn angle
cmd_buf[0] = 0x92;
cmd_buf[1] = 0x00;
cmd_buf[2] = 0x00;
cmd_buf[3] = 0x00;
cmd_buf[4] = 0x00;
cmd_buf[5] = 0x00;
cmd_buf[6] = 0x00;
cmd_buf[7] = 0x00;
write_can();
delay(1);   // ここを入れておかないと，サーボ側の処理が間に合わない
read_can();

// 角度と角速度の計算
pos_buf = angle;    //速度を計算するために前回の値を取っておく

present_pos = 0;
present_pos = reply_buf[1] + (reply_buf[2] << 8) + (reply_buf[3] << 16) + (reply_buf[4] << 24) + (reply_buf[5] << 32) + (reply_buf[6] << 48);

angle = present_pos * 0.01 / 6;             //サーボホーンの角度 [deg]
vel = (angle - pos_buf)/(LOOPTIME*0.001);    //サーボホーンの角速度 [deg/s]
```

`LOOPTIME`はループにかかる時間(ms)を表しています．
速度を計算するためにループの時間は一定で回しておきたいので，マイコン内部の時刻をミリ秒単位で取得する`millis()`を用いて

```c
void loop()
{
    timer[1] = millis();
    /*
    // 諸々の処理
    */
    timer[2] = millis() - timer[1];
    if (timer[2] < LOOPTIME)
    {
        delay(LOOPTIME - timer[2]);
    }
}
```

としておきます．`//諸々の処理`の部分に`LOOPTIME`以上の時間がかかると意味がありませんので注意しましょう．

## 電流指令値の作成
次に，電流指令を行います．

```c
int32_t tgt_cur = -KP * (angle - TGT_POS) - KD*vel;

// current control command
cmd_buf[0] = 0xA1;
cmd_buf[1] = 0x00;
cmd_buf[2] = 0x00;
cmd_buf[3] = 0x00;
cmd_buf[4] = tgt_cur & 0xFF;
cmd_buf[5] = (tgt_cur >> 8) & 0xFF;
cmd_buf[6] = 0x00;
cmd_buf[7] = 0x00;
write_can();
delay(1);   // ここを入れておかないと，サーボ側の処理が間に合わない
read_can();
```

`TGT_POS`はサーボホーンの目標値(deg)，`KP`，`KD`はそれぞれ比例ゲイン，微分ゲインです．
これで，PD制御の実装ができました．
sqlalchemy での　API化に必須なコード　

sqlalchemy での　API化に必須なコード　　

https://python5.com/q/dqtofqqq

お・ま・じ・な・い　（滝川クリステル調に）

```python
     items = [{column: value for column, value in rowproxy.items()} for rowproxy in items] 
```
PHP 配列をカウントする場合　どうする？　count関数

<h1>配列の要素数をカウントする場合

count関数

```

$array1 = ['apple', 'orange', 'melon', 'apple', 'pineapple'];

$count = count($array1);

出力結果：5

```
配列には５つの要素があるためカウント関数では５とカウントされて出力されています。

<h1>多次元配列をカウントする場合

それでは同じ方法で多次元配列をカウントしてみます

```
$array1 = [
['apple', 'orange', 'melon', 'apple', 'pineapple'],
['apple', 'orange', 'melon', 'apple', 'pineapple'],
['apple', 'orange', 'melon', 'apple', 'pineapple'],
];

echo count($array1);

出力結果：３
```

出力結果が「１５」となるはずなのに「３」と出力されました。
配列の中の孫要素数ではなく、子要素のみをカウントしているようです。


<h1>複雑な配列構造であってもカウントする方法とは？

COUNT_RECURSIVEの登場です。

```

$array1 = [
    ['apple','orange', 'melon', 'apple','pineapple'],
    ['apple','orange', 'melon', 'apple','pineapple'],
    ['apple','orange', 'melon', 'apple','pineapple']
    ];
 
 
 echo count($array1 , COUNT_RECURSIVE);
 
出力結果：１８


```

出力結果が18と出力されました。
配列の子要素数[3]、孫要素[15]で合計18といったカウント方法です。

それでは孫要素のみをカウントしたい場合どうする方法があるでしょうか？

<h1>どうしても孫要素のみカウントしたい！



以下



```
$array1 = [
    ['apple','orange', 'melon', 'apple','pineapple'],
    ['apple','orange', 'melon', 'apple','pineapple'],
    ['apple','orange', 'melon', 'apple','pineapple']
    ];
 
 
 echo count($array1 , COUNT_RECURSIVE)-count($array1);
```

こんな方法があるようです。
多分使わないと思います。
iframeで子フレームのイベントを親フレームで拾う

モーダル系のチャットサービスでの行動を計測するためにイベントを取得しようと思ったら、チャット枠がiframeで作られていた。

https://s8a.jp/javascript-event-iframe

分かりやすい記事にまとめられていたため解決！

感謝です。



・・・と思ったら、ローカルでテストすると何故か動かない。。

かなり悩んでしまったが、ローカル環境（file://）ではファイルが違うと別オリジンになるとやらで、フレーム外から直接フレーム内へアクセスすることができないよう。。

https://teratail.com/questions/304543#reply-427805

本番で動けばよいので、ローカルでの検証をしないことに。



ふう、できた、と思ったら、やはり動かない。。

というよりも、そもそもiframeの読み込み元が別ドメインなので、その場合はほぼ無理ということを知る。。

理由は、ブラウザ側のセキュリティのよう。


https://reiwinn-web.net/2019/08/23/%E3%83%89%E3%83%A1%E3%82%A4%E3%83%B3%E3%81%AE%E9%81%95%E3%81%86iframe%E3%82%BF%E3%82%B0%E5%86%85%E3%83%9A%E3%83%BC%E3%82%B8%EF%BC%88%E5%AD%90%E3%83%9A%E3%83%BC%E3%82%B8%EF%BC%89%E3%81%A7%E7%89%B9/

豊富としては、このように子フレーム側で「window.parent.postMessage("value","target");」というのを送って、親フレームで受け取るという方法になるみたい。
【入門者向け】Canvas入門講座#7 円を描こう【JavaScript】

#問題7
中心が(200, 200)、半径60の円を描画しなさい。
線分は青色(#0000ff)で太さが3であること。
なお、以下のHTMLを使うこと。

```html
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="utf-8">
<title>問題7</title>
<script src="https://code.jquery.com/jquery-3.5.1.min.js"></script>
<script>
$(() => {
    // ここにプログラムを書く
});
</script>
</head>
<body>
<canvas id="my-canvas" width="500" height="300"></canvas>
</body>
</html>
```

#答え

```html
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="utf-8">
<title>問題7</title>
<script src="https://code.jquery.com/jquery-3.5.1.min.js"></script>
<script>
$(() => {
    // コンテキストを取得
    const ctx = $('#my-canvas')[0].getContext('2d');

    // 線の色を青色にする
    ctx.strokeStyle = '#0000ff';

    // 線の太さを3にする
    ctx.lineWidth = 3;

    ctx.beginPath();        // 現在のパスをリセットする
    ctx.arc(200, 200, 60, 0, Math.PI*2, true);	// 円を描画する
    ctx.closePath();        // パスを閉じる
    ctx.stroke();           // 現在のパスを描画する
});
</script>
</head>
<body>
<canvas id="my-canvas" width="500" height="300"></canvas>
</body>
</html>
```

円が描画できました！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/163605/728c0007-e211-615b-ade1-f20cbbb8138e.png)

#解説
コンテキストを取得します。これは問題1と同じです。

```js
// コンテキストを取得
const ctx = $('#my-canvas')[0].getContext('2d');
```

次に線の色と太さを指定します。
線の色は<b>strokeStyle</b>で指定します。
線の太さは<b>lineWidth</b>で指定します。

```js
// 線の色を青色にする
ctx.strokeStyle = '#0000ff';

// 線の太さを3にする
ctx.lineWidth = 3;
```

後はパスを作成し、最後にstrokeを呼びます。
本問題では、パスの始点と終点が一致しているのでclosePathを呼んでも呼ばなくても結果は同じです。

円弧の書き方ですが、
<b>ctx.arc( x, y, 半径, 開始角度, 終了角度, 回り方)</b>のように指定します。
x, yは円の中心点の座標を指定します。
開始角度、終了角度はラジアンで指定します。
回り方はtrueで反時計回り、falseで時計回りであり、今回はどちらを指定しても結果は同じです。

```js
ctx.beginPath();        // 現在のパスをリセットする
ctx.arc(200, 200, 60, 0, Math.PI*2, true);  // 円を描画する
ctx.closePath();        // パスを閉じる
ctx.stroke();           // 現在のパスを描画する
```
Laravelで別プロジェクトを作成しようとして元々のプロジェクトが開けなくなってしまった

##現象
新規に別プロジェクトを作成しようとしたら、元からあったほうのプロジェクトが502 bad gatewayエラーになってしまった。

##心当たり
$ vagrant up --provision
を実行してしまったのが原因？初期化してしまったかもしれない。

##やったこと
・元々のプロジェクトまで移動してls　→　ソースファイルは無事
・Homestead.yamlファイルのsites:にphp: "7.2"を追加　→　効果なし
・nginx.confの中身を見る（下のコマンド実施）　→　問題なし

```
cd /etc/nginx
cat nginx.conf
```

##原因を探す
homestead.testの中身を確認したら原因が分かった
（homestead.test＝Homestead.yamlファイルのsites:のmap）

```vagrant接続.
cd /etc/nginx/sites-available/
cat homestead.test
```

location ~ \.php$ {…　で下記のようになっていた。ここが原因だった。

```
fastcgi_pass unix:/var/run/php/php7.3-fpm.sock;
```


下記コマンドを実行してphpの稼働状況を確認すると、稼働しているのは7.1と7.2だったので7.3→7.2に修正したい。
稼働していないものを設定にしていたため、サービスが見つけられず502 bad gatewayエラーになっていた様子


```
service --status-all | grep php
```

```ログの一部.
vagrant@homestead:/var/log/nginx$ service --status-all | grep php
 [ + ]  php7.1-fpm
 [ + ]  php7.2-fpm
```

##解決方法
```
// 移動して
cd /etc/nginx/sites-available/
// 編集する
sudo vi homestead.test
```

fastcgi_pass unix:/var/run/php/php7.3-fpm.sock;を
fastcgi_pass unix:/var/run/php/php7.2-fpm.sock;に直す
（iで編集モード、:wqで保存して終了）

保存したら再起動

```
sudo service nginx restart
```
ページを更新すると正常に表示された！
サイドカーコンテナを持つJobが完了しない問題の対処法

# はじめに
Cloud SQL Proxyをサイドカーコンテナとして使用するJobが完了しない問題に出会したので、その解決方法を共有します。なぜ完了しないかというと、メインプロセスが終わったあとでもサイドカーのプロセスが動いているからです。
なので、メインプロセスが終わった時点でサイドカー側にプロセスを終了するようなシグナルを送らなければいけません。

# 解決法
解決法は何種類かあるみたいです。

1. まず、コンテナ間でボリュームを共有する。メインのプロセスが終わった時点で、そのボリュームに適当なファイルを作る。サイドカーコンテナ側ではボリューム内にファイルができたかを検知するループを回し、できた時点でプロセスを終了する。
2. Pod内のコンテナ間でPID Namespaceを共有し、メインコンテナ側でサイドカーコンテナのプロセスをkillする。

今回は２番の方が簡潔だったため、こちらを採用しました。

```yaml:my-db-job.yaml
apiVersion: batch/v1
kind: Job
metadata:
  name: my-db-job
spec:
  template:
    spec:
      restartPolicy: OnFailure
      shareProcessNamespace: true
      containers:
      - name: my-db-job-migrations
        command: ["/bin/sh", "-c"]
        args:
          - |
            <your migration commands>;
            sql_proxy_pid=$(pgrep cloud_sql_proxy) && kill -INT $sql_proxy_pid;
        securityContext:
          capabilities:
            add:
              - SYS_PTRACE
      - name: cloudsql-proxy
        image: gcr.io/cloudsql-docker/gce-proxy:1.17
        command:
          - "/cloud_sql_proxy"
          - "-instances=$(DB_CONNECTION_NAME)=tcp:3306"
```

ポイントはsecurityContext/capabilitiesにSYS_PTRACEを追加している点です。
SYS_PTRACEをつけるとseccomp制限が無効になり、セキュリティレベルが低下するためオススメできるかわかりませんが、公式のドキュメントにも書かれている内容ではあります。

[Pod内のコンテナ間でプロセス名前空間を共有する](https://kubernetes.io/ja/docs/tasks/configure-pod-container/share-process-namespace/)

心配な方は１の方法でやるといいと思います。参考記事も共有しておきます。

[サイドカーコンテナを含む Kubernetes Job を完了させる](https://qiita.com/apstndb/items/bbace4c4d02f2f8183fd)

# まとめ
サイドカーコンテナを持つJobが完了しない問題の対処法を紹介しました。Cloud SQL Proxyを使っているとサイドカーならではの問題に対処しないといけないし、日本語の記事も意外と少ないので、また何か共有できそうな情報があれば随時書いていこうと思います。
Visual Studio CodeでRemote-SSH接続ができない

エンタメ系企業の社内もろもろを担当しているakibinです。

小学生の頃に良く父親からマドンナを聴かされていました。
[Papa Don't Pleach](https://www.youtube.com/watch?v=G333Is7VPOg)という曲のサビが聴き取れず、ままちょんプリン！と歌ってたのは素敵な記憶です。

#内容
他のターミナルソフトからSSH公開鍵と秘密鍵でアクセスできるのに、VSCODEでRemote-SSHができなかった件の解消方法がこれか...って感じでした。

#対応方法
[こちら](https://blog.masahiko.info/entry/2019/06/15/202003)の記事（わかりやすかったです！）を参考にして設定進めましたが、なぜかVSCODEからSSH接続できませんでした。

いろいろ調べて、¥Users¥user¥.ssh¥config ファイルのHostに@が含まれていると×といった記事があったので@を抜いてみたら接続できました！
どのサーバへのアクセスか見た目で識別するためも項目だから、@は不要ですし、もしVSCODEでRemote-SSHうまく行かない場合は試してみてもいいと思います。

ままちょんプリン！

こちらもよろしくです。
＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊
◆ Twitterアカウント
@AkibinMusic

◆ Youtubeチャンネル
https://www.youtube.com/channel/UC-JOpwEnJn3gCrUA4NdCYgg
[Ruby編]等差数列

#[Ruby編]等差数列を解いてみる
#問題
以下のような数列を出力するプログラムを作りましょう。

5 8 11 14 17 20 23 26 29 32

最初の数字が5で、3ずつ増加していく事がわかります。
一般的にこれを初項5、公差3の等差数列といいます。

このような数列を出力するプログラムを作りましょう。
初項 m が与えられ、公差 n が与えられるので 10番目までの数字をスペース区切りで出力するプログラムを作成してください。
#入力される値
入力は以下のような初項 m、公差 nが半角スペース区切りのフォーマットで与えられます。

入力値最終行の末尾に改行が１つ入ります。

m n

#期待する出力
初項 m ,公差 n の等差数列を1〜10番目までスペース区切りで出力して下さい。
#入力例1
3 3
#出力例1
3 6 9 12 15 18 21 24 27 30
#入力例2
5 10
#出力例2
5 15 25 35 45 55 65 75 85 95
#入力例3
1 3
#出力例3
1 4 7 10 13 16 19 22 25 28
#私の答え
```java:
num = gets.chomp.split(" ").map(&:to_i)
x = num[0]
i = 1
array = []
while i <= 10
  array << x
  x = x + num[1]
  i += 1
end
print array.join(" ")
```
#今回のポイント
###1行目の入力値はスペース区切りがあるので split と map で[3, 3]のような配列にする
###2行目で先ほどの配列の一部を指定して x変数に代入しておく
###3行目で i = 1 としておく事で1回ずつカウントさせる
###4行目でスコープ外でもarrayを使えるようにし、また繰り返し結果を配列に格納する
###5~9行目で i が10回を超えるまで繰り返される。 array[] に x = num[0]を配列演算子 << を使って連結している。while文の場合、 i += 1 の自己代入演算子を忘れてはいけない
###最終行でjoinメソッドを用いて (" ") とする事で配列間にスペースを開けられる
#以上！
備忘録No.6「文字列として受け取った１桁の和差の式を計算する」[Java]

#はじめに
初めてgetNumericValueメソッドを使用したので、記録。

#やりたい事
・長さ自由の文字列で計算式を受け取る（使われる数字は全て1桁、演算子は'+'と'-'のみ）
・受け取った文字列を数値にして計算
・計算結果を出力する

（例）
入力："1+2+3"
出力：6

#コード
```java
        Scanner sc = new Scanner(System.in);
        String line = sc.nextLine();
        sc.close();
        char [] c = line.toCharArray();

        int sum = 0;
        boolean add = true;

        for(int i = 0; i < line.length(); i++) {
            if(i % 2 == 0) {//数値と演算子が交互に来るため、偶数は数値の計算,奇数は演算子の入れ替えを行う
                if(add) {
                    int n = c[i];
                    sum += n;
                } else {
                    int n = c[i];
                    sum -= n;
                }
            } else {
                if(c[i] == '+') {
                    add = true;
                } else {
                    add = false;
                }
            }
        }
        System.out.println(sum);
```

入力："1+2+3"
出力：150

#コード１の問題点
・char型の配列に入れられた数値をint型にした際に、ASCII文字コードで代入されてしまっている。→ 配列に入っている数値の見た目そのままで取り出したい！

#改善したコード
```java
                if(add) {
                    int n = Character.getNumericValue(c[i]);
                    sum += n;
                } else {
                    int n = Character.getNumericValue(c[i]);
                    sum -= n;
                }
```
入力："1+2+3"
出力：6

#まとめ
char型の数値をそのまま使いたい時には、Character型のgetNumericValue()を使う。

#追記
#####省略前

```java
                if(c[i] == '+') {
                    add = true;
                } else {
                    add = false;
                }
```
上記の部分では、比較演算子はboolean型を返すので、addに直接代入することで、真偽判定ができる。

#####省略後

```java

                add = c[i] == '+';
```
Webアプリでカメラ操作したいときに見るメモ（javascript）


HTML

```html
<video id="myvideo" width="160" height="160" muted autoplay playsinline></video>
```
・width：横幅
・height：縦幅
・muted：動画の音をでないように設定
・autoplay：動画を自動再生
・playsinline：インライン再生を可能にする

参考
[【videoタグ】HTMLで動画を埋め込む方法を徹底まとめ]
(https://webliker.info/52510/)

JS

```javascript
async function main() {
    // デバイス（カメラ・マイク）からのデータ取得を試みる
    // 映像や音声が使えるデバイスが確定するまで時間がかかるためawaitを使う
    const stream = await navigator.mediaDevices.getUserMedia({
        audio: true,
        video: true,
    });
    // IDが"myvideo"であるDOMを取得
    const video = document.getElementById('myvideo');
    // myvideoなvideo要素のsrcObject（映像オブジェクトを入れるところ）にデータ（メディアストリーム）をセットする
    video.srcObject = stream;
}

// 実行する
main();
```

参考
[javaScriptでWEBカメラの映像をブラウザで表示する(PC/iPhone)]
(https://qiita.com/shiba_mitue/items/6b6b6c1482c8815226de)
[video要素、audio要素をJavaScriptから操作する]
(http://www.htmq.com/video/)

#フロントカメラとリアカメラを切り替える方法（スマホで使う）
フロントカメラ＝内側のカメラ（インカメ）
リアカメラ＝外側のカメラ

■フロントカメラ

```javascript
navigator.mediaDevices.getUserMedia({
  audio: false,
  video: {
    width: 640, height: 480,
    facingMode: "user"
  }
})
```

■リアカメラ

```javascript
navigator.mediaDevices.getUserMedia({
  audio: false,
  video: {
    width: 640, height: 480,
    facingMode: { exact: "environment" }
  }
})
```

参考
[[HTML5] カメラのフロントとリアを切り替える]
(https://blog.katsubemakito.net/html5/camera-toggle)
【Java】部分文字列を抜き出す（AOJ13 - シャッフル）

#文字列から部分文字列を抜き出す
* Stringクラスのsubstringメソッド
* 第一引数に抜き出し開始の位置を設定

```java
public class Main {
	public static void main(String[] args) {
    String str = "ねこはなんでこんなにMOFUいんでしょうか";
    //10~14文字目まで抜き出す
    String mofu= str.substring(10,15);
    //山崎を表示
    System.out.println(mofu); //MOFUい
    }
}
```
#シャッフル（ITP1-9）
>１つのアルファベットが描かれた n 枚のカードの山をシャッフルします。
1回のシャッフルでは、下から h 枚のカードをまとめて取り出し、それを残ったカードの山の上に積み上げます。
カードの山は以下のように１つの文字列で与えられます。
abcdeefab
最初の文字が一番下にあるカード、最後の文字が一番上にあるカードを示しています。
例えば、これを h が 4 でシャッフルすると、最初の4文字 abcd が、残りの文字 eefab の末尾へ連結されるので以下のようになります：
eefababcd
このシャッフルを何回か繰り返します。
カードの山の最初の並び（文字列）と h の列を読み込み、最後の並び（文字列）を出力するプログラムを作成して下さい。
Input
複数のデータセットが入力として与えられます。各データセットは以下の形式で与えられます：
最初の並びを表す文字列
シャッフル回数 m
h1
h2
  .
  .
hm
最初の並びを表す文字列が "-" のとき入力の終わりとします。
Output
各データセットに対して、最後の並び（文字列）を１行に出力して下さい。


```java
import java.util.Scanner;

public class Main {
	public static void main(String[] args) {
		Scanner scanner = new Scanner(System.in);
		while (true) {
			String a = scanner.next();
			if (a.equals("-")) {
				break;
			}
			int b = scanner.nextInt();
			//b行分の合計値を計算
			int sum = 0;
			for (int i = 0; i < b; i++) {
				sum += scanner.nextInt();
			}
			System.out.println(sum); //7
			System.out.println(a); //vwxyz 5
			//2倍 にする
			String c = a + a; //vwxyzvwxyz
            //System.out.println(c);
            
            /*文字列aの文字を一文字ずつ、(sum/文字列)のあまり分だけ左に動かしたい
            substringメソッド
			開始位置：(sum/文字列a長さ)のあまり 7/5=1...2   2
			終了位置：(sum/文字列a長さ)のあまり+文字列a長さ 2+5=9
			*/
			System.out.println(c.substring(sum % a.length(), sum % a.length() + a.length()));
		}
	}
}
```
【AWS認定試験】SAA-C02取得しました

# はじめに
先日、SAA(AWS認定ソリューションアーキテクトアソシエイト)に合格した為、やったことを残します。

# 勉強期間
SAA取得を目指すまでのAWS経験や勉強内容は以下に記載があります。
[新卒1年目が1.5ヶ月でAWS認定 クラウドプラクティショナーを取得するまで][link-1]

SAAの勉強を始めたのが10月頃なので約1ヶ月の勉強期間で行ったことを記載します。

[link-1]:https://qiita.com/t_tsuchida/items/3d43385f7348f1702ca8

# 試験対策
### Udemy
正直、SAAを意識して行った対策はこれだけです。
[これだけでOK！ AWS 認定ソリューションアーキテクト – アソシエイト試験突破講座（SAA-C02試験対応版）][link-2]

[link-2]:https://www.udemy.com/course/aws-associate/

講座を聞きながら、ハンズオンをあまり使ったことのないリソースだけ行いました。
その後、付属の模擬問題を行いました。

1週目はすべての回答を読み込み、わからなかった内容をメモしました。
2週目以降は間違えた問題だけ読み込みました。

計3~4周したと思います。

アプリもあるので、落としておいて出先で勉強するのもお勧めです。

### テスト環境で構築
個人的にAWSアカウントを作成していくつかのハンズオンで構築を行いました。
こちらのハンズオンがおすすめです。
[モダンウェブアプリケーションを構築する][link-3]
[link-3]:https://aws.amazon.com/jp/getting-started/hands-on/build-modern-app-fargate-lambda-dynamodb-python/
個人的に理解できていなかったECS,ECR,Fargateの役割や、
CodeCommit,CodeDeploy,CodePipelineのCI/CDパイプラインが理解できました。

そのほかにも模擬問題を受けてみてよくわからないリソースはハンズオンを見つけて作ってみることをお勧めします。

### よく出た(印象に残った)リソース
- S3
    - Standerd,Glacier,Deep Archive,IA,One Zone-IAの違い
  
- EBS
    - 汎用SSD,プロビジョンドIOPS,スループット最適化HDD,cold HDDの使い分け

- Route53
    - レコードタイプ(特にCNAMEとALIASのサポートされるサービスの違い)
    - ルーティングポリシー
  
- ファイルストレージ(EFSとFSx)
    - NFSならEFS,SMBならFSxみたいな話

- SQS
    - 基本的なことはもちろんだが、メッセージ送信が失敗した場合の挙動なども知っておくべき

- ELB
    - ALB,NLBの違い。どのレイヤーの通信ならこっちなど。

また、Udemyの模擬問題集であるような、具体的な数字についての言及(SQSのキューの保持期間など)は少ないように感じました。
AWSは日々仕様が改善されるのでそれを考慮しているのかもしれません。
リソースの「できないこと」という制限事項も同様の理由で少ない印象でした。


# 試験本番について
### 受験方法
ピアソンVUEが在宅受験での日本語対応を行っていたので、活用しました。

以下に詳細を書いたので、ご参照ください。
[【AWS認定試験】日本語で自宅受験をしてみてトラブった話][link-4]
[link-4]:https://qiita.com/t_tsuchida/items/4842cc137398cf47239e

### 解き方の方針
本番の試験を受けるとわかるのですが、4択のうち「これはないだろう」と分かる回答が2つほどあります。

それが除外できると後悩むのは二択なので、そこから絞り込めると正解率が高くなります。

### 問題文がおかしいと感じたら
試験を受けていると問題文がおかしいと感じることがありました。
そういう場合は問題文を英語に戻すことをお勧めします。

私の場合は「IAMユーザ」が「IAMロール」と翻訳されており、非常に悩みました。


# まとめ
中級の試験らしく、プラクティショナーよりは難しいと感じました。
しかし、しっかりと対策を行い、ある程度のAWSでの経験があれば十分合格できる試験だと思います。
AzureKinectDKでボディトラッキング動作の確認

### Azure Kinect Body Tracking SDK 1.0.1.msiをインストール
https://docs.microsoft.com/ja-jp/azure/kinect-dk/body-sdk-download
![SnapCrab_NoName_2020-11-16_11-17-35_No-00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/48015/45fb78a8-a886-70cf-409d-63265892bbf2.png)

###Azure Kinect Body Tracking Viewerで動作確認
起動すると表示されました
SDKがインストールされていれば、何もしなくても表示されるようです
![SnapCrab_NoName_2020-11-16_11-19-44_No-00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/48015/af4a3dc4-e3d1-2065-3347-33cf6a1a771f.png)

###20210608追記

下記の環境がないとBody Tracking Viewerが表示されないことに気づきました。。

![aaaaa.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/48015/272d9907-e46c-73bc-bc6e-68b80872c654.png)

https://aka.ms/vs/16/release/vc_redist.x64.exe

###参考サイト

クイック スタート:Azure Kinect の体のトラッキングを設定する
https://docs.microsoft.com/ja-jp/azure/kinect-dk/body-sdk-setup
データ分析に活躍！スクレイピングの活用事例をご紹介

###Webスクレイピングとは？
Wikiで[Webスクレイピング](https://jp.scrapestorm.com/)がWebクローラと呼ばれるのを記載します。実際に、両者にはちょっとだけ差別があります。[スクレイピング](https://jp.scrapestorm.com/)と[クローリング](https://jp.scrapestorm.com/)はどちらもインターネット上の情報を収集することですが、スクレイピングは取得した情報の加工ができます。より詳しくデータを抽出すると、より深いデータ分析を行います。
データスクレイピングは今様々分野に活躍しています。これから、幾つかの[ScrapeStorm](https://jp.scrapestorm.com/)のスクレイピング活用事例を紹介します。
##1.SEO
SEOとは、“Search Engine Optimization”の略で、検索エンジンに向けてWebサイトを最適な状態に近づけること（検索エンジン最適化）を意味します。自分のサイトを検索エンジンに上位表示させるため、キーワードの収集は不可欠です。Webスクレイピングを通じて、検索エンジンでキーワードのトップを収得できます。自分もよくGoogleまたはYahooでキーワードをスクレイピングして、競争者サイトはどんなキーワードを持っていますか、今人気があるキーワードは何ですか、ユーザさんはよく検索するキーワードにも、スクレイピングされたデータから分析できます。
![SEO.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/482909/c62a5b43-3440-7ff1-e81e-d4fb7ac2f887.jpeg)
##2.E-コマース
ネットショッピングは人々に大歓迎される以来、Amazon、Yahoo！ショッピング、楽天市場、色々なネットショッピングサイトが人々の日常生活に入ります。売り手にとって、価格の監視、商品詳細、商品レビューなどの収集はマーケティングに大切なものです。競争店の商品の売上高、人気商品など取得して、人々の興味深い商品をちゃんと了解すれば、必ずこれからの経営戦略に役立ちます。
[楽天市場から商品最安価格をスクレイピングする](https://note.com/11210858628/n/n73cb20e035d8)
![E-コマース.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/482909/4d2e66c7-2689-ae85-ffba-d02c5c6be7a3.jpeg)
##3.株価指数
株式市場は目まぐるしく変動しています。定時的に株価指数を収集する、MySQL、SQLサーバーにエクスポートすることもできます。リアルタイムで株価指数を把握します。Yahoo！ファイナンスで株価予想と言う項目があります。株式の数か月以来のデータと予想を分析して、株式の購入に役立つかもしれません。
[株価投資メモで複数のURLから株価指数をスクレイピングする](https://note.com/11210858628/n/nb096ca54fb0b)
[Yahoo!ファイナンスから単元株価格上位情報をスクレピングする](https://jp.scrapestorm.com/tutorial/how-to-scrape-unit-stock-price-top-information-from-yahoo-finance/)
![株式.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/482909/73cf2f15-3513-dd05-f59e-c6a6eba01169.jpeg)
##4.学術研究
学術研究には通常大量のデータ調査が必要です。数多くのデータ分析をしてこそ、正確な結論が得られます。スクレイピングを通じて、過去の情報を収集するか、現在のデータを抽出するか、スクレイピングは各分野に存分に活躍しています。
![学術研究.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/482909/cd17eedc-9466-7073-df2f-3a3f416a81bc.png)
##5.日常生活
データ収集は思っているより人々の生活に近いです。ホテルの施設、近頃の交通、駐車場、朝食などを調査して、旅の攻略を作成するとか、料理のレシピを取得するとか、近頃有名なレストランを探すことなど、全部スクレイピングで情報収集できます。
[Bookingからホテル情報をスクレイピングする](https://ameblo.jp/suzikisyou/entry-12573445940.html)
[Tripadvisorからホテル情報をスクレイピングする](https://ameblo.jp/suzikisyou/entry-12573451206.html)
![食.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/482909/d9874066-5614-4c92-b293-bba790ac7222.jpeg)
価格監視や研究用途、情報分析するといった際に必要なデータを収集するのにスクレイピングが活躍します。今回は、SEO、E-コマースなどの活用事例を紹介しますが、もちろん、以上の領域しかありません。**一つ注意すべきことがありますが、スクレイピングで悪意リクエストを送ることは法律違反です！Robots協議、法律を守った上で正しく利用してください。**
Rで混合ガウスモデル実装 (周辺化ギブスサンプリング)

# <font color="DarkSlateBlue">記事の目的</font>
混合ガウスモデルの周辺化ギブスサンプリングをRで実装します。

参考: [ノンパラメトリックベイズ 点過程と統計的機械学習の数理](https://www.amazon.co.jp/%E3%83%8E%E3%83%B3%E3%83%91%E3%83%A9%E3%83%A1%E3%83%88%E3%83%AA%E3%83%83%E3%82%AF%E3%83%99%E3%82%A4%E3%82%BA-%E7%82%B9%E9%81%8E%E7%A8%8B%E3%81%A8%E7%B5%B1%E8%A8%88%E7%9A%84%E6%A9%9F%E6%A2%B0%E5%AD%A6%E7%BF%92%E3%81%AE%E6%95%B0%E7%90%86-%E6%A9%9F%E6%A2%B0%E5%AD%A6%E7%BF%92%E3%83%97%E3%83%AD%E3%83%95%E3%82%A7%E3%83%83%E3%82%B7%E3%83%A7%E3%83%8A%E3%83%AB%E3%82%B7%E3%83%AA%E3%83%BC%E3%82%BA-%E4%BD%90%E8%97%A4-%E4%B8%80%E8%AA%A0/dp/4061529153)


# <font color="DarkSlateBlue">目次</font>

<table>
<tr><td><font color="DarkslateBlue">No.<td><font color="DarkslateBlue">目次
<tr><td><font color="DarkslateBlue">1</font><td><a href="#1-モデルの説明">モデルの説明</a>
<tr><td><font color="DarkslateBlue">2<td><a href="#2-データとライブラリ">データとライブラリ</a>
<tr><td><font color="DarkslateBlue">3<td><a href="#3-実装">実装</a>
<tr><td><font color="DarkslateBlue">4<td><a href="4-確認">確認</a>
</table>

# <font color="LimeGreen">1.</font> <font color="DarkSlateBlue">モデルの説明</font>
![IMG_0197.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/775500/af1bf251-6d88-8ca4-5564-2cd31f5608ca.jpeg)


# <font color="LimeGreen">2.</font> <font color="DarkSlateBlue">データとライブラリ</font>
データはirisのデータセットを使用します。

```R:
X <- iris[,1:4]
D <- ncol(X)
N <- nrow(X)
library(mvtnorm)
library(MCMCpack)
library(cluster)
```

# <font color="LimeGreen">3.</font> <font color="DarkSlateBlue">実装</font>
```R:
#(1)Kを求める
K <- 3
#(2)muを乱数で初期化
set.seed(100)
z <- apply(rmultinom(N, 1, rep(1/K, K)), 2, which.max)
#(3)
a0 <- 1
b0 <- 1
alpha0 <- 1
#(4)(ⅰ)を繰り返す
max.iter <- 2
a <- 2*a0 + (N-1)*D
for(s in 1:max.iter){
  #(ⅰ)zのサンプリング
  for(i in 1:N){
    #bの計算
    b <- 2*b0 + sum(apply(X[-i,], 2, function(x) (x-mean(x))^2)) +
      (N-1)/N*sum(apply(X[-i,], 2, mean)^2)
    #mの計算
    n <- tapply(z[-i], z[-i], length)
    x.k <-  apply(X[-i,], 2, function(x) tapply(x, z[-i], mean))
    m <- as.vector(n/(n+1))*x.k
    #zのサンプリング
    tmp <- apply(m, 1, function(x) dmvt(X[i,], delta=x, df=a, sigma=solve(diag(D)*b/(1+1/N)), type="shifted", log=FALSE))*
      (n+alpha0)/(sum(n)+alpha0)
    z[i] <- which.max(rmultinom(1, 3, tmp))
  }
}
```

# <font color="LimeGreen">4.</font> <font color="DarkSlateBlue">確認</font>
左が正解で、右が実装の結果です。

```R:
par(mfrow=c(1,2))
clusplot(X, iris[,5], color=TRUE, shade=FALSE, labels=4, lines=0)
clusplot(X, z, color=TRUE, shade=FALSE, labels=4, lines=0)
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/775500/8d43faed-a393-38fb-4a07-8e025c4e04d6.png)
AzureKinectDKのセットアップ

###SDK のダウンロードとインストール
https://docs.microsoft.com/ja-jp/azure/kinect-dk/sensor-sdk-download

###Azure Kinect ビューアーを起動確認
![SnapCrab_NoName_2020-11-16_11-2-58_No-00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/48015/73ac0c44-295c-16ec-a634-60a9ba247568.png)

###Kinectを接続してAzure Kinect ビューアーを再起動
デバイスIDが出ていればOKのようです
OpenしてStartで動作確認できるようです
![SnapCrab_NoName_2020-11-16_11-5-36_No-00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/48015/fb188176-02fa-dfb2-295b-81cca06172be.png)

###ファームウェア更新
「C:\Program Files\Azure Kinect SDK v1.4.1\tools」に更新用のexeがあるようです
※Azure Kinect ビューアーを閉じないとデバイスありませんってなったので閉じてから実行しました
「bin」ファイルは「firmware」に入っているものにリネームしました

```
cd C:\Program Files\Azure Kinect SDK v1.4.1\tools
AzureKinectFirmwareTool.exe -u firmware\AzureKinectDK_Fw_1.6.110079014.bin
```
![SnapCrab_NoName_2020-11-16_11-12-6_No-00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/48015/012958d1-07f7-1b90-045d-8fbe16120bf3.png)



###参考サイト
クイック スタート:Azure Kinect DK を設定する
https://docs.microsoft.com/ja-jp/azure/kinect-dk/set-up-azure-kinect-dk
【Ruby】downcase,sliceメソッドの応用

「a = "abc"」,「b = "HiAbc"」という二つの変数がある時、a,bいずれかの文字列がもう片方の文字列の最後にある場合にTrueを返すプログラムの作成方法です。
今回の場合、aのabcがbの後ろ三文字に存在するためTrueとなります。

以下二つのメソッドを使用することで作成することができます。

## メソッドの使用例
- 大文字を小文字に変換するためにはdowncaseメソッド

```java:ruby
a = "AbC"
a_down = a.downcase
// これにより a_down には abc が入る
```

- 特定の位置にある文字列などを切り抜きたい場合はsliceメソッド

```java:ruby
a = "AbC"
a_slice = a.slice(1)
// これにより a_slice には b が入る
```

## 回答例

```java:ruby
def compare(a, b)
  a_down = a.downcase
  b_down = b.downcase
  a_len = a_down.length
  b_len = b_down.length
  if b_down.slice(-(a_len)..- 1) == a_down || a_down.slice(-(b_len)..- 1) == b_down
    puts "True"
  else
    puts "False"
  end
end
```

## 解説
2~5行目でこの後に使用する変数の定義をしています。

```java:ruby
a_down = a.downcase    // aの文字列を全て小文字化してa_downに代入
b_down = b.downcase    // bの文字列を全て小文字化してa_downに代入
a_len = a_down.length  // a_downの文字列の長さをa_lenに代入
b_len = b_down.length  // a_downの文字列の長さをa_lenに代入
```
その後、以下のif文で判定しています。

```java:ruby
if b_down.slice(-(a_len)..- 1) == a_down || a_down.slice(-(b_len)..- 1) == b_down
  puts "True"
else
  puts "False"
end
```
「b_down.slice(-(a_len)..-1 == a_down」を日本語訳すると、「b_downの右から1〜a_len部分を切り取る」となります。
仮にa_lenが「3」、b_downが「hiabc」という5文字だったとして、「hiabcの右から1〜3文字を切り取る」となります。すると切り取った文字列は「abc」となります。
``sliceメソッドは正の値を渡すと先頭から計算し、負の値を渡すと末尾から計算しますので、これを覚えておいてください。``

b_downの場合とa_downの条件を「または」という演算子を使っていることで、どちらの変数からも確認できるようにしています。（正直最初見たときは訳せなくて落ち込みました。）

## 追記(20201117)
コメントにて``String.end_with?``メソッドを教えていただきました。
前述の回答例よりも可読性が高いためこちらを追記します。

```java:ruby
def compare(a, b)
  a_down = a.downcase
  b_down = b.downcase
  if b_down.end_with?(a_down) || a_down.end_with?(b_down)
    puts "True"
  else
    puts "False"
  end
end
```
なお、文字列の先頭が一致しているかを確認する場合は``String.start_with?``メソッドが使用できるようです。コメントを下さりありがとうございました！
[Rails]redirect_toとrenderの違いについて[初心者]

#はじめに
いきなりですが、``redirect_to``と``render``って、初めて見たときは、両者の違いがよく分からなかったですよね。
深掘りして、一緒に学んでいきましょう！

#redirect_toとrenderの違い
redirect_to: HTTPリクエストをサーバーに送り、ユーザーはそこから返ってくるHTMLが表示される。
render: アクションの中で、呼び出すViewファイルを指定するメソッド。

言葉だけだと、分かりづらい部分があると思うので、それぞれの**処理の流れ**について解説します。

#それぞれの処理の流れについて

```ruby:redirect_toの処理の流れ
①controllerの処理でredirect_toを実行
②redirect_toの引数で指定したURLにHTTPリクエスト(GET!!)を実行
③HTTPリクエスト(GET!!)されたURLに対応するルーティング処理を実行
④ルーティング処理に対応したcontroller、アクションが呼び出され処理を実行
⑤処理に応じたviewのレンダリングを実行
```

①controller（redirect_to）　→ ②HTTPリクエスト(GET!!)　→　③ルーティング　→　④controller　→　⑤view

```ruby:renderの処理の流れ
①controllerの処理でrenderを実行
②renderのオプションで指定したviewファイルを表示する
```

①controller(render)　→　②view

ここで注意が必要なのは、redirect_toの指定先は、**必ずGETメソッド**のルーティングになるということです。

#redirect_toやrenderの指定がない場合
たまに見かけますよね。
下の状態のようなコントローラーを。

```ruby:controllers/books.rb
class BooksController < ApplicationController
  def index
  end
end
```

アクション内に、何も記載がない場合は、自動的にrenderが実行されます！！
つまり、上の場合だと、``render 'index'``が省略されているものと考えられ、このアクションから``views/books/index.html.erb``が呼び出されます。

#よく見る記載方法
それではここで、よく使われているredirect_toとrenderの記述例について見てみましょう！

```ruby:controllers/books.rb
class BooksController < ApplicationController
  def create
    @book = Book.new(book_params)
    @book.user_id = current_user.id
    if @book.save
      redirect_to books_path, flash[:notice] = "投稿成功！！"
    else
      flash.now[:alert] = "投稿失敗!!"
      render 'new'
    end
  end
end
```

投稿を行う際に、saveメソッドの結果がtrueならば投稿一覧ページにリダイレクトし、falseなら新規投稿用のページを再表示するように設定しています。
※``render 'アクション名'``で同じコントローラの別アクションのViewを表示できます。
　コントローラ名を指定することで、他のコントローラのViewも表示できます。

#なぜfalseの場合はrenderを使用するのか
renderを利用して、viewファイルを表示する際に、アクションを呼び出していないことにお気づきでしょうか。
↑の``render 'new'``は、``books/new.html.erb``を表示させているだけであり、newアクションを経由しているわけではないのです。

今回のパターンだと、投稿に失敗しているからnewページを表示させたいのですが、redirect_toを使用してしまうと、newアクションを呼び込み、インスタンス変数に空のメソッドを渡してしまうことで、newアクションがリセットされた状態になるので、ユーザーが打ち込んだデータが消えます。
よって、エラーメッセージを打ち出す為の情報も消えてしまう為、ユーザーは「なぜ投稿できなかったのか」を窺い知ることができなくなります。

ややこしいですが、大事な分岐点を決めるものなので、腹落ちするまで向き合ってもらえればと思います。

##(補足)render時のフラッシュメッセージについて
本筋とは離れてしまうので、詳細は述べませんが、表示したビュー内にメッセージを出したい場合、以下のように記述します。

```ruby:redirect_toの場合
flash[:notice] = "メッセージ"
　または
notice: "メッセージ"
```

```ruby:renderの場合
flash.now[:alert] = "メッセージ"  #nowがついている！！！！
```

#おわりに
初心者の方が間違いやすいredirect_toとrenderの違いについて説明しました！！
解説している中で、自分自身勉強になることが多く、アウトプットの重要性を痛感しています。
Angular11リリース！AWS Glue DateBrew, Gateway Load Balancerリリース！ Appleシリコン搭載Mac発売【やっすんのエンジニアNews】【11月3週目】

# はじめに
11月3週目のニュースを独断と偏見で紹介していきます。

4分程度の動画でまとめているので、興味のある方は動画もどうぞ！
[【YouTube動画】 やっすんのエンジニアNews【11月3週目】](https://youtu.be/N3_0mGmwdJM)
[![やっすんのエンジニアNews【11月3週目】](https://img.youtube.com/vi/N3_0mGmwdJM/0.jpg)](https://youtu.be/N3_0mGmwdJM)

# Angular11リリース
Angular11がリリースされました。
https://blog.angular.io/version-11-of-angular-now-available-74721b7952f7

簡単にまとめると以下のようになります。

- コンパイルが2-4倍高速化
- フォントを自動でインライン化し、アプリを高速化
- CLIの表示を変更
- より簡単にホットリロードができるようになった
- Webpack5を実験的にサポート
- ESLintへの移行を促すため、TSLint等を廃止
- IE9/IE10のサポート廃止

# AWS Glue DateBrewリリース
AWS Glue DateBrewがリリースされました。
[AWS Glue DataBrew の発表 – データのクリーニングと正規化を迅速にするビジュアルデータ準備ツール](https://aws.amazon.com/jp/blogs/news/announcing-aws-glue-databrew-a-visual-data-preparation-tool-that-helps-you-clean-and-normalize-data-faster/?utm_source=feedburner&utm_medium=feed&utm_campaign=Feed%3A+aws%2Fjp-blog-news+%28Amazon+Web+Services+%E3%83%96%E3%83%AD%E3%82%B0%29)

簡単にまとめると以下のことができます。

- 機械学習用のデータの前処理ができるサービス
- S3やRDSまたはコンソール画面でデータをアップロードする
- データパターンを視覚的に確認できる
- いくつかの項目を選び、データをクリーニング・正規化できる
- 上記データのクリーニング・正規化を自動化できる

<img src='https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/751408/cfd4ff2c-063d-5851-c1a1-71c5ee391d0c.png' width='700'>

# AWS Gateway Load Balancerリリース
AWS Gateway Load Balancerがリリースされました。
[AWS Gateway Load Balancer のご紹介 — パートナーアプライアンスの簡単なデプロイ、スケーラビリティ、高可用性](https://aws.amazon.com/jp/blogs/news/introducing-aws-gateway-load-balancer-easy-deployment-scalability-and-high-availability-for-partner-appliances/?utm_source=feedburner&utm_medium=feed&utm_campaign=Feed%3A+aws%2Fjp-blog-news+%28Amazon+Web+Services+%E3%83%96%E3%83%AD%E3%82%B0%29)

簡単にまとめると以下のことができます。

- 他のVPCにあるサードパーティのセキュリティ製品が使いやすくなる
- Gateway Load Balancerとそのエンドポイントだけで、VPC間を繋げることができる
<img src='https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/751408/8f283417-4adf-dd2d-bfdf-f00bcdce4921.png' width='600'>


# Apple シリコン搭載Mac発売
Appleシリコン M1搭載のMacが発売されました！
[Apple、M1チップを発表](https://www.apple.com/jp/newsroom/2020/11/apple-unleashes-m1/)

完全以降までは約2年かかるそうです。

エンジニア目線でみると、以下が不安なところです。

- メモリが最大16 GB (32 GBぐらい欲しい)
- 外付けGPU非対応
- Dockerが動かないらしい (https://github.com/docker/for-mac/issues)

# その他
Goが11月10日で11周年になりました。
https://blog.golang.org/11years

Laravelは8.14がリリースされました
https://laravel-news.com/laravel-8-14-0
ローカルのSQL DUMPをRDSなどへインポートした際に以下のエラーが出た時の対処法

ローカルのSQL DUMPをRDSなどへインポートした際に以下のエラーが出た時の対処法

```
ERROR 1227 (42000) at line 18: Access denied; you need (at least one of) the SUPER, SYSTEM_VARIABLES_ADMIN or SESSION_VARIABLES_ADMIN privilege(s) for this operation
```
コマンドラインにて、いかを実行。

```
sed -i -e '/^\/\*!50013 DEFINER=/d' dump.sql
sed -i -E 's/CREATE DEFINER=.+ (FUNCTION|PROCEDURE)/CREATE \1/g' dump.sql
sed -i -E 's/\/\*\!50020 DEFINER=`.*`@`localhost`\*\/ //g' dump.sql

sed -i '/SESSION.SQL_LOG_BIN/d' dump.sql
sed -i '/GLOBAL.GTID_PURGED/d' dump.sql
```
【JavaScript】splice()メソッド

#プログラミング勉強日記
2020年11月16日
spliceメソッドを学習したので、記録していきます。

#spliceメソッドとは？
配列の中身を削除したり、置き換えたり、新しく値を追加できるメソッドです。
戻り値として、取り除いた値を返します
#構文
```
num.splice('start','deleteCount', item1, item2....);
```
###1.start

配列を変更する開始位置を表すインデックス番号を記述します。

####2.deleteCount
startから値を取り除く数を記述します。

記述しなかった場合、start以降(startの値も含めます)の値を全て削除します。

0の場合、値は削除されませんが、itemに新しく追加する値を記述する必要があります。

###3.item1,item2....
startから配列に追加する値を記述します。

#例文

###インデックス番号3(50)から、2個(50と60)の値を削除して、新しく35を追加する。

```script.js
const scores = [80,90,40,50,60,45];
scores.splice(3, 2, 35);
```

```出力結果.
[80,90,40,35,45]
```

#参考資料
* [MDN:Array.prototype.splice()](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array/splice)
3分アジャイル バーンダウンチャート

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/47327/13b07ff8-9545-717f-f2ef-11d7e427df10.png)

---
## バーンダウンチャート
- スプリントで計画された機能の消化率
- ベロシティ（傾き）を測る
- スプリントの完了に向かって走る

---
## 目的
- 検査と適応（スクラム）
- チームメンバー、ステークホルダーが常に見えるようにしておく（透明性と検査）
- バーンダウンできない場合には何が問題かを考える（適応）

---
## 事例
- デイリーミーティングでバーンダウンを確認する
- 計画の見直し、ベロシティが低い、割り込み、変更、スキル、知識...
- テストの知識が必要であればテスト勉強会など

---
## デイリー
- 開発チームがスプリントゴールを達成するために、私が昨日やったことは何か？
- 開発チームがスプリントゴールを達成するために、私が今日やることは何か？
- 私や開発チームがスプリントゴールを達成する上で、障害となる物を目撃したか？
IBM Cloud: （小ネタ）VPCで/etc/hostsに追加した情報がrebootした際に消される問題について

#問題

```txt:/etc/hostsへのレコード情報の追加
[root@syssuda5-vpc2 ~]# echo "8.8.8.8   googledns" >> /etc/hosts
```
```txt:pingに成功
[root@syssuda5-vpc2 ~]# ping -c 3 googledns
PING googledns (8.8.8.8) 56(84) bytes of data.
64 bytes from googledns (8.8.8.8): icmp_seq=1 ttl=119 time=13.6 ms
64 bytes from googledns (8.8.8.8): icmp_seq=2 ttl=119 time=1.02 ms
64 bytes from googledns (8.8.8.8): icmp_seq=3 ttl=119 time=0.999 ms

--- googledns ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2002ms
rtt min/avg/max/mdev = 0.999/5.220/13.634/5.949 ms
```

しかし、再起動したらまたpingができなくなっています。

```txt:再起動後。pingに失敗。
[root@syssuda5-vpc2 ~]# ping -c 3 googledns
ping: googledns: 名前またはサービスが不明です
```

```txt:再起動後。/etc/hostsから追加したはずのレコードが削除されている。
[root@syssuda5-vpc2 ~]# cat /etc/hosts
# Your system has configured 'manage_etc_hosts' as True.
# As a result, if you wish for changes to this file to persist
# then you will need to either
# a.) make changes to the master file in /etc/cloud/templates/hosts.redhat.tmpl
# b.) change or remove the value of 'manage_etc_hosts' in
#     /etc/cloud/cloud.cfg or cloud-config from user-data
#
# The following lines are desirable for IPv4 capable hosts
127.0.0.1 syssuda5-vpc2 syssuda5-vpc2
127.0.0.1 localhost.localdomain localhost
127.0.0.1 localhost4.localdomain4 localhost4

# The following lines are desirable for IPv6 capable hosts
::1 syssuda5-vpc2 syssuda5-vpc2
::1 localhost.localdomain localhost
::1 localhost6.localdomain6 localhost6
```

#解決方法

`/etc/hosts`のヘッダ部分に書かれているとおり、cloud-initで上書きされてしまったためです。`/etc/cloud/cloud.cfg`にて、`manage_etc_hosts: True`の箇所をコメントしてしまいます。

```txt:/etc/cloud/cloud.cfg(before)
manage_etc_hosts: True
```
```txt:/etc/cloud/cloud.cfg(after)
#manage_etc_hosts: True
```

これで再起動後に`/etc/hosts`がcloud-initによって上書きされることがなくなりました。
【Blueprint】ARFilterの構造体の中身についてのメモ

#ARFilter
ARfilterはAssetDataの取得のために使用するツールです。
特定のフィルターを元にUe4内の全アセットからフィルタリングしてAssetDataを取得できます。
各パラメーターを忘れがちなので、自分用にメモ。

↓ちなみに使用するときはこんな感じ。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/367001/00924a14-8a54-acdf-572f-2e3fa5fba6c7.png)

用途によってオブジェクトデータとかにcastして使用する感じですね。
AssetData自体をbreakしちゃえば名前やパスを引っ張ってくることもできます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/367001/1225fbf4-2a9d-5ae2-e6c4-8899e901799b.png)

## ARFileterの構造体中身
ARFileterの構造体中身ですが以下のようになってます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/367001/51df5c2a-68e4-f08c-b385-dccf6381eab4.png)

以下"/Game/test/"に"NewMaterial"という名前のマテリアルが入っている場合の検索例

##Package Names
"Game/"から始まりアセットの名前で終わるパスを元に検索配列で検索。配列で複数指定可
例 "/Game/test/NewMaterial"

##Package Paths
"Game/"から始まるディレクトリパスを元にアセットを検索します。配列で複数指定可
例 "/Game/test"

##Object Paths
Package Nameに"."+Package Nameが付いたような形（これが何を指定しているかわからない）で検索します。配列で複数指定可
例 "/Game/test/NewMaterial.NewMaterial"

##Class Names
クラス名でフィルタリングし検索します。
例"Material"

##Recursive Classes Exclusion Set
RecursiveClassesがtrueの場合のみ、結果はこのリストのクラス（およびサブクラス）を除外します

##Recursive Paths
trueの場合、PackagePathコンポーネントは再帰的になります

##Recursive Classes
trueの場合、ClassNamesのサブクラスも含まれ、RecursiveClassesExclusionSetは除外されます。

##Include Only on Disk Assets
trueの場合、ディスク上のアセットのみが返されます。

##参考
https://docs.unrealengine.com/en-US/PythonAPI/class/ARFilter.html
Visual Studio Code 拡張機能GitLensで誰がそのソースを書いたか確認しよう

# 目的

- Visual Studio Code（以後VScode）の拡張機能GitLensが便利だったので導入方法から紹介する

# 前提条件

- VScodeが導入されていること。

# 前提情報

- 筆者はMacにVScodeを入れている。拡張機能なのでOSには左右されないと思うのでWindowsの方も同じ方法でできると思う。

# 詳細

1. 導入
    1. VScodeを開き、サイドメニューにある拡張機能のアイコンをクリックする。
    
        ![Visual_Studio_Code.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306417/f24fcf89-58ee-f51a-dac7-f90b89203d40.png)
    
    1. 課長機能の検索部分に「GitLens」と入力し、ヒットしたGitLensの「インストール」をクリックする。
    
        ![Visual_Studio_Code-3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306417/3e2c96ea-0f10-dca6-5f32-69006f2b4e42.png)

1. 確認
    1. Gitでバージョン管理をしているファイルをVScodeで開く。
    1. 既存ソースコードをクリックして入力できるようにする。
    1. 下記のように誰が、どのくらい前に、どんなコミットメッセージでコミットしたかの情報が表示される。

        ![git_blame_test_txt.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306417/5f25ddf8-b7f8-4b88-c9ba-3e576e09fa9a.png)
自分用アフターエフェクトショートカット

画面に合わせて表示
shift+/

http://oldrookie.info/2019/11/19/%E3%80%90ae%E3%80%91%E7%94%BB%E9%9D%A2%E3%81%AE%E5%A4%A7%E3%81%8D%E3%81%95%E5%A4%89%E6%9B%B4%E3%81%AE%E3%82%B7%E3%83%A7%E3%83%BC%E3%83%88%E3%82%AB%E3%83%83%E3%83%88/
FlutterとFirebase連携するさいの設定置き場

Firebase側でアプリ追加するときの手順でFlutterの場合設定ファイルのディレクトリに場所が違うのでメモ。


### Android設定
`{project_nane}/android/app/`下に`google-services.json`を置く。



### iOS設定

`{project_nane}/ios/Runner/`に`GoogleService-Info.plist`を置く。
javascriptで文字列を分解して配列化メモ

#書き方
分割対象の文字列.split(区切りに使用する文字列)

#今回の場合
LINEから受け取ったメッセージ「飲みに行きたい　名前」なので、

```javascript

const message_arr = event.message.text.split("　")
```
全角スペースかな。


全角スペースを入れていないときは、配列の2個目の要素は「undefined」になる。
macOS Big Sur の起動音を消す

# macOS BigSur

macOS Big Sur は Mac の電源を入れると鳴る「ジャーン」が復活している。


うるさい。音でかい。消したい。

Mac システム環境設定 → サウンド → サウンドエフェクト → 起動時にサウンドを再生

チェックを外す。完璧。
ボタンを作る時のタグの使い分け

ボタンを作る時のタグの選択肢は

- aタグ
- buttonタグ
- input type="button"

があるがそれぞれどんな時にどれを使えばいいか理解していないかった。
だから今回しっかりと理解するためにいろいろと調べてみた。

# 結論


クリックで他のページの飛ぶ時→**aタグ**

クリックでJavascriptを動かすとき→**buttonタグ**
フォームの送信→**buttonタグ**

buttonタグが使えないhtml4の時→**input type="button"**





それぞれの場面について考えていく。





### クリックでページ遷移はaタグ
ページ遷移を作動させるにはタグにリンクを記述する必要がある。
その際buttonタグよりaタグの方が記述が少なく済むからだ。
またaタグが最も普及してることも考慮するとaタグの方が無難である。


### input type="button"はほとんど使わない
buttonタグと機能はほとんど同じだがinputタグには閉じタグがないため子要素を作る・擬似要素を使うことが出来ないのでデザインのカスタマイズ性が下がってしまう。
~~擬似要素が使えないとhoverなどのアニメーションが作れない。~~
有難い事に自分のミスについてご指摘頂きました。
hoverは擬似要素ではなく擬似クラスのためinputにも使えるそうです！

だからaタグを使わないならbuttonタグを使うべきである。

### 注意事項
 aタグの中にbuttonタグを入れてはいけない

参考にしたサイト様
> https://www.sejuku.net/blog/82466
https://code-kitchen.dev/html/button/
Delphiで湯婆婆する

元ネタ: [Javaで湯婆婆を実装してみる](https://qiita.com/Nemesis/items/c7192a7c510788d2cba2)

## Delphi婆婆
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/93824/b4a75c0c-eac1-880f-3bec-f12827354788.png)

## 中身
```yubaba.pas
procedure TForm1.Button1Click(Sender: TObject);
var
  len, pos :Integer;
  str, org :WideString;
begin
  org := Edit1.Text;
  len := Length(org);

  if MessageDlg('ふん。' + org +'というのかい。', mtConfirmation, [mbYes, mbNo], 0) = mrYes then
  begin
    pos := random(len);
    str := Copy(org, pos, 1);
    MessageDlg('贅沢な名だね。今日からお前の名前は ' + str +' だよ。', mtWarning, [mbYes], 0)
  end;

end;
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/93824/1ed54e8a-b273-e9fa-dd1b-104b63802f3f.png)

はしょり気味婆婆。

## 参考
http://kwikwi.cocolog-nifty.com/blog/2005/12/delphi_2bd5.html

https://www.petitmonte.com/bbs/answers?question_id=5641