OmniAICreator/Qiita-1.07M huggingface dataset:
Hyper-V の Ubuntu 18.04.1 LTS のディスク容量を拡張する

Hyper-V クイック作成で作った Ubuntu 18.04.1 LTS の仮想マシンはデフォルトでディスクが 11GB しかなく、すぐにディスクフルになってしまったので拡張しました。

# Hyper-V 仮想ディスクのサイズ拡張

先に拡張したい仮想マシンは Power OFF にしておきます。

1. 「Hyper-V マネージャー」を起動する
2. 「ディスクの編集...」で仮想ハードディスクの編集ウィザードを実行
3. 「ディスクの場所」で [参照] から仮想マシンの vhdx ファイルを選択
4. 操作から「拡張」を選択して、増やしたいサイズを入力
5. [完了] して変更を適用する。

今回は 11GB -> 300GB にしました。

これで Hyper-V 仮想ディスクの容量が拡大します。

# Ubuntu 内のパーティション拡張

さて、以下で見ると Ubuntu でパーティションを変えてないためサイズがそのままです。

```shell-session
$ df -h
$ sudo fdisk -l
```

今度は Ubuntu 仮想マシンのほうで拡張したディスクにあわせてパーティションを拡大します。

```shell-session
$ sudo parted
GNU Parted 3.2
Using /dev/sda
Welcome to GNU Parted! Type 'help' to view a list of commands.
(parted) print                                                            
Warning: Not all of the space available to /dev/sda appears to be used, you can
fix the GPT to use all of the space (an extra 606085120 blocks) or continue with
the current setting? 
Fix/Ignore? Fix                                                           
Model: Msft Virtual Disk (scsi)
Disk /dev/sda: 322GB
Sector size (logical/physical): 512B/512B
Partition Table: gpt
Disk Flags: 

Number  Start   End     Size    File system  Name  Flags
14      1049kB  5243kB  4194kB                     bios_grub
15      5243kB  116MB   111MB   fat32              boot, esp
 1      116MB   11.8GB  11.7GB  ext4

(parted) resizepart 1                                                     
Warning: Partition /dev/sda1 is being used. Are you sure you want to continue?
Yes/No? Yes                                                               
End?  [11.8GB]? 322GB                                                     
(parted) print                                                            
Model: Msft Virtual Disk (scsi)
Disk /dev/sda: 322GB
Sector size (logical/physical): 512B/512B
Partition Table: gpt
Disk Flags: 

Number  Start   End     Size    File system  Name  Flags
14      1049kB  5243kB  4194kB                     bios_grub
15      5243kB  116MB   111MB   fat32              boot, esp
 1      116MB   322GB   322GB   ext4
```

最後に resize2fs でファイルシステムのサイズを変更します。

```shell-session
$ sudo resize2fs /dev/sda1
resize2fs 1.44.1 (24-Mar-2018)
Filesystem at /dev/sda1 is mounted on /; on-line resizing required
old_desc_blocks = 2, new_desc_blocks = 38
The filesystem on /dev/sda1 is now 78584865 (4k) blocks long.
```

これで拡大した容量が使えるようになりました。
COCOAPODSでよく使ってそうなライブラリ

自分の中で有名そうなPOD一覧　＋　一言
結構汎用性の高そうな物中心
かなり偏った知識な感じ＋思い込みで書いています。
ツッコミなどお待ちしております。

記事を書いている時点の最新Version
iOS 12　/　xcode 10.0　/　Swift 4.2

## Alamofire　★29K
https://github.com/Alamofire/Alamofire
通信系のライブラリ

## SwiftyJSON　★15K
https://github.com/SwiftyJSON/SwiftyJSON
JSONのパーサー
但し、Swift4ではもともとついているので今は不要になってきているか？

## RxSwift　★17K
https://qiita.com/owen/items/c51c6ec27c9e2f5804b0

MVVMアーキテクスチャを利用するときによく使われている

## R.swift　★6K
https://github.com/mac-cain13/R.swift
リソースを使うときにtypoの心配が無くなる
RxSwiftと名前が似ている気がするが全くの別物

↓参考
https://qiita.com/shimesaba/items/e7832b2559c3c89caff1

## Realm　★13K
https://github.com/realm/realm-cocoa
DB、CoreDataより早いらしい。

## FireBase
https://firebase.google.com/docs/ios/setup?hl=ja
Googleが運用しているmBaas
サーバーを用意できなくても、このサービス使えばなんとかなるみたいな感じ
ユーザー管理部分とかこれ使えばできる？

↓記事が色々
https://qiita.com/owen/items/c51c6ec27c9e2f5804b0
https://qiita.com/Simmon/items/dc3490be59acea7fbe0c

## 番外編
PODを探す上で便利そうなサイト（まとめとか）

https://cocoapods.org/
→Table　Cellとか、とりあえずそれっぽい検索ができる
https://www.cocoacontrols.com/
→UI系を探すときに便利
https://qiita.com/homyu/items/e36faf42e64577f76692
→まとめてる人がいた便利
Objectをループさせて条件判定するときはarrayに変換してsome()とevery()を使うと便利

## 概要
jsのObjectではarrayの便利な関数が使えません。
なので、一度`Object.keys()`を使ってキーのarrayを取得してあげる必要があります。
その後メソッドチェーンしてあげればarrayのメソッドがそのまま使えます。

## オブジェクトの中のキーが有効なものであるか確認して処理を分岐したい
今回は一つでもvalueが空ではないプロパティがあればデータを有効とみなすので`array.some()`を使ってみましょう。
[MDN公式ドキュメント](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array/some)

array.some()とは…
> some() メソッドは、配列の少なくとも 1 つの要素が、渡された関数によって実施されるテストに通るかどうかをテストします。

↑の通り、1つでも有効なキーがあれば結果としてtrueを返すということですね。

### サンプルコード
```javascript
function isArrayActive(obj) {
  return Object.keys(obj).some(function (key) {
    return obj[key] ? true : false;
  });
}

// 無効ユーザ
const user = {
  name: "",
  type: "",
  flag: false,
  data: null
};

// 有効ユーザ
const user2 = {
  name: "Tanaka",
  type: "",
  flag: false,
  data: null
};

if(isArrayActive(user)) {
  console.log("active");
} else {
  console.log("not active");
}


if(isArrayActive(user2)) {
  console.log("active");
} else {
  console.log("not active");
}

// not active
// active
```

このサンプルコードの場合、オブジェクトのプロパティに1つでも有効なものがあればtrueと判定されます。`name`と`type`が有効で`upload`がtrueのデータのオブジェクト…とか判定しようとする時はsomeは使えないですね…
オブジェクトのプロパティに対して複数条件指定して有効であるか調べるなら、everyを使うのが良さそうです。

[MDN公式ドキュメント](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array/every)

> every() メソッドは、与えられた関数によって実行されるテストに、配列のすべての要素が通るかどうかをテストします。

```javascript
function isUserActive(user) {
  const isActive = {
    name   : user.name             ? true : false,
    type   : user.type === "human" ? true : false,
    upload : user.upload           ? true : false
  };
  // Objectの要素全てがtrueであればtrue、ひとつでもfalseがあればfalse
  return Object.keys(isActive).every(function (type){
    return isActive[type];
  });
}

const user = {
  name   : "",
  type   : "",
  upload : false,
  data   : null
};

const user2 = {
  name   : "Tanaka",
  type   : "human",
  upload : true,
  data   : null
};

console.log(isUserActive(user));
console.log(isUserActive(user2));

// false
// true
```

こんな感じでしょうか。
また、return部分ですが

```javascript
if(isActive.name && isActive.type && isActive.upload) {
  return true;
}
```
みたいな感じでもうまくいきますが、条件が増えたときこちらの条件式に手を加えなきゃいけなくなるので2度手間になります。arrayのテストメソッドを上手く使ってスリムに書くといい感じなのでおすすめです。
【個人的備忘録】　Eclipseのjavafxで作成する　ボタンの配置(HBox・VBoxの場合)

```
◎サンプルコード
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.HBox;
import javafx.stage.Stage;



public class Sample extends Application {
	public static void main(String[] args) {
		launch(args);
	}

	public void start(Stage stage) {
		stage.setWidth(500);
		stage.setHeight(500);

		Button button1 = new Button("1");
		Button button2 = new Button("2");
		Button button3 = new Button("3");
		Button button4 = new Button("4");
		button1.setPrefSize(100,100);
		button2.setPrefSize(100,100);
		button3.setPrefSize(100,100);
		button4.setPrefSize(100,100);


		HBox box = new HBox(1);//VBoxの場合は、ここを VBox box = new VBox(1)に変更する　　　  
   　　　box.getChildren().addAll(button1,button2,button3,button4);


		BorderPane root = new BorderPane();
		root.setLeft(box);
		stage.setScene(new Scene(root));
		stage.show();
	}
}
```
MacBook TouchBar の動作がおかしいときの対処

TouchBar は固まったり表示が崩れたりすることがたまにあります。
試すことは以下の2つです。

