OmniAICreator/Qiita-1.07M huggingface dataset:
git最低限覚えておくべきの基本コマンド

<h1>gitコマンドの最低限 覚えていたほうがいい基礎的コマンド</h1>
gitコマンドで個人開発する際に使う基本コマンドをまとめました。
こちらの記事を見るとgit操作で困る事がほとんど無くなると思います。
（チーム開発向けのgitコマンドは別の記事にまとめたいと思います。）


<h1>前準備</h1>
GitHubアカウントの登録をお願いします。
gitの初期設定は下記のサイトを参考にしてください。

https://prog-8.com/docs/git-env

<h1>前提知識</h1>
・ローカルとは自分のパソコン側の事だと思ってください
・リモートとはネット側にある倉庫だと思ってください
・リモートに変更を加える場合は先にローカル側を変更してからでないとリモートに反映出来ない

<h1>git基本コマンド</h1>
細かいとはさておきgitコマンドを触りながら覚えた方が早いので早速さわっていきましょう！


<b>・自分のローカル環境に新規でクローンする（ギット　クローン）</b>
クローンとはリモート側にあるファイルを自分のパソコンにダウンロードする事。


```
git clone ダウンロードしたいパス

(例)
git clone https://github.com/xxxxxxxxxxxxxxxxxxx.git
```

（ダウンロードしたいパスはGitHubのサイトでコピーしたHTTPSのパス）



<b>・gitの現在の状態の確認コマンド</b>
ローカル側のファイルを変更した後に`git add`をせずに`git status`行うと
赤文字でファイル名が表示される。
赤文字のファイル名はgitに管理されていないので`git add`をする必要がある。

(ギット　ステータス)

```
git status
```


<b>・ローカルのファイルをgitで管理</b>

gitに管理してほしい場合はgit add（ギット　アド）コマンドを使用する。
gitに管理してもらう事が目的なので行うこと。

・指定したファイルのみgitの管理下におくコマンド↓

```
git add ファイル名
```

・全てのファイルをgitの管理下におくコマンド↓

```
git add .
```

上記のgit addコマンドを行った後に`git status`行うと、ファイルの状態が変わるので確認する事。

※ファイルがgitの管理下にある状態になると
ファイル名がgitに管理され、文字が 赤色 → 緑色 に変わる。これをステージングという。



<b>・コミット</b>
ローカルにファイルの変更内容を反映させるためにgit commitを使用する。
`-m`はメッセージのことです。””（ダブルクォーテーション）の中にコミットメッセージを書く。
コミットメッセージはファイルにどの様な変更を加えたのかを書くようにしましょう。

```
git commit -m “コミットメッセージを入力”
```

<b>・gitのコミット履歴を確認できる</b>
どんなコミットをしたかさかのぼって確認したい場合に使用。

```
git log
```


<b>・リモートにファイルの変更内容をアップロードするためのコマンド</b>
最後にローカルの変更内容をリモートに反映させたいので、下記のコマンドを実行する事。


```
git push origin
```

origin（オリジン）とはリモートサーバのこと。
Jupyter notebookでセルの出力を制御する

![imageonline-gifspeed-8918972.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1037574/d1a06689-f648-233c-f2ae-d927de35563a.gif)
# はじめに
ディープラーニングの学習をjupyter notebookで行っている際、ログの出力でページが埋め尽くされます。
学習には時間がかかりますので、ログ出力は必要なんですが、たまに邪魔に感じる時もありますので、制御できないか調べてみました。

:::note warn
セルを参照するために延々と上スクロールが必要
:::

![スクリーンショット 2021-12-16 15.57.30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1037574/5eda35c4-60b4-53c6-5267-3a5c2bd13c60.png)

# セルの出力を消してみる
IPythonを利用してセルの出力を消してみました。
![imageonline-gifspeed-8878378.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1037574/99fb8650-f318-f6c4-d45d-6b34516987b3.gif)

（Pythonコード）

```
# 表示の消去
from IPython.display import clear_output
import time

for i in range(10):
    clear_output()
    print('このメッセージを表示後に消します。を繰り返します。')
    time.sleep(1)
print('終わり')
```

# 出力行の更新をしてみる
出力した行の更新をしてみました。
![imageonline-gifspeed-8918972.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1037574/c0139899-0e1e-286a-dd0d-4b59310be6da.gif)
（Pythonコード）

```
# 表示行の更新
from IPython.display import display
from time import sleep

print('次行の表示内容を更新します。')
update_line = display('更新前です。 -', display_id=True)
sleep(1)
for i in range(10):
    update_line.update( str(i) + '回目の更新をしました。')
    sleep(1)
print('終わり')
```

# 出力行の更新をしてみる（キャリッジリターンを利用）
IPythonではなく「キャリッジリターン」でやってみます。
![imageonline-gifspeed-9107570.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1037574/f37d200c-2422-cac3-be9d-1ebf432c39b9.gif)
（Pythonコード）

```
# 表示行の更新（キャリッジリターンを利用）
from time import sleep

print('次行の表示内容を更新します。')
print("\r"+ '更新前です。', end="")
sleep(1)
for i in range(10):
    print("\r"+ str(i) + '回目の更新をしました。',end="")
    sleep(1)

print("\n"+'終わり')
```

 print命令に__end=""__がないと改行していまいますので注意です。

# まとめ
これでログだらけのページを整理できそうです。
M5Stack GrayでMPU9250を使うときのバグ(？)

#M5Stack GrayでMPU9250を使うときのバグ(？)
float型でポインタ渡ししているところがバグって（？）M5Stackが強制再起動される問題が発生。
自分だけなのかよくわからないが対処できたので書いておく。

##発生個所
initAK8963()

```MPU9250.cpp
void MPU9250::initAK8963(float* destination) {
  destination[0] = 0; // <- 代入できなくて(？)強制再起する
  destination[1] = 0; // <-
  destination[2] = 0; // <-

  // First extract the factory calibration for each magnetometer axis
  uint8_t rawData[3];  // x/y/z gyro calibration data stored here
  writeByte(AK8963_ADDRESS, AK8963_CNTL, 0x00); // Power down magnetometer
  delay(10);
  writeByte(AK8963_ADDRESS, AK8963_CNTL, 0x0F); // Enter Fuse ROM access mode
  delay(10);
  readBytes(AK8963_ADDRESS, AK8963_ASAX, 3, &rawData[0]);  // Read the x-, y-, and z-axis calibration values
  destination[0] =  (float)(rawData[0] - 128) / 256. + 1.; // <- Return x-axis sensitivity adjustment values, etc.
  destination[1] =  (float)(rawData[1] - 128) / 256. + 1.; // <-
  destination[2] =  (float)(rawData[2] - 128) / 256. + 1.; // <- ここらへんも
  writeByte(AK8963_ADDRESS, AK8963_CNTL, 0x00); // Power down magnetometer
  delay(10);
  // Configure the magnetometer for continuous read and highest resolution
  // set Mscale bit 4 to 1 (0) to enable 16 (14) bit resolution in CNTL register,
  // and enable continuous mode data acquisition Mmode (bits [3:0]), 0010 for 8 Hz and 0110 for 100 Hz sample rates
  writeByte(AK8963_ADDRESS, AK8963_CNTL, Mscale << 4 | Mmode); // Set magnetometer data resolution and sample ODR
  delay(10);
}
```

###解決した方法
floatは小数点7桁らしいので10の7乗かけてあげてintで渡す。
正直intで渡せるならfloatでも渡せるだろと思わなくもないけど、floatだとできないし、intだとできる。。。(。´･ω･)?

```MPU9250.cpp
void MPU9250::initAK8963(int* destination) {
  destination[0] = 0;
  destination[1] = 0;
  destination[2] = 0;

  // First extract the factory calibration for each magnetometer axis
  uint8_t rawData[3];// x/y/z gyro calibration data stored here
  writeByte(AK8963_ADDRESS, AK8963_CNTL, 0x00); // Power down magnetometer
  delay(10);

  writeByte(AK8963_ADDRESS, AK8963_CNTL, 0x0F); // Enter Fuse ROM access mode
  delay(10);

  readBytes(AK8963_ADDRESS, AK8963_ASAX, 3, &rawData[0]);  // Read the x-, y-, and z-axis calibration values  
  float d[3];
  d[0] = (float)(rawData[0] - 128) / 256.0f + 1.0f;
  d[1] = (float)(rawData[1] - 128) / 256.0f + 1.0f;
  d[2] = (float)(rawData[2] - 128) / 256.0f + 1.0f;

  *(destination + 0) =  d[0] * 10000000;// Return x-axis sensitivity adjustment values, etc.
  *(destination + 1) =  d[1] * 10000000;
  *(destination + 2) =  d[2] * 10000000;

  writeByte(AK8963_ADDRESS, AK8963_CNTL, 0x00); // Power down magnetometer
  delay(10);

  // Configure the magnetometer for continuous read and highest resolution
  // set Mscale bit 4 to 1 (0) to enable 16 (14) bit resolution in CNTL register,
  // and enable continuous mode data acquisition Mmode (bits [3:0]), 0010 for 8 Hz and 0110 for 100 Hz sample rates
  writeByte(AK8963_ADDRESS, AK8963_CNTL, Mscale << 4 | Mmode); // Set magnetometer data resolution and sample ODR
  delay(10);
}
```

