OmniAICreator/Qiita-1.07M huggingface dataset:
焦燥感にかられた三十路エンジニアが勢いでやったこと一覧

##経緯
のんびりとレガシーな環境で開発してきたweb系エンジニアが三十路になり、自分のキャリアつについていろいろと焦りだしました。
とりあえず、やってみたことをつらつらと書き連ねます。
自分の備忘録が目的ですが、同じように焦ってる人たちに参考になれば嬉しいです。

##Podcastを聞くようにした
一流エンジニアと呼ばれている人たちがなにを考えているのか、どう思っているのかを配信してくれている。無料で全部聴けるのは素晴らしい。わからない単語を調べるだけでも勉強になる。Rebuild.fmは神。
・Rebuild.fm
・PHPの現場
・のぼりーさんのクラウドインフラPodcast
・しがないラジオ

##勉強会へ参加してみた
ハンズオンの勉強会は簡単すぎたり、meetupは内容が難しすぎたりして自分に丁度よいのが見当たらなかった。
明確に参加したいものがない限りは優先度は下げようと思う。

##Rails Turtorialをやってみた
転職の求人とかをみると、Ruby on Railsで開発してるweb系企業の多さに唖然。
とりあえず触っておこうの精神ではじめてみた。
コマンド一発で画面からテーブルまで構築できるという爽快感を味わえた。
Railsだけではなく、GitやHerokuなどの周辺ツールの使い方もハンズオン形式で取り組めるため、まともにフレームワークとか触ってこなかった人はやってみるといいかもしれない。

##読書
読書は裏切らない。
読んで一つでもためになったと思えるところがあれば、その本を読んだ価値はある。

以下、読んだ本一覧。

####■このまま今の会社にいていいのか？　転職の思考法
技術書ではないけど、いい本だったので紹介。
やりたいことがある人間なんて一握りしかない。ほとんどの人間はどうありたいかが大事。
これを知れただけでもすごくよかった。

###■カイゼン・ジャーニー
今の現場に不満があるエンジニアが自分からチームをかえていくお話。
スクラムやカンバンの話がでてくる。ストーリーの展開が熱い。

###■入門UNIXシェルプログラミング
良書。シェルスクリプトを作るときの教科書。
標準入力とか標準出力、ファイルディスクリプタ、オプション実装まですごくわかりやすい。

###■なるほどUnixプロセス ― Rubyで学ぶUnixの基礎
良書。プロセスについて一通り学べる。デーモンとかプロセスの親子関係とか。
Rubyを扱い出したらもう一回読み直す。

###■7つのデーベース 7つの世界
NoSQLをツアー形式で学べる。
NoSQLを扱ったことがないことに危機感があるなら、これをベースに勉強してみて。

###■マスタリング TCP/IP
良書。豊富な図。わかりやすい説明。ネットワーク周りはこれと3分間ネットワーク基礎講座があればよさそう。

###■3分間ネットワーク 基礎講座
博士と助手のストーリー形式でネットワークを短い講座ごとに学べる。ネットワーク周りの導入はこれで十分。

###■暗号化技術入門
良書。公開鍵、秘密鍵、SSL/TLSについて自信がないなら読んでおけばいい。

###■プログラマのための文字コード技術入門
巷では良書とされている。余裕がなかったのかあまり頭に入ってこなかった。
余裕があれば読みなおすかもしれないけど、優先度は低い。

###■わかばちゃんと学ぶ Git使い方入門
恥ずかしながらGitを理解できていないので読んだ。
pull requestしたときは嬉しかった。業務でも使いたい。。。

###■実用Git
概念説明のところはあまりよくわからなかったのでネットで補完しながら読んだ。
ネットだと、
https://made.livesense.co.jp/entry/2017/08/22/080000
http://keijinsonyaban.blogspot.com/2011/05/git.html#ct3_1
がおすすめ。

###■Web API The Good Parts
web APIの教科書。体系的に学べる一冊となっている。
OAuthについても言及されている。

###■「仮想化」実装の基礎知識
Dockerの前にコンテナ技術を知る必要があるが、その前に仮想化を知る必要がある。
仮想化についての本はあまりなかったが、広く浅く知るにはこれで良いのかも知れない。
仮想化の種類すらちゃんと知らなかったので、とりあえずはこれで知ったかはできそう。
コンテナを知りたいならこっちも使える。
https://employment.en-japan.com/engineerhub/entry/2019/02/05/103000

###■エンジニアのためのマネジメントキャリアパス
キャリアパスの道しるべになるかと思い読んだ。
あくまでそのキャリアで悩んでる人たちに向けたメッセージだった。
テックリードについて言及されていたのが前半で終了していたので、
後半は今度読み返す予定。優先度は低い。

###■Java言語で学ぶデザインパターン入門
良書。デザインパターンは美しい。自分がなんとなく実装しているパターンが言語化されるのは気持ちいい。
※PHPのこっちもすごくわかりやすい。
http://shimooka.hateblo.jp/entry/20141211/1418298136

###■UNIXという考え方
パケ買い。できるだけ早く作ってすぐ直す、がかっこよかった。
1つのプログラムに機能を詰め込まないこと。機能は小さく作る。
単一責任の法則に通ずるものがある一冊。

###■リーダブルコード
言わずもがな。あくまで文章として書き方にこだわってる。
デザインパターンのほうが読んでて面白い。

###■数学文章作法
良書。文章を書くのが少し楽しくなる。
メールのレベルが上がった気がする。

###■ビッグデータを支える技術
タイトルの通り。一連の技術が章立てて紹介されており、わかりやすい。
溜まったデータが可視化できるようになるまでのフローを追えるようになる。

###■webを支える技術
webの発展を歴史的に理解できる。SOAPとwebAPIの対立も書かれており面白い。
へーなるほど。という感じ。

###■プログラマが知るべき97のこと
一流の考えは知っておいて損はない。
「コーディングの後でやろうはやってこない」は印象的。
できることが増えたら定期的に読み返したい一冊。

##以上
焦燥感が終わるまでずっと何かをやり続けると思う。
本の感想は継続的にアウトプットする。

###次やろうと思っていること、
・関数型言語の勉強
　→関数型を理解することがプログラムを理解することの第一歩らしい
・Docker/Goでマイクロサービス化したwebアプリケーションを作成すること
　→流行りの技術で流行りのことをやる。
・目標となる人をみつける
　→自伝とか読んでみる
C++でメンバー関数を、thisを第１引数にとる関数ポインタに変換する


* 2019/08/07 コメントを反映しておされになった

# 本文
vc2019で実験。