# 別のアプリケーションにフォーカスする
アクティブにしているアプリを切り替えると治ることがあります。
Chrome から エディタ、エディタから Finder など切り替えてみましょう。

# Touchbar を再起動する

以下のコマンドで再起動します。

```
#!/bin/sh
sudo pkill "TouchBarServer" && sudo pkill "Touch Bar agent"
killall ControlStrip
```

cli を作ったのでどうぞ。

```sh
$ restart-touchbar
```

```sh
$ npm i -g restart-touchbar
```


GitHub: https://github.com/elzup/restart-touchbar
fstabについて

サーバーの定義書を作る際に調べたついでに備忘録です。

# fstabとは

>/etc/fstab ファイルはディスクパーティションや様々なブロックデバイス、リモートファイルをどうやってファイルシステムにマウントするかを記述します。
[*fstab - ArchWiki*](https://wiki.archlinux.jp/index.php/Fstab) *より引用*

ということで、マウントに関することが書かれているファイルです。
読み込まれるタイミングは起動時やシステムマネージャの設定を再読み込みしたとき。
つまり、起動時に自動でマウントするのに使います。
fstabを変更したあと、設定を反映させるには再起動もしくは`mount -a`を実行する必要があり。

# ファイルの例
ファイルの中身を見ます。

```
$ cat /etc/fstab
```

実行結果

```:/etc/fstab
/dev/sda1              /             ext4      defaults,noatime      0      1
/dev/sda2              none          swap      defaults              0      0
/dev/sda3              /home         ext4      defaults,noatime      0      2
```
# フィールドの定義
前述の結果は以下の表のようにフィールドに対応しています。
それぞれスペースかタブで区切られています。

|file system|dir  |type|options         |dump|pass|
|-----------|-----|----|----------------|----|----|
|/dev/sda1  |/    |ext4|defaults,noatime|0   |1   |
|/dev/sda2  |none |swap|defaults        |0   |0   |
|/dev/sda3  |/home|ext4|defaults,noatime|0   |2   |

それぞれのフィールドの意味は

**file system**
マウントされるパーティションやストレージデバイス
**dir**
file systemがマウントされるマウントポイント
**type**
マウントされるパーティションやストレージデバイスのファイルシステムタイプ。たくさんあるのでざっくり紹介。

| file system | 説明 |
|:-----------:|:----|
| ext2        |古いlinuxで使われていたファイルシステム。ジャーナリング機能がない。|
| ext3        |ext2にジャーナリング機能を追加したファイルシステム。|
| ext4        |現在のlinuxでの標準ファイルシステム|
| btrfs       |オラクル製ファイルシステム|
| xfs         |CentOS7のデフォルトファイルシステム|
| iso9660     |CD-ROM、DVD-ROMのファイルシステム|
| swap        |swap用のファイルシステム|
| auto        |どのファイルシステムかをマウントに推測させる。|

2014年の記事ですが、以下の記事でファイルシステムまとめが見れます。
[Linuxファイルシステムをまとめてみました](https://qiita.com/sion_cojp/items/c8e015db39ddbf43012e)

**option**
ファイルシステムのマウントオプション。ファイルシステムに固有なものもあります。
[Linux：noatime でパフォーマンスは向上するのか？](https://slacknotebook.com/linux-notime-and-relatime-performance/)

**dump**
dumpコマンドによるバックアップ対象にするかを決める。1か0を設定できる。
1にならバックアップ対象に、0ならdumpの対象外になる。

**pass**
起動時にfsckがチェックする順番。0,1または2を設定できる。
1はチェックの優先度が一番高い。ルートファイルシステム(/)は1である必要がある。
2はその他のファイルシステムをいれればよい。
0のファイルシステムはチェックされない。
困ったときの git reset コマンド集

# 困ったときの git reset コマンド集

## Introduction
Gitで間違ってadd、commitしたときに緊急回避するためのコマンド集.

## Gitがリモート上がるまで
Gitは下記の順番でリモートにアップロードされます。

```
ワーキングツリー → インデックス → ローカルリポジトリ → リモートリポジトリ
```

- ワーキングツリー : 最新のファイル状態
- インデックス : コミットするためのファイル状態
- ローカルリポジトリ : ファイルの変更履歴を記録(ローカル環境)
- リモートリポジトリ : ファイルの変更履歴を記録(共有できる)

下記の用にそれぞれに変更履歴を反映させていきます。

- git add    : 「ワーキングツリー → インデックス」
- git commit : 「インデックス → ローカルリポジトリ」
- git push   : 「ローカルリポジトリ → リモートリポジトリ」

## resetコマンド
間違えて"git add"、"git commit"をした場合、"git reset"を行うことでそれらの操作をなかったことにできます。

- オプション
 - reset --hard ：add、commit、ワーキングツリーの取り消し
 - reset --mixed：commitとaddの取り消し。
 - reset --soft ：commitのみ取り消し。

- HEAD
 - 最新のコミットの状態を表している
 - @でも表現ができる : HEAD = @
 - ^ や ~ をつけることで直前のコミットを表すことができる : HEAD^ 、 HEAD~

- コマンド集

```bash

直前のコミットをなかったことにする
git reset --soft HEAD^

直前のコミットを取り消し
git reset --hard HEAD^

コミット後の変更を全部消したい
git reset --hard HEAD

addを取り消したい
git reset --mixed HEAD

git resetをなかったことにする
git reset --hard ORIG_HEAD
```

## Conclusion
やっちまったときはgit resetで逃げましょう！！＾＾
でもやりすぎるとわけが分からなくなるので注意です！！

## 参考文献

- git resetでどのオプション(hard, mixed, soft)を指定すべきか、シチュエーション別に分けてみる
https://qiita.com/kmagai/items/6b4bfe3fddb00769aec4

- [git reset (--hard/--soft)]ワーキングツリー、インデックス、HEADを使いこなす方法
https://qiita.com/shuntaro_tamura/items/db1aef9cf9d78db50ffe
Bootstrapに負けてCSSが反映されない

#課題
外部ファイル読み込みのコードを書いているにもかかわらずCSSが読み込めない
BootStrapのコードが反映される

#原因
読み込みの順番により決まる優先順位がBootStrapのほうが高かったため。

#解決
記述の順番を変えてやる。

```views/layouts/application.html.erb
  <head>
    --省略--
　　★Bootstrapの読み込み
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css" integrity="sha384-MCw98/SFnGE8fJT3GXwEOngsV7Zt27NXFoaoApmYm81iuXoPkFOJwJ8ERdknLPMO" crossorigin="anonymous">
    <script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.3/umd/popper.min.js" integrity="sha384-ZMP7rVo3mIykV+2+9J3UJ46jBk0WLaUAdn689aCwoqbBJiSnjAK/l8WvCWPIPm49" crossorigin="anonymous"></script>
    <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/js/bootstrap.min.js" integrity="sha384-ChfqqxuZUCnJSK3+MXmPNIyE6ZbWh2IMqE241rYiqJxyMiZ6OW/JmZQ5stwEULTy" crossorigin="anonymous"></script>

　　★CSSのスタイルシートの読み込み
    <%= stylesheet_link_tag    'application', media: 'all', 'data-turbolinks-track': 'reload' %>
  </head>
```
CSSは同じスタイルを指定したとき、**後から記述したものの方が優先される**ようになっている。だからCSSのスタイルシートの読み込みを後に持ってくることで上書きできるようになる。

#注意
優先順位は読み込みの順番だけではないので、その都度気を付けていく必要がある。
[Android] イベントを取り扱う為のLiveData

イベントを取り扱う為の LiveData です。observe 開始時に過去のイベントが発火するのを防止します。

```kotlin
@MainThread
class LiveEvent<T> : LiveData<T>() {

    init {
        super.setValue(null)
    }

    @MainThread
    override fun observe(owner: LifecycleOwner, observer: Observer<T>) {
        val isFirst = AtomicBoolean(true)
        super.observe(owner, Observer {
            if (isFirst.getAndSet(false)) return@Observer
            observer.onChanged(it)
        })
    }

    @MainThread
    public override fun setValue(t: T?) {
        super.setValue(t)
    }
}
```

ただこの実装だと、監視を開始後の初めの `onStart()` 前に発生したイベントは拾えないので注意です。

### 参考にさせていただいた記事

- [Android: 拡張関数でLiveDataのSingle Eventを扱う](https://satoshun.github.io/2018/05/singlelivedata/)
Chrome DeveloperToolだけでできるお手軽スクレイピング

##　先に答え

https://www.minkou.jp/university/ranking/deviation/c=2/ct=2
から大学名だけ取出したいときには、こういうJavaScriptをChrome DeveloperToolのコンソールにペースト

```js
var list = $$('.rankMod-schoolList-detail-name a')
list.map(x=>x.innerText).join("\n")
```

画面上ではこういう感じ

![SS 2018-10-12 13.33.05.png](https://qiita-image-store.s3.amazonaws.com/0/53489/fc820e7f-f349-78c0-b7d8-83867b4f5768.png)

## 解説

```js
// ＄＄関数で、CSSセレクタを指定すると、要素が配列で返って来ます
var list = $$('.rankMod-schoolList-detail-name a')
// 帰ってきた配列の各値はノードなので、テキストに置き換えた配列にします
// テキストの配列に変換されたら、それを改行でJOINします
list.map(x=>x.innerText).join("\n")
```

## 別の方法

`$$`と似たメソッドにquerySelectorAllもあります。ほとんど同じ機能なのですが、`＄＄`が配列を返すのに対して、querySelectorAllはNodeListを返します。NodeListが曲者で、配列ではないため、mapが使えません。一度配列に変換するという一手間を入れるのが面倒なので、今回は`$$`を使いました。
macでC++のOpenCVを動かす。

Homebrewがインストールされているとします。

```sh 
brew install pkg-config
brew install opencv  
```

適当なプログラムを書きます。

```c++:test_opencv.cpp
#include <opencv2/opencv.hpp>

int main(){
    cv::Mat a = cv::imread("img.jpg", 1); 
    cv::imshow("hello", a); 
    cv::waitKey();
}
```

コンパイル時に`pkg-config`を使って必要なヘッダやライブラリを設定します。

```sh
g++ `pkg-config --libs --cflags opencv` test_opencv.cpp
```

動作確認をします。

```sh
./a.out
```
jsdoでweb3.js

#概要
jsdoでweb3.jsやってみた。

#写真

![](http://jsdo-static-contents.s3.amazonaws.com/images/capture/8/C/s/8CsX.jpg?t=1539317894)

#サンプルコード

```
var out1 = document.getElementById('src');
var Web3 = require('web3');
var web3 = new Web3();
web3.setProvider(new web3.providers.HttpProvider('http://127.0.0.1:8545'));
function getCoinbase() {
    var res = web3.eth.coinbase;
    out1.value += 'coinbase: ' + res + '\n';
}
function getaccounts() {
    var res = web3.eth.accounts;
    out1.value += 'account: ' + res + '\n';
}
function getblockNumber() {
    var res = web3.eth.blockNumber;
    out1.value += 'blockNumber: ' + res + '\n';
}
function getbalance() {
    var res = web3.eth.getBalance(web3.eth.coinbase);
    out1.value += 'getBalance: ' + res + '\n';
}
function getmining() {
    var res = web3.eth.mining;
    out1.value += 'mining: ' + res + '\n';
}

```

#成果物
http://jsdo.it/ohisama1/8CsX

以上。
Vue.js dataをhtml data属性から取得

SSRサイトでVue.jsを導入する際に、モデルをDOMの各要素に吐き出すのではなく、htmlのdata属性にJSONオブジェクトして吐き出してもらいVueで利用する方法です。

これで、バックエンド側とフロントエンドでの棲み分けがしやすくなります。

これまではバックエンド側でもHTMLをガリガリいじってみっともない形に変貌するということが起こっていました。もう触らないでねという願いも込めて。

今回はサーバサイドでdata属性(data-model)にセットしたポイントを表示するというページです。

##今回のファイル
シンプルに必要最低限のファイル群

```bash
$ src
├── app.js
├── _mixin.js
├── App.vue
└── index.html
```

### index.html
よくあるサンプルの形。

```html
<!DOCTYPE html>
<html lang="en">
<head>
  <title>Sample</title>
</head>
<body>
  <div id="app" data-model='{ "point": 8000 }'></div>
</body>
</html>
```

### app.js
よくあるサンプルの形。App.vueをインポートして#appにレンダリングします。
テンプレートはApp.vueで定義しています。
今回は数値に3桁カンマをつけるfilterも利用しています。

```javascript
import Vue from 'vue'
import App from './App.vue'

// 数値の3桁カンマ処理共通フィルタ
Vue.filter('getCommaNum', (val) => {
  return val.toString().replace(/(\d)(?=(\d{3})+$)/g, '$1,')
})

new Vue({
  el: '#app',
  render: h => h(App)
});
```

### _mixin.js
今回のポイントとなるJSです。
複数のページでの共通処理として定義したモジール。
data()にてDOMからdata属性に設定されたオブジェクトモデルをVue.$dataにセットします。
このモジュールを後述のApp.vueでimportします。

```javascript
export default {
  data() {
    const el = document.getElementById('app')

    return JSON.parse(el.dataset.model)
  }
}
```

### App.vue
"_mixin.js"をインポートします。これをVueインスタンスのmixinsにセットします。
これで、取得したdataがセットされます。
今回はpointに3桁カンマをつけるfilterも噛ませています。

```javascript
<template>
  <div id="app">
    <p>あなたのポイントは、{{ point | getCommaNum }}ポイントです。</p>
  </div>
</template>

<script>
import mixin from '@/_mixin'

export default {
  mixins: [mixin],
  name: "App"
};
</script>
```

これだけです。
他にもいろんなやり方があれば教えて欲しいです。SSRサイトでVueをどう使っていますか？
Ubuntu18.04にRTX 2080のドライバーをインストールする

記事作成段階(2018-10-14)ではaptでインストールできるnVidiaのドライバーはRTX2080に対応していないため，nVidiaの公式サイトから`.run`ファイルをダウンロードし，インストールする．

この記事の作成にあたって以下の記事をもとに作成しました．ありがとうございました．
[nvidiaのdriverをインストール(ubuntu)](http://mikemoke.hatenablog.com/entry/2015/06/23/004739)

また，Ubuntu18.04ではnVidia Driverを容易にインストールできる方法もあるようなので下記の記事も参照されたし．
[開発メモ その114 Ubuntu 18.04でNvidia Driverをインストールする ](https://taktak.jp/2018/05/01/2974)

# 環境

OS : Ubuntu 18.04
CPU : intel Core i7 8700K
GPU : GEFORCE RTX 2080

GPU Driver:
Linux x64 (AMD64/EM64T) Display Driver 
バージョン : 410.57
リリース日 : 2018.9.19
オペレーティングシステム : Linux 64-bit
言語 : Japanese
ファイルサイズ :	102.25 MB 

# 手順1:ドライバーの入手
下記URLから対応したドライバーの`.run`ファイルをダウンロードする
https://www.nvidia.co.jp/Download/index.aspx?lang=jp

```:実行権限の変更
$ sudo chmod +x ダウンロードした.run
```

# 手順2:GUIサービスの停止
以下のコマンドを実行するとGUIが停止する場合があるのでCUIに切り替える．

```
$ sudo service lightdm stop
$ sudo service gdm stop
```

上記のコマンドを実行後，GUIが停止しない場合でも"Ctrl+Alt+F1"でCUIに切り替える．
(何故か私の環境では"Ctrl+Alt+F2"で切り替えを行った.)

# 手順3:すでにインストールされているnVidiaドライバーの停止
私の場合は，クリーンインストールされた状態から開始したため，以下のコマンドは実行していないが，GPUを差し替えた場合などは既存のドライバーを停止する．

```
sudo apt-get purge nvidia*
```

# 手順4:インストーラーの実行
クリーンインストールから始めた場合は必要なものをインストール

```:.runファイルの実行に必要なものをインストール
sudo apt-get install build-essential
```

```:.runファイルの実行
sudo ./ダウンロードした.run
```
# 手順5:再起動
```:再起動
sudo reboot
```

# 手順6:Driverがインストールされているか確認
```:実行結果
$ nvidia-smi
Fri Oct 12 13:15:09 2018       
+-----------------------------------------------------------------------------+
| NVIDIA-SMI 410.57                 Driver Version: 410.57                    |
|-------------------------------+----------------------+----------------------+
| GPU  Name        Persistence-M| Bus-Id        Disp.A | Volatile Uncorr. ECC |
| Fan  Temp  Perf  Pwr:Usage/Cap|         Memory-Usage | GPU-Util  Compute M. |
|===============================+======================+======================|
|   0  GeForce RTX 2080    Off  | 00000000:01:00.0  On |                  N/A |
|  0%   36C    P0    37W / 225W |    147MiB /  7949MiB |      0%      Default |
+-------------------------------+----------------------+----------------------+
                                                                               
+-----------------------------------------------------------------------------+
| Processes:                                                       GPU Memory |
|  GPU       PID   Type   Process name                             Usage      |
|=============================================================================|
|    0      1606      G   /usr/lib/xorg/Xorg                            71MiB |
|    0      2032      G   /usr/bin/gnome-shell                          72MiB |
+-----------------------------------------------------------------------------+
```

この計算機は機械学習用のサーバとして利用する．
NVIDIA GPU Cloud(NGC)を使用することでとりあえずtensorflowの実行ができたので暇があればそれについても記事を書きたい．（未定）
ニュートン法で平方根を求める

#はじめに
今回はニュートン法で平方根を求めていきたいと思います。

#簡単に実装

```cpp:Source.cpp
#include <iostream>

namespace sqn {

	inline const double func(const double x_, const double num_) { return x_ * x_ - num_; }
	inline const double func2(const double x_) { return 2 * x_; }
	const bool abs_eps(double num_) {
		constexpr double EPS{ 0.0001 };
		if (num_ < 0.0) num_ *= -1;
		return (num_ < EPS);
	}
	//平方根を求める
	double sqrtn(double num_) {
		double a{ 1.0 };
		const double c{ num_ };
		int i{};
		while (true) {
			num_ = a - func(a, c) / func2(a);
			std::cout << i << "回目： x = " << num_ << std::endl;
			if (abs_eps(a - num_)) break;
			else a = num_;
			++i;
		}
		return num_;
	}
}

//メイン関数
int main() {
	//平方根を求める
	sqn::sqrtn(256.0);
	return 0;
}



```

```:出力結果
0回目： x = 128.5
1回目： x = 65.2461
2回目： x = 34.5849
3回目： x = 20.9935
4回目： x = 16.5939
5回目： x = 16.0106
6回目： x = 16
7回目： x = 16
```

ニュートン法のループ回数と途中経過の値を出力します。

#ライブラリとして実装

```cpp:Sqrtn.hpp
namespace sqn {
	inline const double func(const double x_, const double num_) { return x_ * x_ - num_; }
	inline const double func2(const double x_) { return 2 * x_; }
	const bool abs_eps(double num_) {
		constexpr double EPS{ 0.0001 };
		if (num_ < 0.0) num_ *= -1.0;
		return (num_ < EPS);
	}
	double sqrtn(double num_) {
		double a{ 1.0 };
		const double c{ num_ };
		while (true) {
			num_ = a - func(a, c) / func2(a);
			if (abs_eps(a - num_)) break;
			else a = num_;
		}
		return num_;
	}
}
```

```cpp:Source.cpp
#include <iostream>
#include "Sqrtn.hpp"

//メイン関数
int main() {
	//平方根を求める
	std::cout << sqn::sqrtn(256.0) << std::endl;
	return 0;
}
```

```:出力結果
16
```

平方根の値を出せました。

##ソースコードのライセンス

These codes are licensed under CC0.
[![CC0](https://mirrors.creativecommons.org/presskit/buttons/88x31/svg/cc-zero.svg "CC0")](http://creativecommons.org/publicdomain/zero/1.0/deed.ja)

ソースコードは自由に使用してください。
C++ Builder XE4 > TThread > 「実行中または一時停止中のスレッドに対してはStartを呼び出せません。」 > : TThread(/* CreateSuspended= */ true)で作ったスレッドのnew直後のStartは問題ない

```txt:動作環境
C++ Builder XE4
```

C++ Builder 2010以降、TThreadのResume()はdeprecatedになり、Start()の使用が推奨になっているようだ。

### Startのエラー

一方で、下記のようにするとエラーとなり、「実行中または一時停止中のスレッドに対してはStartを呼び出せません。」というダイアログが表示される。

```Unit1.cpp
...
		m_thr_XXX = new TThreadXXX();
		m_thr_XXX->Start();
		Sleep(100);
		m_thr_XXX->Suspend();
		Sleep(100);
		m_thr_XXX->Start();
```

ここでm_thr_XXXはTThead型の変数。
CreateSuspended=false定義として実装している。

上記でエラーが出るのは２回目のStart()。

つまりは以下である。

- Start()時エラーが出ない条件
    - CreateSuspended=falseでTThreadをnew直後にStart()
- Start()時エラーが出る条件
    - Suspend()したものをStart()

### 参考

以下においてはResume()の代わりにどうするかの様々な回答がある。

- [TThread.resume is deprecated in Delphi-2010 what should be used in place?](https://stackoverflow.com/questions/1418333/tthread-resume-is-deprecated-in-delphi-2010-what-should-be-used-in-place)

### Startでエラーが出る場合の回避?

Start()でエラーが出る場合でも`Suspended = false;`ではエラーが出ない。

- [c++ builder XE4 > TThread > Suspended()後のStart() > 実行中または一時停止中のスレッドに対してはStartを呼び出せません](https://qiita.com/7of9/items/09542ff8bace30712593)

`Suspended = false;`は以下のIlyaさんによる回答にもあるようにResume()と同等のようだ。
https://stackoverflow.com/questions/1418333/tthread-resume-is-deprecated-in-delphi-2010-what-should-be-used-in-place
windowsでsolcjsでno such fileエラーの解決方法

### はじめに
windowsでのsolidity開発の情報って少ないですよね。。
解決策というほど大げさなものじゃないですが、少しハマってしまったので一応メモしておきます。

### エラーについて
solcjsを使ってsolファイルをコンパイルしてabiファイルを作成できるのですが、
以下のようにするとエラーになっちゃうんですよね。
コマンド
`solcjs .\hoge.sol --abi`
エラー
`Error: ENOENT: no such file or directory`

### 解決策
シンプルすぎてアレですが、「.\」の部分が原因だったようで、
`solcjs hoge.sol --abi`
ってやると正常にコンパイルが完了してabiファイルを作成できます。

### おわりに
Solidityに限らず開発系の情報はMacの方が多いですよね。
次PC買い替えるときはMacにしようと思いました。
Google Apps Scriptを使ってスプレッドシートから一斉メールを送信する

メール送信を手動でGmailに貼り付けてやっている人がいたので簡単にスクリプトを作ってみました。

# シート作成

1.スプレッドシートを新規作成します。

2.シート名を「メール送信リスト」とします。

3.１行目を下記のような表にします。２行目以降はデータとします。
※列の項目名はアレンジしてもかまいません。

| | A | B | C | D | E |
|:-:|:-:|:-:|:-:|:-:|:-:|
|1|氏名|メールアドレス|タイトル|メッセージ|URL|
|2|hoge|hoge.com|テスト|ほげ|http://hoge.com/|
|3|

# スクリプトエディタ

4.「ツール」→「スクリプトエディタ」を開き、下記のコードをコピペします。

```
function onOpen(e) {
  var spreadsheet = SpreadsheetApp.getActive();
  var menuItems = [
    {name: '送信実行', functionName: 'sendEmails'}
  ];
  spreadsheet.addMenu('メール送信', menuItems)
}

function sendEmails(){
  var selection = Browser.msgBox("メールを一斉送信しますがよろしいですか？", Browser.Buttons.YES_NO);
  if (selection == 'no') {
    Browser.msgBox('送信をキャンセルしました。');
    return;
  }
  var ss = SpreadsheetApp.getActiveSpreadsheet();
  ss.setActiveSheet(ss.getSheetByName("メール送信リスト"));
  var sheet = SpreadsheetApp.getActiveSheet();
  var dataRange = sheet.getRange("A2:F101"); // 一応100件まで 
  var data = dataRange.getValues();
  for(i in data){
    var rowData = data[i];
    var emailAddress = rowData[1];
    var recipient = rowData[0];
    var subject = rowData[2];
    var message = rowData[3];
    var url = rowData[4];
    var body = message + '\n\n' + url;  // 本文を作る
    if (emailAddress && subject && message){   
      MailApp.sendEmail(emailAddress, subject, body);
    }
  }
  Browser.msgBox('送信が完了しました。');
}
```
5.プロジェクト名は「メール」送信」等適当な名前で保存します。

6.編集→現在のプロジェクトのトリガーを開きます。

<img width="415" alt="キャプチャ2.PNG" src="https://qiita-image-store.s3.amazonaws.com/0/14768/22f83947-f4ab-ff8c-29c7-a35476d38c2f.png">

7.新規トリガーとして「onOpen」をスプレッドシート起動時に設定します。

<img width="544" alt="キャプチャ3.PNG" src="https://qiita-image-store.s3.amazonaws.com/0/14768/bf226039-b462-e76f-a1cd-8974cd37ddb4.png">


8.承認が求められるので「許可を確認」を押し、自分のGoogleアカウントで許可を行います。

<img width="421" alt="キャプチャ4.PNG" src="https://qiita-image-store.s3.amazonaws.com/0/14768/56c982c2-4fa3-50c5-4192-2bbd5bd88782.png">

<img width="385" alt="キャプチャ5.PNG" src="https://qiita-image-store.s3.amazonaws.com/0/14768/870017d1-08e0-f0de-ea19-90e91212d9f5.png">

# 完成

9.シートリロードしたらヘルプの横に「メール送信」という項目ができたら完成です。

<img width="123" alt="キャプチャ6.PNG" src="https://qiita-image-store.s3.amazonaws.com/0/14768/3e56a973-bf62-d7db-090c-9200b2c8ac00.png">
stylelint で設定できるAMP 用のルール

# 前提
- AMP ページのスタイルも stylelint の対象にしたい、という方向けです。
- なお、プルリク作成時にCircleCI経由で実行させることを想定しています。
- AMP ページのスタイルは基本的に `<style>` 内に書かれているので、別途プロセッサ stylelint-processor-arbitrary-tags のインストールが必要です。

# 環境
- stylelint @9.5.0
- npm 6.0.0
- Ruby On Rails 5.2.0
- CircleCI

# TL;DR
AMPに必要なルールだけを抜粋すると以下の通りです。

```yml:.stylelintrc.amp.yml
processors: ["@mapbox/stylelint-processor-arbitrary-tags"]
rules:
  ...
  declaration-no-important: true
  declaration-property-value-whitelist:
    transition: [/^(opacity|transform)\s\d*(\.\d+)*s\s(ease|ease-in|ease-out|ease-in-out|linear|step-start|step-end|step|cubic-bezier|frames)+/]
  selector-class-pattern: "^(?!.*-amp-).+$"
  ...
```

なお、AMPでは `@keyframes` 内に書いていいプロパティが制限されているんですが、stylelintのルールでは現状できないようなので、本ファイルでは考慮していません。
https://www.ampproject.org/docs/design/responsive/style_pages#restricted-styles


# 詳細
AMP ページでは、書いてはいけない CSS 、制限のある CSS が定められています。
![スクリーンショット 2018-10-12 12.02.08.png](https://qiita-image-store.s3.amazonaws.com/0/156176/c017b615-3ed7-4bc7-96b5-f18659e0130f.png)

### 禁止されている CSS
- `!important` を使用してはいけない
- `<link rel="stylesheet">` を使用してはいけない
- `-amp-` で始まるクラス、`i-amp` タグをセレクターとして使用してはいけない

### 制限のある CSS
- `transition` プロパティには、`opacity|transform|-vendorPrefix-transform` のどれかしか使ってはいけない（正確に言うとGPUを使用する値しか使ってはいけない。今後CSSの仕様が変わって増えることもあるかも…？）。
- `@keyframes` 内では、 `opacity|transform|-vendorPrefix-transform` のどれかしか使ってはいけない（正確に言うとGPUを使用する値しか使ってはいけない。今後CSSの仕様が変わって増えることもあるかも…？）。

## stylelint で指定できるAMPのルール

上記のルールのうち、現状で stylelint で指定できるルールは以下のみです。
- `!important`
- `-amp-` クラス、 `i-amp` タグ
- `transition`

`<link>` タグはそもそもスタイルを検知できなさそうなのでさておき、 `@keyframes` は `!important` 使っちゃだめ！というルールはあるんですが、それ以外はなさそうな感じです。

## CircleCI で自動で stylelint を実行
このあたりはプロジェクトによるのでおまけなんですが、自分の関わっているプロジェクトでは、いちいち手動で stylelint を実行するのはめんどくさいので、プルリクを出した段階で回る CircleCI 上で実行させています。


以下　のように、 `lint` というジョブを用意して、その中でスクリプトを実行させています。

```yml:.circle/config.yml
...
  lint:
    steps:
      - attach_workspace:
          at: ~/project
      - run:
         name: Run stylelint
         command: bash ./.circleci/stylelint_exec.sh
...
```


スクリプトの中身を抜粋するとこんな感じです。 master と差分のあるファイル（html|erb|scss|css）を抽出して、 diff_files に保存。それを for 文で回して、 `.amp` 拡張子のついたファイルだけに AMP 用の設定ファイルを適用して stylelint を実行しています。

```bash:stylelint_exec.sh
for diff_file in $diff_files; do
  if [[ $diff_file =~ \.amp ]]; then
    ./node_modules/.bin/stylelint -f verbose $diff_file --config .stylelintrc.amp.yml
  else
    ./node_modules/.bin/stylelint -f verbose $diff_file --config .stylelintrc.yml
  fi
done
```

# 参考文献
- https://www.ampproject.org/docs/design/responsive/style_pages
- https://stylelint.io/user-guide/rules
Unexpected attribute 'dispatch' for object of type AppInfoExternal.


## 事象

Google App Engineのデプロイの際、メンテナンス画面に切り替えできるように dispatchファイルを `dispatch-to-app.yaml` と `dispatch-to-maintenance.yaml` の２種類用意した

```sh
$ gcloud app deploy dispatch-to-app.yaml
ERROR: (gcloud.app.deploy) An error occurred while parsing file: [/path/deployment/dispatch-to-app.yaml]
Unexpected attribute 'dispatch' for object of type AppInfoExternal.
```

実行すると `dispatch-to-app.yaml` が `app.yaml` と認識されてしまい、エラーとなってしまう

## 　解決

dispatchファイルは `dispatch.yaml` 　というファイル名しか認識してくれないようなので、 複数のdispatchファイルを管理したい場合はディレクトリ分割する必要がある

```
.
|-- app.yaml
|-- dispatch.yaml
|-- index.html
`-- maintenance
    |-- app.yaml
    |-- dispatch.yaml
    `-- index.html
```
ESP-32 ESP32S Development Board 2.4GHz Dual-Mode WiFi+Bluetooth Antenna Module 環境設定

# ESP32S Development Board 使用開始
## いろんな説明がありますが自分なりに整理しました。（途中）

## 基本的な情報はここ

https://github.com/espressif/arduino-esp32

## ボードマネージャを追加手順

### 下記の記事の通り、環境設定でボードマネージャを追加を追加

```
https://dl.espressif.com/dl/package_esp32_index.json
```

![ボードマネージャ](https://qiita-image-store.s3.amazonaws.com/0/77496/7ee80165-c70c-b6da-fce5-c0e32b689a0d.png)


### Installation instructions using Arduino IDE Boards Manager - 説明

```
Starting with 1.6.4, Arduino allows installation of third-party platform packages using Boards Manager. We have packages available for Windows, Mac OS, and Linux (32 and 64 bit).
Install the current upstream Arduino IDE at the 1.8 level or later. The current version is at the Arduino website.
Start Arduino and open Preferences window.
Enter https://dl.espressif.com/dl/package_esp32_index.json into Additional Board Manager URLs field. You can add multiple URLs, separating them with commas.
Open Boards Manager from Tools > Board menu and install esp32 platform (and don't forget to select your ESP32 board from Tools > Board menu after installation).
Stable release link: https://dl.espressif.com/dl/package_esp32_index.json
Development release link: https://dl.espressif.com/dl/package_esp32_dev_index.json

```

### プログラム書き込み時のメッセージ
他のboardに比較してコンパイルも書き込みも時間がかかります。

```

最大1310720バイトのフラッシュメモリのうち、スケッチが178840バイト（13%）を使っています。
最大327680バイトのRAMのうち、グローバル変数が13904バイト（4%）を使っていて、ローカル変数で313776バイト使うことができます。
esptool.py v2.3.1
Connecting........_____....._
Chip is ESP32D0WDQ6 (revision (unknown 0xa))
Features: WiFi, BT, Dual Core, VRef calibration in efuse
Uploading stub...
Running stub...
Stub running...
Changing baud rate to 921600
Changed.
Configuring flash size...
Auto-detected Flash size: 4MB
Compressed 8192 bytes to 47...

Writing at 0x0000e000... (100 %)
Wrote 8192 bytes (47 compressed) at 0x0000e000 in 0.0 seconds (effective 5957.9 kbit/s)...
Hash of data verified.
Compressed 15072 bytes to 9733...

Writing at 0x00001000... (100 %)
Wrote 15072 bytes (9733 compressed) at 0x00001000 in 0.1 seconds (effective 996.5 kbit/s)...
Hash of data verified.
Compressed 178976 bytes to 90738...

Writing at 0x00010000... (16 %)
Writing at 0x00014000... (33 %)
Writing at 0x00018000... (50 %)
Writing at 0x0001c000... (66 %)
Writing at 0x00020000... (83 %)
Writing at 0x00024000... (100 %)
Wrote 178976 bytes (90738 compressed) at 0x00010000 in 1.8 seconds (effective 799.9 kbit/s)...
Hash of data verified.
Compressed 3072 bytes to 144...

Writing at 0x00008000... (100 %)
Wrote 3072 bytes (144 compressed) at 0x00008000 in 0.0 seconds (effective 2048.0 kbit/s)...
Hash of data verified.

Leaving...
Hard resetting via RTS pin...

```
forループ内でリストの添字と値を同時に取得できるenumerate

```Python
foods = ["apple", "banana", "candy", "donuts"]

# こういうことをしたい
for i in range(len(foods)):
    print("foods[{}] = {}".format(i, foods[i]))
#foods[0] = apple
#foods[1] = banana
#foods[2] = candy
#foods[3] = donuts

# enumerateを使えばシンプル
for i, food in enumerate(foods):
    print("foods[{}] = {}".format(i, food))
#foods[0] = apple
#foods[1] = banana
#foods[2] = candy
#foods[3] = donuts

# 第二引数を与えるとiはその値から始まる
for i, food in enumerate(foods, 100):
    print("foods[{}] = {}".format(i, food))
#foods[100] = apple
#foods[101] = banana
#foods[102] = candy
#foods[103] = donuts

```
最小二乗法

> 最小二乗法 (least squares method) とは、測定で得られた数値の組を、
> 適当なモデルから想定される1次関数、対数曲線など特定の関数を用いて近似するときに、
> 想定する関数が測定値に対してよい近似となるように、
> 残差の二乗和を最小とするような係数を決定する方法、あるいはそのような方法によって近似を行うことである
(引用 Wikipedia)

## 線形最小二乗法

XY 座標を表す構造体を定義

```C#
struct Coordinate
{
	public double X { get; set; }
	public double Y { get; set; }
}
```

一次方程式 (y = Ax + B) を表す構造体を定義

```C#
// y = Ax + B
struct LinearEquation
{
	public double A { get; set; }
	public double B { get; set; }

	public double Solve(double x) => this.A * x + this.B;
}
```

LinearEquation クラスに最小二乗法の静的メソッドを追加

```C#
public static LinearEquation Approximate(Coordinate[] data)
{
	if (data == null) throw new ArgumentNullException(nameof(data));
	var n = data.Length;
	double Σx = 0, Σy = 0, Σxx = 0, Σxy = 0;
	for (int i = 0; i < n; i++)
	{
		var x = data[i].X;
		var y = data[i].Y;
		Σx += x;
		Σy += y;
		Σxx += Math.Pow(x, 2);
		Σxy += x * y;
	}
	return new LinearEquation()
	{
		A = (n * Σxy - Σx * Σy) / (n * Σxx - Math.Pow(Σx, 2)),
		B = (Σy - Σx * a) / n,
	};
}
```


### 最小二乗法の手順
1. フィッティングさせたい数式を決定 (例では y = Ax + B)
2. 二乗和の式を展開
3. 各係数で偏微分
4. 連立方程式を解いて係数の値を決定


### 導出例

線形方程式を定義

```math
f_x = Ax + B \\
\tag{1}
```

二乗和の式に式 (1) を代入して展開

```math
\begin{align}
\sum_{i=0}^{n-1} (y_i-f_i)^2
&= \sum{}y^2 - \sum{}2yf_x + \sum{}f_x^2 \\
&= \sum{}y^2 - 2A\sum{}xy - 2B\sum{}y + A^2\sum{}x^2 + 2AB\sum{}x + nB^2 \\
\end{align}
\tag{2}
```

式 (2) について、A と B のそれぞれで偏微分すると

```math
\begin{align}
-2\sum{}xy + 2A\sum{}x^2 + 2B\sum{}x = 0 \\
-2\sum{}y + 2A\sum{}x + 2nB = 0 \\
\end{align}
\tag{3}
```

式 (3) を連立方程式として解くと

```math
\begin{align}
A &= \frac{n\sum{}xy - \sum{}x \sum{}y}{n\sum{}x^2 - (\sum{}x)^2} \\
B &= \frac{\sum{}y - a\sum{}x}{n} \\
\end{align}
\tag{4}
```


### 指数関数に応用

指数方程式 (2-1) について

```math
y = B･e^{Ax}
\tag{2-1}
```

両辺の対数をとって (2-2) の形に変形

```math
log_e{y} = log_e{B} + Ax \\
\tag{2-2}
```

対数部分を式 (2-3) の変数に置き換え

```math
\begin{align}
y\,' &= log_e{y} \\
B\,' &= log_e{B} \\
\end{align}
\tag{2-3}
```

一次方程式と同じ式 (2-4) となる

```math
y\,' = Ax + B\,' \\
\tag{2-4}
```

これをコードで記述すると、下記のようにシンプルに！

```C#
// y = B･exp(Ax)
struct ExponentialEquation
{
	public double A { get; set; }
	public double B { get; set; }

	public double Solve(double x) => Math.Exp(this.A * x) * this.B;

	public static ExponentialEquation Approximate(Coordinate[] data)
	{
		var pt = data.Select(item => new Coordinate(item.X, Math.Log(item.Y)));
		var eq = LinearEquation.Approximate(pt.ToArray());
		return new ExponentialEquation() { A = eq.A, B = Math.Exp(eq.B) };
	}
}
```
commitとかmergeとかfetchとか

#書くに至った経緯


「Git = セーブポイント」
「add→commit→push、反対はpull」
程度の理解でなんとかなってきました。

しかし、
**「ローカルとリモートでこじれた複数のブランチをどう収拾するか」**
という事態に直面し、gitをより深く理解する必要に迫られました。

その中で
**「なるほどそういうことか！！！！！」**
とアハ体験ができたのでまとめます。

上で挙げた程度の理解度の方にとって、助けになれば幸いです。

**想定する読者：**
・add / commit / push / pull くらいは何となく使っている。
・でもGitの仕組みは実はよくわかってない。

#Git = セーブポイント？
Gitとゲームのセーブは似ています。
（最近のゲームはよく分からないので断っておくと、
　PS2のようなネットに繋がないゲームを想定して書いています）


テレビゲームをイメージしていただくと、
**1日目：**
今日初めてゲームをして、**ステージ１**をクリア。ここでセーブ.
↓
**2日目:**
今日は調子がよくて、**ステージ4**までクリア。ここでセーブ。
↓
**3日目:**
今日は**ステージ5**までクリア。ここでセーブ。


これをGitに置き換えると、
**テレビ画面に広がっている光景＝PCで実際にいじっているソースコードや、そのファイル**
**セーブデータ　　　　　　　　＝Gitの「ブランチ」**
ということになります。

注意する点は、
###「ブランチ＝ソースコードそのもの」ではない
という点です。

つまり、**commitやpushはファイルのコピーや保存とは違う**、ということですね。
テレビ画面に広がっている光景とセーブデータが同じではないように、
ブランチはあくまで、**以前の状態を再現するための履歴**です。

ゲームのセーブデータとGitのブランチが**違う点**は次の２つです。

#①セーブポイントが全て記録されていく
上のゲームの例だと、セーブデータが
「ステージ1　→　ステージ4　→　ステージ5」
と上書きされていきます。
3日目の時点では、ステージ5の状態しかロードできなくなります。


しかしGitは違います。
「ステージ1　→　ステージ4　→　ステージ5」
と、**全てのセーブポイントが記録されていきます。**
そして、どのポイントの状態も再現できます。


**このセーブポイントが連なったものが「ブランチ（=branch:枝）」です。**

#②ローカルとリモートの２箇所に保存する
**「ローカル」**というのは目の前にあるPC内の保管場所のこと、
**「リモート」**というのはインターネット上にある、別の保管場所のことです。

一人で開発するならローカルのみで十分なのですが、
複数人で開発する場合はローカル（＝各々のPC）だけしかないと困ったことが起こります。
**誰がどこを変えたのか**が非常に分かりづらくなってしまうからです。

それが分からないと、自分の書いたコードが誰かのコードとバッティングしてしまい、
**ゼロからやり直し**、ということも起こり得ます。

そこで、
**「全体としてはここまで進んでますよ**」という状態をリモートに置き、
各々がローカルで作業しつつキリの良いところでリモートを更新する、
というやり方で開発します。

リモート（＝全体の最新の状態）とローカル（＝各々のPC）の差分を把握することで、
バッティングややり直しを防いでいます。



#二種類のブランチ： 「〇〇〇」と「origin/〇〇〇」

ローカルにあるセーブデータのことを**「ローカルブランチ」**、
リモートのデータのことを**「リモートブランチ」**と呼びます。

これだけならシンプルで良いのですが、実はローカルにはもう一つブランチがあります。
**「リモート追跡ブランチ」**
と呼ばれるものです。
（※以降、ローカルにある「リモート追跡ブランチ」
　ではない方のブランチを**「ローカルブランチ」**と呼びます。）

リモートブランチをローカルブランチに反映させる際、
この**リモート追跡ブランチを経由して反映**させます。

リモート追跡ブランチはローカル/リモートブランチを作成すると自動生成され、
「origin/〇〇〇」という名前になります。

たとえば**apple**という名前のブランチだと、
**ローカル　　　　=> apple
リモート追跡　　=> origin/apple
リモート　　　　=> apple**
となります。


リモートブランチ→リモート追跡ブランチへ変更を反映させるコマンドを
**「fetch（フェッチ）」**
リモート追跡ブランチ→ローカルブランチへ変更を反映させるコマンドを
**「merge（マージ）」**
**fetchとmergeをまとめて行う**コマンドを
**「pull（プル）」**
と呼びます。



ちなみにmergeすると、PCで今開いている実際のコードにも内容が反映されます。
mergeとは実質**「セーブデータのロード」**といえそうです。

反対向きで見ると、
ソースコードの修正内容をローカルブランチに反映させるコマンドを
**「commit（コミット）」**
ローカルブランチをリモート追跡ブランチ、リモートブランチの両方に反映させるコマンドを
**「push（プッシュ）」**
と呼びます。



リモート追跡ブランチの解説は、この記事が分かりやすいです。↓↓
>Git で「追跡ブランチ」って言うのやめましょう
https://qiita.com/uasi/items/69368c17c79e99aaddbf

mergeには、リモート追跡ブランチからローカルブランチへの反映だけでなく、
もう一つの意味があります。
#mergeの２つの意味
上ではappleという名前のブランチで説明しました。
同じ構造のブランチ「orange」があるとします。

このローカルブランチ「orange」の内容を、
ローカルブランチ「apple」に反映させることもmergeと呼びます。

つまりmergeには、
**「リモート追跡ブランチ → ローカルブランチ」
「ローカルブランチA → ローカルブランチB」**
の2種類の意味があります。


#まとめ
・ブランチとはTVゲームのセーブデータのようなもの
・ゲームと違う点は、ゲームはセーブのたびにデータが上書きされるのに対して、
　ブランチはすべてのセーブポイントが時系列で保存されていく点。
・もう一つの違いは、ローカルとリモートの２箇所に保存する点。
・ブランチには「ローカルブランチ」「リモート追跡ブランチ」「リモートブランチ」
　の三種類がある。
・mergeには、
　「リモート追跡ブランチA(=origin/A)」から「ローカルブランチA」への反映、
　「ローカルブランチB」から「ローカルブランチA」への反映、
　の２つの意味がある。

#その他
時間があればイラストも加える予定です。
Firebase Test LabのRoboテスト使用感

## Firebase Test Labとは？

Googleのデータセンターでホストされている端末上で、アプリをテストしてくれるサービスです。
iOSおよびAndroidに対応していて、テスト結果はFirebaseコンソール上で確認出来ます。

<img width="977" alt="スクリーンショット 2018-10-12 10.35.48.png" src="https://qiita-image-store.s3.amazonaws.com/0/281445/52be0f8d-b437-3041-f761-e7edabebf3cd.png">

公式ドキュメント： https://firebase.google.com/docs/test-lab/

### 利用方法

Test Labの利用には、Firebaseコンソール上から実行する他に、AndroidStudioやgcloudコマンドラインからも可能です。
特にgcloudコマンドラインを使うことで、CI/CDツールに組み込むことも可能となります。

### 料金

Test Labの利用には、従量課金制のBlazeプランが推奨されています。
Blazeプランの場合、以下の設定です。（https://firebase.google.com/pricing/）

端末|料金
---|---
仮想|$1/device/hour
物理|$5/device/hour

### 出来ること

* iOS版
  * XCTestフレームワークを使ったテストの実行
  * Firebaseコンソール、gcloudコマンドラインからのテスト
  * 物理端末を用いたテスト
  * 利用可能な端末: https://firebase.google.com/docs/test-lab/ios/available-testing-devices
* Android版
  * Espresso, UI Automator 2.0を使ったテストの実行
  * Roboテストの実行
  * ゲームループテストの実行
  * Firebaseコンソール、AndroidStudio、gcloudコマンドラインからのテスト
  * 仮想端末もしくは物理端末を用いたテスト
  * 利用可能な端末: https://firebase.google.com/docs/test-lab/android/available-testing-devices

## Roboテストを利用した背景

仕事でAndroidアプリの開発を行う中で、以下のような課題がありました。

- リリース前に複数バージョンのOSおよび機種で動作確認をしたい
- 上記は自サービスのシェア上位のものをカバーしたい
- 特定の機能よりは、画面の網羅性を重視したい

自サービスでは、ログインしていないと確認できない画面もあるため、EspressoかUI Automatorでのテストを考えていましたが、Roboテストもログイン操作をパスさせることができることが分かり、試用結果次第では導入してみたいと思いました。

## Roboテストの特徴

### UI構造の分析
AndroidアプリのAPKファイルをアップロードすると、UI構造を分析し自動的にユーザー操作をシミュレートしてくれます。
モンキーテストとは異なり、同じ設定下では同じ順序でシミュレートしてくれるとのことで、テスト結果に従ってバグを修正した場合、その修正の検証をすることが可能になります。

### テキスト入力の指定
Roboテストを作成する際、EditTextのリソースIDと入力値を設定してあげることで、テスト中に入力をシミュレートしてくれます。
ログイン操作に用いる他にも、検索機能などにも対応させることができました。

<img width="811" alt="スクリーンショット 2018-10-12 11.52.26.png" src="https://qiita-image-store.s3.amazonaws.com/0/281445/4abed9e4-1395-b5ca-41a4-e4039e1ef4eb.png">


### スクリプトによる制御

今回は試してません。
AndroidStudioのFirebaseツールから、実際のアプリ操作からRoboテスト用のスクリプトを生成することが出来るようです。

他にもいろいろあるので、詳細は[ドキュメント](https://firebase.google.com/docs/test-lab/android/robo-ux-test)を見てください。

## 試用結果

いくつか不安を感じる部分もありましたが、薄く広く動作確認を自動でやってくれるという目的であれば、現段階でも十分実用的だなと思いました。（感じ方は、期待する精度によって変わると思います。）

### Roboテストによって得られる結果

Firebaseコンソール上で、以下の結果をデバイス毎に確認できます。AndroidStudioでデバッグするときに見られる情報は、だいたい見ることができます。

以下の結果はGCSバケットに自動保存され、下図の「テスト結果」をクリックすることで該当バケットに遷移し、ダウンロードも可能でした。
ただし、このテスト結果は90日間しか保持されないので、必要に応じて自分のGCSバケット等に手動でバックアップする必要があります。
https://firebase.google.com/docs/test-lab/android/analyzing-results

- クロールグラフ（画面遷移図に発生したイベントが書き込まれた画像）
- デバッグログ
- スクリーンショット
- 動画
- パフォーマンス計測（CPU、メモリ、ネットワーク）

<img width="1103" alt="スクリーンショット 2018-10-12 12.05.09.png" src="https://qiita-image-store.s3.amazonaws.com/0/281445/35088608-a9e4-01db-5c32-7eed53b081b6.png">

### Roboテストでイマイチだったところ

アプリ側のクオリティにも寄る部分がありますが、シミュレート内容に以下のような不安を感じる部分がありました。

- ログイン出来た端末と出来なかった端末があった
  - テキスト入力はされていたものの、なぜかログインボタンを押さずにテキスト入力を繰り返してしまっていた
- UI階層が深い箇所を先にテストが開始されると、他の画面をテスト出来ずにタイムアウトしてしまっていた
  - これはアプリ側の画面設計にも課題がある
- 特定の操作の組み合わせで同じ画面をループしてしまうケースがあり、タイムアウトまでそれを繰り返してしまっていた
  - これもアプリ側の問題ではある

テストのタイムアウトは自由に設定できるので設定値を延ばすことも可能ですが、むしろアプリの画面遷移パターンやUIを見直すことが必要だなと考えるきっかけになりました。
それはそれとして、テスト時間で課金される仕様上、同じ操作や同じ画面間などでループしていたらテストを中断するようになってくれるといいなと思います。
多分間違えてるColaboratoryの使い方(最新nodejsを利用する)

# はじめに

多分間違えてるColaboratoryの使い方シリーズ第３弾

今回はnodejsの最新版を利用してみたいと思います。

過去の記事

- [多分間違えてるColaboratoryの使い方(Go入門)](https://qiita.com/kei0425/items/19bebc966dcf50e5af2e)
- [多分間違えてるColaboratoryの使い方(now入門)](https://qiita.com/kei0425/items/e82b1796f8a7a0dbd445)

Colaboratoryでnodeを利用しようとすると、LTSの8系がインストールされています。

```:入力セル
!node --version
```
```:出力セル
v8.11.3
```

現在、10系が最新版で、次のLTS予定で機能的にもいろいろ追加されているのでどうせなら10系を使いたいなと思いました。

# 結論

以下を実行すれば特定バージョンのnodeを利用することができます。

## 設定

```:入力セル
!npm i -g n
!n v10.12.0
!node --version
```
```:出力セル
/tools/node/bin/n -> /tools/node/lib/node_modules/n/bin/n
+ n@2.1.12
added 1 package from 4 contributors in 0.799s

     install : node-v10.12.0
       mkdir : /usr/local/n/versions/node/10.12.0
       fetch : https://nodejs.org/dist/v10.12.0/node-v10.12.0-linux-x64.tar.gz
######################################################################## 100.0%
   installed : v10.12.0

v10.12.0
```

## 実行

### ファイル作成

```:入力セル
%%writefile test.js
const fs = require('fs').promises;

(async () => {
  const texts = await fs.readFile('./test.js', 'utf8');

  console.log(texts);
})();
```
```:出力セル
Writing test.js
```

### 実行

```:入力セル
!node test.js
```
```:出力セル
(node:396) ExperimentalWarning: The fs.promises API is experimental
const fs = require('fs').promises;

(async () => {
  const texts = await fs.readFile('./test.js', 'utf8');

  console.log(texts);
})();
```

fs.promisesはまだexperimentalなのでワーニングがでます。
気になる人は--no-warnings を付けて実行しましょう。

# 経緯

開発時にnodeのバージョンを管理する場合は通常nvmを利用するかと思います。
なので、Colaboratoryでもnvmを利用しようとしたのですが、残念なことにnvmをインストールはできるのですが、~/.bashrcが読み込まれず設定ができませんでした。

かといって、公式サイトからダウンロードしてインストールするのもなかなか使いにくかったりするため、パッケージのnを利用することにたどり着きました。

# まとめ

Colaboratoryなんでもできます！
Gartner Hype Cycleの技術推移パターン

GartnerのHype Cycle for Emerging Technologiesに出てくる技術が、年を経過するとどのように線上を辿るのかを追ってみました。2002年から2018年のHype Cycleを見てます。

# パターン

## 綺麗に推移するパターン

黎明期から幻滅期へ綺麗に推移するパターンです。以下の3つとBig Dataぐらいで、ほとんど例はありませんでした。

![cloud.png](https://qiita-image-store.s3.amazonaws.com/0/283474/af41ed07-4e6d-95eb-91b3-42be20ef0209.png)

Hype Cycleには2008年に初めて現れました。Amazon EC2のベータ版が初めて公開されたのが2006年8月、Google App Engineのベータ版は2008年4月に公開されてます。

![augmented.png](https://qiita-image-store.s3.amazonaws.com/0/283474/88de9d69-f617-6199-f6b2-43f0fa86c877.png)

![connected_home.png](https://qiita-image-store.s3.amazonaws.com/0/283474/e9704602-f1ac-ec09-bffc-f184e3bf44f8.png)

## ピークから現れるパターン

急に注目を集めたことで、黎明期を飛ばして、過度な期待のピーク期からHype Cycleに出てくるパターンです。

![gesture.png](https://qiita-image-store.s3.amazonaws.com/0/283474/ea6a85e2-3aa3-6b27-5c10-dbb3716c8799.png)

![deep_learning.png](https://qiita-image-store.s3.amazonaws.com/0/283474/cdf85778-90b4-1f6b-4715-ed59f3c2d29f.png)

Deep Learningが大きな注目を集めたILSVRCは2012年です。

![blockchain.png](https://qiita-image-store.s3.amazonaws.com/0/283474/931cfbd9-7df4-f647-6569-9b370c58ae0b.png)

ビットコインの利用開始が2009年、イーサリアムのベータ版リリースが2015年、R3の設立も同じく2015年です。

## 黎明期から上がれないパターン

黎明期のままピーク期へ移行できないパターンです。以下の3つは特に黎明期が長い例です。

![human_augmentation.png](https://qiita-image-store.s3.amazonaws.com/0/283474/e5934e35-4455-cac9-b1bd-4ed2957e1e28.png)

![quantum.png](https://qiita-image-store.s3.amazonaws.com/0/283474/96357030-be87-ce3d-0b9a-30dd595f9078.png)

![smart_dust.png](https://qiita-image-store.s3.amazonaws.com/0/283474/fd98b395-ceea-3cc0-86a8-9c7cb8226a07.png)

# まとめ

長期間、Emerging TechnologiesのHype Cycleに現れる技術自体が少ないです。2〜3年で消える（注目されなくなる、または主流になる）技術が多い。そのため、Emerging Technologiesに関しては、過去のHype Cycleと比べるのではなく、その年のHype Cycleだけ見ればよいです。

黎明期の下の方から流行期の上まで上がった例は、ほとんど見られませんでした。今後流行る技術を先取りするのにEmerging TechnologiesのHype Cycleを使うのは向かないでしょう。

黎明期が長い技術はあるが、ピークに長く居続ける技術はありませんでした。長くても3年程度で幻滅期に入るようです。現在がピークかどうかを見るためにHype Cycleを使うと良いと思います。

主流への採用までの年数が線上のマークとして示されており、△が10年以上、濃い青の◯は5〜10年、薄い青の◯は2〜5年となっています。主流というのがあいまいというのもあり、過去の経過を見ても、その時点の評価においても、役にたっているようには見えません。技術の成熟度を見るのには、Hype Cycleは使えないでしょう。
AMP Analyticsでページトラッキングとイベントトラッキングを設定する

# 経緯
* 新規でWEBサイトを立ち上げることになり、AMP対応することになったため

# やりたいこと
* ページトラッキングを使用し、WEBページで発生したビューの数を測定したい
* 設置しているバナーリンクがクリックされた回数を測定したい

# 手順
## 1. <head>タグに次のスクリプトを挿入
* GAのトラッキングコードの代わりに、AMP用のスクリプトを挿入します

```html
<script async custom-element="amp-analytics"
    src="https://cdn.ampproject.org/v0/amp-analytics-0.1.js"></script>
```

## 2. ページトラッキングの使用
* AMPアナリティクスのページトラッキングを使用します

```html

<amp-analytics type="googleanalytics">
<script type="application/json">
{
  "vars": {
    "account": "UA-XXXXX-Y"
  },
  "triggers": {
    "trackPageview": {
      "on": "visible",
      "request": "pageview"
    }
  }
}
</script>
</amp-analytics>
```

* accountにはGAのトラッキングIDを設定します
    * 設定＞プロパティ＞トラッキング情報＞トラッキングコードで確認できます
<img width="906" alt="GA.png" src="https://qiita-image-store.s3.amazonaws.com/0/61395/aa0efb2f-0413-9cdb-51d7-3056d6092bf7.png">

## 3. イベントトラッキングの使用
* 2に加えて、バナーリンクのクリックイベントの回数を拾うため、イベントトラッキングを使用します

```json
{
  "vars": {
    "account": "UA-XXXXX-Y"
  },
  "triggers": {
    "trackPageview": {
      "on": "visible",
      "request": "pageview"
    },
    "trackClickOnHeader" : {
      "on": "click",
      "selector": "#header",
      "request": "event",
      "vars": {
        "eventCategory": "ui-components",
        "eventAction": "header-click"
      }
    }
  }
}
```

* trackClickOnHeaderがイベントトラッキングの記述です。任意のイベント名を設定します
* 今回はクリックイベントを拾いたいので、onにclickを設定します
* selectorにイベントを拾いたい要素のIDを設定します
* eventCategoryとeventActionはそれぞれイベントカテゴリ名、イベントアクション名を設定します  

# 結果
* GAの画面上では以下のように表示されます

【イベントカテゴリ】
<img width="913" alt="GA2.png" src="https://qiita-image-store.s3.amazonaws.com/0/61395/03628890-599d-bdb1-4dbb-af91cc0c375b.png">

【イベントアクション】
<img width="913" alt="GA3.png" src="https://qiita-image-store.s3.amazonaws.com/0/61395/16331953-8587-85c4-d30d-4a9a697ff878.png">

# 参考
* [公式サイト](https://developers.google.com/analytics/devguides/collection/amp-analytics/?hl=ja)
GKEのCloud SQLにmysqlのdumpがimportできなかったメモ

# 構成

GKEのpodのなかにdjangoとCloudSQL(MySQL)のコンテナがある。

# このメモを見る前に

やろうとしことはそもそもこの手順で簡単にできたかもしれない 😢😢😢

### exporting

[https://cloud.google.com/sql/docs/import-export/exporting?hl=ja](https://cloud.google.com/sql/docs/import-export/exporting?hl=ja)

### importing

[https://cloud.google.com/sql/docs/import-export/importing?hl=ja](https://cloud.google.com/sql/docs/import-export/importing?hl=ja)

# やろうとしたこと

1. CloudSQLからdumpをexportする
2. DBを空にして色々作業する
3. 1のデータを戻す

## 1.Cloud SQLのdumpをexportする

dumpを取得するときは `mysqldump` で普通にできた。

    $ /usr/local/bin/mysqldump --result-file=/path/to/dump/dump.sql syncable --user=user --host=host --port=port -p --column-statistics=0

## 2.DBを空にして色々作業する

対象のpodのidを取得後flushして消す

    $ kubectl get pods
    $ kubectl exec -it hoge python manage.py flush

## 3.データを戻す

このコマンドは、権限云々で弾かれた。

    $ /usr/local/bin/mysql --database=database --user=user --host=host --port=port < /path/to/dump/dump.sql -p

参照したURLを失ってしまったが、権限をつけようともCloud SQLはmysqlコマンドでのimportができないようなことが書いてあったような気がする(*要出典...)

# 結局どのようにimportしたのか

1. ローカルのMySQLにimportしてからdjangoで `dump.json` を生成する
2. GKEのdjangoのコンテナに `dump.json`をコピーする
3. GKEのdjangoのコンテナで `dump.json`をロードする

## 1.ローカルのMySQLにimportしてからdjangoで `dump.json`を生成する

mysqlコマンドでimportしたのち、

    $ python manage.py dumpdata > dump.json

## 2.GKEのdjangoのコンテナに `dump.json`をコピーする

    $ /usr/bin/scp -P 6000 -i /Users/gotch/.ssh/google_compute_engine -o StrictHostKeyChecking=no /path/to/file/dump.json gcpuser@xxx.xxx.xxx.xxx:~/

`kubectl` はいつもCloud Shellで 実行しているので、まずCloud Shellに `dump.json` をscpした。([GCPのCloud Shellにscpできなかったメモ]([https://qiita.com/tofu2323/items/88d7a466f6901ecc1a7a](https://qiita.com/tofu2323/items/88d7a466f6901ecc1a7a)))

    $ kubectl cp ./dump.json hoge:/app

## 3. GKEのdjangoのコンテナで `dump.json`をロードする

データ量が多いとすごく時間がかかる。

    $ kubectl exec -it hoge sh

    # python manage.py loaddata dump.json