引数の型が変わっているのでMPU9250.hも変えないといけないのでお忘れなく。

他にも出てくるかもしれないので、その時に書き足していく
EC2のディスク拡張作業の備忘録

ちょいちょい忘れがちなので備忘録として。


ghqでリポジトリ追加したらディスク容量がいっぱいになった

```
$ ghq get hogefuga

～

remote: Enumerating objects: 5315, done.
remote: Counting objects: 100% (2349/2349), done.
remote: Compressing objects: 100% (967/967), done.
remote: Total 5315 (delta 1165), reused 1954 (delta 882), pack-reused 2966
Receiving objects: 100% (5315/5315), 40.70 MiB | 12.12 MiB/s, done.
Resolving deltas: 100% (2497/2497), done.
fatal: cannot create directory at 'xxxxxxxxxx': No space left on device
warning: Clone succeeded, but checkout failed.

error failed to get "https://github.com/xxx/xxxxxxxx.git": /usr/local/bin/git: exit status 128
```

ディスク拡張しましょうか。

現状確認

```
$ df -h
Filesystem      Size  Used Avail Use% Mounted on
～
/dev/nvme0n1p1  7.7G  7.7G     0 100% /
～
```

AWSコンソールで該当インスタンスのEBSボリュームの容量を変更してから、
パーティション拡張する


拡張した容量「8GB→30GB」が認識できているか確認

```
$ lsblk
NAME        MAJ:MIN RM  SIZE RO TYPE MOUNTPOINT
～
nvme0n1     259:1    0   30G  0 disk
└─nvme0n1p1 259:2    0    8G  0 part /
```

拡張したディスク容量は認識できていて、パ-ティションが8GB

パーティション拡張する

```
sudo growpart /dev/nvme0n1 1
```

確認

```
$ lsblk
NAME        MAJ:MIN RM  SIZE RO TYPE MOUNTPOINT
～
nvme0n1     259:0    0   30G  0 disk
└─nvme0n1p1 259:1    0   30G  0 part /
```

resize2fs コマンドで、「/dev/nvme0n1p1」のサイズをボリュームの上限まで自動的に拡張

```
$ sudo resize2fs /dev/nvme0n1p1
resize2fs 1.42.13 (17-May-2015)
Filesystem at /dev/nvme0n1p1 is mounted on /; on-line resizing required
old_desc_blocks = 1, new_desc_blocks = 2
The filesystem on /dev/nvme0n1p1 is now 7864059 (4k) blocks long.
```

確認

```
$ df -h
Filesystem      Size  Used Avail Use% Mounted on
～
/dev/nvme0n1p1   30G  7.7G   22G  27% /
～
```

OK
【React】【Vue】 など流行りのフレームワークを使うもののためのJS基礎「オブジェクトとしての関数」


JavaScript では、関数は Function オブジェクトである。

なので、ほかのオブジェクトと同じように使用することができる。

<hr>
ex)
・変数や、オブジェクトのプロパティ、配列要素に代入できる
・関数の引数にできる
・関数の戻り値にできる
・プロパティやメソッドを持つことができる
・無名のリテラルとして表現できる（無名関数）
・動的に生成できる

<hr>

<h3>this</h3>
関数が呼び出されるたびにthisの値が決定される。
thisの値は、「関数が呼び出されたときにその関数が所属していたオブジェクトへの参照」。
下の例では所属していたオブジェクトが[person‗1]でありこれが＝thisなのである。
オブジェクトのnameプロパティがtomなのでコンソールのような結果になる。

```javascript
let person_1 = {
  name: "tom",
  say: function() {
    console.log("hello", this.name);
  }
}

person_1.say();

//コンソール
hello tom

```

person_1.say();は関数への参照である。このプロパティはほかのオブジェクトのプロパティに代入できる。

たとえば、

```javascript
let person_2 = { name: 'billy' };
```

このようなオブジェクトを作る。

person_2.の say プロパティに person_1.の say プロパティを代入してみる

```javascript
person_2.say = person_1.say;
```

これをよびだすと

```javascript
person2.say()

//コンソール
hello billy
```

となる。

person_2 の say プロパティの this は person_2 を指しており、person_2 の name プロパティは billy のためである。

javascript の関数は、様々なオブジェクトから参照され、その都度 this は変わっていくのである。

<h3>apply</h3>
JavaScriptの関数はオブジェクトであるため、関数自身がメソッドを持っている。
その中には、thisを操作できるメソッドもいくつかある。そのうちの一つがapply。
第１引数にthis、第２引数はそのまま関数の引数となる。
引数が配列。

```javascript
function say(greeting, honorifics) {
    console.log(greeting + " " + honorifics + this.name)
  }

let suda = {name:"sudaMasaki"}
say.apply(suda,["hello","Mr."])

//コンソール
hello Mr.sudaMasaki

```

.apply メソッドの第１引数は suda = this。
第２引数は配列で["hello","Mr."]これが say 関数の第１引数 greeting = "hello" , honorifics = "Mr" となる。

<h3>call</h3>
.applyメソッドとほぼ同じ。。
引数が配列がカンマ区切りのリスト。

```javascript
function say(greeting, honorifics) {
    console.log(greeting + " " + honorifics + this.name)
  }

let suda = {name:"sudaMasaki"}
say.call(suda,"hello","Mr.")

//コンソール
hello Mr.sudaMasaki

```

<h3>bind</h3>
bind()は、thisの値を最初に固定して関数を作る。
第一引数に指定したものが、thisとなる。
この方法で作られた関数は、今後どのような文脈で呼ばれても、thisの値は最初に設定したもののまま、変わることがない。

```javascript
function sayNameForAll(label) {
  console.log(label + 'の名前は、' + this.name);
}

var man = {
  name: 'masaki',
};
var woman = {
  name: 'nana',
};

var sayNameForMan = sayNameForAll.bind(man); //thisはmanを指す
sayNameForMan('男性'); //男性の名前は、masaki

var sayNameForWoman = sayNameForAll.bind(woman); //thisはwomanを指す
sayNameForWoman('女性'); //女性の名前は、nana

woman.sayName = sayNameForMan; //sayNameForManのthisはmanのまま
woman.sayName('女性'); //女性の名前は、masaki
```
GitとUnityを初めて連携するときにSourceTreeでプッシュできずにエラーが出る件

Qiitaへの投稿は初めてです。
自分用に簡単な記録を残していくのも大事だと思い、書いてみます。


##GitもUnityもSourceTreeもインストールはできてる
まだイマイチ慣れていないiMacでインストールを進めていくが、ここは問題ないようです。


##Gitで新しいリポジトリ作成→Unityで新しいプロジェクト作成
ここまではオッケーです。

##SourceTreeを立ち上げ、Unityのファイルをローカルにドラッグする
ここも大丈夫かと思いきや、こんな序盤で躓いていたのかも知れません。SourceTreeを立ち上げるときにGitと連携するかどうかポップが出てきて「ユーザー名とメールアドレス」を打ち込む部分があったと思うのですが、そこです、多分。Gitで使っているアドレスとは違うものを入力してしまいました。

##ローカルリポジトリをコミット
メールアドレスのミスの影響がなぜかここでは現れず、ここは普通にコミットできました。ちなみにgitignoreとするものをコミットしています。

##コミットしたリポジトリをプッシュ
ここで、「何もしていないのに」パソコンがおかしくなってしましました。（来年にはエンジニアとして就職したい奴が言うセリフ（））最初のブランチであるoriginが更新ボタンを押しても出てきてくれませんでした。そこでとりあえずプッシュしてみるとエラー403が出てきてしまい、もういよいよ足止めを食らいました。

##error 403でたくさん記事がでてくる
どうやら皆さん同じエラーが起きているみたいです。少し安心し、調べてみると「リモートのパスのURLをこのように変えると直りました！」と解決しているようです。私も同じようにやりました。が、調べてでてきた解決法を試せど試せど結果は変わりませんでした。

##不貞腐れてソリティアに耽る
朝から活動しているにも関わらず、もう一日が終わりそうです。

##気を取り直して全部やり直す
インストールまでは大丈夫そうだったので、とりあえず新しいリポジトリやらプロジェクトやらを作るところからやり直しました。結果的にこのお陰でメールアドレスのミスに気づき、うまく連携させることができました。一旦振り出しに立ち返るのは良い結果を産むこともありますよね。駆け出しエンジニアの今後に期待です。
cssをBEMに則って書いてみた感想