* 非型テンプレートパラメータのauto宣言(関数ポインタをtemplate引数にする)　`c++17`
* local class `c++11`
* valiadic template `c++11`
* [ラムダ式と単項+演算子](https://onihusube.hatenablog.com/entry/2019/04/19/204552) `c++ ?` `unary + operator`

```c++
#include <iostream>

namespace {

template <auto M, // R (C::*M)(ARGS...) なのだがautoでないとARGS...があって指定することができない
typename R, typename C, typename... ARGS>
constexpr auto _OpenMethod(R (C::*m)(ARGS...))
{
#if false
    struct inner // local class
    {
        static R call(C *self, ARGS... args)
        {
            return (self->*M)(args...);
        }
    };
    return &inner::call; // static関数なので普通の関数ポインタ
#else
    // コメントで教えてもらった方法でアップグレード
    return +[](C *self, ARGS... args){ return (self->*M)(args...); };
#endif
}

template <auto M>
constexpr auto OpenMethod()
{
    return _OpenMethod<M>(M);
}

}

struct Some
{
    int Value = 0;

    int Plus(int n)
    {
        Value += n;
        return Value;
    }
};

int main()
{
    constexpr auto f = OpenMethod<&Some::Plus>();
    std::cout << typeid(f).name() << std::endl;
    // int (__cdecl*)(struct Some * __ptr64,int)

    Some some;
    some.Plus(1);

    auto result = f(&some, 2);
    std::cout << result << std::endl;
    // 3

    return 0;
}
```

実用的に使うべく、
MsgPack-RPC の関数登録や、Lua の関数登録に応用できないか試行錯誤しているところでございます。


最近の C++ 知らない間に強まっている・・・
Dockerを使ってKali Linuxの環境を構築した時のメモ

# はじめに

Dockerを使ってKali Linuxの環境を構築した時のメモ

# 実行環境

* MacBook Air (Retina, 13-inch, 2018)
* macOS Mojave バージョン10.14.5
* Docker version 18.09.2, build 6247962

# 環境構築

## Kali Linuxの公式イメージダウンロード

```docker

$ docker pull kalilinux/kali-linux-docker

Using default tag: latest
latest: Pulling from kalilinux/kali-linux-docker
014a6d74f96c: Pull complete 
9febb14563a0: Pull complete 
c38f04972c6b: Pull complete 
9d39d049d5d0: Pull complete 
4e80058918bf: Pull complete 
ccd85f0810ad: Pull complete 
6ab25bddb799: Pull complete 
789ba1ebcb41: Pull complete 
524584107b55: Pull complete 
40a1af1b9680: Pull complete 
fb6edc730b9f: Pull complete 
270f87c17cf3: Pull complete 
8159e4fffac9: Pull complete 
01d3dc4e9fe9: Pull complete 
a386beee6e20: Pull complete 
46fa80bd0f33: Pull complete 
2d3ff71a091d: Pull complete 
6f41a333af7c: Pull complete 
Digest: sha256:7f1253cba663662d78c121369e23d6c0b58b7b95de268886ecfdb73b003a3bd8
Status: Downloaded newer image for kalilinux/kali-linux-docker:latest
```

## イメージの確認
```docker
$ docker image ls

REPOSITORY                                      TAG                 IMAGE ID            CREATED             SIZE
kalilinux/kali-linux-docker                     latest              f26f3ae90aee        9 months ago        1.57GB
```

## コンテナをデタッチドモードで起動（起動後標準出力をアタッチしない）
```docker
$ docker run -itd --rm kalilinux/kali-linux-docker
KALI_LINUX_CONTAINER_ID # 実行時に出力されるコンテナID
```

## コンテナ内のシェルを起動
```docker
$ docker exec -it KALI_LINUX_CONTAINER_ID /bin/bash
```

## Kali Linuxのフルパッケージインストール
※２時間ぐらいかかりました。。。

```
# apt-get install -y kali-linux-full
# exit
```

## フルパッケージのコンテナをイメージとして保存
```docker
$ docker commit KALI_LINUX_CONTAINER_ID my-kali
```

## 元にしたコンテナを停止
```docker
$ docker container stop KALI_LINUX_CONTAINER_ID
```

## Kali Linuxのコンテナに接続
```docker
$ docker run -it --rm my-kali

# Kali Linuxの標準出力
root@e24afbf65240:/#
root@e24afbf65240:/# exit
exit
# exitで元のコマンドラインに操作が戻る
```

## おまけ〜「kali」コマンドで簡単に起動できるようにする〜
```bash
$ echo "alias kali='docker run -it --rm my-kali /bin/bash'" >> ~/.bash_profile
$ source ~/.bash_profile
$ kali
root@e24afbf65240:/#
```

# おわりに
「サイバーセキュリティレッドチーム実践ガイド」の書籍を買って、さっそくKali Linux環境を作ろうと思いました。
いらなくなった時にすぐ捨てられるよう、今回はDockerで構築してみました。
あとは、いろいろ使って問題がありそうな点が見つかったら適宜記事を更新していきたいと思います。

# 参考
https://www.kali.org/news/official-kali-linux-docker-images/
Minimum set up for building React using ES7 features

# Set up

```
% vim .babelrc
% cat .babelrc
{
  "presets": [
    "@babel/react"
  ]
}
% npm init -y
% npm i -D @babel/core @babel/cli @babel/preset-react
```

# Versions

```
% npm --version
6.4.1
% cat package.json
{
  "name": "fe",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "@babel/cli": "^7.5.5",
    "@babel/core": "^7.5.5",
    "@babel/preset-react": "^7.0.0"
  }
}
```

# Compile

Compile JSX files in `js/` into `gen/`

`npx babel --watch js --out-dir gen`

# Demo

We can use async/await.

```jsx:js/demo.js
function Root(props) {
  return <h1>{props.data}</h1>;
}

function sleep(ms) {
  return new Promise(resolve => setTimeout(resolve, ms));
}

async function setUp() {
  const domContainer = document.querySelector('#root');
  await sleep(1000);
  const data = "Hello";
  ReactDOM.render(<Root data={data} />, domContainer);
}

setUp();
```

```html:index.html
<!-- crossorigin is recommended. https://reactjs.org/docs/cdn-links.html -->
<script crossorigin src="https://unpkg.com/react@16/umd/react.production.min.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.production.min.js"></script>

<div id="root"></div>

<!-- Load our React component. -->
<script src="gen/demo.js"></script>
```
なるはや Vue SPA入門：Vuex ファイル分割

Vue CLI3 で作成した SPA（Single Page Application）プロジェクト上で、段階的に Vue.js を学んで行きましょう。

[目次はこちら](https://qiita.com/tsubo/items/24df49ef2f1ba87984d1)

今回は Vuex ファイル分割編です。

## 前提事項

[Vuex モジュール編](https://qiita.com/tsubo/items/be12451533db74428d95) が完了していること。 

## Vuex ファイル分割

前回、`store.js` 内に複数のモジュールを作成しました。しかし、ある程度の規模のアプリケーションになると、モジュールが多数必要になり、`store.js` が肥大化してしまいます。そこで、store.js を複数のファイルに分割してみたいと思います。

以下のファイル構成に分割します。

```
src
├── store
│   └── modules
│       ├── counter.js
│       └── todolist
│           ├── actions.js
│           ├── getters.js
│           ├── index.js
│           └── mutations.js
└── store.js
```

`store.js` 内に記述していた、`counter` モジュールと `todoList` モジュールを別ファイルに切り出します。さらに `todoList` は `index.js`, `getter.js`, `mutations.js`, `actions.js` といった単位に細分化することにします。

```js:store.js
import Vue from 'vue'
import Vuex from 'vuex'
import counter from './store/modules/counter'
import todoList from './store/modules/todolist'

Vue.use(Vuex)

export default new Vuex.Store({
  modules: {
    counter: counter,
    todoList: todoList,
  },
})
```

```js:store/modules/counter.js
export default {
  namespaced: true,

  state: {
    count: 0,
  },
  getters: {
    double(state) {
      return state.count * 2
    },
  },
  mutations: {
    increment(state) {
      state.count++
    },
    decrement(state) {
      state.count--
    },
  },
  actions: {
    increment({ commit }) {
      commit('increment')
    },
    decrement({ commit }) {
      commit('decrement')
    },
  },
}
```

```js:store/modules/todolist/index.js
import getters from './getters'
import mutations from './mutations'
import actions from './actions'

export default {
  namespaced: true,

  state: {
    todos: [],
  },
  getters,
  mutations,
  actions,
}
```

```js:store/modules/todolist/getters.js
export default {
  todos(state) {
    return state.todos
  },
  nextId(state) {
    if (state.todos.length) {
      return Math.max(...state.todos.map(todo => todo.id)) + 1
    }
    return 1
  },
}
```

```js:store/modules/todolist/mutations.js
export default {
  todos(state, todos) {
    state.todos = todos
  },
  remove(state, idToRemove) {
    state.todos = state.todos.filter(todo => {
      return todo.id !== idToRemove
    })
  },
  add(state, todo) {
    state.todos.push(todo)
  },
}
```

```js:store/modules/todolist/actions.js
export default {
  getTodos({ commit }) {
    fetch('http://localhost:8080/todos.json')
      .then(response => response.json())
      .then(json => {
        console.log(json)
        commit('todos', json.todos)
      })
      .catch(error => console.error('Error:', error))
  },
  add({ commit, getters }, text) {
    const trimedText = text.trim()
    if (trimedText) {
      commit('add', {
        id: getters.nextId,
        text: trimedText,
      })
    }
  },
}

```

## 動作確認

カウンター、TODO リストともに以前と同様に動くか確認してください。

## まとめ

今回で「なるはや Vue SPA 入門」は終了となります。

シンプルな例で、Vue.js の基本を体験できるようにしたつもりです。実際のアプリケーション開発では、バリデーションだったり、API の認証やエラーハンドリング、データの永続化等、もっと細部を作り込む必要があるとは思いますが、ここから先は実際にご自身でアプリケーションを作りながら、調べながら更に前に進んでいってください。
TerraformからServerless Frameworkで作ったAPIを参照する

# はじめに
開発にあたり、インフラはTerraform、バックエンドはServerless Frameworkで作りたかったので、
それぞれをどのように定義するといい感じに参照できるか検討したので備忘メモ✍️

# 考え方
- CloudFront -> API Gateway -> Lambdaでバックエンド処理をしたい
    - `/api` 配下に来たリクエストをAPI Gatewayへ流す
- CloudFront -> S3で静的コンテンツを配信したい
    - 上記にマッチしなかったリクエストをS3へ流す
- インフラとバックエンドは別々に管理したい
    - CloudFrontl、S3はインフラ（Terraform）
    - API GatewayとLambdaはバックエンド（Serverless Framework）

# 方法
Serverless Frameworkは、 `sls deploy` すると裏でCloudFormationのスタックを作成するので、
Terraformから[aws_cloudformation_stack](https://www.terraform.io/docs/providers/aws/d/cloudformation_stack.html)として参照します

```yaml:serverless.yml（抜粋）
service:
  name: example-backend

provider:
  name: aws
  runtime: nodejs10.x
  stage: ${opt:stage, self:custom.defaultStage}
  region: ap-northeast-1
  # リージョナルのAPI Gatewayを作成
  endpointType: REGIONAL

  # Lambdaで使うRoleはこちらで作る。ActionやResourceは適宜設定
  iamRoleStatements:
    - Effect: Allow
      Action:
        - secretsmanager:GetSecretValue
      Resource: "*"

functions:
  example:
    handler: src/example.lambdaHandler
    # これだけでLambda Proxy統合のAPI Gatewayができる
    events:
      - http: POST api/example

custom:
  defaultStage: prod
```

`ServiceEndpoint` というキーの値が使えそう

![スタック](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/106259/c7988d31-b8c9-4d07-a2aa-9f64fd4bc1fd.png)

Terraformは以下のような感じ（ほぼ省略ですが...）
実際はスタック名はvarで注入するなどしてください

```hcl:terraform.tf（抜粋）
data "aws_cloudformation_stack" "backend" {
  # これでCloudFormationの出力が参照できる
  name = "example-backend-prod"
}

resource "aws_cloudfront_distribution" "infra" {

  # 省略

  # API Gatewayのオリジンを作る
  origin {
    # ServiceEndpointから xxx.execute-api.ap-northeast-1.amazonaws.com と prod を抜き出す
    domain_name = "${split("/", data.aws_cloudformation_stack.backend.outputs["ServiceEndpoint"])[2]}"
    origin_path = "/${split("/", data.aws_cloudformation_stack.backend.outputs["ServiceEndpoint"])[3]}"

    # 省略
  }

  # S3のオリジンを作る
  origin {
    # 省略
  }

  # API Gatewayの定義 
  ordered_cache_behavior {
    # Serverless Frameworkで指定したのと合わせる
    path_pattern     = "/api/*"

    # 省略
  }

  # こっちでS3を定義。/api/*にマッチしないリクエストを扱う
  default_cache_behavior {
    # 省略
  }

}
```
Donkey Car 環境を Linux 上に構築 (Docker, Nvidia-GPU)

Donkey Car のコードを実機ではなくて動作させたいので Docker 上で利用できるようにしておきたいと思います。
導入手順と同じになりますが donkey リポジトリからコードをクローンします。

```
git clone https://github.com/autorope/donkeycar.git
cd donkeycar
```

* 今回は手持ちのノートパソコンに Nvidia MX150 が載っているので一応GPU利用できるように Nvidia-docker 環境を構築済みであると想定しています。

Dockerfileのベースイメージを修正し、pipで導入するファイルセットを tf_gpu に変更しています。

```Dockerfile
diff --git a/Dockerfile b/Dockerfile
index 42d0f25..7fe7ae5 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -1,11 +1,12 @@
-FROM python:3.6
+#FROM python:3.6
+FROM tensorflow/tensorflow:latest-gpu-py3
 
 WORKDIR /app
 
 # install donkey with tensorflow (cpu only version)
 ADD ./setup.py /app/setup.py
 ADD ./README.md /app/README.md
-RUN pip install -e .[tf]
+RUN pip install -e .[tf_gpu]

```

またsetup.pyが指定しているtfのバージョンもDonkeyCar用に合わせておきます

```setup.py
diff --git a/setup.py b/setup.py
index 6230703..7565ad3 100644
--- a/setup.py
+++ b/setup.py
@@ -66,7 +66,7 @@ setup(name='donkeycar',
                         ],
                     'ci': ['codecov'],
                     'tf': ['tensorflow>=1.9.0'],
-                    'tf_gpu': ['tensorflow-gpu>=1.9.0'],
+                    'tf_gpu': ['tensorflow-gpu>=2.0.0-Beta1'],
                     },
     package_data={
         'donkeycar': extra_files, 
```



に変更してDockerをBuildします

```
docker build . -t donkey-gpu
```

このイメージは Jupyter notebook を /app/notebooks ディレクトリで起動するようになっていますので以下のコマンドを実行して動作させます

```
optirun docker run --runtime=nvidia --rm -it -v ~/Desktop/donkey/notebooks:/app/notebooks -p 8888:8888 donkey-gpu
```

* optirun は nvidia ボードを利用するための切替用のコマンドです
* runtime = nvidia としてGPUボードの利用を指定しています
* ディレクトリとして /app/notebooks にローカルディスクをマウントしています

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/11540/c678729c-64e1-552d-c246-9bb922d0b3d3.png)


これでGPUも見えているので実際に利用できそうです

`donkey` コマンドが入っているかも確認しておきます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/11540/19d9a456-81b2-d6d6-5938-68984291b0a6.png)
【Linux】基本やコマンド

今日はLinuxについて書いていこうと思うよ。

もともとターミナルによく打ち込んではいたんだけど、正直ちゃんと理解していたわけではない・・。
カリキュラムに頼りっぱなしなところがある。

てことでせめてLinuxの概念とか、簡単なLinuxコマンドくらいは簡単にまとめようかなと思います。

<h2>Linuxとは</h2>

Linuxとは、Unix系オペレーティングシステムカーネルであるLinuxカーネル、およびそれをカーネルとして周辺を整備したシステムである。
(引用:https://ja.wikipedia.org/wiki/Linux)

わかりにくいっすね・・・。

Linuxとはコンピュータ用のOS(オペレーティングシステム)の一種のことで、コンピュータ全体を管理している基本的なプログラムのことを言うみたいです。

例えば、

* キーボードから文字を入力すると、入力した文字が画面に表示される。
* マウス・タッチパネルなどで画面を操作できる。
* イヤフォンをさすと、イヤフォンから音が聞こえる。

普段僕たちがパソコンを使用する上で、特段ストレスなく操作することを可能にしてくれているということのようです。

<h2>Linuxの特徴</h2>

主にサーバー向けによく利用されています。理由としては、

* オープンソースであり、誰でも自由に無償で利用できる
* 品質の高い多くのソフトウェアが利用できる
* 世界中でサーバ用途として広く利用されているため信頼性が高い
* 操作を自動化するための仕組みが用意されており、サーバの運用が行いやすい

無償かつ拡散性があり、スペックが高く、世界中で共通認識として使えるってところで色々便利みたいですね。

仕事するときにMicrosoftのOfiiceをよく使うと思うんですが、ああいう感じなんでしょうね。

<h2>基本的なコマンド</h2>

コマンドを実際に試していくわけですが、普段ターミナルに打ち込むかと思います。

そのときにユーザーの入力したコマンドを解釈するソフトウェアのことをシェルと呼びます。

普段何気なくターミナルに打ち込んでいましたが、あとはシェルが読み込んでくれているみたいですね。

<h3>ls</h3>

lsはlistの略です。
lsコマンドでは、カレントディレクトリにあるファイルやフォルダの名前一覧を出してくれます。

```bash
userMacBookPro:~ username$ ls

Applications		Google ドライブ		Public			pitchshiftLogFile.txt	workspace
BackgroundMusic		Library			SHOW			projects
Desktop			Movies			bash_profile		rbenv
Documents		Music			dump.sql		reset.sql
Downloads		Pictures		evalonly.txt		ruby
```

<h3>cp</h3>

cpコマンドはcopyの略で、そのままファイルをコピーするコマンドです。

下記コマンドで同じディレクトリにコピーファイルを作成します。

```bash
userMacBookPro:blog username$ cp scope.rb scope1.rb
                          <!--cp [コピー元] [コピー先] で表します-->
```

<h3>mv</h3>

ファイルの移動、およびリネームを行います。

```bash
userMacBookPro:blog username$ mv scope.rb /Users/kouyamaakira/projects/ruby
                          <!--mv [移動させたいもの] [移動先]-->
                       
userMacBookPro:blog username$ mv scope.rb rename.rb
                          <!--mv [元のファイル] [新しいファイル名]-->

```

<h3>rm</h3>

ファイルを削除するコマンドです

```bash
userMacBookPro:blog username$ rm kesu.rb
                          <!--rm [消したいファイル名]-->
```

<h3>mkdir</h3>

Linuxで新規にディレクトリ（フォルダ）を作成するコマンドです。

```bash
userMacBookPro:blog username$ mk make
                          <!--mk [作りたいファイル名]-->
```


<h3>cat</h3>

ファイルの内容を表示できるコマンドです。
サーバーをつなげたときに、エラーを見たいときなんかによく使います。


```bash

userMacBookPro:blog username$ cat cat1.rb
なかがみえるよ

こんなかんじ

```

2つのファイルを結合して中身を見ることもできます。

```bash
userMacBookPro:blog username$ cat cat1.rb cat2.rb
なかがみえるよ

こんなかんじ

なかみを

くっつけれるよ


```

<h3>tail</h3>

ファイルの終わり部分を表示するコマンドです。

オプションをつけずに実行すると終わりから10行表示されます。 

これもエラーデバッグなんかで使われます。

```bash
userMacBookPro:blog username$ tail scope.rb


(5)
1 数値型のid , 文字列型のname , 数値型のpriceをカラムに持つfoodsテーブルを作成しろ
2 foodsテーブルのid,name,priceそれぞれの値として、いれろ
3 foodsテーブルのid2のデータのpriceを600に更新
4 foodsテーブルのid2のデータを削除
5 nameがカレーライスであり、かつpriceが1000より小さいデータを検索
6 nemeがカレーライスまたはラーメンのデータを検索
7 nameがカレーライスのデータを探し、priceごとにまとめろ

```

この辺はアプリケーションをサーバーに繋いで動かすときによく使う気がします。
次回はvimとかについて書きたいな。
Switchbotのタイムアウトエラーは、内蔵電池の残量不足によるもの

#Switchbotでエラーが発生、起動しない。。
対処法は、掲題の通り。電池を交換すれば治ります。Switchbotの電池はあまり見かけないCR2リチウム電池というものです。
https://www.amazon.co.jp/%E9%9B%BB%E6%B1%A0%E4%BC%81%E7%94%BB%E8%B2%A9%E5%A3%B2-BP-%E3%83%AA%E3%83%81%E3%82%A6%E3%83%A0%E9%9B%BB%E6%B1%A0-CR2-2%E6%9C%AC%E3%83%91%E3%83%83%E3%82%AF-CR2-2P/dp/B00F921OTK

##エラーメッセージ
<img width="1024" alt="E7FE1AFD-C3FA-43E3-9087-4DFDA940C489.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/110110/fd4509a5-7006-4049-a84f-3ac892a9a63e.png">


我が家では、アナログの電池をSwitchbotによってオフオンできるようにしている。最近ではIFTTTを使用しなくとも直接Google Assistantと接続できるようになり使い勝手が増したなあ、と思っていた矢先のことだった。

過去の対処法でそんなものを見たことあるなあ、と思っていたがエラーメッセージがタイムアウトだったので、なんだろうと思っていた。
電池残量が赤になったら替え時のようだ。デバイスそのものを認識させる電力はあっても、モーターをうごかせなくなるため操作が先にできなくなるようだ。この辺りはナレッジとして残しておく。

各デバイスの電池の見方は、確認したいSwitchbotのギヤアイコン→一番下の「ファームウェアとバッテリー」をタップすると出てくる。

交換の仕方は、後日アップデート。先人のサイトもあります。
ES2015 (ES6) の import や export (default)（React基礎講座4）

# はじめに

今回は、import や export (default) というES2015 (ES6) の シンタックスについて書きます。

# シリーズ

本記事はReact基礎講座のための連載になっています。気になる方のために、前の章は以下です。

[React Component について（React基礎講座3） \- Qiita](https://qiita.com/ryosuketter/items/7eb93d2d8402862403e9)

最初の記事は、以下です。

[Reactを使ってJSXの内容をレンダリングする（create\-react\-app）（React基礎講座1） \- Qiita](https://qiita.com/ryosuketter/items/dbac89f398787a1a73d4)

# import, export とは

これまで、なんども書いてきた。以下。

```js
import React from "react";
import { render } from "react-dom";
```

これは、JSのモジュールを他のファイルから読み込むシンタックスです。

## 試しに書いてみましょう

`sample.js`で定義した文字列を、`create-react-app` で作成した`src/`直下の同階層にある`index.js`に表示させるスクリプトを書いていきます。

```react:sample.js
export const file = "declared from sample.js";
```

```react:index.js
import { file } from "./sample";
console.log(file);
```

コンソールで以下が吐き出されます。

```txt
declared from sample.js 
```

これで、変数のimport, exportができました。もちろん、変数だけでなく、関数や`React.Component`もimport, exportすることができます。

```react:sample.js
import React from "react";

export const file = "declared from sample.js";

export const function_test = () =>
  console.log("declared from function in sample.js");

export const ReactComponent = () => <h1>React Component</h1>;
```

`React.Component`を使うには、`React`パッケージをインストールしないといけません。

```react:index.js
import React from "react";
import { render } from "react-dom";

import { file, function_test, ReactComponent } from "./sample";
console.log(file);

function_test();

render(<ReactComponent />, document.getElementById("root"));
```

コンソールには、以下が表示されます。

```txt
declared from sample.js 
declared from function in sample.js 
```

また、viewには、文字列`React Component`がレンダリングされたと思います。

このように、ES2015 (ES6)では、import / export を使うことで、変数やクラスやReact Componentなどを、別ファイルに切り分けて管理することができます。

# export (default) とは

`export default`は、`export`と 基本的には同じ機能で、シンタックスのバリエーションと言った感じです。

とはいえ、こちらの書き方の方が、お仕事現場のReactではよく見るシンタックスなので、見てみましょう。

## export default と書く場合のシンタックスのルール

- `export default` したものを `import` するときには `{}` を使わない
- 1 ファイル内で、1 `export default`のみ(通常は `export` は複数使用できる)
- なので、1ファイル1コンポーネントであれば、 `export default` を使う場合方がいい

## 実際に書いてみましょう

`sample.js`で定義したReact Component を、`create-react-app` で作成した`src/`直下の同階層にある`index.js`に表示させるスクリプトを書いていきます。

`sample.js`は`export default`を2パターンで書くことができます。

### 1パターン

```react:sample.js
import React from "react";

export default class ClassComponent extends React.Component {
  render() {
    return <h1>React Component Export Default した</h1>;
  }
}
```

### 2パターン

```react:sample.js
import React from "react";

class ClassComponent extends React.Component {
  render() {
    return <h1>React Component Export Default した</h1>;
  }
}

export default ClassComponent;
```

`index.js`の方は `import`する際になみ括弧 `{}` 無しで受けることができます。

```react:index.js
import React from "react";
import { render } from "react-dom";

// {} は使わない
import ReactComponent from "./sample";

render(<ReactComponent />, document.getElementById("root"));
```

これで、表示されたと思います。

![スクリーンショット 2019-08-06 00.38.30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/14191/96d0f1c6-22a1-1f3c-d4eb-b18f18d5030c.png)

以上が、`export`と`import`のシンタックスでした。

# 参考

- 改訂新版JavaScript本格入門 ~モダンスタイルによる基礎から現場での応用まで | 山田 祥寛
AtCoder Beginner Contest 102　C - Linear Approximation



# C - Linear Approximation

0を原点とする直線との距離の総和を最小化する問題として考えられる。
あるbについて、直接より上の点がp個、下の点がq個あるとすると、p>bなら上に、p>qなら下に動かした方が総和を最小化できる。だから、p=qとなるようなbを探すという方針で行けばok


```python

n=input()
num=list(map(int,input().split()))
sorted_num=sorted([num[i]-i for i in range(len(num))])
# bがこの数値だと、ぴったり重なる。
b=sorted_num[len(sorted_num)//2]
print(sum([abs(b-i) for i in sorted_num]))
```
ビットコインに使われるブロックチェーンの仕組みについてまとめてみる②

# 今回学ぶこと
前回の記事で、ブロックチェーンとは

+ 記録を変更・改ざんできない
+ 管理者不在であり、参加者で運用する

という特徴が必要であることが分かりました。今回は、この二つを達成するためのブロックチェーンの大まかな仕組みについて解説していきます。まず大雑把な概要を解説して、次回からさらに細かく解説していくことにします。


## ブロックチェーンの全体像
ビットコインを例にとって、ブロックチェーンの全体像を解説します。ブロックチェーンの仕組み自体は様々な技術に応用されているのですが、もともとブロックチェーンはビットコインのために生まれた技術なので、まずビットコインに使われているブロックチェーンから学んでいきましょう。全体像を把握するために、AさんからBさんにお金を支払うシーンを想像してください。

###AさんからBさんにお金を支払うとき
まず必要になるのはAさんやBさんのブロックチェーン上の住所です。これはアドレスといわれ、銀行の口座番号のようなものです。このアドレスは電子署名という技術を用いて作成されるものですが、それは次回以降詳しく解説します。
AさんのアドレスからBさんのアドレスにお金を支払うという取引情報は、ネットワークを通じてビットコインのP2Pネットワークに拡散されます。P2PとはPeer to Peerの略称で、対等なものから対等なものへ、という意味です。ビットコインは管理する存在がいないため、ビットコインネットワークに参加している人達みんなでその取引情報を管理します。しかし、まだこの取引情報は書き換え可能なものなので、拡散された時点では取引は完了していません。つまり、まだAさんからBさんにお金は支払われていない状態です。それでは、いつAさんからBさんにお金は支払われるのでしょうか。

---
答えは、「AさんからBさんへお金を支払ったという情報がブロックチェーンに取り込まれたとき」です。一つずつ解説していきます。まず、ブロックチェーンとは簡潔にいうと、ブロックが繋がれたものです。そして、ブロックとは、取引情報の集合体です。AさんからBさんにお金を支払ったという情報は、P2Pのネットワークに拡散した後、マイナーと呼ばれる人たちによりブロックにされます。そして、マイナーはここで数当てゲームのようなものをします。この数当てゲームは意味のない数字を当てるゲームで、ただコンピューターの性能に任せてしらみつぶし数を探していくゲームです。ここで大事なのは、この数当てゲームは数を探すのは大変だけれど、答えが見つかればそれが答えだと確かめるのは一瞬でできるようにゲームです。イメージでいえば、サイコロを二個投げて、その合計数がある数字以下になるまで繰り返し投げさせられるようなゲームです。なんとなくイメージができますか？

---
世界中のマイナーはみんな必死でサイコロを投げます。この数当てゲームの難易度は、世界中のマイナーが本気で数を探して10分間でやっと発見できるように難易度調整されています。今、あるマイナーCさんが数を見つけました。この数はproof of workのnonceと言われます。nonceを見つけたCさんはP2Pのネットワークに自分がnonceを見つけたことを報告します。そして、そのnonceが正しいことをネットワークのみんなで確かめます。そして、nonceが正しいことが確かめられれば、そのブロックはブロックチェーンに記録されます。

---
今、AさんからBさんにお金を支払うという取引情報がブロックに取り込まれました。この取引情報を改ざんするためには、再びこの数当てゲーム、つまりはproof of workを行わなければいけません。また、このブロックの上に10分後には新しいブロックが記録されます。ブロックチェーンを改ざんするためには、そのブロックの上のブロックもすべて改ざんしなければいけないというルールがあるため、どんどん積みあがっていくブロック、それも世界中のマイナーが10分でやっと解けるような難易度の問題を解かなければならないそれぞれのブロックのproof of workをすべて解いてデータを改ざんするのは、事実上不可能です。実際には上に四つブロックが連なっているブロックはもう改ざん不可能であるといわれているため、上に四つブロックが連なった状態で初めてそのブロックの取引が完了されます。

---

以上が取引完了までのおおまかな流れとなっています。各々の詳細はまた一つ一つ解説していきます。これからもゆるりと記事を書こうと思います。ここまで読んで下さりありがとうございました。

[ビットコインに使われるブロックチェーンの仕組みについてまとめてみる①](https://qiita.com/renesisu727/items/b8899240044b8685bb27)
Firebase HostingにVue CLIで作ったページをデプロイする

Firebase HostingにVue CLIで作成したビルド済みページをデプロイしてブラウザで表示します。

## 前提

- Googleアカウントを持っている
- Vue CLIをインストール済み

## Firebaseプロジェクトの作成

[Firebase](https://firebase.google.com/)ページから「コンソールへ移動」をクリック。移動したらプロジェクトの追加をクリック。
プロジェクト名を適当に決めます。

![スクリーンショット 2019-08-05 10.34.55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/235453/d925cb3b-d46d-e475-ea2a-ecdc27eeb1de.png)

アナリティクスは今回はオフに
![スクリーンショット 2019-08-05 10.35.14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/235453/72971bd6-27d8-34e8-51d7-2e904a183f6d.png)

「プロジェクトを作成」を押してしばらくすると新しいプロジェクトが出来上がります。

## Vueプロジェクトの開始

デプロイするVueアプリを作成していきます。バージョンは3.8.4を使用しました。

```shell
$ vue --version
3.8.4
```

今回はデフォルト設定のVueプロジェクトを作ります。

```shell
$ vue create firebase_deploy_sample
```
![スクリーンショット 2019-08-05 10.48.58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/235453/1ea7ebc2-4638-eff4-25c8-a6c20997a0ec.png)
defaultを選択。

## Firebase CLIを使ってHostingにデプロイ

先ほど作成したFirebaseのプロジェクトのページから左のメニューから「開発 > Hosting」へと移り、「はじめる」ボタンを押します。
![スクリーンショット 2019-08-05 10.53.45.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/235453/db954f05-fb52-32dc-9fb0-68d731601b39.png)

以下に書かれている`npm`コマンドを使ってFirebase CLIツールをインストールします。

```shell
$ npm install -g firebase-tools
```

![スクリーンショット 2019-08-05 10.55.12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/235453/a48429d0-88cf-f08d-ae27-c5ef28837944.png)

先ほど作成したVueアプリのディレクトリに移動し、Firebaseへのログインとプロジェクトの初期化を行います。Firebase CLIのバージョンは7.2.2を使っています。

```shell
$ firebase --version
7.2.2
$ firebase login #自分のGoogleアカウントへログイン
$ firebase init
```

Hostingにカーソルを合わせてスペースキーで選択し、Enter。

![スクリーンショット 2019-08-05 11.12.33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/235453/3ca36e7a-2421-bc68-0abf-1056aedd0d96.png)

使用するFirebaseプロジェクトを聞かれるので先ほど作ったものを選択。
次にデプロイする対象のディレクトリを聞かれるのでVueをビルドした時に作成される`dist`と入力しEnter。（distributionのdistらしいです。）

![スクリーンショット 2019-08-05 11.13.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/235453/c0e97fa8-e6ab-e4d1-1ddc-cea23e6ca06e.png)

SPAページかどうか聞かれるのでyを入力。

```shell
? Configure as a single-page app (rewrite all urls to /index.html)? (y/N) 
```

これでfirebaseの設定は完了で`.firebaserc`と`firebase.json`がディレクトリに追加されています。

最後にVueアプリをビルドし、コマンドでデプロイします。`Hosting URL: ...`にブラウザーでアクセスするとちゃんとページがデプロイされているのがわかるかと思います。

```shell
$ npm run build
$ firebase deploy
```

![スクリーンショット 2019-08-05 11.23.56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/235453/20bf682b-f881-ae1b-f7a8-a0790fe89b9c.png)
DeepLabCutとOpenPoseとで推定した骨格を見比べる

# はじめに
###記事の内容
[DeepLabCut](https://github.com/AlexEMG/DeepLabCut) (Windows + Google Colaboratoryでの使い方は、[前回記事](https://qiita.com/Cony-san/items/62df5365878baaa5e275))と[OpenPose](https://github.com/CMU-Perceptual-Computing-Lab/openpose)で、姿勢推定を行い、その出力を見比べてみました

いずれも、2D動画の各フレームに対し深層学習モデルを適用し、身体部位を推定しています

#使った動画
今回使った動画は、2015年の夏に撮影した30fps, フルHD(1920×1080)の動画です
(たしかiPhone 5sで撮ったと思います)
被写体は、筆者
場所は分かる人が見ればわかるかと思いますが、とある陸上競技場です

元はmovファイルでしたが、Qiitaへアップロードするために、[gifに変換](https://qiita.com/bohebohechan/items/f8bf6d4bbe0f14497a7b)しました
フレームレートを10へ落とし、リサイズ、クロップをしています

![2015_org_small.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/311690/03e6f48d-ffa4-fb82-78a7-f9930e89a47c.gif)



#DeepLabCutによる推定
- 解析環境
    - windows10 home (64bit)
    - Miniconda 3 ←ラベリングまで
    - Google Colaboratory (python3)
   
- 推定する身体部位 (下記17部位)
    - 首
    - 右肩
    - 右肘
    - 右手首
    - 左肩
    - 左肘
    - 左手首
    - 右尻(大転子)
    - 右膝
    - 右踝
    - 右踵
    - 右爪先
    - 左尻
    - 左膝
    - 左踵
    - 左爪先

- 各パラメータ
    - ラベル枚数: 20枚 (numframes2pick)
    - 最初のモデル: mpii-single-resnet-101 (init_weights)
    - トレーニング回数: 800000回 (iteration)

###学習したモデルの評価

|iterations |%Training dataset |Train error(px)	 |Test error(px) |
|---        |---               |---              |---            |
|80000	    |95      	       |1.82	         |19.58          |

カメラが動く上、20枚しかラベリング(お手本)に使ってないためか、結構エラーがあります

###deeplabcutによる動画

![2015_dlc_small.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/311690/c2809857-97d5-1d06-db9e-13e3e1ad0c5c.gif)

ラベリングが地味に大変なのと、学習にも時間がかかりましたが、ぱっと見の推定精度はなかなかではないでしょうか




#OpenPoseによる推定

- 解析環境
    - windows10 home (64bit)
    - Miniconda 3
    - GeForce GTX 1050Ti + CUDA 
※一回目にDLCをインストールしようとしたときに入れたが、詳細は忘れてしまいました。苦労した気がします
   
- 推定する身体部位 (下記25部位、[BODY_25](https://github.com/CMU-Perceptual-Computing-Lab/openpose/blob/master/doc/output.md#pose-output-format-body_25))
    - 鼻
    - 右目、左目
    - 右耳、左耳
    - 首 
    - 右肩、左肩
    - 右肘、左肘
    - 右手首、左手首
    - 腰
    - 右尻、左尻
    - 右膝、左膝
    - 右踝、左踝
    - 右踵、左踵
    - 右母指球、左母指球
    - 右爪先、左爪先

- OpenPose
    - windows用[Portable Demo](https://github.com/CMU-Perceptual-Computing-Lab/openpose/blob/master/doc/installation.md#windows-portable-demo)を使っています
めちゃめちゃ簡単です

一人しか推定しないので、下記コードを実行しています

```python:
bin\OpenPoseDemo.exe --video videopath.mov --tracking 0 --number_people_max 1 --write_video videopath_op.avi --write_json videopath_op\ --display 0 
```

windowsではaviしか出力できないようです
関節点データは、json形式で吐き出させます。フレーム毎にファイルができるので、まとめる必要がありますね


###deeplabcutによる動画

![2015_op_small.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/311690/500fa6e9-4874-4039-4c1f-74050b04e51c.gif)

このぐらいの動画なら、ものの数十秒で推定できちゃいますね
得意な動画とそうでない動画でパフォーマンスが全然違うのが困ったところなのですが、今回の動画に対しては驚きの精度です

#おわり
ちょっと興味があるけど、どのくらいの精度なのかを知りたい方の参考になればと思います。
[JavaScript]オブジェクトのプロパティをコピーする２つの方法（Object.assign, スプレッド構文（...））


## 環境

```sh
> node --version
v10.15.3
```

古いバージョンでは動かないので、よろしくお願いします。（特にスプレッド構文の方）

## やってみる
### Object.assign

```js
> Object.assign({a:1, b:2}, {c:3})
{ a: 1, b: 2, c: 3 }
```

### スプレッド構文

```js
> {...{a:1, b:2}, ...{c:3}}
{ a: 1, b: 2, c: 3 }
```

## オブジェクトのコピーにも使える
### Object.assign

```js
> Object.assign({}, {a:1, b:2})
{ a: 1, b: 2 }
```

### スプレッド構文

```js
> {...{a:1, b:2}}
{ a: 1, b: 2 }
```

## でも、シャローコピー（浅いコピー）だから気をつける

```js
> obj = {a:{b:1}}
{ a: { b: 1 } }

> obj_copied = Object.assign({}, obj)
{ a: { b: 1 } }

> obj.a.b = 2    // コピー元を変えると
2

> obj_copied    // コピー先も変わる
{ a: { b: 2 } }
```

この動作は、スプレッド構文を使ったコピーでも同様。

## ディープコピー（深いコピー）をしたいとき

lodash（外部ライブラリ）を使う。

```console
$ npm install lodash
```

```js
> const _ = require('lodash')
undefined

> obj = {a:{b:1}}
{ a: { b: 1 } }

> obj_copied = _.cloneDeep(obj)
{ a: { b: 1 } }

> obj.a.b = 2    // コピー元を変えても
2

> obj_copied    // コピー先は変わらない
{ a: { b: 1 } }
```



## 参考資料
* https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Operators/Spread_syntax
* https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Object/assign
* https://lodash.com/docs/4.17.15#cloneDeep
SSHキーの生成、~/.ssh/config の設定、実際の接続までの手順

## キーの生成

`ssh-keygen` コマンドで秘密鍵と公開鍵を生成する。

- `t` は鍵タイプを指定するオプション

```
$ ssh-keygen -t rsa
Generating public/private rsa key pair.
Enter file in which to save the key (/home/hoge/.ssh/id_rsa): my_ssh_key #< 鍵の名前を入力
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
```

## キーが生成できたか確認

```
$ ls ~/.ssh
my_ssh_key #< 秘密鍵
my_ssh_key.pub #< 公開鍵
```

## SSH接続する際の設定

`~/.ssh/config` ファイルにSSH接続の設定を書く

### 設定のフォーマット

```
Host 接続名
  Hostname 接続したいリモートのホスト名 or IPアドレス
  User ユーザー名
  Port ポート番号
  IdentityFile 鍵のパス
```

### 設定例

```
Host hoge
  Hostname 1.12.123.234
  User fuga
  Port 22
  IdentityFile ~/.ssh/my_ssh_key
```

## SSH接続

config に設定を書かないと、こんな感じで接続することになる

```
$ ssh -i ~/.ssh/my_ssh_key fuga@1.12.123.234
```

config に設定を書くと、接続名を指定してあげるだけSSH接続できる

```
$ ssh hoge
```

## 参考

- https://webkaru.net/linux/ssh-keygen-command/
Excelでミリ秒を含む時刻の計算

##記事を書いた経緯
プログラムにlog4netを使ってログを出力していた。
ログには時刻を含め、時刻の書式はデフォルトの" 時:分:秒,ﾐﾘ秒 "としていた。

出力ログを使って処理にかかった時間をExelで算出しようするが、
「そういえばミリ秒が入ってる時刻ってどう計算するんだ・・・」となって
焦る。
モウコンナトコロデ詰ミタクナイ。


##ミリ秒を含む時刻を計算する方法
####まず時刻データの書式を見直す
今回は秒とﾐﾘ秒の間にカンマが入っていたが、カンマ区切りだとExcelさんに時刻として扱ってもらえないので、ドットに置換した。
　例)　14:13:57,809　→　14:13:57.809

####セルに書式を設定する
時刻を入れるセルに適切な書式を設定する。
時刻の入ったセルを選択してCtrl+1で「セルの書式設定」ダイアログを開く。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/424306/6bfa297b-bca3-16f5-5611-4132269d57cd.png)

「分類」から「ユーザー定義」を選択し、
「種類」のテキストボックスに任意の時刻形式を入力する。

今回はミリ秒を3桁分表示したいので、秒(ss)のあとを".000"とした。
桁数は調整可。

####時間を計算する
今回は処理の終了時間から開始時間を差し引いて、処理にかかった時間を求めた。
計算結果の時刻が同じ書式でいいなら、そのまま引き算。
普通にマイナスするだけでOKです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/424306/a4576335-c189-9c6d-ebb9-22779b1f7d3e.png)
php-master-changes 2019-08-05

今日は run-tests.php のバグ修正があった！

# 2019-08-05
## cmb69: Fix handling of succeeding XFAIL tests
- https://github.com/php/php-src/commit/790b0b109ad269b7367e3720d056530a86fa7123
- [7.4~]
- run-tests.php で、[XFAIL](https://qa.php.net/phpt_details.php#xfail_section) でマークされていて EXPECTF も EXPECTREGEX もないテストがこけなかった際、警告が出ず PASS となっていた問題の修正
- elseif のつもりで if と書いていた typo なもよう
Measure-Object は簡単に計算誤差が発生するので使わないほうが良い

Measure-Object で配列の合計を計算した際、計算誤差が発生しまくって大変だったため、再現方法と回避策をメモ。

# 本記事の概要と結論

Measure-Object で、100 に 0.000001 を 200 回足すと、誤差が発生する。誤差が発生する原因は、 Measure-Object が内部で浮動小数点数を利用しており、浮動小数点の演算時に誤差が発生するためである。（と推測している）
そのため、Measure-Object は、会計処理などの計算誤差が許されない領域に利用してはならない。
以下に、誤差発生の再現方法（=誤差の発生例）と回避策を記載する。

# Measure-Object で計算誤差を発生させる

```powershell
PS C:\> # decimal 型の 配列を作成。最初の要素は 100。
PS C:\> $list = @([decimal]100); 
PS C:\> # 配列に 0.000001 を追加し、Measure-Object で合計を計算する。これを 210 回繰り返す。
PS C:\> $tmp = 1..210 | %{ $list += [decimal]0.000001; ($list | measure -sum).Sum }
PS C:\> # 計算結果の 195番目から 205 番目までを出力する。すると 200 番目から誤差が発生している。
PS C:\> $tmp[195..205]
100.000196
100.000197
100.000198
100.000199
100.0002
100.000200999999
100.000201999999
100.000202999999
100.000203999999
100.000204999999
100.000205999999
PS C:\> 
```

# Measure-Object の計算誤差を回避する方法
Measure-Object の計算誤差を回避する方法は、Measure-Object を使わずに、decimal 型で合計する（という方法しか思いつきませんでした！）

```powershell
PS C:\> # Measure-Object の計算誤差を回避する方法
PS C:\> $list = @([decimal]100)
PS C:\> # $result 変数を作成し、配列の数だけ加算する。
PS C:\> $tmp = 1..210 | %{ $list += [decimal]0.000001; $result = 0; ($list | %{ $result += $_ }); $result }
# 計算結果の 200 番目以降も誤差が発生していない。
PS C:\> $tmp[195..205]
100.000196
100.000197
100.000198
100.000199
100.000200
100.000201
100.000202
100.000203
100.000204
100.000205
100.000206
PS C:\>
```

# 結論

Measure-Object は、会計処理などの計算誤差が許されない領域に利用してはならない。当たり前の結論です。
【個人メモ】業務で使う git command

# はじめに
いわゆる ｎ番煎じ
業務で使うコマンドの中でも特に気に入ってるものを並べました。

初心者から、中級者向け？だと思います。

コマンドを覚えると開発がより楽しくなると思います。
あんなこともできるこんなこともできる、できるが増えるって素晴らしいですね。

## 便利コマンド

### 差分をステージングエリアに追加する
```
git add -p
```
役立ち度：★★★★★
基本的に、このオプションでしか add はしない。

### 差分を取り消す
```
git checkout {FILE_NAME}
git checkout # 全部なかったことに。
git checkout -p # もある
```
役立ち度：★☆☆☆☆
時々使うけど、結構危険だと思う。

### ステージングエリアから戻す(add する前に戻す)
```
git reset {FILE_NAME}
git reset # 全部戻す
git reset -p # もある
```
役立ち度:★★★☆☆
コミットしようとした時に、「あれなんでこいついるの？」ってなった時に使う
コミット前には必ず `git status` しましょう。

### 指定したユーザーのコミットログを見る
```
git log --committer={USER_NAME}
```
重要度:★★☆☆☆
怪しい人を見つけた時に。

### コミットIDを指定して、中身を確認する
```
git show {COMMIT_ID}
```
重要度：★★★★☆
怪しいコミットがあった時に。
pull したらコミットをたくさん取り込んだ時によく使う。

### 別のブランチからファイル/コミットを持ってくる
```
git checkout {BRANCH_NAME} {FILE_NAME}

git cherry-pick {COMMIT_ID}
```
役立ち度：★★★☆☆
別のブランチの作業者が作った共通部品を盗みたい時に。

### 直前のコミットを修正する
```
git commit --amend # コミットメッセージも変えられる
git commit --amend --no-edit # vim をスキップ
```
役立ち度:★★★★☆
「この差分もこのコミットに乗せたい」という時に。

### ファイル名の変更
```
git mv {OLD_NAME} {NEW_NNAME}
```
役立ち度：★★★★★
普通にエクスプローラーから名前をすると delete と create になってしまう。
これでファイル名を変更するとログに変更が残るから嬉しい。
（これもオプションがあるわけじゃないけど、意外と使ってる人が少ない...。のでランクイン)

### 特定のファイルの歴史を確認
```
git log -- {FILE_NAME}
git blame {FILE_NAME}
```
役立ち度:★★★☆☆

blame の方が有名だけど、 log で見るのも便利な時がある。

### マージ済みのブランチの確認
```
git branch --merged
git branch --no-merged # その逆
```
役立ち度：★★★★☆
削除して良いローカルブランチを見つける。

### 直前のブランチを指定して〇〇
```
git checkout - # ブランチ切り替え
git merge - #  マージ
```
役立ち度：★★★★★
ひょっとしたら一番便利かもしれない。
ブランチ名が長くて打ってらんない時に。
ブランチ名を忘れちゃった時に。

### マージしたらコンフリクトしたのでなかったことに
```
git merge --abort
```
役立ち度：★★★☆☆
他の人に聞かないと解消できない時に。

### ざっくりした差分をみる
```
git diff --stat
```
役立ち度：★★★☆☆
ファイル名と、そのファイルが何行変わったかだけを表示

### ステージングエリアの差分を見る
```
git diff --cached
```
立ち度：★★★★☆
直前のコミットと、ステージングエリアとの差分を見る。
add + commit を連結して考えてると不要。（結構危険な考えです、やめましょう）
あれ？これコミットしたら何がリモートに上がっちゃうんだろう、と気になって見てください。

##ネタ系

### コミット数のランキング
```
git shortlog --summary -n
```
楽しさ:★★★★☆
努力を誰となく認められたい時に。
Git はあなたのコミット数を見てくれてます。

## 最後に
どうでしょうか。
git command でもっと楽しもうって気になれましたでしょうか。
CLI での git 操作ができるようになるともっと楽しく開発ができるかもしれません。
僕は楽しいです。

結構便利コマンド多いなって思います。
shell環境整えたら git command を愛する人になったので、たくさん知りたいです。
「これも使いなよ」っていう、とっておきのコマンドがあったら教えてください。

## おまけ
### 僕の git の alias を晒します

```
＄ git config --list | grep alias
alias.b=branch
alias.s=status
alias.co=checkout
```
あんまりたくさん作ってもしょうがないかな派です。

ありがとうございました。
Pythonで親ディレクトリのファイルのクラスをimportしたい時のPath追加方法

# Pythonで親ディレクトリのファイルのクラスをimportしたい時のPath追加方法

この例では、一階層上のディレクトリと二階層上のディレクトリにPathを通してみる。
```python
import os, sys
sys.path.append("..")
sys.path.append("../..")
```

これでPathの追加完了。あとは同じ階層にあるファイルのクラスをimportする時と同じようにすれば良い。例えば、

```python
from sample_file import SampleClass
sample_obj = SampleClass()
```

など

三階層上のディレクトリのPathを通したい時は、

```python
sys.path.append("../../..")
```

また、Python2.7だけの仕様かもしれませんが、Pathを通したいディレクトリに __init__.py を作成すると良いです。

## 子ディレクトリにPathを通す方法
忘れました。どなたかご教授ください。調べればすぐ出てくるはずですが、賢いやり方を忘れました。
React + TypeScript で react-router の URLパラメーターを取得する

React + TypeScript で react-router の URLパラメーターを取得する時に、このようなコードで`props.match`を参照すると`TS2339: Property 'match' does not exist on type '{ children?: ReactNode; }'.`とエラーがでました。

```tsx:page.tsx
import React, {FC} from "react";

const Page: FC<{}> = props => {
  return (
    <div>This is {props.match.params.id} Page.</div>
  )
};

export default Page;
```

たしかにmatchプロパティは、propsが受け取るオブジェクトとして定義されていないよな。。
と思ったものの、それならどのような型を読み込めば良いのかが分からなかったので調べました。

調べたみた所、react-router-dom の型定義ファイルにある`RouteComponentProps`を読み込めば良いとの事。

```tsx:page.tsx
import React, {FC} from "react";
import {RouteComponentProps} from 'react-router-dom'

type PageProps = {} & RouteComponentProps<{id: string}>;

const Page: FC<PageProps> = props => {
  return (
    <div>This is {props.match.params.id} Page.</div>
  )
};

export default Page;
```

コンポーネントが受け取るpropsの型と`RouteComponentProps`を型結合してまとめて、コンポーネントの型定義にします。

`RouteComponentProps`のコードは、下のようになっており、ジェネリクスで受け取る型定義でmatchプロパティの中にあるプロパティを指定する事ができます。

```index.d.ts
export interface RouteComponentProps<Params extends { [K in keyof Params]?: string } = {}, C extends StaticContext = StaticContext, S = H.LocationState> {
  history: H.History;
  location: H.Location<S>;
  match: match<Params>;
  staticContext?: C;
}
```


## 参考
[React Router with TypeScriptでちゃんと型をつける](https://qiita.com/taneba/items/b50078e1ac9d1971d413)
[What TypeScript type should I use to reference the match object in my props?](https://stackoverflow.com/questions/48138111/what-typescript-type-should-i-use-to-reference-the-match-object-in-my-props)
RailsのActiveRecordのデータタイプでJSONが便利な件

## RailsのデータタイプでJSONが便利な件
RailsのActive Recordではstringやintegerと並んでjsonを指定することができます。
DBとしては文字列として保存されるパターンが多いですが、Active Record側ではすでにハッシュとしてパース済みになり、任意のkey valueペアが保存できるため柔軟な構成になります。

パフォーマンスや堅牢性は落ちますが、高速な開発が求められる際には使用してみてはいかがでしょうか。

公式ドキュメントはこちらです。
https://edgeguides.rubyonrails.org/active_record_postgresql.html#json-and-jsonb
この記事が参考になれば幸いです。
## 終わりに
私は現在、Web3のサービスの開発をしています。詳しくはこちらの記事をご覧下さい。
        [無料でイーサリアムが当たる、Web3時代の寄付サイトを作った話](https://note.com/kenroda/n/n814347fbdcd7)
ASP.NETの全体像

# ASP.NETの全体像（要変更）
![ファイル_001.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/275331/8d6aecc8-4c0d-8dc6-92bc-d4c4f5fe2952.png)

#Webフォーム
ASP.NETの最古参がASP.NET Webフォーム。
サーバーコントロールと呼ばれるUI部品が豊富で、Visual Studioでドラッグ・アンド・ドロップするだけで高機能なアプリが作成できる。
イベントドリブンモデルを採用している。
ややトレンドに取り残され、現在では積極的に採用すべきFWとは言えない。
ASP.NET MVCの利用が推薦される。

# APS.NET MVC
VS2008の拡張コンポーネントとして登場。その後VS2010で標準採用されてサブFW。
比較的新しいFWながら、現在のトレンドを取り込みながらバージョンアップが頻繁に重ねられ、現在ではASP.NET開発の主流とも言える地位を確立。

# ASP.NET Web Pages
.NET Framework以前のASP（Active Server Pages）、PHPによく似た技術でHTML埋込み型モデルを採用。

```
Hello! @name さん！
```

のように＠のアノテーションでHTML内にコードを埋め込める。
2011年にリリースされた無償のWebサイト構築ツールWebMatrixの標準技術として採用された。
残念ながら現在はあまり普及していない。

# ASP.NET Web API
ASP.NET Web APIとは、WebAPIを実装するためのサブフレームワーク。
ASP.NET MVCでもWebAPIを実装することは可能であるが、ASP.NET Web APIの方が機能特化しているだけ同じ機能を実装するのにもシンプルに実現できる。
アプリケーション開発とWebAPI開発でASP.NET MVC とASP.NET Web APIを用途に合わせて使い分けるべきでしょう。

# SignalR
SignalRはWebアプリケーションのリアルタイム通信を実現するためのライブラリ。
適切な通信手段を選択するのでアプリケーションが低レベルな手続きを意識しなくて良くなる特徴がある。

# ASP.NET Single Page Application(SPA)
SPAとは、単一ページで構成されるWebアプリケーションのこと。
初回アクセス時にページ全体を取得し、以降のページ更新は基本的にはJavascriptで賄う。
JSでは賄いきれない部分は（データ取得、更新）Ajaxなどの通信技術を利用し実装する。
デスクトップアプリケーションによく似た操作性、俊敏な動作を実現するアプローチとして注目される。
ASP.NET Single Page Application は、SPAを実装するためのプロジェクトテンプレート（純粋な意味でFWではない）。
ASP.NET MVC + APS.NET Web API をベースにJavascriptのフレームワークであるKnockout.js,Summy.jsをデフォルトで取り込んでおり、即座にSPAを開発できる。

# まとめると
ASP.NETの世界は

- ブラウザからアクセスするためのアプリケーション開発（Sites)
- アプリケーション連携のためのサービス開発（Services)

の技術に大別できる。
このうちSitesで抑えるべきFWは、ASP.NET MVCだけ。
ServicesではASP.NET Web API,SignalRもいずれも学んでおきたい。

# 参考
- [ASP.NET MVC 5 実践プログラミング](https://a.r10.to/hfIzaX)
Typescriptでパターンマッチもどき


下記のスライド読んでて、enum的なもの以外でもできるのかなと思って少し考えてみた。

* [TypeScriptでType Match的なことをする話](https://speakerdeck.com/kyo_ago/typescriptdetype-matchde-nakotowosuruhua-number-suenamitiyansushu-qi-fu-i-9e6c5cce-7658-43aa-815b-966eb5d22051)

もう少しボイラープレート減らせないのかなぁ、とは思うがTypeScriptよく知らないので、私にはこれ以上どうにもならなかった。

なお、[TypeScript playground](http://www.typescriptlang.org/play/index.html#code/Q)でコンパイルエラーがないか確認しただけなので、ちゃんと動くかはわかりません（爆）。

あと、判別共用体やるなら[種別を表す共通のプロパティを作ってswitch文で分岐する](http://js.studio-kingdom.com/typescript/handbook/advanced_types#discriminated_unions)のが正解っぽい。

```.ts
type CaseOf = { [K in string]: any[] }

type CaseOfMethod<C extends CaseOf> = 
    <R>(c: { [K in keyof C]: (...x: C[K]) => R }) => R
    
// data Maybe a = Nothing | Just a
type CaseOfMaybe<A> = {Nothing:[], Just:[A]}

class Maybe<A> {
    private constructor(readonly caseOf: CaseOfMethod<CaseOfMaybe<A>>){}

    static readonly Nothing = <A>(...x: CaseOfMaybe<A>["Nothing"]) =>
        new Maybe<A>(c => c.Nothing(...x))

    static readonly Just = <A>(...x: CaseOfMaybe<A>["Just"]) =>
        new Maybe<A>(c => c.Just(...x))
    
    readonly map = <B>(f: (x: A) => B): Maybe<B> => this.caseOf({
        Nothing:() => Maybe.Nothing(),
        Just:(x) => Maybe.Just(f(x))
    })
}

// data List a = Nil | Cons a (List a)
type CaseOfList<A> = {Nil:[], Cons:[A, List<A>]}

class List<A> {
    private constructor(readonly caseOf: CaseOfMethod<CaseOfList<A>>){}

    static readonly Nil = <A>(...x: CaseOfList<A>["Nil"]) =>
        new List<A>(c => c.Nil(...x))

    static readonly Cons = <A>(...x: CaseOfList<A>["Cons"]) =>
        new List<A>(c => c.Cons(...x))

    readonly map = <B>(f: (x: A) => B): List<B> => this.caseOf({
        Nil:() => List.Nil(),
        Cons:(x, xs) => List.Cons(f(x), xs.map(f))
    })
}

// data Bool = False | True
type CaseOfBool = {False:[], True:[]}

class Bool {
    private constructor(readonly caseOf: CaseOfMethod<CaseOfBool>){}

    static readonly False = (...x: CaseOfBool["False"]) =>
        new Bool(c => c.False(...x))

    static readonly True = (...x: CaseOfBool["True"]) =>
        new Bool(c => c.True(...x))
    
    readonly and = (other: Bool): Bool => this.caseOf({
        False:() => this,
        True:() => other
    })

    readonly or = (other: Bool): Bool => this.caseOf({
        False:() => other,
        True:() => this
    })

    readonly not = ():Bool => this.caseOf({
        False:() => Bool.True(),
        True:() => Bool.False()
    })
}
```
【EC-CUBE4】⑥EC-CUBE本体の開発環境を整える（Codeception編）

EC-CUBE4の環境構築続きです。
[【EC-CUBE4】①EC-CUBE本体の開発環境を整える（インストール編）](https://qiita.com/junpeko5/items/199af36a31a335a73d38)
[【EC-CUBE4】②EC-CUBE本体の開発環境を整える（GitHub Flow編）](https://qiita.com/junpeko5/items/8706a91452e85eef5109)
[【EC-CUBE4】③EC-CUBE本体の開発環境を整える（MYSQL,MailCatcher編）]
(https://qiita.com/junpeko5/items/3316b654b4b80ee59376)
[【EC-CUBE4】④EC-CUBE本体の開発環境を整える（Postgres,MailCatcher編）]
(https://qiita.com/junpeko5/items/ef572490c44da90eac59)
[【EC-CUBE4】⑤EC-CUBE本体の開発環境を整える（Xdebug、PhpStorm編）](https://qiita.com/drafts/890e6b73b0e1f9930093)

## 前提条件

- Mac
- .phpenvでphp7.2.8がインストール済み
- EC-CUBE4がローカル環境にインストール済み（<a href="https://qiita.com/junpeko5/items/199af36a31a335a73d38">【EC-CUBE4】①EC-CUBE本体の開発環境を整える（インストール編）</a>が終わっていること）
- Postgres、Mailcatcherがローカル環境で利用できること（<a href="https://qiita.com/junpeko5/items/ef572490c44da90eac59">【EC-CUBE4】④EC-CUBE本体の開発環境を整える（Postgres,MailCatcher編）</a>が終わっていること）

## 方針

- webサーバーはビルドインウェブサーバーを利用。


## ChromeDriverをインストールします。

```
$ brew cask install chromedriver
```

## local.ymlの作成

`codeception/_envs/local.yml`を作成します。

```local.yml
modules:
  config:
    Db:
      user: 'docker'
      password: ''
      dsn: 'pgsql:host=127.0.0.1;dbname=eccube4'
    WebDriver:
      host: 'localhost'
      port: 9515
      url: 'http://localhost:8000'
    MailCatcher:
      url: 'localhost'
      port: 1080
```

## ChromeDriverを実行する

```
$ chromedriver --url-base=/wd/hub
```

## Codeceptionを実行
別ウィンドウで、Codeceptionを実行します。

```
$ vendor/bin/codecept run acceptance --env chrome,local -g admin01
```

少し立つと、ブラウザが自動で立ち上がり、E2Eテストが実行されていきます。

<img width="1655" alt="スクリーンショット 2019-08-05 23.27.54.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/166768/e60abf0e-b2e1-a711-c8bb-24cbe4b4f236.png">


※ 上記テストで、`[Facebook\WebDriver\Exception\ElementNotVisibleException]`のようなエラーが出る場合は、ChromeDriverを最新にすると良いようです。

## 次回

[【EC-CUBE4】⑦EC-CUBE本体の開発環境を整える（PHPUnit編）](https://qiita.com/junpeko5/items/2c8aa89ecb1df1c8a40c)に続きます。

## 参考

https://codeception.com/
https://github.com/EC-CUBE/ec-cube/pull/3048
#PowerApps スライダータイマーを柔軟に制御する

# スライダータイマーとは？？
@github129 氏のこちらの記事になります
[【#PowerApps】PowerAppsでタイマーコントロールを使わずにタイマーコントロールよりも高速なループを実行する方法](https://qiita.com/github129/items/75f5f83d9842aab89da3)

この手法により、タイマー制御が非常に高速になりまして、本当に有用なものとなったのですが
問題は、早すぎるということですね。

Patchなどを使って、データソースのアップデートを実行したい場合、更新完了を待たずに次に行ってしまいかねません。

ならば、タイマーを使えばいいという話になるのですが

@tomikiya 氏のこちらの記事の通り
[[PowerApps]バックグランドで緯度経度を取得する](https://qiita.com/tomikiya/items/867c9d56c2cf5cadda72)
タイマーはバックグラウンドでは実行されないということがわかりました。

なので、スライダータイマーでかつ、実行タイミングを制御する方法を以下にまとめることにしました。

# 完成系
![SliderTGimer.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/269159/d0267c94-1db2-8a30-4e20-0f05afccbea7.gif)


# 使用する変数

|変数名|意味|
|:--|:--|
|SliderTimer|スライダータイマーのループ判定に使用<br>0～1 チェンジ用<br>2はストップ|
|Cnt|間隔をあけて実行する用のカウンタ変数|
|ExecCnt|実行間隔を指定（回数）|

## OnStartプロパティ

```php:Onstart
Set(Slidertimer,2);
Set(Cnt,0);
Set(ExecCnt,500)
```

# START/STOPの実装
スライダータイマーの方式にも記載ありますが、こういうやり方もあるんだぞということで・・・

## Startボタン

### OnSelect

```php:OnSelect
Set(Slidertimer,0)
```

## Stopボタン

### OnSelect

```php:OnSelect
Set(Slidertimer,2)
```

## スライダー

### Default

```php:Default
Slidertimer
```

### Max

```php:Max
2
```

### Min

```php:Min
0
```

### OnChange

```php:OnChange

Switch(
	Slidertimer,
		0,Set(Slidertimer,1),
		1,Set(Slidertimer,0)
);

```

# 実行間隔制御の実装

次は、先ほど作ったものに実行間隔制御を実装していきます。

## スライダー

### OnChange

```php:OnChange
Switch(
	Slidertimer,
		0,Set(Slidertimer,1),
		1,Set(Slidertimer,0);Set(ExecCnt,Cnt+1)
);
If(
	ExecCnt=Cnt,
		// 間隔制御して実行させたい処理を入れる
		Collect(
			GPSData,{
				datetime:Now(),
				lat:Location.Latitude,
				long:Location.Latitude,
				alt:Location.Altitude,conp:Compass
			}
		);
		// ここまで
		
		// 間隔カウンタリセット
		Set(Cnt,0),
	""
)
```

これでスライダーの値が500回になったときに処理が実行されるという間隔制御ができるようになります。

# 応用

ラジオボタンなどを使うことで、このように、実行間隔をアプリ上で変更することもできるようになります！

![SliderTGimer2.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/269159/cc4aa9ea-55c5-e79a-2995-2eb5300edfe5.gif)