OmniAICreator/Qiita-1.07M huggingface dataset:
ユビキタス言語とドメインエキスパートの言語のミスマッチ

# はじめに
DDDでの開発をしています。自分も他のメンバーもDDDのプロジェクトはほぼ初です。日々書籍や記事などからDDDについて学びながらの開発です。今回は実際に手探りでプロジェクトでDDDを実践してみて、あまり語られているのを見た事がなく悩んだ問題について書きます。

# プロジェクトの状況
- とある企業からの受託開発。
- 発注元の商品そのものというよりは、DDDで言うところのサブドメインにあたる従来システムを0からリプレイス。
- 従来システムは発注元のビジネスの初期から存在し、ビジネスの変化にその場その場のスピード重視で追従することを優先した結果、いまや技術的負債が積み重なり機能追加や改修が困難になっている。
- この反省から新しいシステムには保守性が求められており、DDDを採用。
- リプレイスではあるものの、完全に同一の動作をするものを再度作るのではなく、従来のシステムがビジネスの変化に付いていけずに放置され運用で苦労していた部分、今後のビジネスの展望から新しい業務フローに置き換えるべき部分を明らかにしながらアジャイルに開発。

- CQRSを採用

# 問題
開発初期のドメインエキスパートとのミーティングでは聞きなれない言葉が多く出てきます。その中にはかなり曖昧に、不整合に使用されている用語も珍しくはありません。ユビキタス言語が存在しない状態だと、ドメインエキスパートは同じことを異なる言葉で表現したり、違うことを同じ言葉で表現したり、本質とはかけ離れた表現を使います。プログラムとは違い、用語が曖昧なままでも実際のドメインエキスパートの業務に支障はないということでしょう。自身の日常や業務を鑑みても、常に厳密に用語を使っているかというとNoなので納得できます。しかし、システムを開発する上でこれら曖昧な用語は取り除くべき障害です。ドメインエキスパートから発せられる曖昧で不整合な用語に目を光らせながらユビキタス言語として整理していくことが正確なドメイン理解の第一歩と言えるでしょう。ミーティングの中でドメインエキスパートに曖昧で不整合な点を指摘すると大抵の場合「あー言われてみれば確かに」という反応を示して頂け、そこから新たな用語をユビキタス言語として考案していきました。

しばらくはこの調子で順調にやっていたのですが、フロントエンドの開発に取り掛かった段階で問題が発生しました。従来のシステムで曖昧な用語が使われていた部分をユビキタス言語に置き換えて開発したところ、ドメインエキスパートから「そこにはユビキタス言語を使わないで欲しい」と言われました。聞くところによると発注元の社内でだけならまだしも、発注元の顧客からブラウザを通して見える部分にまでユビキタス言語を徹底してしまうと、従来の顧客から分かりにくくなってしまうということでした。また、フロントエンドで開発しようとしていたQueryモデルの項目の中にはCommand側のドメインモデルやユビキタス言語には存在しないものがありました。

# 対応
今回の案件では保守性を要求されていたため、フロントエンドで使用される用語にもユビキタス言語を使用するべきだと最初考えていました。しかし、ユビキタス言語はあくまでもドメインエキスパートと開発者の間の共通言語で、ユビキタス言語がドメインエキスパートの用語にフィードバックされる訳ではないことに気がつきました。そこで、フロントエンドで使用される用語は基本的にドメインエキスパートの用語を踏襲することにしました。しかしそうなると、フロントエンドで表示されてからUseCaseを実行するまでのどこかでそのミスマッチを解消しなければなりません。そこでControllerからUseCaseを実行する引数を作成する段階でそれらを全て解消することにしました。HTTPリクエストまではドメインエキスパートの用語、UseCaseからはユビキタス言語、それらを変換するのがControllerという形です。

# おわりに
DDDを手探りでやっていると思わぬ悩みポイントが発生します。特に今回はDDDをやっていたメンバーがいなかった為「もしかしたらここで妥協すると後々致命的に保守できなくなるのかもしれない」という懸念はありました。しかし、ある程度開発した現段階ではそういったことは起きておらず、むしろフロントエンドが発注元の要望に合わせやすいようになったため、ある意味保守性が上がったと言えます。今回の話題はもしかしたらDDDにより詳しい方からすれば当たり前の話(もしくはより良い方法がある)かもしれませんが、同じことに悩む人の手助けになればいいなと思います。
Maplat UI（UIあり版）をnpmから設定