これは、[OPENLOGI Advent Calendar 2021](https://qiita.com/advent-calendar/2021/openlogi)の17日目の記事です。
今までコーディング規則とは程遠い位置にいたデザイナー（仮）がcssをBEMに則って書いてみました。
かなり初歩的なことを話しているので、こんな時代もあったなあと読んでいただければ幸いです。

## そもそもBEMとは？
Block Element Modifierの略で、
Block → 大きい括り（親要素全部）
Element → 大きい括りの中にいる要素（親要素の中の子要素）
Modifier → 上記2つの変化球（形や色が変わる場合）
の3つに分けて考えていくことでCSSを設計･命名していく手法のことです。
![BEM-イラスト.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/922198/fd387249-5e84-0e8c-adf5-94fc165ab4f6.png)


## 前提（取り入れたもの）
- BEMの中でも特にMindBEMdingと呼ばれている命名法
    - MindBEMdingはcsswizardryことHarry Robertsが提唱したCSSの命名規則のこと。
- FLOCSS
- 株式会社サイバーエージェントのエンジニアであるHiroki Taniさんが提唱したCSS設計手法で、日本人が作成していてドキュメントが日本語ということで、日本での利用頻度が高まっていると思われるCSS設計になります。
    - `.c-` [Components] 小さい使い回しの聞く要素。ボタン、タイトルから、リストなど大き目のコンポーネントまで。あまり margin をつけない。
    - `.p-` [Projects] 特定のページに固有の要素。例えば 「会社概要」だけで使われているスタイルを書く場合、 `.p-company` というふうにページ名を指定し、使う。margin持たせてもいい。
    - `.l-` [Layouts]レイアウトに関わる要素。margin や max-width などが書かれている。
    - `.u-` [Utilities] 汎用クラス。
        - mt10 → `u-mt10`
        - hide-pc → `u-hide-pc`
- Sass
    - Rubyで作られたメタ言語のこと。CSSの拡張版で、書き方はCSSと同じ。
    - 変数が使える
      - $main-colorとかで色を設定したら、main-colorって入れたらその設定された色になる（カラーコードがいらない）
      - 例
      
```
$main-color : #fff;
.some-class {
    color: $main-color;
}
```

## 感想
### BEMの内容を調べたときの感想
Block要素が幅広いことに気づかず、HTMLで言う`<section>`とか`<div>`だけだと勘違いしていました。
親要素が全てBlockになるというのを理解するまでちょっとだけ時間がかかりました。
今までスタイルシート一つで管理していたので、まずスタイルシートをページごとに作成することに慣れなければいけないと感じました。
今までは、FLOCSSでいう`u`をたくさん作っていろんなところに使う書き方をしていたので、そのページにしか使わない要素なのかどうなのかの判断にも慣れなければいけないと思いました。

### いざBEMでコーディングしてみたときの感想
classの名付けに苦労しました。本当に苦労しました。
他と被ってはいけないけど似たようなレイアウトが多い・・・みたいな感じで苦労しました。
FLOCSSでいう`u`なのか`p`なのか問題も出てきました。
コーディングするデザインをしっかり見て、他に使いまわせるのかどうかの確認が大事だなあと思いました。
いつもはmarginだけのclass作って適当にやっていたので実際好みが分かれるところだと思いますが、marginを上のclassに入れるか下のclassに入れるかも迷いました。
Sassだとネストや変数が使えるのですが、ネストも変数も慣れておらず特に変数が難しく感じました。

正直BEMもSassの変数も完全理解はできてないので完全理解できるように頑張ります。
ステートレスとステートフルとは

「**ステートレス**」と「**ステートフル**」という言葉が出てきたのでまとめておく。

# ステートレス
**ステートレス**とは、サーバがクライアントのセッション状態を**保持しない**こと。つまり、前に行ったやり取りの内容を覚えていない。
ここでセッションとは、クライアントとサーバ間での接続から切断までの一連の操作のこと。
HTTPは**ステートレス**であり、リクエストとレスポンスの1往復のやり取りが完結した、1つの処理としてみなされる。そのため、複数の処理を関連付けることができない。
■ **メリット**
・サーバ側の設計がシンプルになる。
■ **デメリット**
・やり取りを行うデータ量が多くなる。

# ステートフル
**ステートフル**とは、サーバがクライアントのセッション状態を**保持している**こと。つまり、前に行ったやり取りの内容を覚えている。
以前の処理を覚えているため、次の処理でその内容を反映させることができる。
■ **メリット**
・データのやり取りが簡潔でデータ量が少なくなる。

■ **デメリット**
・クライアントが増えると負荷が重くなる。
・サーバが複数台ある場合、サーバー間でクライアントの状態を同期する必要がある。
python 日本語メールボックスを操作したい

imaplibを利用して、特定のメールボックスを操作する時に、メールボックスが日本語だとエラーになります。  

## 原因

IMAPのメールボックス名はModified UTF-7でencodeしないといけない模様
しかし、imaplibだと対応していない・・・

検索すると、自作でうんぬんが出てくるが、めんどくさそう  
https://itasuke.hatenadiary.org/entry/20120126/p1

## imap_tools.imap_utf7　を利用して簡単に解決

```
pip install imap_tools
```
で imap-toolsを入れて  

```python
from imap_tools.imap_utf7 import encode  

hogehoge = encode('日本語でーす')

imapclient = imaplib.IMAP4(host,port)
imapclient.select(hogehoge)
```

で、問題なくメールボックスがselectできました
SPSS Modelerで二値分類のPrecision,Recallなどの評価指標を計算するスーパーノード

SPSS Modelerで二値分類の評価指標(Confusion Matrix, Accuracy, Precision, Recall, F1, MCC)を計算する方法が以下のブログで公開されています。

Modelerデータ加工Tips#04-行列入替で適合率PrecisionやF1スコア・MCCを求める | IBM ソリューション ブログ

https://www.ibm.com/blogs/solutions/jp-ja/modeler-tips-04/

このストリームの汎用性を少し高めて使いまわせるスーパーノードにしました。

サンプルストリームとデータは以下です。

https://github.com/hkwd/spsssample/tree/master/211216%E4%BA%8C%E5%80%A4%E5%88%86%E9%A1%9E%E8%A9%95%E4%BE%A1%E6%8C%87%E6%A8%99

■テスト環境
Modeler 18.3
Windows 10 64bit

以下で使い方を説明します。

#例1 のブログのサンプルをつかって実行
まず上のブログのサンプルをつかって実行してみます。
以下のようなデータでした。
実績列：故障
予測列：$-故障
ポジティブクラス：1
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223763/5a0d420f-c29d-440b-3839-0fe279f6c43f.png)

ポジティブクラスとは予測したい方の値です。故障と$-故障には0と1の値が入っていますが、故障が1、故障なしが0を表していて、予測したいのは故障なので1です。

スーパーノードを実行するためには、その前にフィルターノードと置換ノードが必要です。ご自身のストリームでお使いになる場合にはこのフィルターノードと置換ノードとスーパーノードの3つをコピペして使ってもらえればと思います。

まず、フィルターノードで実績列（故障）と予測列（$-故障）の名前を「実績」と「予測」に変更します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223763/f2c7d89d-11f4-41fe-06f9-0a489e8013ee.png)

次に、置換ノードでポジティブクラスを1、ネガティブクラスを0に設定します。今回は1なら1ということで変換は不要ではあるのですが、汎用的にする意図で書いています。ノード名も分かりやすく「ポジティブクラス１」としています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223763/c00e31a2-80c7-32ca-a27f-130b8689d3d0.png)

これでスーパーノード内でPrecision,Recallなどが計算できるようになりました。テーブルノードを接続して実行してください。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223763/6b02bccc-7628-18d7-4a1a-2bf7055cca94.png)

#例２モデルの結果から算出
次にモデルも作って実行してみます。
以下のようにUP_TIME,POWER,TEMP,PRESを使ってERR_CDを予測するモデルを作ります。ERR_CDには0と101の値があり、101が予測したいポジティブクラスです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223763/a1eaaf07-fd87-4690-a5dd-eb53c257015a.png)

やはりまず、フィルターノードで実績列と予測列の名前を「実績」と「予測」に変更します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223763/a81868d0-8647-e8d0-5bc1-d1ea44f6116e.png)

次にポジティブクラスが101なので101を1に変換します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223763/e2a57d43-ddaa-30a5-e9da-3fe62b89189c.png)

これだけで評価指標が計算できます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223763/e7dbc6fa-3931-1dba-9a3e-e4949c82fe62.png)

#例３モデル間の比較
これらの性能指標は単体で評価するよりも複数のモデルを作って比較することが多いと思います。
ここではCRTに加えてRandomTreeでのモデルも作り比較してみています。
モデルのタイトルを入れてレコード追加で連結すると、以下のようモデル間の比較がわかりやすく行えます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223763/f034bf72-34a9-59c8-7cc6-0355ff4a5b86.png)
Amazon S3内のファイルをCSV形式で一覧化



### 0. 前提条件

aws cliとjqをインストール済であること



### 1.　実行コマンド


```bash:ファイル一覧の取得例
# aws s3apiのコマンド実行例
aws s3api list-objects-v2 --bucket file-storage-sample | jq -r '.[] | .[] | [.Key, .LastModified, .Size, .StorageClass] | @csv'   

# コマンド実行例
"prefix/","2021-12-16T06:10:49.000Z",0,"STANDARD"
"prefix/zumen.tiff","2021-12-16T06:14:53.000Z",0,"STANDARD"
"zumen.pdf","2021-12-16T06:10:28.000Z",0,"STANDARD"
```

### 2. 別の手段

S3 Inventory機能を使えば、上記方法でなくてもファイルをCSV形式で出力できる。
但し、取得頻度は日次もしくは週次であり、この条件を満たす場合のみ有効である。


以上
flutterバグ解消(DiagnosticableMixin not found)

###バグ解消時のメモ
flutter_svgの非互換によるバグが発生。下記issueを元に解決を図ったので、メモ程度に投稿

```dart:バグ内容
~/develop/flutter/Google-Calendar-API-Flutter-Example- $ flutter run
Warning: You are using these overridden dependencies:
! flutter_svg 0.17.4 (1.0.0 available)
Running "flutter pub get" in Google-Calendar-API-Flutter-Example-...         3.3s
Launching lib/main.dart on iPhone 13 Pro in debug mode...
Running Xcode build...                                                  
Xcode build done.                                           16.0s
Failed to build iOS app
Error output from Xcode build:
↳
    ** BUILD FAILED **


Xcode's output:
↳
    ../../../.asdf/installs/flutter/2.8.0-stable/.pub-cache/hosted/pub.dartlang.org/flutter_datetime_picker-1.3.8/lib/src/datetime_picker_theme.dart:6:28: Error: Type 'DiagnosticableMixin' not found.
    class DatePickerTheme with DiagnosticableMixin {
                               ^^^^^^^^^^^^^^^^^^^
    ../../../.asdf/installs/flutter/2.8.0-stable/.pub-cache/hosted/pub.dartlang.org/flutter_datetime_picker-1.3.8/lib/src/datetime_picker_theme.dart:6:7: Error: The type 'DiagnosticableMixin' can't be mixed in.
    class DatePickerTheme with DiagnosticableMixin {
          ^
    ../../../.asdf/installs/flutter/2.8.0-stable/.pub-cache/hosted/pub.dartlang.org/flutter_datetime_picker-1.3.8/lib/flutter_datetime_picker.dart:215:48: Error: No named parameter with the name 'shadowThemeOnly'.
        ThemeData inheritTheme = Theme.of(context, shadowThemeOnly: true);
                                                   ^^^^^^^^^^^^^^^
    ../../../.asdf/installs/flutter/2.8.0-stable/packages/flutter/lib/src/material/theme.dart:106:20: Context: Found this candidate, but the arguments don't match.
      static ThemeData of(BuildContext context) {
                       ^^
    Failed to package /Users/kawamurakouji/develop/flutter/Google-Calendar-API-Flutter-Example-.
    Command PhaseScriptExecution failed with a nonzero exit code
    note: Using new build system
    note: Planning
    note: Build preparation complete
    note: Building targets in dependency order

Could not build the application for the simulator.
Error launching application on iPhone 13 Pro.
```

###バグの解消方法
pubspec.ymlに下記を追加し、pubspec.lockを削除のうえ、ビルドしなおす。

```yml:pubspec.yml
dependency_overrides:
   flutter_svg: ^0.17.4
```

■参考
https://github.com/dnfield/flutter_svg/issues/368
VBA　SQL接続してテーブル取得

VBAエディタ→「ツール」→「参照設定」
Microsoft ActiveX Dta Objects X.X Library

```vb:
' 変数の宣言を強制
Option Explicit

' SQL抜き出し
Sub SOL Extract()

    Dim Provider As String:Provider="SOLOLEDB"    ' 固定
    Dim Server As String:Server="サーバー名"    ' サーバー名
    Dim DataBase As String:DataBase="データベース名"    ' データベース名
    Dim DataTable As String:DataTable="テーブル名"    ' テーブル名
    Dim UserID As String:UserID="viewer(ユーザーID)"    ' ユーザーID
    Dim Pass As String:Pass="パスワード"    ' パスワード
    Dim strSOL As String    ' SQL文
    Dim cn As New ADODB.Connection    ' 接続
    Dim rs As New ADODB.Recordset    ' データ取得、貼り付け

    ' 接続
    cn.ConnectionString="Provider=" & Provider _
                        & ";Data Source=" & Server _
                        & ";Initial Catalog" & DataBase _
                        & ";UID=" & UserID _
                        & ";PWD=" & Pass                
    cn.Open

    ' SQL文を記載
    strSOL="select * from " & DataTable

    ' SQL実行
    rs.Open strSQL, cn

    ' データ先頭へ移動
    rs.MoveFirst

    ' データをA1へ貼り付け
    ActiveSheet.Range("A1").CopyFromRecordset rs

    ' 接続解除
    If Not rs Is Nothing Then
        If rs.State adStateOpen Then
            rs. Close 
        End If
        Set rs Nothing
    End If

    If Not cn Is Nothing Then
        If cn.State adStateOpen Then
            cn. Close
        End If 
        Set cn Nothing
    End If

End Sub

```
git tagのsemantic versionを自動でインクリメントしてpushするシェルスクリプト

## 前提
現在携わっているサービスでGitLab CI/CDを利用してリリース番号がついているtagをpushすると
自動でデプロイされるように設定しています  

``` yml:.gitlab-ci-production.yml
...
...
...
only:
  - /^release-.*$/
```

リリースのたびにtagのsemantic versionをインクリメントするのがめんどくさいので
自動化できないか考えてみました

``` bash
# masterブランチで差分を取り込む
$ git checkout master
$ git pull
# インクリメントするために最新のタグを取得
$ git describe --abbrev=0 --tags
> release-1.1.1
# 新しいタグを追加
$ git tag release-1.1.2
# タグをリモートにプッシュ
$ git push --tags

# この一連の作業を自動化したい
```

## 巨人の肩に乗る

https://stackoverflow.com/questions/3760086/automatic-tagging-of-releases

調べるとパッチバージョンのみインクリメントできるシェルスクリプトを書いてくれる人がいたので
シェルスクリプト初心者ですが少し改良してみました

## 作成したシェルスクリプト

``` deploy.sh
#!/bin/bash

#checkout master and pull
git checkout master
git pull

#get highest tag number
VERSION=`git describe --abbrev=0 --tags`

#replace . with space so can split into an array
VERSION_BITS=(${VERSION//./ })

#get number parts and increase
VNUM1=`echo ${VERSION_BITS[0]} | sed -e 's/[^0-9]//g'`
VNUM2=${VERSION_BITS[1]}
VNUM3=${VERSION_BITS[2]}

if [ ${VNUM3} -ge 9 ]; then
  if [ ${VNUM2} -ge 9 ]; then
    VNUM1=$((VNUM1+1))
    VNUM2=0
    VNUM3=0
 else
  VNUM2=$((VNUM2+1))
  VNUM3=0
 fi
else
  VNUM3=$((VNUM3+1))
fi

#create new tag
SEMVER="$VNUM1.$VNUM2.$VNUM3"
TAG_PREFIX="release-"
NEW_TAG="$TAG_PREFIX$SEMVER"

read -p "Do you really updating $VERSION to $NEW_TAG (y/n)" YN_LOADSETTING
if [ "${YN_LOADSETTING}" != "y" ]; then
  echo "bye"
  exit 1
fi

#get current hash and see if it already has a tag
GIT_COMMIT=`git rev-parse HEAD`
NEEDS_TAG=`git describe --contains $GIT_COMMIT 2>/dev/null`

#only tag if no tag already
if [ -z "$NEEDS_TAG" ]; then
    git tag $NEW_TAG
    echo "Tagged with $NEW_TAG"
    git push --tags
else
    echo "Already a tag on this commit"
fi
```


## 改良してみた点

- **readコマンドで確認**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/190874/52477c3a-7b78-3b86-02b9-d9fefba7e2d7.png)
万が一うまくインクリメントできていなかったりリリースの必要がなかった場合など一回確認しておきたいため`read`を追加しました

- **パッチバージョンのインクリメント以外も対応**
パッチバージョンが`9`かどうかで上位のバージョンもインクリメントするか分岐させました

## 終わりに
シェルスクリプトを初めてちゃんと書いてみましたがとても勉強になりました 
そもそもリリースの内容によってパッチを上げるかマイナーを上げるかなど考慮する必要がありますが
そこができていないのでいずれ引数を持たせてあげるバージョンを選べるようにしてみたいです

こっちの方がイケてるとかあればぜひご教示ください
ご読了ありがとうございました
QNAP NASでcrontabの設定

# QNAP NASのCRONTAB
QNAPにSSHでログインして

```
crontab -e
```
を実行してもエディタとして動いてくれない。

# 回避策

## 設定ファイルの書き換え
```
vim /etc/config/crontab
```

で内容を変更

## 設定を反映及び再起動
```
crontab /etc/config/crontab
/etc/init.d/crond.sh restart
```

## 反映の確認
```
crontab -l
```
【Unity】WebGL書き出しをモバイル向けに行う際に、自動的に全画面にする方法