Maplat Advent Calendarですが、22日目はUI付きのMaplatをnpmを使って設定してみましょう。
動くものはこちらになります。 => [CodeSandBox Maplat Advent Calendar day 22](https://codesandbox.io/s/maplat-advent-calendar-day22-h37n5)

20日目のコードをベースに、npmを使うので、まずは`package.json`を設定しましょう。

```package.json
{
  "name": "maplat-advent-calendar-day22",
  "version": "1.0.0",
  "description": "",
  "main": "index.html",
  "scripts": {
    "start": "parcel index.html --open",
    "build": "parcel build index.html"
  },
  "dependencies": {
    "@maplat/ui": "0.6.4"
  },
  "devDependencies": {
    "@babel/core": "7.2.0",
    "parcel-bundler": "^1.6.1"
  },
  "keywords": []
}
```
`dependencies`で`@maplat/ui`の0.6.4を読み込んでいます。

CodeSandboxでは変更かけるとすぐ反映してくれますが、ローカルでやる場合は当然`package.json`を変更するだけでなく、`npm install`などが必要です。

続いて、`app.css`はほぼ同じなので、まず`index.html`からCDNへのリンクを外します。

```index.html
<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8" />
    <title>Maplat Advent Calendar Day 22</title>
    <link rel="stylesheet" href="app.css" />
  </head>
  <body>
    <div class="mainview">
      <div id="map_div"></div>
    </div>
  </body>
  <script src="app.js"></script>
</html>
```

大きく変わるのは`app.js`。

```app.js
import "@maplat/ui/dist/maplat.css";
import { MaplatUi } from "@maplat/ui";

var option = {
  appid: "maplat_ac_day22"
};

var app = new MaplatUi(option);
app.waitReady.then(function() {});
```
まず、`import`で`@maplat/ui/dist/maplat_core.css`を指定し、cssを読み込んでいます。
こんな構文はES6にはなく、完全にparcel環境依存なのですが、まあそれはいいでしょう。
続けてやはり`import`で、`@maplat/ui`から`MaplatUi`クラスを読み込んでいます。

`option`は昨日とほぼ一緒。

違うのはMaplat UIのオブジェクトを作るところです。
npm呼び出しの場合は、`new`構文で`MaplatUi`のオブジェクトを作り、そのオブジェクトのプロパティ`waitReady`が`Promise`を返すので、それを`then`や`await`で待ってオブジェクトを作ります。

これは、CDN呼び出しの方のインタフェースが、まだMaplatがモジュールシステムに`require.js`を使っていた頃の名残なので、将来的にCDN呼び出しの場合もnpmの方のインタフェースに合わせる可能性があります。
もっとも、CDN呼び出し側の後方互換性も維持するつもりではあります。

これでMaplat UIがnpm経由で動作するようになります。

動作結果は昨日と同じなので省略。

さて、ほぼほぼAdvent Calendar 3日目と同じ文章で記事をでっちあげた22日目完了です。
省エネ省エネ。
明日は、Maplat UIの中のMaplat Coreオブジェクトを通じて、UI付きのMaplatもAPI制御する方法を試してみます。
文字型変数の重箱の隅

Advent Calendar 埋め草記事として、文字型変数の重箱の隅をつつくようなことを書かせていただきます。

# 内部ファイルへの I/O は pure 
I/O は一般に副作用を持つ動作なので impure ですが、文字型を内部ファイルとして使う場合はどうなるのでしょう？ 内部ファイルを使えば、数値を文字列に変換したり、文字列を数値に変換したりできますが、これは型変換を伴う代入の様に思えます。

文法書をしらべてみると、これは pure としていいようです。

## プログラム例
内部ファイルを用いて実数を書いた文字列を実数に変換する関数を、pure で elemental な関数として定義して実際に使ってみます。

要素数３の文字列配列の実数値を、そのまま引数として渡して、一気に数値に変換しています。なお文字列の配列は文字列の長さをそろえる必要がありますが、人間が手で数えて等しい長さの文字列を与えるのは面倒なので、配列構成子 (array constructor) に変数型（と宣言長）を与えることで、自動で数えて調整してもらっています。

```fortran
    module test_m
        implicit none
    contains
        pure elemental real function r_from_str(text) result(res)
            character(len = *), intent(in) :: text
            read(text, *) res
        end function r_from_str
    end module test_m

    
    program pure_internal_io
        use test_m
        implicit none
        character(len = :), allocatable :: str(:) 
        str = [character(len=20)::'1.0', '-2.0e-3', '3.14159265359']
        print *, r_from_str(str)
    end program pure_internal_io
```

```
   1.000000     -2.0000001E-03   3.141593
``` 

ところで、内部ファイルは書式付きの I/O なので、C 言語とかの atof 関数とかよりとても遅かったりします。

# 文字列定数に種 (kind)

整数型や実数型の定数などの種別を明示する時には、お尻の方に 3.14_real32 などとアンダースコアに続いて種を与えますが、文字列の場合はどうでしょうか？

文字列の場合は頭の方に与えます。

今まで使ったことが無かったですが、これは見かけが異常なプログラムを作るのにとても便利な気がします。

Fortran は予約語が無いことを利用し命令語を変数名とし、固定形式なら空白が無視されることから空白を単語の途中に挿入し、73 桁より先が無警告で切り捨てられることと合わせて、異常な見かけのプログラムを書くのにいい感じになりそうです。

## プログラム例
ここでは dot という変数を文字型の種別として用いることで、内積を求める組み込み関数の dot_product と見かけの似た文字並び dot_'product(p, p)' を作っています。'product(p, p)' という文字定数の種を dot に指定しています。

Fortran 90 の時に日本が漢字対応を前提に文字型にも種を与えたのですが、残念なことにたいがいの Fortran コンパイラは unicode などの世になっても文字型の種対応がおざなりです。intel/gfortran/flang とも dot、npn とも 1 を返しました。今後 emoji 効果であるいは･･･

（異常なプログラムではありません。）

```fortran 
    program char_kind
        implicit none
        complex :: p(3) = [(1.0, 2.0), (2.0, 1.0), (1.0, 1.0)]
        integer, parameter :: dot = kind("a"), npn = kind("あ")
        
        print *, dot, npn

        print *, dot_product(p, p)
        print *, dot_'product(p, p)'
    end program char_kind
```

内積は複素ベクトルの内積を取っています。

```
           1           1
 (12.00000,0.0000000E+00)
 product(p, p)
```
既存プロジェクトを別プロジェクトとして作り直す

既存のプロジェクトを他のプロジェクトに流用する際の手順を備忘録として残します。
# プロジェクトの名前を変更する
まず、プロジェクトのリネームをします。

![スクリーンショット 2019-12-22 19.06.55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/457333/4e542b65-9451-8f88-8b0d-f2d6e2ac31a4.png)

リネームすると以下のように自動的に関連するファイルのリネームしてくれます。
![スクリーンショット 2019-12-22 19.07.11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/457333/820336bf-756e-e119-88d7-a047c61f9e09.png)

これだけだとScheme名とプロジェクトフォルダ名は元のままなので、それぞれリネームをします。

![スクリーンショット 2019-12-22 19.30.33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/457333/dc8302c8-7da6-07b0-7038-b985251fd3e0.png)
![スクリーンショット 2019-12-22 19.31.08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/457333/c2132fdb-837a-acbb-b530-b936e7035863.png)

次にinfo.plistの設定をします。
「Choose Info.plist File...」をクリックして、plistを指定します。
![スクリーンショット 2019-12-22 20.18.16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/457333/1061f8b0-66ba-3ea2-b310-a82bf9589a8b.png)

最後にBundle Identifierを変更します。
![スクリーンショット 2019-12-22 20.24.00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/457333/8307aba9-0871-3365-2251-d85304d78a15.png)

# リモートを変更
```
$ git remote -v
origin	git@github.com:gdate/MVVMTest.git (fetch)
origin	git@github.com:gdate/MVVMTest.git (push)

$ git remote set-url origin git@github.com:gdate/FluxTest.git
$ git remote -v
origin	git@github.com:gdate/FluxTest.git (fetch)
origin	git@github.com:gdate/FluxTest.git (push)
```

あとは変更点をコミットし、プッシュすれば新たなプロジェクトとして開発できます。

```
$ git add .
$ git commit -m 'initial commit'
$ git push origin master
```
パイプの前のプロセスが成功したときだけ処理したい2(Eitherっぽいパイプ)

前の記事では[Maybeっぽいパイプ](https://qiita.com/opiliones/items/44ee82e7b8f5dd5f6cb4)を作成したので今度はEitherっぽいパイプを作ってみる。

シェルスクリプトを書いているとこんなコードを書いてなんだかなぁという気持ちになることがある。(シェル力の問題なのかもしれないが)

```bash
x=`command` 2>$TMPDIR/cmd_err || {
  my_logger "ERROR: command failed, ecode=$?, msg=`cat $TMPDIR/cmd_err`"
}
```

こんな感じでどうでもいい一時ファイルや変数は処理から見えないようにしたい。

```bash
# ケース1
x=`either command | fmap command | cmd 2>&1` || {
  my_logger "ERROR: hoge failed, ecode=$?, msg=$x"
}
# ケース2
either command | fmap command | either_case
in 0) cat -
;; *) my_logger 'ERROR: hoge failed, ecode=%d, msg=%s' $? $(cat)
either_esac
```

## 実装例

前回のコードを素直に拡張する。

### 標準入出力のフォーマット

```
# 成功の場合
either
0
<いつもの標準出力>

# 失敗の場合
either
<0以外の数値>
<標準エラー出力>
```
maybeの場合はエラーの場合は出力はなかったが、eitherの場合は(ややこしいが)エラー出力が標準出力に出力する。

### 関数
fmapやcmd関数は[前回](https://qiita.com/opiliones/items/44ee82e7b8f5dd5f6cb4)を参照

```bash
either() {
  local out=`mktemp` err=`mktemp`
  { rm $out $err
    "$@" >/dev/fd/3 2>/dev/fd/4 &&
      right cat /dev/fd/3 ||
      left  $? cat /dev/fd/4
  } 3>$out 4>$err
}

right() {
  echo either
  echo 0
  "$@"
  return 0
}

left() {
  local ret=$1
  shift
  echo either
  echo $ret
  "$@"
  return $ret
}

fmap_either() {
  bind_either either "$@"
}

bind_either() {
  local value
  read value
  case "$value"
  in 0) "$@"
  ;; *) left "$value" cat -
  esac
}

cmd_either() {
  local r
  read r || exit
  case $r
  in 0) cat -
  ;; *) cat - >&2
        return $r
  esac
}

_eithercase() {
  local r
  read && read r || exit
  return $r
}
alias either_case='{ _eithercase; case $?'
alias either_esac='esac; }'
```

## 使ってみる

```
$ x=`either a | fmap b | cmd 2>&1` || {
> echo "ERROR: command failed, ecode=$?, msg=$x"
> }
ERROR: command failed, ecode=127, msg=a: コマンドが見つかりません
```
これだと `x=$(cmd 2>&1)` と何が違うのかと言われそうだが、正常系の場合にxに変なワーニングが入り込まないことが保証されていることが異なる。

```
$ either echo a | fmap a | either_case
> in 0) cat -
> ;; *) echo "ERROR: command failed, ecode=$?, msg=$(cat)"
> either_esac
ERROR: command failed, ecode=127, msg=a: コマンドが見つかりません
$
$ either echo a | fmap grep a | either_case
> in 0) cat -
> ;; *) echo "ERROR: command failed, ecode=$?, msg=$(cat)"
> either_esac
a
```
kafka-pythonでconsumerのオフセットを他にコピーする

Kafka consumerを実装するときはJavaやScalaなどの言語を使うことが多いのですが、そこまで複雑でなければ軽く実装できるPythonを使いたいですね。
今回はPython向けのApache Kafkaライブラリのkafka-pythonを使って、あるconsumerのオフセットを他のconsumerに移すメンテナンス処理を書いて見たいと思います。

# コンシューマーのオフセット取得

今回はKafkaAdminClientを使用します。KafkaConsumerから取得することもできるのですが、consumerを購読したりpollしたりと煩雑なのでこちらのクライアントを使うのがおすすめです。

```python
from kafka import KafkaAdminClient

# consumer01はtopic01を購読中という想定
target_consumer_name = "consumer01"

# KafkaAdminClientを取得
cluster_admin = KafkaAdminClient(bootstrap_servers=bootstrap_servers)

# オフセットを取得
offsets = cluster_admin.list_consumer_group_offsets(target_consumer_name)
```

参考までにこんな感じのものが返却されてきます。
TopicPartitionクラスをキーとしたオフセットの情報です。

```python
{TopicPartition(topic='topic01', partition=0): OffsetAndMetadata(offset=14475, metadata='aa6c00e6-ffbf-41a3-b011-6997549f6166a'),
 TopicPartition(topic='topic01', partition=1): OffsetAndMetadata(offset=14494, metadata='8fcc736c-1cb0-41b5-b111-6d55d67b3096a')}
```

# 別のコンシューマーにオフセットを書き込み

consumerの書き変えを行うにはKafkaConsumerを使用します。
先程取得したオフセット情報をconsumer02に書き込みます。
consumerが存在ない場合は自動で作成が行われます。

```python
from kafka import KafkaConsumer

consumer_group_name = 'consumer02'

consumer = KafkaConsumer(
        group_id=consumer_group_name,
        bootstrap_servers=bootstrap_servers,
        enable_auto_commit=False)

# offsetの情報を書き込み（consumerが存在しない場合作成される）
consumer.commit(offsets)
```

これでconsumer02にはconsumer01と同じtopicのオフセット情報が書き込まれました。
consumer02を使用して購読を開始すると、オフセット取得時のconsumer01と同じオフセットから購読を開始するはずです。

# 購読の例
```python
consumer_group_name='consumer02'

# consumerを取得
consumer = KafkaConsumer(
        group_id=consumer_group_name,
        bootstrap_servers=bootstrap_servers)

# topic01を購読する設定に変更
consumer.subscribe(topics=['topic01'])

# topic01 consumer02に実際に参加
consumer.poll()

# 受信できたメッセージをprintし続ける
for msg in consumer:
    print(msg)

```



# 参考
https://kafka-python.readthedocs.io/en/master/apidoc/KafkaConsumer.html
https://kafka-python.readthedocs.io/en/master/apidoc/KafkaAdminClient.html
選択ソートをCで書いた

#選択ソート(C言語)

#選択ソートとは
・インプレース整数アルゴリズム。選択ソートは小さなファイルに適している。
・昇順(小さい順)のときは最小値、降順(大きい順)のときは最大値を見つけることを繰り返し行う。
・n個の要素を整列させるのにn-1回の交換が行われる。
パス１でn-1回の比較
パス２でn-2回の比較...（比較対象のデータが1つ減るため）
なので、(n-1)+(n-2)+・・・+1=n(n-1)/2回の比較が行われる。

#利点
・わかりやすい
・インプレースソート(追加の記憶領域が不要)
・バブルソートより高速
#欠点
・規模による計算量の悪化:O(n²)

#全体的な流れ
1.リスト内の最小値(最大値)を見つける。
2.現在の位置の値と交換する。
3.配列全体を整列するまでこの処理をすべての要素に繰り返す。

#実装にあたって
C言語で実装する。
英語と数学の点数を降順(大きい順)に表示する。データの並び替えに選択ソートを用いる。

#コード

```c:selection_sort.c
#include <stdio.h>
#define NMAX 1000
int main(){
    int eigo[NMAX], math[NMAX], gokei[NMAX], n, max, work;
    printf("data="); scanf("%d", &n);
    for (int i = 0; i <n ; ++i) {
        printf("[%3dbanme]=", i); scanf("%d %d", &eigo[i], &math[i]);
        gokei[i]=eigo[i]+math[i];
    }
    for (int i = 0; i <n-1 ; ++i) {
        max=i;
        for (int j = i+1; j <n ; ++j) {
            if (gokei[j]>gokei[max]) max=j;
        }
        if(i!=max) {
            work=eigo[i];eigo[i]=eigo[max];eigo[max]=work;
            work=math[i];math[i]=math[max];math[max]=work;
            work=gokei[i];gokei[i]=gokei[max];gokei[max]=work;
        }
    }
    printf("*** RESULTS ***\n");
    printf("RANK   ENGLISH   MATH   TOTAL\n");
    for (int i = 0; i <n ; ++i) {
        printf("%4d%6d%6d%6d\n", i, eigo[i], math[i], gokei[i]);
    }
}
```

#ソートの計算量


|種類|計算量|
|:-:|:-:|
|最悪時計算量|O(n²)|
|最良時計算量|O(n)|
|平均計算量|O(n²)|
|最悪時空間計算量|O(1)補助領域|

またなにかあったら書き加えるかもしれません
VisualStudioCodeでタグをクリックした際にマルチカーソルになってしまう時の対処法（HTML）

Visual Studio Code（以下VS Code）でHTMLを編集しようとしたところ、突然開始タグと終了タグの両方にカーソルが入ってしまう様になりました。
なんでやと思っていろいろ調べていたら、どうやらVS Codeの最新版「November 2019」リリース（バージョン1.41）でそういった機能が追加されたそうです。（デフォルトで設定されてるとか余計なことを。。。）
#対処法

ファイル→基本設定→設定　を開く
![カーソル対処法①.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/493825/c4ee9b46-1ebd-88c9-6e60-10e6a604e12d.png)


拡張機能→HTML　よりMirror Cursor On Matching Tagのチェックを外す
![カーソル対処法②.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/493825/6d48bf6a-e49e-ce27-ccbc-847a3bdb85b4.png)

これでタグをクリックすると片方のみカーソルが入るようになっているはずです。（何か間違ってたらごめんなさい）
いかんせん出たばっかりで情報が少なかったので、誰かしら役に立ったらいいかなーと思います。（あと半分備忘録的な感じ）

以上、Qiita初投稿でした。
ファイル削除について思う所まとめ

この記事は、[大国魂（ITブログ） Advent Calendar 2019](https://adventar.org/calendars/3955) の22日目です。

# 記事概要
[本番環境でやらかしちゃった人 Advent Calendar 2019](https://qiita.com/advent-calendar/2019/yarakashi-production) で教訓になる記事が多く、
データ削除系に関するやらかし防止のための自分の考えをまとめておきます。
(まとめておこうと思った)

# 想定環境
本番環境など、自分のローカル環境ではないサーバ環境全般が対象です。

# 全体として
その環境でバックアップがどのように構成されているかを知ることが大事です。

オンプレ環境の場合、ストレージのスナップショットで個別のファイル抽出が可能か、
NetBackup/Veeam といったバックアップ製品でどのファイルをどのような周期でバックアップしているか、といった内容になります。
クラウド環境であれば、上記のような仕組みが何かで実装されているのか、といった形になります。
DBも同様に、どのようにバックアップを取得して、一部のテーブルだけであればいつのデータでリカバリ可能かを抑えておくと良いでしょう。

ハードウェアに関しても、いつのコンフィグバックアップが取得されていて、復旧時はどのように戻せるのかという点は抑えておきましょう。
これらに加えて、ファームウェアやOSバージョンの戻しも重要ですね
(教訓になる良い記事でした [1セグメント全断の土曜日](https://qiita.com/Words4MyRegret/items/e0b70aff25412655b9ed) )

これらのことを知っておくと、消して二度と取り戻せないファイルか否かの判断がつき、
二度と取り戻すことができないファイルに関しては慎重に扱おうという気持ちが生まれることでしょう。
(とはいえ、バックアップアップがあるからと言って安易なファイル削除をされても困るとは思います)

また、これ絶対事故りそうだよね、ここバックアップ無いのヤバイのでは？みたいな気付きを得られれば、改善提案に繋がっていくのもよいかなと思います。

# Linux 編

`rm -rf はなるべく使用しないことを心がける`
これに尽きますね。

rm -rf は実行対象のディレクトリを誤ることで、大量ファイルの誤削除を引き起こす可能性があります。
特にシェルスクリプトで rm -rf を用いてファイル削除をする場合には十分な注意が必要です。
cron にて実行するのであれば、rm -rf で削除される対象ファイルのみリストに表示するような書き換えを行ない、
数日 cron で(手動実行ではなく)動作させて、削除対象ファイルに問題ないことを確認した上でリリースしましょう(戒め)

手動オペレーション時も同様に、ls -ltrR などで削除対象ファイル一覧を取得して、
本当に問題ないことを確認してから、ls -ltrR と同じパスをコピペして削除するのが良いのかなと思います。
(物凄く堅実な削除は、リストからファイルを1つずつ rm で削除ですが、それはそれでつらい運用になると思います)

# Windows 編
`shitf + delete によるごみ箱を経由しない削除はしないように心がける`
これに尽きますね。

と書いて、PowerShell の場合はここを意識してなかったなぁと思いいたりしました。
[PowerShell でファイルやフォルダをごみ箱に入れる](https://qiita.com/Zuishin/items/1fa77bccd111b55f7bf6) という記事もあるので、後ほど試してみようと思います。
【Linux】複数あるファイルの中から特定の文字列を検索したいとき

#はじめに
Railsでカラム名を変更した際、各ファイルに書いていた、変更前のカラム名を探して、変更後のカラム名に治すのがめんどくさかったので今回この記事を書きます。
##コマンド

```
$ find ./ -type f -print | xargs grep 'hoge'
```

##上記のコマンドの説明
`find`
find の次で指定したディレクトリ以下のファイルを検索する。
ファイル検索の構文は「find [path] [検索条件] [アクション]」

`./`
今いるディレクトリ以下が検索対象。「~/」とするとホームディレクトリ以下が検索対象となる。
./ の代わりにフルパスでも可。この場合も指定したディレクトリ以下が検索対象になる。


`-print`
検索結果を標準出力する。このとき結果をフルパスで表示する


`-type f`
指定したファイルタイプを検索する。fが通常ファイルを，cまたはdとするとディレクトリを，lとするとシンボリック・リンクを検索します。


`xargs`
標準入力からコマンドラインを作成し、それを実行する


`grep`
ファイルから文字列を検索する。grep の後に検索したい文字列を指定する。



##参考
http://kawatama.net/web/1141
【2019年版】Nextcloudを使うべきか？


毎度、ググっても出てこない小ネタを取り扱っております。
本記事は個人的な見解であり、筆者の所属するいかなる団体にも関係ございません。
(関係はありませんが、筆者はNextcloudの日本代理店スタイルズ社に所属しています)

# 0. はじめに

2016年12月01日に以下の記事をQiitaに投稿しました。

Nextcloud を使うべきか？ - Qiita
https://qiita.com/ynott/items/4d54b1210981cd292123

その頃は、まだNextcloudは出たばかりでした。(Nextcloudのリリースは、2016年6月です)

なので、あまりNextcloudについて肯定的な意見ではありませんでした。
しかし、3年が経ちどうなったか振り返りたいと思います。

# 1. 現在の世界でのNextcloudのGoogleトレンド

赤がNextcloudです。
青がownCloudです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/15176/b3c45abe-2f0e-5153-76b6-0aa3913c1674.png)

過去5年のトレンドを見ると一目瞭然です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/15176/b6e00342-664c-2942-7930-7bf95d1da956.png)

## 1-2. 日本でのNextcloudのGoogleトレンド

日本では、以下のようになっています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/15176/68512327-e4b0-87c3-deab-8164840473a8.png)

https://trends.google.com/trends/explore/TIMESERIES/1577242800?hl=ja&tz=-540&date=today+5-y&geo=JP&q=ownCloud,Nextcloud&sni=3

全世界ほどは顕著ではありませんが、Nextcloudが優勢といって良いでしょう。

# 2. 機能追加

Nextcloudの機能追加の勢いの方が優勢です。

ownCloudが2019年にリリースした数は、フィーチャーリリース(マイナーFix以外)
10.0.0 - 2017-04-26
10.1.0 - 2019-02-06
10.2.0 - 2019-05-16
10.3.0 - 2019-10-15
10.3.2 - 2019-12-04
となっており、10.3で大きく機能追加がされています。

特筆すべきは、ownCloudのDesktop ClientでNextcloudにはない仮想ファイルシステムが導入されています。
Desktop Client 2.6 Release - Native Virtual File System on Windows 10 – ownCloud
https://owncloud.org/news/desktop-client-2-6-release-native-virtual-file-system-on-windows-10/

一方、Nextcloudはどうでしょうか？
2016年からメジャーバージョンアップが
Version 11.0.0 December 13 2016
Version 12.0.0 May 22 2017
Version 13.0.0 February 6 2018
Version 14.0.0 September 10 2018
Version 15.0.0 December 10 2018
Version 16.0.0 April 25 2019
Version 17.0.0 September 30 2019
となっており、バージョンアップがインフレ気味という問題はあるものの精力的に機能追加が行われています。

Nextcloudでの特筆すべきは、Nextcloudアプリの存在でしょう。

NextcloudアプリはNextcloudをプラットフォームとして様々な機能を追加できる仕組みですが、
このアプリ開発をする開発者が非常に多くなっており、コミュニティーでの開発が進んでいます。

App Store - Nextcloud
https://apps.nextcloud.com/

現状公開されているアプリの数は、200を越えています。

ownCloud Marketplace | ownCloud Marketplace
https://marketplace.owncloud.com/

こちらにもMarkerplaceという同様の仕組みがありますが、数は80前後となっています。

# 3. 開発者数

GitHubで見るソースコードの開発者は、以下から見ることができます。
People · ownCloud
https://github.com/orgs/owncloud/people
現在、93人

People · Nextcloud
https://github.com/orgs/nextcloud/people
現在、167人

年間のコミットグラフをみても

Commit Activity · owncloud/core
https://github.com/owncloud/core/graphs/commit-activity
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/15176/26bd9f1e-b6f0-0d58-d6f6-33352b9fd702.png)

Commit Activity · nextcloud/server
https://github.com/nextcloud/server/graphs/commit-activity
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/15176/2bfe30fd-3339-adcc-72ed-1c3c7f6b0720.png)

以上のようにNextcloudの方が優勢です。

# 4. まとめ

現状では、Nextcloudの方が開発の勢いは強い。
利用者が増えるほど、企業向けの導入も増えてくるので安定性も増してくると考えられる。

これからのメンテナンスも考えるとNextcloudを導入することをお勧めします。

(筆者はNextcloudの日本代理店スタイルズ社に所属しています)
メモ

```swift
//呼び出し元
@objc enum Status: Int {
    case web
    case normal
    case none
    
    func get1(str: String) -> Status {
        switch str {
        case "WEB会員":
            return .web
        case "ノーマル会員「":
            return .normal
        default:
            return .none
        }
    }
}

class Enum {
    
    func get() {
        // 文字列取得
        let sta = "WEB会員"
        
        // 初期値取得
        let status: Status = .none
        
        // 文字列をもとに数字を取得今回は0
        let i = status.get1(str: sta).rawValue
        
        // dictに詰める
        var dict: [String: Any]
        dict = ["rank": i]
        
        let a = Tamu()
        a.consoleWrite(dict)
    }
}
```

呼び出し先（objective-c側）

```swift
- (void)consoleWrite:(NSDictionary *)dict {
    // integerValueで 型変換を行う。でないと正式にint型になってないから
    NSInteger ka = [dict[@"rank"] integerValue];
    if(StatusWeb == ka) {
        NSLog(@"a");
    }
}
```
JIGのsbt-pluginを作った

本記事は、 [Scala Advent Calendar 2019](Scala Advent Calendar 2019) の22日目です。

sbt-jigは、 こちら→ https://github.com/yoshiyoshifujii/sbt-jig

以下、制作における背景とざっくり説明。

# 背景

みなさんはJIG（治具）というツールをご存知でしょうか。

詳しくは、以下のリンクを読んでいただくとして…

- https://speakerdeck.com/irof/jigfalseshao-jie
- https://github.com/dddjava/jig

JIGは、Javaで書かれたコードとビルドされたクラスファイルを解析して、ドメインモデルの関連を良い感じにダイアグラムやExcelで示してくれるツールです。

最近、こちらのツールを業務やワークショップなどで使わせていただき、大変重宝させていただいております。

何とか、こちらのツールをScalaでも使えないものかとツール作者の @irof さんにお聞きしたところ、「ソースコードは解析できないけど、クラスファイルは解析できるので、図は出ますよ」ということで、試しに動かしたところ、出ました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24050/b7c85dcc-ec75-8151-5472-746285119be3.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24050/2bbb807f-035b-f2c5-6d25-d7d5c95e8167.png)

ただし、

- ソースコードの解析ができないので、ScalaDocを読み込んで図に表示できない
- case classやコンパニオンオブジェクトがあると、prefixに `$` がついていてるモデルが出力されて冗長な図になる
- Scalaだとenumをパターンで実装することが多いので列挙型が表示できない

といった折角の機能を全て使うことはできていません。

このあたりは、おいおい、カバーするようなPull Requestを上げれれたらなーと夢想しております。

# 使い方

bintrayなりsonatypeなりにアップしようと思ったのですが、ちょっと記事に間に合わず…

GitHubを直接指定する方法でいきます。

[こちら](https://qiita.com/eielh/items/2924632babc974b2ebb9) を参考させていただきました。

```scala:project/plugins.sbt
resolvers += Resolver.jcenterRepo

lazy val root = project.in(file(".")).dependsOn(githubRepo)

lazy val githubRepo = RootProject(uri("git://github.com/yoshiyoshifujii/sbt-jig.git#master"))
```

あとは、sbtを起動して、 `jigReports` を実行するだけです。

実行すると、 `target/jig` ディレクトリにレポートが出力されます。

## Configuration

JIGのCLIで指定できる内容をそのままConfigurationで指定できます。

```scala
    jigDocumentTypeText in jig := "",
    jigOutputDirectoryText in jig := "./target/jig",
    jigOutputOmitPrefix in jig := ".+\\.(service|domain\\.(model|type))\\.",
    jigModelPattern in jig := ".+\\.domain\\.(model|type)\\..+",
    jigProjectPath in jig := "./",
    jigDirectoryClasses in jig := s"target/scala-${scalaBinaryVersion.value}/classes",
    jigDirectoryResources in jig := s"target/scala-${scalaBinaryVersion.value}/classes",
    jigDirectorySources in jig := "src/main/scala"
```

# まとめ

今回は、とりあえず、JIGをsbtから実行できるようにしただけですが、JIG本体のほーに、Scala用の拡張ポイントを設けさせていただくようにしたいなーと思ってます。

以上です。
wslでubuntu その３

#概要

wslでubuntuやってみた。

#環境

windows 10 64bit

#ソースをwindowsで作って、wslでコンパイルする手順。

 - デスクトップにasmフォルダを作る。
 - hello.Sをメモ帳で作る。
 - asmフォルダにセーブ。
 - asmフォルダをshift+右クリックして"Linuxシェルをここに開く"。
 - gcc -no-pie hello.S
 - ./a.out

#コマンドプロンプトから起動。

```
ubuntu1804
```

以上。
ROSパッケージ(gx_sound_player)を使ってUSBスピーカーから音楽再生する

# 目的
ROSパッケージ(gx_sound_player)を使ってUSBスピーカーから音楽再生しました。
再生するまでに何点か詰まった箇所がありましたので、実際に実施した確認手順とともに本記事にまとめさせて頂きます。

尚、本記事の内容は以下の記事をベースにしております。
> [gx_sound_player の紹介と ROS パッケージのリリース手順](https://qiita.com/yura/items/ba622a542385cdab6692#comment-c9c198f138c7d76d2122)

# 準備

USBスピーカー　：例えば[こちら](https://www.amazon.co.jp/gp/product/B0796VFD73/ref=ppx_yo_dt_b_asin_title_o00_s00?ie=UTF8&psc=1)
Ubuntu16.04 + ROS kinetic環境
テスト用音楽ファイル(.wav) ：例えば[こちら](http://www.ne.jp/asahi/music/myuu/wave/wave.htm)からダウンロードさせて頂く

# step1. USBスピーカーから音楽再生できることを確認

```
１．USBスピーカーをPCに接続する

２．サウンドデバイスがみえることをチェック
　　$ ls -l /dev/snd/*
　　　⇒　pcmC1D0p などがみえるはず
　　（以降、pcmC1D0p がUSBスピーカーのデバイスファイルであることを前提）

３．aplayでWAVファイルを再生
　　$ aplay -D hw:1,0 musicbox.wav
　　　⇒　USBスピーカーから音楽再生できればOK
```

USBスピーカーから音楽再生できなければ手順を見直します。

# step2. gx-soundパッケージでWAVファイル再生できることをテスト

gx-soundパッケージをインストールする。

```
$ sudo apt install ros-kinetic-gx-sound
```

```
１．roscore起動
$ source ~/catkin_ws/devel/setup.sh
$ roscore

２．gx-soundノード起動
$ roslaunch gx_sound_player sound_player.launch device_name:="hw:1,0"

３．WAV再生
$ rosrun rulo sound-test.py
　⇒　USBスピーカーから音楽再生できればOK
　　 音楽ファイルを/home/ubuntu/Downloads/musicbox.wavに格納しておく
```

```python:sound-test.py
#! /usr/bin/env python
# -*- coding: utf-8 -*-

import actionlib
import os
import rospy

from gx_sound_msgs.msg import SoundRequestAction, SoundRequestGoal


def main():
    rospy.init_node('sound_request_client_node')
    client = actionlib.SimpleActionClient('/gx_sound_player/sound_player/sound_request', SoundRequestAction)
    client.wait_for_server()
    rospy.loginfo("connected to actionlib server")

    now = rospy.Time.now()

    # 0秒後に audio3.wav を再生
    # 音楽ファイルを/home/ubuntu/Downloads/musicbox.wavに格納しておく
    goal1 = SoundRequestGoal(stamp=now + rospy.Duration(0.0), file="/home/ubuntu/Downloads/musicbox.wav")

    rospy.loginfo("send request")
    client.send_goal(goal1)
    rospy.loginfo("send complete")
    #client.wait_for_result(rospy.Duration.from_sec(5.0))


if __name__ == '__main__':
    main()
```

### 音声停止方法

無音ファイルをsendすればOK
無音ファイルは[こちら](http://hitotose-switch.blogspot.com/2013/12/wav.html)からダウンロードさせて頂きます。

# Error対策

### gx-soundパッケージが見つからない状況になった場合

```
gx-soundパッケージインストール
$ sudo apt install ros-kinetic-gx-sound
ros-kinetic-gx-sound not found
```

以下の通りパッケージリストを更新して解決しました。

```
sudo sh -c 'echo "deb http://packages.ros.org/ros/ubuntu $(lsb_release -sc) main" > /etc/apt/sources.list.d/ros-latest.list'
sudo apt-get update
```

--
### 音声フォーマットエラーになった場合

ffpmegでフォーマット変換すれば解決しました。

```
音声ファイルを48000Hz, 16bit LittleEndian, stereoに変換する方法
$ sudo apt-get install ffmpeg
$ ffmpeg -i input.wav -ar 48000 -format S16_LE -channel 2 output.wav
```

# 参考
[gx_sound_player の紹介と ROS パッケージのリリース手順](https://qiita.com/yura/items/ba622a542385cdab6692#comment-c9c198f138c7d76d2122)
[フリーWave,MP3](http://www.ne.jp/asahi/music/myuu/wave/wave.htm)
Vue x Bootstrap Vue x Netlifyでさくっと作るTrello風アプリ

#はじめに
こんにちは！
Mikatus株式会社でインフラエンジニアっぽいようなことをしている福田です。
最近フロントエンド領域に興味があり、デザインやJavaScriptの勉強をしています。
インフラネタにしようか迷ったのですが、今回はjavaScriptだけで動く簡単なアプリを作ってみました。

#開発経緯
今や知らない人は少ないかもしれませんが、Trelloというのはタスク管理ウェブアプリケーションです。
https://trello.com/home

私は業務タスクだけでなく、家事タスクもTrelloを使って管理しています。

私はTrelloにおいて、タスクがドラックアンドドロップで移動できる部分が好きなので、この部分を自分で実装してみたいと思ったのが今回Trello風アプリを作ろうと思ったきっかけです。

#こんなの作った
[Trello風アプリ](https://vigilant-wilson-35521a.netlify.com/)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531164/7ca4df27-11bc-abd4-a80b-92b1b0b5c9dd.png)
はい、名前の通りTrelloっぽいアプリです。
機能としては以下。

- リストを作成できる
- リストの中にタスクを作成できる
- タスクをドラッグアンドドロップで移動できる

コード
https://github.com/pistachiyoda/practice-trello-like-app

#使用技術
- Vue.js
- Vue.Draggable
- Bootstrap Vue
- Netlify

#致命的なバグ（実装間に合わんかった）
- リストの移動ができない
- リストの削除ができない
- タスクの削除もできない
- ブラウザをリロードしたら作ったリスト・タスクは消える
- 背景をサンタクロースから変更できない
- 空欄でもリスト・タスクが作成できちゃう（フォームバリデーション実装してない）

などなど…
目標だったドラッグアンドドロップでのタスク移動の部分は実装できた（といってもライブラリを使ってしまったので、実装できたと言っていいのかという葛藤…）のですが、細かいと部分はもっと詰めていかないといけません。
ちょっとずつ修正したり機能追加してみようと思います。

#振り返り
実際に動くものを作るのは楽しいし勉強になりますね。
flexboxやgrid systemについて復習するいい機会になりました。

アプリのデプロイが終わった後の満足感にやられて記事の執筆に全く身が入らなかったため、アウトプット前提のアプリを開発する場合は開発と執筆を並行して実施したほうがいいなと思いました。
FlaskでIP制限する

[flaskでIP制限をかける \- Qiita](https://qiita.com/takuya-andou/items/32a3002aa951b835871b)

あったけれどマスクでかける。

```py
from flask import Flask, request, abort
import ipaddress

app = Flask(__name__)


@app.route('/')
def hello_world():
    return 'Hello World!'


ALLOW_NETWORKS = ["10.0.0.0/8", "172.16.0.0/12", "192.168.0.0/16", "127.0.0.1"]


@app.before_request
def before_request():
    remote_addr = ipaddress.ip_address(request.remote_addr)
    app.logger.info(remote_addr)

    for allow_network in ALLOW_NETWORKS:
        ip_network = ipaddress.ip_network(allow_network)
        if remote_addr in ip_network:
            app.logger.info(ip_network)
            return
    return abort(403, 'access denied from your IP address')


if __name__ == '__main__':
    app.run()



```
自作アプリをFlutterで作成しCI/CDを構築するまでの道のり

# はじめに
自己紹介をします。
現在、IT企業で働く若手エンジニアです。
しかし、エンジニアと言っても、プログラムは大学で画像処理をやっていた程度のため、
システム開発などの知識はほとんどありません。
一応、この記事を読む人がいるかもしれないので、どのようなレベルかをお伝えするためにスキルについて簡単に列挙します。

- 国立大学の修士卒
- 大学時代にはC言語でopencvを主に用いて画像処理を経験
- 応用情報資格試験取得（逆にそれ以外は特になし）
- アプリ開発経験はインターンでAndroid Studioは使用したことがある程度

# 経緯
そもそも、なぜ表題のようなことを始めようかと思ったのか。
それは話すと長くなるので簡単に。
職場でもモバイル開発において、Flutterというクロスプラットフォームでの開発を行ったこと。
その際に、CI/CDの仕組みに非常に助けられたことから、それを自分でもできるようになりたいと考えました。
自分の将来のキャリア的に本当に必要になるか分からないスキルですが、鉄は熱いうちに打てということで、MacBookProを購入して開発に乗り切った次第です。

# 目的
表題にもある通り、自作のアプリを作成して、その作成の過程においてCI/CDを学んで行こうという流れになっています。
具体的なアプリの機能としては、**ラーメンレビューアプリ**を構想しています。
と言っても大勢の人で共有するのではなく、
- ラーメンを食べたらアプリを起動
- 写真をアップロード
- レビューを記載
- 「完了」したら、自分のGoogleスプレッドシートに写真とレビューと位置情報が載る
のような構想をしています。

そして、CI/CDの構想としては
- MRをあげる際にはCI(UTとE2E)が走るようにする
- MRが通った際には、Slackに通知がいく
- tagをPushするとその時点でのapk/ipaが作成される
とします。まだ具体的ではないですが、後々詰めていきましょう。

# 開発方法
Flutterの勉強として、以下の書籍を一通り勉強してからアプリの作成に移ろうと思います。
https://book.mynavi.jp/ec/products/detail/id=108125
上にアプリの機能は上げたけど、あくまで技術を学ぶために分かりやすく目標設定しているだけなので、
アプリの完成までは時間かかると思います。

### 期限感
ひとまず、一連のCI/CDができるようになるまでに３ヶ月とします。
### 使用するツール
- Flutter
- Android Studio
- Xcode
- Git Lub
- JIRA
- Slack

# 終わりに
色々な人の手や知恵を借りながら実施していきます。
仕事の合間にやるので進捗は芳しくないかもしれませんが、必ず完成まで持ってくようにします。
自分の成長日記になることを祈って、ここで締めさせていただきます。
WSLはいいですよ

#WSLはいいですよ。
正直MacBookAirを愛機に使っているのでやっぱCommandShellが恋しくなるんです。
そんな人にもってこいなのがWSLです。

##WSLってなんなの
Windows Service For LinuxのことでWindowsの中にLinuxを入れちゃうってことです。
昔はCygwinだったり重いものが多かったです。
実際に自分のMacBookAir二機にはWSLを入れてますがVMとしてはHyper-Vをいれています。
WSLでことが足りない場合にはHyper-VやVirtualBoxがいいです。

##WSLで何ができるの
WSLはWindowsにLinuxのレイヤーを入れているのでLinuxでできていることは大半できてしまいます。
テスト環境にはちょっとモノだりないですがどんな事ができるのかを試したり実験環境として使えます。

##Dockerってどお思う。
Dockerは重くなるので止めておいたほうがいいです。
インストラーも重かったです。
半泣きしました。

WindowsつかっていてLinuxが恋しくなったりMacがこいしくなったらこの手もありですよ。
VM作るのは辛いですから。
Python3のvirtualenvでrospyを使う

# はじめに
[ROS Advent Calendar 2019](https://qiita.com/advent-calendar/2019/ros) 23日目の記事です。
Python2のEOLまで残すところあと[8日](https://pythonclock.org/)になりましたが、皆様Python3への以降はお済みでしょうか。
今回、ROS1の`rospy`をPython3の`virtualenv`で実行できるようにしてみたので紹介したいと思います。

公式なROS1の `rospy` を使うためには、以下のような環境の制約があります。
　1. Ubuntuを使う
　2. ROSをインストールする
　3. システムにインストールされたPython2/ライブラリを使う

これは
　a. 既存の`pip`を使ったPythonプロジェクト(Python3)とROS1を共存させたい
　b. MacOSで`rospy`をちょっと試したい

のような場合には不便です。

解決方法として、[roslibpy](https://github.com/gramaziokohler/roslibpy)もありますが、[rosbridge](http://wiki.ros.org/rosbridge_suite)で一度通信をwebsocketでブリッジするため、通信のオーバヘッドがかなりかかります。そこで`rospy`関係のROSのコードは、Pythonのみで書かれている事を利用し、純粋なPythonのパッケージとして`rospy`をインストールできるPyPI(Python Package Index)を用意することで、Python3でも`rospy`を使えるようにしてみました。

# 使い方

以下の環境で確認しています。

* OS: Ubuntu 18.04
* Python: Python3.6.7

`virtualenv` を使う方法をサンプルで示します。ROSのインストールは不要です。
(`pipenv`等でも基本同じです)

```bash
virtualenv -p python3 venv
. ./venv/bin/activate
pip install --extra-index-url https://rospypi.github.io/simple rospy-all
```

TF2やcv_bridgeを使いたい場合は、さらに追加で

```bash
pip install --extra-index-url https://rospypi.github.io/simple cv_bridge tf2_ros
```
とするとできます。

以下のサンプルを用意し、

```talker.py
import rospy
import std_msgs.msg

rospy.init_node("talker")
pub = rospy.Publisher("chat", std_msgs.msg.String, queue_size=1)
rate = rospy.Rate(2)
while not rospy.is_shutdown():
    pub.publish("hello")
    rate.sleep()
```

```listner.py
import rospy
import std_msgs.msg

def callback(msg):
    print(msg.data)

rospy.init_node("listener")
rospy.Subscriber("chat", std_msgs.msg.String, callback)
rospy.spin()

```
rosmasterを追加でインストールします

```bash
pip install --extra-index-url https://rospypi.github.io/simple rosmaster defusedxml
```

3つの端末からそれぞれ

1. まず、rosmasterを起動します。

    ```sh
    . ./venv/bin/activate
    rosmaster --rcore
    ```
2. 次に、talkerノードを起動します。

    ```bash
    . ./venv/bin/activate
    export ROS_MASTER_URI=http://localhost:11311
    python talker.py
    ```
3. 最後に、listnerノードを起動します。

    ```bash
    . ./venv/bin/activate
    export ROS_MASTER_URI=http://localhost:11311
    python listener.py
    ```

4. 最後のlistnerノードで以下の用にSubscirbeしたトピックが表示できたら成功です。

    ```bash
    $ python listener.py
    WARNING: cannot load logging configuration file, logging is disabled
    hello
    hello
    hello
    hello
    hello
    ```

これでROSをインストールすることなく、Python3のみでROSのノードを書けるようになりました。
MacOSでも同じ事ができることを確認済みです。

# 中身について

* PyPIは静的ファイルさえホストできれば作れる([PEP53](https://www.python.org/dev/peps/pep-0503/))
* tf2_py、PyKDL、cv_bridge等のパッケージははc++のビルドが必要なPythonパッケージだがちょっと[頑張れば](https://github.com/rospypi/simple/blob/master/tf2_py/setup.py)ROSのruntimeに依存せずに実行できる

ような事をしています。

# おわりに

今回用意したPyPIは個人で趣味的に作ってみたもので、どこまでサポートできるかわからないですが、ちょっと使って見るには便利だと思うので是非試してみてください。
https://github.com/rospypi/simple

公式でだせるようにしていきたい・・・

Let's enjoy robot programming!
Drupal8で自分が作ったコンテンツを翻訳する方法

## 環境開発

## Drpal翻訳機能について
Drupalにすでにデフォルトで入っている内容、文字などは環境設定→言語より翻訳したい言語を追加し選択すればいいのですが（詳しくは先日アップした[Drupal8でコンテンツを多言語化する方法] (URL：https://qiita.com/SodaiHirano/items/69d26a256440e794541eで画像付きで)で画像付きで説明しております。),
自分が作成したコンテンツは例えばコンテンツタイプ ：お知らせのお知らせコンテンツを翻訳したい！みたいなとき。
この時は、環境設定ー＞言語を英語にしても他の言語にしてもコンテンツの内容は日本語のままなんですね。

なぜか→それは、**Drupalの言語翻訳の対象はすでにデフォルトで入っている文字だけ**だからです。
要は、**後から加えたコンテンツなどを自動で翻訳してくれるものではない**ということ。

 
## 自作コンテンツの翻訳
でも、自分で作ったコンテンツも多言語化したいですよね？
<img width="466" alt="スクリーンショット 2019-12-14 午前1.52.33.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/468686/a3f50b3f-7fb3-bfa7-9653-e997f4d54d44.png">
言語->英語にしているので、
<img width="1300" alt="スクリーンショット 2019-12-14 午前1.53.58.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/468686/48825c8c-060d-625e-16ef-e0b5dba82476.png">
ツールバーも何から何まで英語に翻訳され・・・ん？？
僕が投稿したタイトル：日本語　本文：俺も・・・　が翻訳されていないですね。
長くなりましたがこれが今回の課題です。

自分の作ったコンテンツを翻訳可能にするには、
環境設定→地域と言語（コンテンツの言語と翻訳）→コンテンツにチェックをいれる。
<img width="1456" alt="スクリーンショット 2019-12-22 午後5.30.14.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/468686/7d3d2f7a-113f-cc89-1d8f-eba1f3de496f.png">
そうすると、その下にコンテンツの翻訳を許可する範囲設定画面が出てくるので翻訳したい箇所は全てチェックを入れたままにする。
<img width="1042" alt="スクリーンショット 2019-12-22 午後5.35.37.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/468686/2b796bb4-7f8b-2a3e-01b8-438faaac4883.png">
構成を保存し、コンテンツへ。
<img width="1345" alt="スクリーンショット 2019-12-22 午後5.36.55.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/468686/5fd89f6b-1bf0-30af-27a0-36d40b423433.png">
編集ボタンの横の矢印をクリックすると、翻訳という選択が追加されています。
翻訳をクリックし、EnglihのAddをクリックし内容を英語の内容に書き換え追加します。

コンテンツが２つに増えていれば成功です！

これで、言語を切り替えると日本語の時は日本語のコンテンツに、英語の時は英語のコンテンツになっている。。。はずです！！笑
こんな感じ！
<img width="1680" alt="スクリーンショット 2019-12-22 午後5.50.43.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/468686/0c868e42-f57c-645f-5e2d-228fec27621c.png">
<img width="1680" alt="スクリーンショット 2019-12-22 午後5.50.48.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/468686/71148c5f-f5f4-efcc-5877-781fbe4e8330.png">

お読みいただきありがとうございました！
Ryzen 5 3400GマシンにHyper-V入れようとして失敗した話

# 2020/12/21 更新
2020/11/11にA300のBIOS更新がされています。これを適用することで下記の問題が解消することを確認しています。
お困りの方はアップデートをご検討ください。
[ASRock A300 BIOSページ](https://www.asrock.com/nettop/AMD/DeskMini%20A300%20Series/index.jp.asp#BIOS)

~~一年越しにようやくHyper-Vが使えるようになりました~~

## 検証環境

下記環境で、Hyper-V, VMwareを共存させた環境が動作することを確認。

 | Spec
--- | --- 
BIOS | 3.70
CPU | Ryzen 3400G
RAM | 32GB
ホストOS | Win10 Education 2004
Hyper-V ゲストOS | Win10 Pro, Ubuntu 18.04 (これらはVMDKを変換して作成した仮想マシン)
VMware Workstation Player | 15.5.5
VMware ゲストOS | CentOS 8, Windows Server 2019 Datacenter

# 以下の情報は古いです

# やろうとしたこと
Deskmini A300くんを買ってHyper-Vで遊ぼうとした
# 結論
AMDがろくなドライバを出さないので、Radeonグラフィックスドライバを入れるとHyper-Vが動かない。
回避策は、Microsoft標準ドライバでお茶を濁すか、Hyper-Vを使わないの2択。
もしくはNVidiaグラボを買う。
私はESXiを入れました。

# 詳細
## システム構成
| 部位 | |
|---|---|
| OS | Windows 10 Education 1903 |
| CPU | Ryzen 5 3400G |

`syteminfo`で、Hyper-Vの動作要件を満たしていることを確認。

## インストールしたドライババージョン
- Adrenalin 2020 Edition 19.12.3 （執筆当時最新バージョン）
- Adrenalin 2019 Edition 19.7.5 （ネットの海のどこかで「動く」と書かれていたバージョン、動かない）

## 症状
上記Radeonドライバをインストールしたのち、Hyper-Vの有効化を行い、再起動をするとWindowsの起動の「ぐるぐる」が表示されたのち、画面に何も表示されなくなる。

いずれのバージョンでも

- Windowsクリーンインストール -> Hyper-V有効化は正常動作　（MS標準ディスプレイドライバ＋Hyper-Vの組み合わせ）
- Windowsクリーンインストール -> Radeonドライバは正常動作 （Hyper-V無効でのRadeonドライバは動く）

ので、Hyper-VとRadeonドライバの相性が悪いらしい。いろいろググると、ずっと前からこの相性問題は報告されているようなのでAMDは早く修正してほしい。
SkyWayでiOS/Androidアプリを作るときの勘所

メリークリスマス :santa: （まだ早い）

# SkyWayでアプリを作ろう

iOS/AndroidのSDKが提供されているので作れはしますが、抑えるところ抑えておかないとユースケースによってはいくつか困るケースが出てきます。最近質問されたのでまとめておきます。

## 各種音声の入出力先のハンドリング

- Line
- Bluetooth
- デバイス

のハンドリングを自分でする必要があります。また抜き先に関しても同様。
iOSであれば`AVAudioSession`が握っている、Androidであれば`AudioDeviceInfo`でとれるので、必要な入力元と出力先の検知と切り替えは自前で実装しましょう。

この際にAndroidでは [isWiredHeadsetOn](https://developer.android.com/reference/android/media/AudioManager.html)のようなメソッドは非推奨。自前でハンドリングするためAudioSessionの管理には注意しましょう。

## バックグラウンドでの処理

Androidは端末によりますが、iOSでは`UIBackgroundModes - audio`を許可してください。
バックグラウンドへの遷移時はどちらもカメラは無効になるためremoteへは黒い画面が表示されます。
上記設定をしておけば音声はつなぎ続けることができます。

## エラーハンドリング

https://webrtc.ecl.ntt.com/en/ios-reference/a00053_source.html

```swift
     SKW_PEER_ERR_NO_ERROR = 0,
     SKW_PEER_ERR_BROWSER_INCOMPATIBLE = -1,
     SKW_PEER_ERR_DISCONNECTED = -2,
     SKW_PEER_ERR_INVALID_ID = -3,
     SKW_PEER_ERR_INVALID_KEY = -4,
     SKW_PEER_ERR_NETWORK = -5,
     SKW_PEER_ERR_PEER_UNAVAILABLE = -6,
     SKW_PEER_ERR_SSL_UNAVAILABLE = -7,
     SKW_PEER_ERR_SERVER_ERROR = -8,
     SKW_PEER_ERR_SOCKET_ERROR = -9,
     SKW_PEER_ERR_SOCKET_CLOSED = -10,
     SKW_PEER_ERR_UNAVAILABLE_ID = -11,
     SKW_PEER_ERR_AUTHENTICATION = -12,
     SKW_PEER_ERR_WEBRTC = -20,
     SKW_PEER_ERR_ROOM_ERROR = -30,
     SKW_PEER_ERR_UNKNOWN = - 9999,
```

Peerイベントだけでもこれだけあり、なおかつ頻度としてもwarningレベルでリトライすればいいケースも多いです。websocketが動く関係上、リトライの概念は必須ですがユースケースによるので最初はエラーきたらとりあえずリトライかけておきましょう。

フロントのエラーイベントは運用上解析のために保存しておきたいですが、このエラーは結構な頻度で投げられてしまうので、何も考えずにストアしていくとだいぶなボリュームになるので注意。

## ネットワークの切断・切り替え

これはちょっと調べきれてないですが、接続時間とかが課金系と関わるユースケースなら考慮が必要で、wifi/3Gの切り替えみたいのが起きるケースは自分でハンドリングするのがベターです。

両OSでそれぞれ接続が3GかWifiかくらいはとれるので、自前でやること。

## 相手のストリームを確認してカメラかどうか見る

これはAPIがないので、自前でやるのが良いです。
真っ黒になるのでpixelを見ましょう。

## サポートデバイス

どうしても限界はあります。iOSでは問題ないですが、やはりAndroidでよくわからない動きをすることがあり・・・全部の網羅は厳しいかと思います。AndroidだとCベースでのライブラリ(*.so)を乗せる必要がありABIやCPUアーキテクチャに突っ込む必要があったりします。
CPUアーキテクチャは[スマタブ](http://smatabinfo.jp/)等で確認することができます。
まぁ全体の90%くらいは大丈夫な印象です。最新版のSDKのサポートは5系以上です。

## 電池と通信量

これはもう食います。なおかつ通信方式(p2p, sft)にも依存するし、そもそも並行して何を立ち上げているかなどなど、外部要因が多いので明記しないほうが良いと思います。

callOptionで帯域指定だけでも入れておきましょう。

# まとめ

マジですぐ作れるけど、マジで安定運用まではWebRTCといろんなユースケースと向き合う必要があるので気合い入れていこうな。
【MySQL】エイリアスを使える句について

[MySQL Advent Calendar 2019](https://qiita.com/advent-calendar/2019/mysql)の20日目エントリです。

枠が空いていたので、遅ばせながら参加させていただきました。

記事に特別感は全くありません。
エイリアスの動作について、最近の気づきをまとめました。

# テスト用テーブルの準備

テーブルを用意します。

```sql
CREATE TABLE sales(
    id INT NOT NULL PRIMARY KEY AUTO_INCREMENT,
    sales_date DATETIME,
    price INT
);
```

適当にレコードをセットします。

```sql
mysql> SELECT * FROM sales;
+----+---------------------+-------+
| id | sales_date          | price |
+----+---------------------+-------+
|  1 | 2019-10-01 00:00:00 |   100 |
|  2 | 2019-10-05 00:00:00 |   300 |
|  3 | 2019-11-01 00:00:00 |   200 |
|  4 | 2019-11-20 00:00:00 |   100 |
|  5 | 2019-12-01 00:00:00 |   500 |
+----+---------------------+-------+
5 rows in set (0.00 sec)
```

# 句の中でエイリアスを使う

試しに``GROUP BY句``の中でエイリアスを使ってみます。

```sql
SELECT
    DATE_FORMAT(sales_date, '%Y%m') AS sales_month,
    COUNT(id) AS sales_count
FROM
    sales
GROUP BY
    sales_month
```

グループ化がされ、正しく反映されました。

```sql
+-------------+-------------+
| sales_month | sales_count |
+-------------+-------------+
| 201910      |           2 |
| 201911      |           2 |
| 201912      |           1 |
+-------------+-------------+
```

## カラム名との重複に注意

エイリアスとカラム名(sales_date)が重複していると、GROUP BY句の中では``sales_dateカラム``の方が優先されてしまいます。

```sql
SELECT
    DATE_FORMAT(sales_date, '%Y%m') AS sales_date,
    COUNT(id) AS sales_count
FROM
    sales
GROUP BY
    sales_date
```

エイリアスではなく``sales_date``としてグループ化されてしまい、期待する結果が得られませんでした。

```sql
+------------+-------------+
| sales_date | sales_count |
+------------+-------------+
| 201910     |           1 |
| 201910     |           1 |
| 201911     |           1 |
| 201911     |           1 |
| 201912     |           1 |
+------------+-------------+
```

# エイリアスが使える句

はじめ、評価順は``SELECT``の方が``GROUP BY``より後なので、句の中でエイリアスは使えないと思っていました。
[SELECT文の評価順序の話](https://qiita.com/suzukito/items/edcd00e680186f2930a8)

他には、``ORDER BY句``や``HAVING句``の中でエイリアスが使えます。
[B.5.5.4 カラムエイリアスに関する問題](https://dev.mysql.com/doc/refman/5.6/ja/problems-with-alias.html)

```sql
SELECT
    DATE_FORMAT(sales_date, '%Y%m') AS sales_month,
    COUNT(id) AS sales_count,
    SUM(price) AS sales_price
FROM
    sales
GROUP BY
    sales_month
HAVING
    sales_month > '201910'
ORDER BY
    sales_month
DESC
```

```sql
+-------------+-------------+-------------+
| sales_month | sales_count | sales_price |
+-------------+-------------+-------------+
| 201912      |           1 |         500 |
| 201911      |           2 |         300 |
+-------------+-------------+-------------+
```

この動作はMySQLの``拡張機能``だそうです。
他のDBMSにおける挙動は、各リファレンスを参照しなければ分かりません。
[ORDER BY句で別名が使えてGROUP BY句では別名が使えない理由](https://muroiwataru.net/entry/sql-order-by)

ただし、標準SQLによると``WHERE句``ではエイリアスを使えないとのことです。

お読みいただきありがとうございました。
良いクリスマスを！
Backlog APIで課題一覧を取得してみた。

# 1. 経緯
Backlogを使ってチームごとでプロジェクトを進めているのですが、それぞれのチームの課題一覧と課題状況を表示するものが欲しかったので製作してみました。

# 2. Backlog APIとは
BacklogにはAPIが公開されており、Backlog API上でできることはAPIで大体行うことができます。
Backlog APIでできることは以下をご覧ください。
[https://developer.nulab.com/ja/docs/backlog/#backlog-api-%E3%81%A8%E3%81%AF](https://developer.nulab.com/ja/docs/backlog/#backlog-api-%E3%81%A8%E3%81%AF)

# 2. 開発環境
HTML, CSS, JSで開発しました。
特にインストールしたりするものはありません。

# 3. APIキーの登録
Backlog APIを使うためにAPIキーを登録しておきます。
[http://www.backlog.jp/help/usersguide/personal-settings/userguide2378.html](http://www.backlog.jp/help/usersguide/personal-settings/userguide2378.html)

# 4. JavaScriptでAPIを呼び出す
JavaScriptでAPIの呼び出しを行います。
今回はXMLHttpRequestを使って呼び出しを行いました。
## 4-1. APIキーを付加して認証する
Backlog APIの認証は簡単です。
先ほど取得したAPIキーをリクエストするURLのパラメータに付加するだけ。

```リクエストするURL例
https://xx.backlog.jp/api/v2/users/myself?apiKey="発行されたapiキー"
```
## 4-2. 子課題一覧を取得する
Backlog APIを使用して親課題の子課題を取得します。
子課題はパラメータ名 parentIssueId[] に親のIDを入れることで取得できます。

```子課題取得
https://xx.backlog.jp/api/v2/issues?apiKey="発行されたapiキー"&parentIssueId[]="親のID"
```

## 4-3. 課題の表示
あとは取得した子課題から欲しい情報を表示するだけです。
![showTask.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/555367/68767225-7e69-2954-c279-9a0bcd011279.png)
node/js向け husky使ってpush前にテストするを共有する

テストや静的コード解析実行前にうっかりpushしてしまう事はないでしょうか？

有意義レビューの為にも事前にテストを実行し、リモートにはテスト通ったコードしか置かないようにしたいですね。

[githooksのpre-push](https://git-scm.com/docs/githooks#_pre_push)を利用したpush前に必ずテストし、失敗したコードはpushできない状態を作る事ができます。

## githooksのpre-pushを利用したpush前テスト

`.git/hooks/pre-push` に実行したいコマンドを書きます。 `pre-push` は `git push` の前に実行されるフックです。

ほとんどのテストコマンドは、すべて通った場合に終了コード `0` を、失敗した場合に `1` などの0以外を返すようになっています。

`0` の場合にのみ `git push` が実行できるようになります。

```
$ cp .git/hooks/pre-push.sample .git/hooks/pre-push
$ chmod +x .git/hooks/pre-push
```

```[.git/hooks/pre-push]
#!/bin/sh

yarn test
```

ただ、この方法ではプロジェクトメンバーへの共有が難しくなります。テンプレ作って `pre-push` 書き換えてと案内するのは面倒ですね。

## husky使ったpush前テスト

[husky](https://github.com/typicode/husky) をinstallして `package.json` にpush前に実行したいコマンドを書くだけです。(`.huskyrc` を用意しても良いです)

```
$ yarn add --dev husky
```

`pre-commit` などのhookも用意されています。コミット単位でテストするのは非効率なので `pre-push` を使います。

```package.json
{
  ...
  "husky": {
    "hooks": {
      "pre-push": "yarn test"
    }
  },
  "devDependencies": {
    "husky": "^3.1.0"
  }
}
```

push時に自動でテストが走り、失敗するとpushできないようになりました。

```
$ git push

husky > pre-push (node v10.14.1)
yarn run v1.17.3
$ yarn test
...
error Command failed with exit code 1.
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.
husky > pre-push hook failed (add --no-verify to bypass)
```

## プロジェクトメンバーはパッケージインストール時にpre-pushが書き換わる

clone時のhooksは何も登録されていないsample状態ですが、

```
$ git clone xxxxx
$ ls .git/hooks
applypatch-msg.sample     fsmonitor-watchman.sample pre-applypatch.sample     pre-push.sample           pre-receive.sample        update.sample
commit-msg.sample         post-update.sample        pre-commit.sample         pre-rebase.sample         prepare-commit-msg.sample
```

パッケージインストール後に書き換えてくれます。

```
$ yarn
yarn install v1.21.1
[1/4] 🔍  Resolving packages...
[2/4] 🚚  Fetching packages...
[3/4] 🔗  Linking dependencies...
[4/4] 🔨  Building fresh packages...
✨  Done in 2.29s.

$ ls .git/hooks
applypatch-msg            fsmonitor-watchman.sample post-merge                post-update.sample        pre-commit                pre-push.sample           pre-receive.sample        sendemail-validate
applypatch-msg.sample     post-applypatch           post-receive              pre-applypatch            pre-commit.sample         pre-rebase                prepare-commit-msg        update
commit-msg                post-checkout             post-rewrite              pre-applypatch.sample     pre-merge-commit          pre-rebase.sample         prepare-commit-msg.sample update.sample
commit-msg.sample         post-commit               post-update               pre-auto-gc               pre-push                  pre-receive               push-to-checkout
```

## まとめ

必ず実行するであろうパッケージインストール後に書き換えてくれるので勝手に共有できるのは良いですね。

githooks管理ツールは他にも[pre-commit](https://github.com/pre-commit/pre-commit)や[overcommit](https://github.com/sds/overcommit)などがありますが、 `husky` はシンプルで良い感じです。
OracleCodeOne報告会に参加してみた

#導入

#Glaal VMパーフェクト入門
##Glaal VMとは
ユニバーサルVM
Glaal VMとはOracle Labsが開発中である、あらゆる言語の実行環境となれる夢の環境（になる予定）
例）Javaとpythonを同じ実行環境で実行可能

##demo
###JavaScriptをGlaal VMで実行してみる
oracle cloudにて実行
/binの中に多数の言語の実行コマンドがある

##メリット
パフォーマンスを劣化させることなく、言語間の相互呼び出しができる

##ビジョン
言語間の抽象化をする

##支援ツール
-chrome Devtools
debugしてくれる
--inspect(?)オプションをつけるとURLを出力し、アクセスするとデバッグツールが起動
-Graal VisualVM

##導入事例
###ゴールドマンサックスの事例
独自に開発した言語をtruffleベースに移行
増え続けるコードに対して、保守コストが増加
導入により、言語の相互利用等が可能になり、コストを抑えられた

##究極目標
オレオレ言語を実行できる

##ネイティブイメージ
###ネイティブイメージとは

###なんの関連が、、、？
oracle databaseが関連してくる
oracle databaseではユーザー定義関数をJavaで実装できる
しかし、oracle database内でJDK/JREをのもと実行しなくちゃいけない
そこで、VMをdatabase内でもつ
しかし、database内でJDK等を持つと、databaseの起動時間が初期化等で増える
そこで、ネイティブイメージをdatabaseで持つことにより、初期化時間を削減
###ネイティブイメージのメリット
起動時間が短い
メモリ使用量がすくない
IOS上で実行できる
Lamda等の起動してすぐ終了もの
クラウド実行するものはメモリ削減により、コスト低下

###demo
既存のJVMでの起動（java *.jar）
およそ起動に1秒
ネイティブイメージ
約0.1秒

###チューニングで使えるところ
初期化に時間を要するクラスがある場合は、ビルド時に初期化するオプションを使用すれば、時間を削減できる

###注意
exprimental
まだproductionでは使用しちゃいけない

###目標
AOTでもJITと同様のパフォーマンス（ピーク時も）を出す
→JITいらなくなるんでは？


##まとめ
Graal VMの二つのモード
・JITモード
・AOTモード

##質問
言語間の変換をするとき、型の変換をどうするか。
→ドキュメントなし。分かりません、、、
　とにかくドキュメントが少なく、手探りの状況

#Getting　Started IOT
yamamoto yusukeさん
Javaと物理世界の橋渡し

##やりたいこと
既存のロボットに自由な動きをさせる
rego mind storm


##demo
チェスとぼっとをJavaで操作

##ラズパイの特徴
めっちゃ電力くう
高度なOSのため、容易に電源を落とせない
→そのため、ラズパイ+Javaは容易ではない

##Arduinoをせんたく
電池でも何日/何か月と持つ電力消費
協力なライブラリ

1.回路をつくる
2.プログラミング
　Ardiuno languageを使用（専用のIDE）
3.コンパイル→転送
4.実行
　転送が終わったら勝手に実行

##demo
指定した動きでLEDやモーターを動かせる

##ここでようやくJava
firmata4j(mavenで提供)を使用する

#Azure Spring Cloud
寺田さん

#監視

##監視は何から考える？
ツール？
アラート？
→監視対象から考える

##監視フロー
監視：今何が起きているか
アラート：今と近い将来に問題がないか
解決：過去に何がおきたか
発見：ビジネス上役立つもの

例）スピードメータ
これは時系列ごとに表示されておらず、今の速度しか表示されていない
→今しか必要ないから

100kmを超えると音が鳴る
→みんな無視するし、その音で眠気を誘ってしまう
→柔軟性のないアラートは無視される

ドライブレコーダー
→トラブルシューティングのための存在

分析
→事故の傾向を探ることで、事故を起こす人の傾向を発見することができる

二つの取り方
サンプリングベース
一定時間ごとにメトリクス収集する
イベントドリブン
GCなど、イベントの発生を検知して、メトリクス収集する

メトリクス収集

##監視対象の選定
なんでもかんでも監視すればよいというわけではない
最も重要なのを意識する（ユーザーへのレスポンス速度やリクエスト数）
そして、リクエスト数も上限だけでなく、下限も見る（そもそも障害でアクセスできないケースもあるため）

##マイクロサービス化による監視影響
モノリシックなサービスでは、エラーが発生したスレッドナンバーでgrepすれば調査できる
しかし、マイクロサービスではこれでは追えない
→そこで、spring cloud sleuth/Elastic APMなど
これらは、リクエストごとに、各マイクロサービスで共通のIDを振ってくれる
調査時はこのIDを元に調査を実施する

##アラート
予測できる問題しかアラートは上げられない
→でも求められるのは未知の問題
→ここで逆アプローチ
既知のログをフィルタリングで消していく
残ったログは未知のものであり、これは未知の問題につながるもの

##KPI
事象発生から解決までの各種数値も収集する
アラート発生までの時間
メンバーが検知するまでの時間