この記事は、[Unity Advent Carender 2021](https://qiita.com/advent-calendar/2021/unity)の17日目の投稿です！
# 概要
本記事では、UnityでWebGL書き出しを選択し、スマートフォン等のモバイル環境で動作させる際に、画面に対して最大化を行うためのポイントについてまとめています。
スマートフォン、特にiPhoneでは、タブバーやアドレスバーが邪魔になり、想定した画面サイズよりも小さい画面で動作させられることが頻発します。そのような際に自動的に画面サイズにフィットされないと、本来想定したものとは違った見え方をしてしまいます。このような現象の対処法についてまとめました。

かなり雑な実装をしていますし、自分の備忘録としての意味合いが強いですので、その点ご了承ください。

# やり方
UnityでWebGL形式で書き出す際のテンプレートをカスタマイズすることで実現します。

まずUnityのインストールフォルダを開き、以下の階層まで潜ります。

```
Unity\バージョン名\Editor\Data\PlaybackEngines\WebGLSupport\BuildTools\WebGLTemplates
```

その中の```Default```フォルダを好きな場所にコピーします。
このフォルダの中に、デフォルトのWebGLテンプレートが入っているので、ここを改造していきます。

次に、```TemplateData内のStyle.css```を好きなエディタで開きます。

Style.css内の先頭4行を削除して、以下のようにします。

```Style.css
#unity-canvas { background: {{{ BACKGROUND_COLOR }}} }
.unity-mobile #unity-canvas { width: 100%; height: 100% }
#unity-loading-bar { position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%); display: none }
#unity-logo { width: 154px; height: 130px; background: url('unity-logo-{{{ SPLASH_SCREEN_STYLE.toLowerCase() }}}.png') no-repeat center }
#unity-progress-bar-empty { width: 141px; height: 18px; margin-top: 10px; background: url('progress-bar-empty-{{{ SPLASH_SCREEN_STYLE.toLowerCase() }}}.png') no-repeat center }
#unity-progress-bar-full { width: 0%; height: 18px; margin-top: 10px; background: url('progress-bar-full-{{{ SPLASH_SCREEN_STYLE.toLowerCase() }}}.png') no-repeat center }
#unity-footer { position: relative }
.unity-mobile #unity-footer { display: none }
#unity-webgl-logo { float:left; width: 204px; height: 38px; background: url('webgl-logo.png') no-repeat center }
#unity-build-title { float: right; margin-right: 10px; line-height: 38px; font-family: arial; font-size: 18px }
#unity-fullscreen-button { float: right; width: 38px; height: 38px; background: url('fullscreen-button.png') no-repeat center }
#unity-mobile-warning { position: absolute; left: 50%; top: 5%; transform: translate(-50%); background: white; padding: 10px; display: none }
```


次に、必要な項目を追加します。
どこでもいいので以下のコードを追加します。（分からなければ、最後の行を改行してその下に追加してください。）

```Style.css
html,body,div { margin: 0; padding: 0; width: 100%; height: 100%;}
canvas { margin: 0 0 0 0; position: absolute; z-index: 9; width: 100%; height: 100%;}
```

以上でStyle.cssの書き換えは終了です。

次に、Defaultフォルダとは別に新規フォルダを作り、名前をTemplateDataとします。その中にDefaultフォルダを入れて、Defaultフォルダの名前を好きな名前に変更します。ここではCustomに変更しました。

変更したら、フォルダごとUnityのProjectタブにドラッグアンドドロップします。

最後に、Unityでの操作です。
File>BuildSettings内の、左下PlayerSettingsを選びます。

![スクリーンショット 2021-12-16 15.16.27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1303271/2768e154-dfd9-9306-1056-7631ab12af78.png)

Resolution and Presentation 内の、WebGLTemplateから、自分で決めた名前のテンプレート（ここではCustom）を選びます。

これにて設定は完了です！
PlayerSettingを閉じて、ビルドしてみてください！
<TouchDesigner> 画像・動画の読み込み / 書き出し方法

#画像・動画の読み込み(import)

![スクリーンショット 2021-12-16 14.34.46.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/429362/5c72a345-aeb7-bd02-74fd-6ca9725a8b9d.png)

・Movie File In TOP で画像・動画ファイルをTD内に取り込む
・パラメータ -> play -> Fileから読み込みたい画像・動画ファイルを選択

#画像の書き出し(export)
<方法1>
・Movie File Out TOP を繋ぐ
パラメータ -> Movie Out -> Type -> Image
パラメータ -> Movie Out -> Record -> On -> Off
![スクリーンショット 2021-12-16 15.01.42.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/429362/efb4b3ec-28fd-0a03-4e76-993a7277d5f8.png)

<方法2>
・書き出したい画像( Movie File In TOP )を右クリック -> Save Image
![スクリーンショット 2021-12-16 14.46.50.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/429362/04b0ef0e-8553-006e-8edf-ec029941709d.png)

#動画の書き出し(export)
<方法1>
・Movie File Out TOP を繋ぐ
パラメータ -> Movie Out -> Type -> Movie
パラメータ -> Movie Out -> Record -> On -> Off
![スクリーンショット 2021-12-16 15.15.50.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/429362/2e8fe83c-f35b-311a-a15e-366579d731cc.png)

<方法2>
・メニュー/ツールバー -> File -> Export Movie
![スクリーンショット 2021-12-16 15.17.13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/429362/a7234d4f-b896-c0ab-c658-abaad1eec262.png)
・Input -> TOP Video に書き出したい動画( Movie File In TOP )をドラッグ&ドロップ
・Output -> Render Movie -> Start
![スクリーンショット 2021-12-16 15.23.58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/429362/479663e0-769c-7188-02de-0a9c1b327683.png)
【SRE・インフラエンジニア素人】がリリース時間を1/8にした話

# はじめに
この記事は[リンクアンドモチベーション Advent Calendar2021](https://qiita.com/advent-calendar/2021/mcs)の17日目の記事です。

はじめまして。リンクアンドモチベーションの岸本です。
本記事では、SREにジョインして、半年ほどで
**リリース時間の短縮**に取り組んだので、
最終的な結果とリリースの時間削減以外にフローを整えるに当たって工面したことを紹介します。

取り組んだ背景は[エンジニアの生産性を高めるために必要な4つの指標](https://qiita.com/tomox1001/items/cca440ffd656d054d9f7)を参照していただければと思います。

# 実際にどのくらい短縮したのか？
先に結果から言うと、
`平均2時間`→`平均15分`
へ短縮できました。

# なぜ短縮できたのか？
ToBサービスであるモチベーションクラウドでは、顧客影響がある場合、決まった時間から、決まった時間内にリリースしないといけない制約がありました。
基本的にいくつかの`codebuild`でリリースを完了ができる状態にはなっていましたが、ダブルチェックの元、一つずつ手動で環境変数等を変えて作業を行なっていたため時間がかかっていました。

そこで自動化できるところと手動でやるべきところを明確にわけ、事前にできるところはリリース時間前にやっておくことで、リリース時間の短縮に成功しました。
![スクリーンショット 2021-12-16 19.55.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/575460/9cfb5380-e729-7f68-e8da-df0ea2ed8b37.png)

#  前提情報
**アーキテクチャ図**
モチベーションクラウドサービスは、ECSのblue/green環境とbatch処理を行うEC2環境での構成になっております。
![簡易アーキテクチャ図.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/575460/03834d4e-436c-e257-0404-b1ec2a86255c.png)

**リリース時間短縮のために使っているAWSサービス**

- codebuild
- codepipeline
- lambda
- chatbot
- eventbridge


# リリースフロー概要
以下で簡単にリリースフローの概要を説明します。
**リリースフロー図**
![デプロイフロー.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/575460/689c8ca9-3d98-3c9e-86f8-547a7e2cf102.jpeg)


|STEP|    概要   |  実施タイミング    |     実施方法            |　詳細 |
|:----------:|:----------|:---------------|:------------------------|:------------------------|
|1| 待機系デプロイ  |    事前作業     |   githubのmaster mergeのタイミング    |・docker imageの作成<br>・復旧用のRDSのスナップショット作成<br>・ECSへの最新masterデプロイ|
|2| Migrate,Seed処理 |     事前作業     |      codebuildで手動実行      |migrate,seedでデータベース更新　|
|3| 待機系の数を上げる   | 事前作業 |     slackから実行      |chatbotを利用して、slackからcodebuildを起動し、待機系のインスタンス数を上げる|
|**4**| **blue/green切り替え**     | **リリース作業**   | **codepipeから手動実行**|**・batchのデプロイ<br>・ALBのblue/greenの切り替え**|
|-| 待機系の数を下げる   | 定期実行   |EventBridgeでcodebuildを定期実行 |営業時間外にcodebuildを自動実行し待機系のインスタンス数を下げる|

上記のように、事前作業でほとんどの作業が完了でき、リリース時間でやる作業は**blue/green切り替えのみ**となり、短縮ができました。

# リリースの時間削減以外にフローを整えるに当たって工面したこと
## 1. 外から情報を集め,まとめる
他社のリリース方法や、blue/greenでのリリース方法のベストプラクティスなど様々な情報をかき集めると、新しいサービス・気付きが得られるので、時間を割いてでもしっかりと情報を集め、自分なりにメリット、デメリットをまとめることが重要だと思いました。


## 2. 現状を把握する
自社内のアーキテクチャやサービスの仕様と顧客とのどのような握りをしているかを把握することで、一番実現高い可能性でのリリースフローを考えられます。
アーキテクチャ・サービス等の状況に応じて変更するのが重要だと思いました。


## 3. カジュアルすぎるリリースフローはやめる
blue/green切り替えをslackからやる方法も考えていましたが、あまりにもカジュアルすぎると人間なので、ミスを犯す可能性があり、避けたほうがいいと思いました。

## 4. 運用に乗るまでサポートを徹底する
リリースフローが大きく変わったため、慣れるまではしっかりとドキュメントの整理やフォロー体制を整えて、慣れるまでしっかりとサポートすると同時に、フィードバックをもらい精査していくことで、浸透させていく努力が必要だなと思いました。

# まとめ
簡単なことしかやってないですが、少しの取り組みで大きな成果が得られることができました。
少しでも何かの参考になれば幸いです。
ゲームQAツールの今と未来


##はじめに 
スマートフォンのゲームアプリのソフトウェアテストで私たちが使っている自動化ツールの今とこれからと、今後導入したいツールについての話です。
##テスト自動化ツール「AutoTester」
テスト自動化のためにAutoTesterというツールを使っています。

ゲーム画面の一部をあらかじめキャプチャーしていた画像で目的のシーンで画像を照合してそこまで進んだと認識したり、アイコンと照合してタップすることでアプリを自動で操作し進めていくことができます。

あくまでもイメージの照合とタッチ操作だけでシナリオを作っていくだけですが、これだけでもかなりの範囲を自動で操作させていくことが可能です。

ただし細かなパラメータを見ながらシナリオを進めていくことが苦手です。

ゲーム画面に表れているテキストや数字は文字としてではなく画像としか認識できません。ですので今はゲームの状態により操作を変化させることは難しいのが現状です。


####これを解決させるため

画面上の文字をテキストとして認識させるためにOCRを利用します。

OCR（Optical character recognition）光学文字認識はテキストの画像を文字コードに変換する技術です。

元々OCRは白い紙に書かれた文字を読み取るところから生まれた技術です。

ゲーム画面のようにテキストエリアに背景が半透明に映っていたり、縁取りされた文字であったりすると文字として全く認識できない状態でした。

###この課題を解決するために

画像の2値化、背景除去、台形補正などの画像補正により読み取り精度を高めて誤認識をなくす技術によりゲーム画面でもOCRでテキストデータを取得することができ始めています。

ゲームアプリ内の情報をテキストとして扱うことにより出来ることが広がります。

例えばこんなことが出来るかもしれません。

- HPが少なくなれば休む
- お金があればガチャを引く
- 入手したアイテムの情報とリファレンスデータを突き合わせてチェックする
- バトル時のダメージ数を読み取って計算間違いがないかチェック
- アドベンチャーパートのテキスト画面を読み取って、校閲ツールを呼んでチェック


##これからのQAツール
今のゲームQAツールは正常系テストのリグレッションテストで使われることがほとんどですが、これからは自動でバグを検出できるツールが必要になってくると思います。

####画像解析によるバグ自動検出

カットシーンのチェックでは動画で撮ってそれを人力で注意深く確認していく作業が辛いところですが、動画のフレーム落ち、ノイズ、カクツキなどを自動で検出できるはずです。

キャラクター・エフェクト・ステータス表示などで優先順位の不正を自動的に検出したいところです。

####音声解析によるバグ自動検出

セリフのテキスト表示とナレーションの相違チェック。

####自然言語解析によるバグ自動検出

次のようなことを自動でテストできると大変助かります。

- キャラクター固有のセリフをAIで把握しておき、新しいセリフと齟齬がないか自動でチェック
- 例えば一人称の私とわたし、ボクとオレなどの間違いを検出
- 語尾などの口調もチェック


このようにこれからは自動でバグを検出できるツールがゲームQAに取り入れられていくものと思います。
最近追加されたrubocop規則を確認してみる👮‍♀️🚨

最近追加されたrubocop規則を確認してみる👮‍♀️🚨

## みんな大好きrubocop
みなさんrubocop👮‍♀️🚨は好きですか?
新しい書き方や効率的な書き方が発見できるし
チームでコーディングスタイルを統一でき、レビューがストレスにならないので僕は良いgemだなと思っています

そんなrubocopですが日々アップデートされ新しい規則が増えています
[リリースノートはこちら](https://github.com/rubocop/rubocop/releases)

最近新しいプロジェクトで最新版のrubocopを入れて実行してみたのですが
Waringがたくさん表示されてびっくりしました

本日は新しいルールで怒られてしまった物を紹介しようと思います



## versionを0.92から1.23にして怒られていたもの

### Style::HashConversion (from 1.12.0)

``` ruby
# bad
Hash[ary]
# good
ary.to_h

# bad
Hash[key1, value1, key2, value2]
# good
{key1 => value1, key2 => value2}
```
これはHashの特異メソッドである[[ ]](https://docs.ruby-lang.org/ja/latest/class/Hash.html#S_--5B--5D)を使うのではなく
Objectクラスのインスタンスメソッドである[to_h](https://docs.ruby-lang.org/ja/latest/method/Object/i/to_hash.html)や[Hash.new](https://docs.ruby-lang.org/ja/latest/class/Hash.html#S_NEW)を使ってくださいねと言ってるようです

> Correction code from splat argument (Hash[*ary]) is not simply determined

理由としては引数に可変長引数[*arg]を使用した際のruby内部の変換が複雑とのことです  


### Lint/AmbiguousOperatorPrecedence (from 1.21)

```ruby
# bad
a + b * c
a || b && c
a ** b + c

# good (different precedence)
a + (b * c)
a || (b && c)
(a ** b) + c

# good (same precedence)
a + b + c
a * b / c % d
```

`Precedence`とは日本語で`優先順位`のことです
算数では`*, ÷`は`+, -`より優先されますよね  

計算では問題ないけど、可読性のためにカッコをつけてくださいということだと思います  
計算ならそこまで問題ではないですが、今回は以下のようなコードで怒られました

``` ruby
if (cat? || dog? || other_animal? && animal_detail)
```

この条件式は`猫`か`犬`か`他の動物かつ詳細が記載されている`が真ですが
最後の条件だけ複合のため、若干可読性にかけるかなと確かに思いました

## Style/StringChars (from 1.12)

``` ruby
# bad
string.split(//)
string.split('')

# good
string.chars
```

これは以前のrubyのversion(~1.9)にて、`split`メソッドの引数が正規表現と文字列で振る舞いが異なるものがあるため  `char`を使った方が安全という歴史的背景があるようです  
ruby2.0以降を使っていれば問題なさそうですが、`chars`を使うように心がけたいです

## Style/NegatedIfElseCondition (from 1.2)

``` ruby
# bad
!x ? do_something : do_something_else

# good
x ? do_something_else : do_something
```

否定を条件式にしない方がいいですよというものですね
これはたまにやってしまっていてレビューで指摘されていたのでrubocopで拾ってくれるのは地味に助かります


## 終わりに
gemのupdateはどうしても億劫になってしまいがちですがrubocopを日頃からアップデートしておくことで
将来チームにメンバーが加わった時でもコードのキャッチアップやレビューが簡単になると思います

また独自ルールも設定できたりするのでチーム開発では必須のgemなんじゃないかと思います




余談ですがVScodeを使用している方は`ruby-rubocop`というエクステンションが便利です
わざわざ`rubocop`を実行しなくてもファイルをsaveするたび自動でそのファイルをrubocopにかけてくれて
怒られていたらその行にニョロニョロをつけてくれます
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/190874/155f29b3-edb9-f59e-9d41-9455197bdbb3.png)
BigQuery MLで時系列異常検出

BigQuery MLを使って教師なしの時系列異常検出をやっていきたいと思います。
参考は公式のブログから⇒https://cloud.google.com/blog/ja/products/data-analytics/bigquery-ml-unsupervised-anomaly-detection

今回は時系列なのでARIMA_PLUS モデルを使っていきたいと思います。

### データの準備
チュートリアルではGoogleが用意したBigqueyのデータセットを使う形ですが、自身で作成したデータセットで行うと理解が深められると思います。
今回は同様の異常検知サービスである Amazon Lookout for Metricsのサンプルデータを拝借します。
https://github.com/harunobukameda/Amazon-Lookout-for-Metrics/blob/main/ecommerce.zip

ダウンロードできたらbacktestフォルダのinput.csvを使います。
eコマースの閲覧数と収益のデータとなっており、カラムはこんな感じ

- platform
- marketplace
- timestamp
- views
- revenue

### Bigqueyのデータセットとして取り込み
Bigqueyでデータセットを作成します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206219/09e0ae96-56ba-721b-8105-0f5d3ef140b1.png)

テーブルにinput.csvをインポートします
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206219/efe844f9-aa93-fba3-d140-c1221a2fe6eb.png)

こんな感じで取り込めました
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206219/e3128a55-d663-df5a-8938-1d740d07bd00.png)

### モデルを作成
Bigqueryで新規クエリを作成

```sql
CREATE OR REPLACE MODEL ecommerce_demo.ecommerce_arima_plus_model
OPTIONS(
  MODEL_TYPE='ARIMA_PLUS',
  TIME_SERIES_TIMESTAMP_COL='timestamp',
  TIME_SERIES_DATA_COL='views',
  TIME_SERIES_ID_COL='marketplace',
  HOLIDAY_REGION='US' 
) AS
SELECT
  marketplace,
  timestamp,
  views
FROM
  `<プロジェクトID>.＜データセット名＞.＜テーブル名＞`
WHERE
  DATE(timestamp) BETWEEN DATE('2021-01-01') AND DATE('2021-07-31');
```

パラメータの解説

- OPTIONS
    - MODEL_TYPE: ARIMA_PLUSを指定
    - TIME_SERIES_TIMESTAMP_COL: トレーニングデータのタイムを指定しているカラム
    - TIME_SERIES_DATA_COL: 予測する値のカラムを指定する
    - TIME_SERIES_ID_COL: ディメンションにあたるカラムを指定する
- WHERE句で1月~7月までのデータを使ってトレーニングするように指定（残りの9月までのデータは実際の異常検知に使う）

このクエリを実行すると1～2分でモデルが出来上がります。

### トレーニング データ内の異常を検出する
先程作成したモデルに対してML.DETECT_ANOMALIESを使用します。
0.8は異常か判断するための閾値です。

```sql
SELECT
  *
FROM
  ML.DETECT_ANOMALIES(MODEL `ecommerce_demo.ecommerce_arima_plus_model`,
                      STRUCT(0.8 AS anomaly_prob_threshold))
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206219/75310524-6618-8c4f-0bce-2fb13dbe7b86.png)

### 新しいデータ内の異常を検出する

```sql
WITH
  new_data AS (
    SELECT
      marketplace,
      timestamp,
      views
    FROM
      `<プロジェクトID>.＜データセット名＞.＜テーブル名＞`
    WHERE
      DATE(timestamp) BETWEEN DATE('2021-08-01') AND DATE('2021-09-30')
  )
SELECT
  *
FROM
  ML.DETECT_ANOMALIES(MODEL `ecommerce_demo.ecommerce_arima_plus_model`,
    STRUCT(0.8 AS anomaly_prob_threshold),
    (SELECT * FROM new_data))
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206219/0903b906-691b-a574-1a8d-f8faa4f6f9a3.png)

今回は8、9月のデータが微妙だった（0が多かった）ため、結果はいまいちでしたがBigquey MLで異常検知を行うイメージは掴めたかと思います。

## まとめ
テーブルデータに対してSQLクエリによって操作することで、モデルの学習から異常検知まで実行することができるところがメリットだと感じました。
また、結果をデーブルとして確認できる点もよかったです。
ファイルを日付ごとに整理するショートカットを作成する

定期的に日付ごとにフォルダーを作成して、ファイル整理するショートカットを作成する手順を紹介します。

例えば、更新日時が2021/12/16のファイルがあるとします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/667945/8a79312c-1323-6514-9c8f-23f4a1267b19.png)

# パターン1 (年-月)
このショートカットを実行すると月ごとのフォルダーが作成され、この中にファイルが作成されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/667945/41e96d90-4172-fcab-2efc-74367d9061d0.png)

# パターン2 (年-月-日)
このショートカットを実行すると日ごとのフォルダーが作成され、この中にファイルが作成されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/667945/625071d1-599f-ae03-15f7-d554efb83713.png)


# ショートカットの作成方法
1. 整理したいファイルがあるフォルダーを開き、新規でショートカットを作成します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/667945/4aaafbbd-99a7-a780-47ab-fe22a6732d41.png)
2. 下記いずれかの中身をコピーしてから貼り付けます。
![ss ショートカットの作成 2021-12-16 001.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/667945/648036c8-4e15-4832-fb86-7e7f2c5cf4d5.png)

## パターン1 (年-月)
```batchfile
C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe -ExecutionPolicy ByPass -Command "dir -File -Exclude *.lnk -Recurse|%{$1=$_.LastWriteTime.ToString('yyyy\\MM');ni -ItemType Directory $1 -Force;$_|mi -Destination $1}|Out-Null"
```

## パターン2 (年-月-日)
```batchfile
C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe -ExecutionPolicy ByPass -Command "dir -File -Exclude *.lnk -Recurse|%{$1=$_.LastWriteTime.ToString('yyyy\\MM\\dd');ni -ItemType Directory $1 -Force;$_|mi -Destination $1}|Out-Null"
```
3. ショートカット名を入力します。
![ss ショートカットの作成 2021-12-16 002.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/667945/9ae364f5-1548-2acb-5936-04d7e75b6996.png)
4. プロパティを開きます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/667945/beb26b04-4926-eaf1-0839-27cb0db65cc8.png)
5. 作業フォルダーを指定します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/667945/1935eb82-fe6b-cef2-dda7-5230237d1152.png)

# メモ
- ショートカットを含め、パスの最大文字数は260文字

https://docs.microsoft.com/ja-jp/windows/win32/fileio/maximum-file-path-limitation

- PowerShellに実際に渡すことができるコマンドは167文字 ("ここにコマンドを入力する")

```batchfile
C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe -ExecutionPolicy ByPass -Command "ここにコマンドを入力する"
```

## パターン1 (年-月)

```powershell
dir -File -Exclude *.lnk -Recurse|%{$1=$_.LastWriteTime.ToString('yyyy\\MM');ni -ItemType Directory $1 -Force;$_|mi -Destination $1}|Out-Null
```

## パターン2 (年-月-日)


```powershell
dir -File -Exclude *.lnk -Recurse|%{$1=$_.LastWriteTime.ToString('yyyy\\MM\\dd');ni -ItemType Directory $1 -Force;$_|mi -Destination $1}|Out-Null
```
WEBデザインの配色のコツとおすすめサービスご紹介

はじめまして。こんにちは。
オークファンでWebデザイナーとして働いている
@aucfan_hasebe です。

今月でオークファンに就業して１年になりました！
昨年ちょうど皆がアドベントカレンダーを書いてるのを見て
「来年は自分も書くのかー」なんてうっすら思いながらもうその時がやってきました。
時の流れは早いものです。

初めての記事となりますが、WEBデザインの配色するときの基本的な注意事項と配色を助けてくれるおすすめサービスをご紹介したいと思います。

<h2>配色のコツ</h2>

配色のコツは、色数が増えれば増えるほど複雑になるので3色くらいに制限することです。
また、同じ色の組み合わせ、相性の良い組み合わせでも割合を間違えると違和感のあるデザインになります。


どこのサイトでも言われてる事ですが、WEBサイトの配色は役割別に３つあり、ベースカラー、メインカラー、アクセントカラーと呼びます。
各比率をベースカラー70％、メインカラー25％、アクセントカラー5％の割合にすると、美しくバランスの取れたデザインになると言われています。

![03.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2299054/36dfc8e6-5a98-9495-28b0-efef20fcbbdb.jpeg)


<strong>ベースカラーの役割</strong>
ベースカラーはデザインの中で最も大きな面積を占める色になります。
「背景」や「余白」に用いることが多いのであまり主張の強くないカラーを選ぶのが無難です。

<strong>メインカラーの役割</strong>
デザインの中心になる色です。
メインカラーはロゴ部分や、メインコンテンツに使用されるカラーになります。

<strong>アクセントカラーの役割</strong>
アクセントカラーは、ワンポイントで目立たせたい、注目させたいポイントに使ったりメリハリをつけるために使用します。
メインカラーの反対色を使ったり他の二色より鮮やかな色を使うと良いと言われいてます。

<h2>真っ黒は使わない</h2>

なんだか目がちかちかするなー、疲れるなーと思うことありませんか？
そんなに浮いたカラーは使ってないのになんでだろうと思う時は#000000を使用してるからかもしれません。

黒からグレー方向へ少しずらしたカーラーコード（色）で設定すると見やすくなります。個人的には#333333くらいがおすすめです。
![04.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2299054/15a99fdc-43d4-5831-6f2f-59a40a26c465.jpeg)


背景との兼ね合いやデザインのテーマによって#000000でも良い場合もありますが、背景やテキスト等に使う場合はグレー方向にずらした方がやわらかく見やすい印象になります。


<h2>グレースケールでデザインしてみる</h2>
「基本的な配色を決めたけど何か見にくい・・・」
「デザインしていくうちに最初に決めた配色がおかしく見えてきた」
ということもあると思います。
しっくりこないなーというときはグレースケールでデザインしてみると良いと思います。

<h4>NGな例</h4>
![01.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2299054/4a426bec-6876-578f-18b5-592089f61f49.jpeg)
色数も多く視認性も良くないのでグレースケールにしたときにテキストがぼやっとしたイメージになります。

<h4>OKな例</h4>
![02.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2299054/30f00741-6530-1cb1-08d7-cfe0a60806d3.jpeg)
色数を減らして視認性を高めました。
グレースケールにしたときにメリハリができ見やすいイメージになります。

<h2>配色でおすすめのサービス</h2>
上記でよく見かける基本的配色方法を記載しましたが
「そんなことは知ってる。もっと手取り早く色決めたい」という方に下記の自動で色を決めてれるサービスを紹介したいと思います。

<strong>■COLOR SUPPLY</strong>
https://colorsupplyyy.com/
１色を選ぶと、良好な組み合わせの候補をいくつか提示してくれます。
使い方もシンプルなのでまずはこちらを使ってみるのをおすすめします。

<strong>■Adobe Color CC</strong>
https://color.adobe.com/
PhotoshopやIllustratorなど、他のAdobeサービスと同期して利用できるツール。
写真をアップロードすると配色カラーパレット作成したり、グラデーションを抽出したりできるので、写真のイメージに合わせたサイトやバナー制作におすすめです。

<strong>■Pallete List</strong>
https://www.palettelist.com/
Pallete Listは、好きな2色を選択すると、その色を使ったカラーパレットを作成してくれるサービスです。
メインカラー等、方向性は決まってる時に利用すると綺麗な配色パレットが出来上がります。

<strong>■Palettable</strong>
https://www.palettable.io/892A09
表示されたカラーを好きか嫌いかの2択で選んでいくツールです。
嫌いをクリックすると別の色が提示され、好きを選ぶと次のカラーが提示され、繰り返していくと最大5色の配色パターンを作ることができます。
「自由にサイトを作ってください！」とオーダーがあったり方向性が決まってない時に利用すると良いと思います。

<strong>■Gradient Magic</strong>
https://www.gradientmagic.com/
こちら配色ではなくグラデーション背景のギャラリーサイトです。
使用したい背景のCSSコードを取得でき、テンプレート背景の模様を回転させたり色を変更したりして、アレンジができるので
バナーよりもLPを作成する際に利用すると便利です。

<h2>最後に</h2>
今回配色について書こうと思ったきっかけは、初めてwebデザインの業務を行った時に「どうしたらそんな配色になるの？」
と先輩に言われたことを思い出し、その時に教えてもらった配色方法やサービスになります。
デザインする方ならご存知の内容かとは思いますが、知ってるのと知らないのとではデザインの作りやすさや効率も変わってくると思います。
初めて知ったという方も、知ってたけど意識してなかった、使ったことなかったという皆様も改めて使ってみてください〜
便利に使おうSyncWith

# はじめに

最近では、Webアプリケーションだけでなく日常さまざまなシーンで、外部APIを活用することがあります。そんなとき便利なWebサービスの紹介です。たぶんハッカソンとかでむちゃむちゃ便利に使えそう。2021/12/16の情報です。

https://syncwith.com/

# なにがいいの？

* Webだけで完結、手軽に試せる
* 表形式で返してくれるのでAPIが返してくるデータを手軽に確認できる
* GoogleSheets連携、CSV出力

# 使い方

たとえばCovid19のような公開されているデータであれば、「Try it」でページを開いて「Run」ボタンをクリックすれば、もうPreviewでデータが見れます。

![スクリーンショット 2021-12-16 14.38.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/23612/7d769db4-a0fd-2f5d-502d-1b53e4cfec29.png)

![スクリーンショット 2021-12-16 14.41.44.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/23612/c65a62a0-d1b9-7097-396c-153e8d9183d8.png)

スクリーンショットでは見切れていますが「Get Google Sheet」でデータをGoogleSheetに連携したり、CSVにexportすることもできます。

fitbitのようにログインして使用するツールであれば、認証してアクセストークンを発行すればアクセスできるようになります。ブラウザを閉じたり、しばらく期間を置いてもアクセスが可能だったので、アクセストークン自体が、SyncWithのサーバーに保持されていると推測しています[^1]。

[^1]: セキュリティ的なところをきちんと確認したわけではないので、まだあたりさわりのないのデータしか使ってません。OAuthで連携するアプリであれば、IDやパスワードが保存されるわけではないので、使わなくなったらアプリ側で解除してしまえばいいはずなのでそこまで不安視してるわけではありませんが。

# 利用可能なAPI

海外のAPI中心ですが、かなりの数に対応しています。
TwitterとかYoutubeとかもあれば、知らないAPIもいっぱい並んでます。面白いところではMySQLとかBigQueryのView専用クライアントとしても使えそう。スポーツのデータとかもあれば、Covid19とかOpenWeatherMapとかオープンデータもかなりあります。

https://syncwith.com/all-apis

SyncWith自体が海外のサービスなので、日本国内のサービスは基本的にありません。

# おわりに

ツールの名前で検索しても、2021/12/16時点では知名度のあるバックアップソフトばっかりでてくるので、まだあまり使ってる人がいないのかも。
作品：ルビーチェス（Ruby Chess）

#概要
Odin Projectレッスンによって作ったチェスゲーム。

レッスンURL: https://www.theodinproject.com/paths/full-stack-ruby-on-rails/courses/ruby-programming/lessons/ruby-final-project

Github: https://github.com/RistoLibera/Ruby_Chess

![1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/613718/9dcfd8e6-8710-ef6a-f23b-d27559895415.png)

作品URL: https://replit.com/@qofgxnm7b/RubyChess?v=1

#使用技術
・Ruby
・Replit
・Git
・GitHub
・Oracle VM VirtualBox

#内容一覧

![3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/613718/5d2bd5f3-874e-d7c8-b2ff-ad02fab84cef.png)

AIまたは友達と遊ぶことができます。名前を入力し、白または黒を選べます。

![1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/613718/367e0a98-3f3a-4623-9069-7eaa66374740.png)

a～hと1～8を連結した文字列を入力し、チェスを選びます。

![6.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/613718/9e40f551-d54c-65a4-58eb-a3e9e51bb9b6.png)

緑のブロックは選ばれているチェス。
紅いブロックは可能な移動範囲。

![7.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/613718/7c3f2288-051e-1dbd-67b2-9d62a14633e1.png)

移動しました！

![8.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/613718/55089527-a929-ba7a-cc5a-8980ec1356a0.png)

キーボードの'S'を押してからゲームを保存していきます。

![9.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/613718/7354303d-a662-889c-a3be-b8b95fab73cf.png)

保存されたゲームをアクセスできます。

![10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/613718/a927b434-8bd0-dee0-1ef3-c84129d02372.png)

お同じところから遊べます。

![11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/613718/1538c4cf-6055-166b-8501-2b825500ee03.png)

勝利！

#まとめ

初めて学んだ知識を活用して一ヶ月かかってこのプログラムを作り、色々な困難にあってもそれらを解決して自分のプログラミング力も急速に成長しております。

さらに、ターミナルとＶＢも熟練しています。
AWSの障害をGlobal Acceleratorで回避できた話

## AWSの障害

昨夜(2021-12-16の日本時間0時過ぎ)、アメリカの方のAWSに障害があったようです。
うちの監視システムでも検知して、Twitter界隈ではPlay Station Networkが巻き込まれて大騒ぎになっていたようですが、AWSのStatusには障害情報はありませんでした。

## うちのサービス環境
うちの会社では[QUALITIA DNS](https://product.qt-dns.com/)というDNSのホスティングサービスを運用しているのですが、DNSは落とすわけにはいかないので、複数のクラウドサービス、リージョンに分散して運用しています。

この中で、AWSで運用している部分は現時点では、日本、シンガポール、フランクフルト、サンフランシスコにサーバーがあって、Global Accelaratorでリージョンを冗長化している状態です。

また、監視は、AWSの東京リージョン、日本のAWS外のサーバー、サンフランシスコのAWS外のサーバーからそれぞれの各サーバーとGlobal Acceleratorを監視しています。

![worldmap1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/326401/2ad86cb4-dacb-dae1-39ca-26196d41d46f.png)
## 監視元ごとの状況

こらちは、監視元ごとの失敗のグラフです。

![failed_by_source.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/326401/e71b2f5f-f7e0-9aa4-ca86-e88a6e3c2618.png)


緑は日本のAWS外のサーバーから、紫はサンフランシスコのAWS外のサーバーから、水色はAWSの東京リージョンからの監視状況です。
DNSのリクエストが失敗した数のグラフになっています。

これを見るとAWS内では問題がなくて、外からAWSへの回線か何かに問題があったのではないかという風に見えます。

![worldmap2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/326401/4ed261c0-3289-6d1a-bca8-63ed4d6190db.png)


赤い線が障害のあったルートです。

## サーバーごとの状況

こらちは、監視対象ごとの失敗のグラフです。

![failed_by_server.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/326401/42ed5c64-f729-679d-d782-9b4d2aaa2045.png)


ns-sf-\*はサンフランシスコリージョンのサーバーを直接監視したもので、ns-ga-\*はGlobal Accelerator経由で監視したものです。
b, cはAvailability Zoneです。

これを見ると、サーバー直接では障害が起きていますが、Global Accelerator経由では別の生きているリージョンに回されるので、日本からでもサンフランシスコからでも接続に問題なかったことがわかります。

この結果から、AWS網内は生きていて、インターネットからサンフランシスコ辺りのAWSへのネットワークがおかしかったんではないかと想像できます。

## 結論

ということで、[QUALITIA DNSサービス](https://product.qt-dns.com/)のお客様から見た状態は、ほぼ完全に無停止でした。

Global Accelerator素晴らしいですね。

*本記事は @qualitia_cdevの中の一人、@hirachanさんに書いていただきました。
PyTorch で CUDA をサブプロセスで動かす

AIを複数プロセスで動かしたいことってあると思います。これまで、PyTorchを使って認識処理をサブプロセスで動かしたいなと思ったことがありましたが、以下のエラーが発生してあきらめていました。以下はCUDAを使う場合に発生します。

```
"Cannot re-initialize CUDA in forked subprocess. To use CUDA with "
RuntimeError: Cannot re-initialize CUDA in forked subprocess. To use CUDA with multiprocessing, you must use the 'spawn' start method
```

### 原因
ちゃんとググってみると、以下の記事を見つけました。
https://stackoverflow.com/questions/48822463/how-to-use-pytorch-multiprocessing

内部の詳しいことは分からなかったのですが、要するに multiprocessing でサブプロセスを作成する時に fork システムコールで子プロセスを立ち上げると CUDA が対応できないらしいです。エラーメッセージに書かれている通りですね。。。

### 解決策
<u>サブプロセスの生成方法を fork から spawn に変更すればよい。</u>
また、multiprocessing の代わりに torch.multiprocessing を使う。

以下をサブプロセス生成前に記述する。

```
import torch.multiprocessing as multiprocessing
if multiprocessing.get_start_method() == 'fork':
    multiprocessing.set_start_method('spawn', force=True)
    print("{} setup done".format(multiprocessing.get_start_method()))
```