OmniAICreator/Qiita-1.07M huggingface dataset:
メモ:Windowsの環境変数をいじる方法

Windows10 Creators Updateで手順がわかりにくくなったのでメモ
今まではコントロールパネルや`Win+X Y` でシステムを立ち上げるとうまくいったのだが，上記アップデートでいろいろと条件が変わった

# GUIツールでいじる
検索ツール(windowsのスタートメニューを開いてタイピングすると勝手に立ち上がる)で`sysdm.cpl`を検索して立ちあげる
<img src="https://qiita-image-store.s3.amazonaws.com/0/142264/ef9a39e8-87ef-9bec-3d94-0e3b02805fab.png" width=50%>

# Power Shell
[SetEnvironmentVariable](https://msdn.microsoft.com/ja-jp/library/96xafkes(v=vs.110).aspx)を基にしたコマンドを使う.
##新しく作る場合
`[System.Environment]::SetEnvironmentVariable("TestVariable", "test", "User")`
第一変数は変数名，第二変数は設定したい変数の中身，第三変数は"User","Machine"を選んで，ユーザー環境変数を設定するのか，システム環境変数を設定するのかを決める．試した限りだと"Machine"の場合管理者権限でpowershellを立ち上げないと変更できない(Win+X Aで管理者権限で実行できる．)

##既存のものに追加する場合

```
$temp = [System.Environment]::GetEnvironmentVariable("Path", "Machine")
$temp += ";new/path"
[System.Environment]::SetEnvironmentVariable("Path", $temp, "Machine")
```

## 長くてめんどくさい！
何をしているのかというと，powershellの機能の一つである.NET Frameworkのクラス・ライブラリを呼び出している．（[クラス名]::クラスメソッド(引数)という形で呼び出しているようだ）.NET Frameworkに精通している人にとっては結構便利なのかもしれない．しかしデフォルトのパワーシェルでは，補完が利きすぎて，あまりうまく使えない．
psスクリプトを作ればよいのだろうが，実行権限などが面倒そうでやめた．そんなに頻繁にやる作業でもないし，良いGUIもあるので……


# 参考
https://docs.microsoft.com/en-us/previous-versions/windows/it-pro/windows-powershell-1.0/ff730964(v=technet.10)
http://www.atmarkit.co.jp/ait/articles/0709/20/news125_5.html
https://hosopro.blogspot.jp/2017/01/powershell-set-environment-variable.html

WSLをはじめとしてWindowsは開発環境としてもどんどん使いやすくなっているように思える．パスの追加ツールのGUIもかなり改善したように思えるのだけど，見つかりにくくなってしまったのは残念．開発者向けの設定はどんどん隠ぺいしていたり，互換性を保つために残しているツールがモダンなUIなものに入れ替わって来ているのでGUI側だと最近は設定方法がころころ変わっていってしまっているように思える．今後はいろいろとPower Shell経由でいじるようにするのが捗るかもしれない．
PHPでキャメルケースに変換する関数: camelize()

PHPで文字列をキャメルケースに変換する関数の実装は次のとおり。

```php
function camelize(string $s): string {
	return str_replace([' ', '-', '_'], '', ucwords($s, ' -_'));
}
```

どのような入力がどのような出力になるかは、次のテストコードをご覧あれ。

```php
assert(camelize('A') === 'A');
assert(camelize('Ab') === 'Ab');
assert(camelize('A A') === 'AA');
assert(camelize('A-A') === 'AA');
assert(camelize('A_A') === 'AA');
assert(camelize('Ab Ab') === 'AbAb');
assert(camelize('Ab-Ab') === 'AbAb');
assert(camelize('Ab_Ab') === 'AbAb');

assert(camelize('a') === 'A');
assert(camelize('ab') === 'Ab');
assert(camelize('a a') === 'AA');
assert(camelize('a-a') === 'AA');
assert(camelize('a_a') === 'AA');
assert(camelize('ab ab') === 'AbAb');
assert(camelize('ab-ab') === 'AbAb');
assert(camelize('ab_ab') === 'AbAb');
```
[学習用]Rails5コメント付きブログを簡単に作成してデザインも一緒にする手順3

![sampleblog6.png](https://qiita-image-store.s3.amazonaws.com/0/132580/3e1dbcdf-ef08-dc57-b2e5-6e218f39e8c1.png)

[[Rails5学習用]コメント付きブログを簡単に作成してデザインも一緒にする手順2](https://qiita.com/tarochan/items/fb12dd74b3e7ed2010a1) の続き

#テスト用データを一括で入れる
##seedへ記入します

```seeds.rb
10.times do |i|
  Post.create(
          name: "名前 #{i}",
          title: "タイトル #{i}",
          content: "コンテンツ #{i}"
  )
end
```

db/seeds.rb へ上記を記入します。
10の部分を 50にすると50件テストデータが入ります。


#ページネーションを作ります
##will_paginateを追加します

```Gemfile
gem 'will_paginate',           '3.1.6'
gem 'bootstrap-will_paginate', '1.0.0'
```

Bootstrapを使っているので、Bootstrapのページネーションが使えるようにします。

```
$ bundle install
```


##posts_controller.rbを変更

```posts_controller.rb
  def index
    @posts = Post.paginate(page: params[:page], per_page: 5).order(created_at: 'desc')
    # @posts = Post.all.order(created_at: 'desc')
  end
```

10個ごとにページを分割して最新順に表示させます。

##index.html.erbに追加
![sampleblog6.png](https://qiita-image-store.s3.amazonaws.com/0/132580/3e1dbcdf-ef08-dc57-b2e5-6e218f39e8c1.png)

```ruby:index.html.erb
<%= will_paginate(@posts, renderer: WillPaginate::ActionView::Bootstrap4LinkRenderer) %>
```

テンプレートの表示させたい部分に上記を追加します。
この様に表示されます。

<%= will_paginate %>だけでも表示されますが
うまくBootstrapが反映されません。
あとで文字列の変更方法を学習して追記したいと思います。


#学習項目
[[Rails5学習用]コメント付きブログを簡単に作成してデザインも一緒にする手順1](https://qiita.com/tarochan/items/f6e8349868db426d6382)
　┗ブログ(掲示板)の様なものを作成します。
[[Rails5学習用]コメント付きブログを簡単に作成してデザインも一緒にする手順2](https://qiita.com/tarochan/items/fb12dd74b3e7ed2010a1)
　┗Bootstrapをテンプレートに当てはめてきれいに表示します。
[[Rails5学習用]コメント付きブログを簡単に作成してデザインも一緒にする手順3](https://qiita.com/tarochan/items/719889345c90ab6e3b59)
　┗ページネーションとテストデータを一括登録します。
會被 `||` 視為 falsey value 的值

`||` 是 JavaScript 裡面的 OR 邏輯運算子
會被它視為 falsy 的值有以下六個

- `undefined`
- `null`
- `NaN`
- `false`
- `0`
- `''` / `""`

比較意外的是空字串也會被視為 falsy value

在 Chrome 的 console 直接執行看看的話會得到這樣的結果：

``` js
undefined || null || NaN || false || 0 || '' || "" || 'a string';
```

![image](https://qiita-image-store.s3.amazonaws.com/0/41979/cbedf86c-6308-1a16-e07a-e17e9a207f6f.png)


## 參考

- [Falsy - MDN](https://developer.mozilla.org/en-US/docs/Glossary/Falsy)
- [The && and || Operator in JavaScript - Marius Schulz](https://blog.mariusschulz.com/2016/05/25/the-andand-and-operator-in-javascript)
CentOS7.2のLANG設定分析


```vim:/etc/profile.d/lang.sh
# /etc/profile.d/lang.sh - set i18n stuff

#ロケールが設置されているかを表示するフラグ、
#デフォルトは0、即ち設置されていない
sourced=0

#LANGが既に存在する（LANGは1文字以上）場合、
#LANGの値をsaved_langに退避し、$HOME/.i18nにある内容を
#引用した後、LANGの値をsaved_langから復元
if [ -n "$LANG" ]; then
    saved_lang="$LANG"
    [ -f "$HOME/.i18n" ] && . "$HOME/.i18n" && sourced=1
    LANG="$saved_lang"
    unset saved_lang

#LANGが存在しない場合、/etc/locale.confと
#$HOME/.i18nにある内容を引用
else
    for langfile in /etc/locale.conf "$HOME/.i18n" ; do
        [ -f $langfile ] && . $langfile && sourced=1
    done
fi
#/etc/locale.confと$HOME/.i18nの内容を引用したら、
#ロケールのフラグを1に変更し、ロケールが設置されているように変更

#ロケールに関する変数が存在し（sourced=1）、
#値が1文字以上（空きではない）の場合、環境変数に昇格
if [ "$sourced" = 1 ]; then
    [ -n "$LANG" ] && export LANG || unset LANG
    [ -n "$LC_ADDRESS" ] && export LC_ADDRESS || unset LC_ADDRESS
    [ -n "$LC_CTYPE" ] && export LC_CTYPE || unset LC_CTYPE
    [ -n "$LC_COLLATE" ] && export LC_COLLATE || unset LC_COLLATE
    [ -n "$LC_IDENTIFICATION" ] && export LC_IDENTIFICATION || unset LC_IDENTIFICATION
    [ -n "$LC_MEASUREMENT" ] && export LC_MEASUREMENT || unset LC_MEASUREMENT
    [ -n "$LC_MESSAGES" ] && export LC_MESSAGES || unset LC_MESSAGES
    [ -n "$LC_MONETARY" ] && export LC_MONETARY || unset LC_MONETARY
    [ -n "$LC_NAME" ] && export LC_NAME || unset LC_NAME
    [ -n "$LC_NUMERIC" ] && export LC_NUMERIC || unset LC_NUMERIC
    [ -n "$LC_PAPER" ] && export LC_PAPER || unset LC_PAPER
    [ -n "$LC_TELEPHONE" ] && export LC_TELEPHONE || unset LC_TELEPHONE
    [ -n "$LC_TIME" ] && export LC_TIME || unset LC_TIME

#LC_ALLの値がLANGと異なる場合のみ環境変数に昇格
#（LC_ALLはLANGより優先）
    if [ -n "$LC_ALL" ]; then
       if [ "$LC_ALL" != "$LANG" ]; then
         export LC_ALL
       else
         unset LC_ALL
       fi
    else
       unset LC_ALL
    fi
    [ -n "$LANGUAGE" ] && export LANGUAGE || unset LANGUAGE
    [ -n "$LINGUAS" ] && export LINGUAS || unset LINGUAS
    [ -n "$_XKB_CHARSET" ] && export _XKB_CHARSET || unset _XKB_CHARSET

    consoletype=$CONSOLETYPE
    if [ -z "$consoletype" ]; then
      consoletype=$(/sbin/consoletype stdout)
    fi

    if [ -n "$LANG" ]; then
      case $LANG in
        *.utf8*|*.UTF-8*)
```
PostgreSQL で中央値を求める

他の RDBMS は知らないが、少なくとも PostgreSQL には MEDIAN という関数は存在しない。
`PERCENTILE_CONT` を用いて 50 パーセンタイルを求めることで中央値になる。

``` sql
SELECT PERCENTILE_CONT(0.5) WITHIN GROUP (ORDER BY col)
FROM tbl
```

## パーセンタイルの種類
PostgreSQL のドキュメントを見ると、パーセンタイルにも二種類あるらしい。

[PostgreSQL: Documentation: 9.6: Aggregate Functions](https://www.postgresql.org/docs/9.6/static/functions-aggregate.html#FUNCTIONS-ORDEREDSET-TABLE)

> **continuous percentile**: returns a value corresponding to the specified fraction in the ordering, interpolating between adjacent input items if needed

> **discrete percentile**: returns the first input value whose position in the ordering equals or exceeds the specified fraction

例えば中央値を求める際は、データ数が偶数でちょうど真ん中を決められない場合は中央の２つの値の平均をとる。これを continuous percentile と言い、平均を取るのではなく大きい方を選ぶのが discrete percentile と言うらしい。

中央値について調べると「偶数の場合は中央２つの平均を取る」と書いてる事が多いので、continuous percentile を使うほうが正しそう。
Android、GAS開発で個人的によく見るサイト一覧

# はじめに
Android,GAS開発をする過程で個人的によく見るサイト一覧

逐次更新


# Android編
## PNGをSVGに変換したい
https://www.vectorizer.io/

## Swaggerのチュートリアル
https://apihandyman.io/writing-openapi-swagger-specification-tutorial-part-1-introduction/

# Github編
## Githubでやらかした時に見るやつ
https://qiita.com/muran001/items/dea2bbbaea1260098051

## fork元のリポジトリへの変更をforkしたリポジトリに反映する
https://qiita.com/chihiro/items/d018599ef13c35781412

## 削除されたremoteブランチがローカルのRepoに残っていて、それを削除する方法
https://qiita.com/kony/items/f0fb18b04bd5337132e3

# テキスト編集編
## MarkDownチートシート
https://qiita.com/tbpgr/items/989c6badefff69377da7

# Slack編

## LegacyToken取得
https://api.slack.com/custom-integrations/legacy-tokens

## SlackAPI確認(グループId取得)
https://api.slack.com/methods/groups.list/test

# GAS編

## **Moments**:時間関連のライブラリ
https://tonari-it.com/gas-moment-js-moment/
`MHMchiX6c1bwSqGM1PZiW_PxhMjh3Sh48`


## **SlackApp**:Slackへ通知するためのライブラリ
https://tech.camph.net/slack-bot-with-gas/
https://qiita.com/fireowl11/items/e703e35073b600528e7c
`M3W5Ut3Q39AaIwLquryEPMwV62A3znfOO`

## **Parser**:スクレイピングのライブラリ
https://www.kutil.org/2016/01/easy-data-scrapping-with-google-apps.html
https://qiita.com/fireowl11/items/e703e35073b600528e7c
`M1lugvAXKKtUxn_vdAG9JZleS6DrsjUUV`

## **parser**:DOM解析用のライブラリ
http://tadaken3.hatenablog.jp/entry/parser-for-gas
`1Jrnqmfa6dNvBTzIgTeilzdo6zk0aUUhcXwLlQEbtkhaRR-fi5eAf4tBJ`

# その他
## QRコード作成
https://www.unitag.io/qrcode
ログイン 仕組みを大雑把におさらいしたい

# 経緯

作成したwebアプリのログイン画面のテストを実施するとなった場合、
どういったテスト項目を作成しますかと質問されたときに
ブラウザ上で確認する検証作業のような内容しか回答できず困ってしまいました。
よって今回は、裏側でどんなことが行われているのか把握することで、
超初心者でもレベルの高い回答ができるようになることを目的として
この勉強メモを残します。

## 1.メールアドレスとパスワードを入力してください。
すでに登録されている会員サイトとかだと
そのままログインボタンを押下してTop画面やマイページに遷移するわけですが、
このときデータベース上にて何が起きているのか詳しい方から話しを聞けたので
私なりに解釈した図を載せたいと思います。![ログイン機能.png](https://qiita-image-store.s3.amazonaws.com/0/234065/727528dc-43d2-b5d1-0415-00d437af7243.png)

ペイントで作成した雑な図でアレなんですが、
結論から言ってしまうと一連の処理にはデータベースも絡んできてますよということです。

## 2.アカウントの新規登録と情報漏洩
会員情報ページの登録情報については、どのサービスも
同じような情報を登録していると思います。

それらの情報は個人情報なので、「暗号化」と呼ばれる
行程が必要になっていきます。これができていないと
人間が目で見て読み取ることができるので、
「情報漏洩」となってしまいます。
(twitterやっている方は最近に
「アカウントセキュリティに関するお知らせ」メールが
届いたと思います。まさにこのことです。)

# おわりに
自分なりにさらに調べて、暗号化という観点から
セキュリティテストの必要性が理解できました。
順を追って口頭で誰かに何かを説明することは
難しいことですが、こういった裏側で
起きていることもちょっと説明できると、
ただの初心者から脱却することが出来るかもしれません。
LaravelのPHPUnitで外部サイトにリクエストを投げる


前に調べた、[これ](https://qiita.com/zaburo/items/083fab19f0fe3b40ed5b)や、[これ](https://qiita.com/zaburo/items/13bfdc349e1421421c98)のおさらい。ただ、Browserのテストは[Duskで行えるようになってます](https://qiita.com/zaburo/items/8715997e1889f6e1582e)。

結局、普通？の$this->get()は外に出られないのかな？？？


###　Guzzleのインストール

Laravelのディレクトリで、下記を実行。

```bash
composer require guzzlehttp/guzzle
```

### 実装

とりあえず、test/Feature/ExampleTest.phpを下記のように書き換えます。

> test/Unitでもまあ、動きますが。

```php
<?php

namespace Tests\Feature;

use Tests\TestCase;
use Illuminate\Foundation\Testing\RefreshDatabase;
use GuzzleHttp\Client; //use

class ExampleTest extends TestCase
{
    /**
     * A basic test example.
     *
     * @return void
     */
    public function testBasicTest1()
    {
        //client
        $client = new Client;

        //request先
        $url = "http://www.bluecode.jp/test/api.php";

        //request
        $res = $client->get($url);

        //jsonからオブジェクトへ
        $obj = json_decode($res->getBody());

        //評価
        $this->assertEquals(200,$res->getStatusCode());
        $this->assertEquals("OK",$obj->status);
        $this->assertRegExp('/^Hello$/',$obj->message);
    }
}
```

### テストの実行

普通にテストを実行します。

```bash
vendor/bin/phpunit
```

### Basic認証への対応

テスト環境ではBasic認証がかかってることも多いかと思いますが、その場合は下記のように記述します。

>なお、Guzzle5.0以降とそれ以前では書き方が違うようなので注意が必要です。

```php
    public function testBasicTest2()
    {
        //client
        $client = new Client;

        //request先（Basic認証がかかっている想定）
        $url = "http://www.bluecode.jp/test/api.php";

        //request( with basic auth)
        $res = $client->get($url,[
            'auth' => [
                'username',
                'password'
            ]
        ]);

        //評価
        $this->assertEquals(200,$res->getStatusCode());
    }
```

### assertのパターン

過去記事の再記載ですが、とりあえず、

* ssertEquals($expect,$var) expectとexpectとvarが等しいか？
* assertRegExp($ptn, $var) 正規表現にマッチするかどうか？
* assertNull($var)
* assertTrue($var)
* assertFalse($var)
* assertCount($num,$array)
* assertEmpty($array)

あたりを押さえておけばいいかなと。
その他はphpunit assertでググればいくらでも出てきます。
回線速度のテストができる「fast」コマンドが便利だった

インターネット回線の速度テストができるウェブサイトと言えば[Speedtest]や[Fast.com]があるが、今回使ってみたのはFast.comのコマンドラインツール[fast-cli]だ。

使い方はシンプルで`fast`を叩くと通信速度を測定してくれる。

![](https://qiita-image-store.s3.amazonaws.com/0/889/b600bf90-fb61-d0f4-9bea-74e0a32cb2b4.gif)

(このデモは会社のNURO回線で測定したもの。早い…。)

## インストール方法

fast-cliはNodeモジュールなのでnpmでインストールする:

```
npm install --global fast-cli
```


[Speedtest]: https://www.speedtest.net
[Fast.com]: https://fast.com/ja/
[fast-cli]: https://github.com/sindresorhus/fast-cli
PaizaでAngularの開発環境を作りました

試してみたいAngularとPHPで作られたアプリがあったのですが、サーバー確保できず無料で使えるところを探していました。

cloud9が使えたら私も慣れていたので一番良かったのですが、Amazonと合併してAWSの中に入ったようで、サーバーを使うためにはAWSのEC2の費用が必要なので、諦めました。
自分でサーバーを確保できていたら、無料で使う方法もあるのですが。

今回は、このような背景があったので、Paizaのクラウドを使うことにしました。

##paizaで環境を作る準備
Paizaのconsole画面に、ターミナルがあります。
node -v と npm -v コマンドで、バージョン確認すると回答が戻ってきます。

でも、グローバルでAngular CLIをインストールしようとすると、エラーになってインストールでいません。
そのため、フォルダを作りローカルで、nodeとnpmをインストールしてみました。
![スクリーンショット 2018-05-09 16.36.25.png](https://qiita-image-store.s3.amazonaws.com/0/20977/b064f616-f023-adce-fa13-d244705be912.png)

https://nodejs.org/en/download/package-manager/
この中で、
```
curl -sL https://deb.nodesource.com/setup_8.x | sudo -E bash -
sudo apt-get install -y nodejs
```
作ったappのフォルダに移動して、ここに上記のコマンドを使ってインストールしました。

##Angular CLIをインストール
https://angular.jp/guide/quickstart
にアクセスして、gのオプションを外してインストールしました。
```
npm install  @angular/cli
```
この後初期のプロジェクトを作りました。

```
ng new my-app
```

##サーブできました
```
cd my-app
ng serve --open
```
の代わりに
```
cd my-app
ng serve  --disable-host-check
```
とターミナルから入力して、起動にサーブに成功しました。
![スクリーンショット 2018-05-09 16.25.00.png](https://qiita-image-store.s3.amazonaws.com/0/20977/bd095916-a9c6-5278-812a-47891f92888a.png)

今回、スタックオーバーフローで教えてくださった人に、感謝しています。

また、念のためコマンドのパスが通っていないといけないので、こちらのページを参考にして対応しました。
http://shiro-goma.hatenablog.com/entry/2015/08/17/003440

こちらの記事も、参考になると思います。
https://tyablog.net/2017/05/13/cloud9-angular2/

##PHPも忘れずに
今回は、PHPのソースが含まれているプロジェクトを使いたかったので、サーバーの設定で、PHPをインストールするようにしていました。

今回目的のパッケージのことに関しては、別の記事で下書き状態になっています。
こちらの記事で、改めて書き残したいと思います。
変数や関数のネーミングには気をつけよう


Qiita初投稿です。よろしくお願いします！

# ネーミング
最近 Robert Martin　の 「Clean Code」　を読み返していてネーミングの重要性を実感したのでまとめました。プログラマーなら一度はネーミングで迷ったことがあるのではないでしょうか。要は変数や関数に名前をつけてあげることですね。一見簡単そうに見えて意外とネーミングで苦戦した人も少なくはないはずです。

## 名前の短縮は避けよう
コード量を減らすために変数や関数の名前を短縮しがちですがあまりオススメしません。実際にコードを見てみましょう。

```php
$d = date('Y-m-d');
```

このように変数を短縮してしまうことにより変数名はなんの情報も与えてくれなくなってしまいます。いざこの変数を使おうという時にはコードを読み返さないといけないはめになり、コード量が増えれば増えるほどそれは困難でありバグを生みかねません。

```php
$sub_cnt = 10;
```

こういった短縮の仕方もオススメできません。まず`sub`は色々な意味が考えられます。「副〇〇」という意味でもあるしSubscriberの略とも考えられます。また`cnt`もおそらく`count`というのは想像がつきますがコードを読んでる相手に誤まって理解されないように略さず書き出しましょう。

```php
$subscriber_count = 10;
```

このようにすれば誰が読んでもサブスクライバー数が１０人いるというのが一目でわかります。

## 関数名は目的をハッキリさせよう
関数名はその関数が何をするのかわかるようにハッキリさせましょう。また、関数の内容も関数名以外のことはしないように気をつけましょう。

```php
function getAll()
{
    // コード...
    
    if ($success) {
        $this->status = 1;
    }

    return $subscribers;
}
```

まず関数名のみでは目的がハッキリしません。この関数で何が取得できるのか中身をみないと判断できません。では中身をみてみましょう。何かの処理をした後にステータスの変更を行ってます。これでは中身を知らずにこの関数を使ってしまった場合知らない間にステータスの変更までかかてしまい、バグを生む可能性が出てきます。

```php
function getAllSubscribers()
{
    // コード...

    return $subscribers;
}
```

関数名を見ればこの関数が全てのサブスクライバーを取得してくれるのがわかります。また、余計な処理も一切されないので安心です。

## まとめ
自分の書いたコードは自分だけが読むとは限りません。チームで開発する場合他のメンバーがそのコードを編集することは少なくありません。その時に自分のコードが読みずらいとチームメンバーの作業効率を下げかねません。コードを書く時は「他人が読む」という風に意識して書きましょう。（第２弾へ続く）
Apacheのmod_proxy_wstunnelのコードを読んでみる


# はじめに

mod_proxyのコードについては、下記のようにひと段落したのですが、mod_proxyの後段のモジュールについても読んでみたので記事にします。

mod_proxyの記事：[Apacheのmod_proxyのコードを読んでみる(3)](https://qiita.com/tomluck/items/ca53bbf8fe0e7e2b72a5)

実行環境や実装のバージョンはmod_proxyの時と同様にApache v2.4.23です。

いつものように我流で読み進めているので、理解内容に間違いなどありましたらご指摘ください。

# mod_proxy_wstunnelの概要

## AP_DECLARE_MODULE(proxy_wstunnel) 

apache標準のhook定義関数です。

基本的に前段のmod_proxyで登録されているため、hook関数の登録しかしていません。

```c

AP_DECLARE_MODULE(proxy_wstunnel) = {
    STANDARD20_MODULE_STUFF,
    NULL,                       /* create per-directory config structure */
    NULL,                       /* merge per-directory config structures */
    NULL,                       /* create per-server config structure */
    NULL,                       /* merge per-server config structures */
    NULL,                       /* command apr_table_t */
    ap_proxy_http_register_hook /* register hooks */
};

```

## register_hooks

hook登録関数で、AP_DECLARE_MODULEの最後に指定されている関数です。

Apache標準のhookの登録はありません。
mod_proxyから呼ばれるhookのみ登録しています。

```c
static void ap_proxy_http_register_hook(apr_pool_t *p)
{
    proxy_hook_scheme_handler(proxy_wstunnel_handler, NULL, NULL, APR_HOOK_FIRST);
    proxy_hook_canon_handler(proxy_wstunnel_canon, NULL, NULL, APR_HOOK_FIRST);
}
```

- proxy_hook_scheme_handler：mod_proxyのproxy_handlerからフックされます
- proxy_hook_canon_handler：mod_proxyのproxy_fixupからフックされます

# mod_proxy_wstunnelの詳細

## proxy_wstunnel_canon

- フックされた時点でurlにつぎのどちらかを含んでいないとDECLINEDになり終了です
　- "ws:"
　- "wss:"

- リクエストに問題がなければ、request_rec構造体のfilenameメンバへ整形したurlを設定してOKを返します。

```c
    r->filename = apr_pstrcat(r->pool, "proxy:", scheme, "//", host, sport,
                              "/", path, (search) ? "?" : "",
                              (search) ? search : "", NULL);

```

## proxy_wstunnel_handler

### 処理対象の判定

- proxy_wstunnel_canonと同様にurlにつぎのどちらかを含んでいない場合はDECLINEDで処理終了です。
　- "ws:"
　- "wss:"

- リクエストヘッダにWebSocket関連のものが含まれていない場合はDECLINEDで処理終了です。具体的には次の判定基準です。
  - "Upgrade"という文字列が含まれており、その値が"WebSocket"という文字列である

```c
    upgrade = apr_table_get(r->headers_in, "Upgrade");
    if (!upgrade || strcasecmp(upgrade, "WebSocket") != 0) {
        ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(02900)
                      "declining URL %s  (not WebSocket)", url);
        return DECLINED;
    }
```

### websocket通信処理の準備

- mod_proxyのコネクション管理用の構造体proxy_conn_recに必要な情報を設定しています。

- proxy_wstunnel_handlerの中で必要な準備を終えるとproxy_wstunnel_requestを呼び出して実際のwebsocketの通信処理をします。

### websocket通信処理(proxy_wstunnel_request)

- 処理に必要な構造体の値の設定をした後にdo-while文に入ります。
- do-while文はどちらかが切断するか、エラー発生までループを継続します。
- do-while文の中身はそれほど読めていませんが、websocketの実際の通信に関する実装になっていると思います。

# おわりに

Apacheのmod_proxy関連の実装は、すべてをmod_proxyに詰め込むのではなく、可変点のみ後段に任せるという設計思想なのだろうなと想像しています。

前段のmod_proxyが約3000行というコード行数であり、後段のmod_proxy_wstunnelは377行ということで、可変点(差分)のみ後段に委譲するという実装をうまく実現しているというのが私の感想です。

備忘録も兼ねていますが、参考になる方がいれば幸いです。

時間があればmod_proxy_balancerについても記事に書いてみようと思っています。
ちょっとしたWebサイトを作るのに最適なツールを考える

会社で、ちょっとしたWebサイトを構築しなくてはいけなくなりました。
ミセス向けのファッションブランドのサイト＋ワークショップのサイト。

そのツールを選んだので、その過程を共有してみます。

### サイトの構造

今回作成するサイトは、このような構造になります。

【会社のサイト：構築済み】
　└ブランドサイト（サブドメイン）
　　└ワークショップの特設サイト（サブディレクトリ）

で、それぞれ、このように違います。

- ブランドサイトは、ほぼワンページャー。
 - ブランドの概要を説明する。
 - 店舗一覧は、会社のサイトに飛ばしちゃう。 

- ワークショップサイトはやや機能が多い。
 - オプトインページでメルマガ購読者を集める
 - 今後のワークショップイベントを告知する
 - 過去のワークショップイベントの記事を投稿する

### 検討の過程

ワークショップサイトは、WordPress一択。これは迷わなかった。

で、ブランドサイトのワンページャーのほうをどうするか・・・となった。ほぼ、一枚物の静的HTMLが作れれば、用が足りてしまうので、オーバースペックになるのが嫌です。

今回、導入を検討したのは、以下の通り。

- [ペライチ](https://peraichi.com/)（Webサービス）
- [justinmind](https://www.justinmind.com/) (プロトタイピングツール)
- WordPress
- [Jekyll](https://jekyllrb-ja.github.io/) (静的HTML出力ツール)

---

#### ペライチ

簡単にワンページャーが作れるWebサービス。
本当に簡単。

##### 【ペライチのメリット】

- テンプレートを選んだ時点で、すでに完成されている。
- パーツを選んで、写真や文章を変えるだけ。本当に速い。

##### 【ペライチのデメリット】

- 当然有料プランを使うものの、持てるページ数が３ページと少ない。
- つまり、本当にワンページャーと割りきって使う必要がある。

---

#### justinmind

GUIでサイトの見た目を構築するとよしなにやってくれる、プロトタイピングツール。
ここから、静的HTMLが取り出せれば、それをアップロードすれば用が足りると考えた。

##### 【justinmindのメリット】

- シミュレーターなど、機能が親切。
- デザインが美しく、操作性もよい。

##### 【justinmindのデメリット】

- HTMLにエクスポートすると、シミュレーターごとエクスポートされる。
- もう少し、本番っぽい単位でHTMLを吐いて欲しい。
- やり方があるのかも知れないが、ドキュメントを読んでもよくわからなかった。

---

#### WordPress

言わずと知れた、最も有名なCMS。サーバーに配置すると、ブログができる。

##### 【WordPressのメリット】

- ノウハウが豊富で、テーマやテンプレートも数多い。
- SEOに強い。

##### 【WordPressのデメリット】

- テーマを自分で作ると工数がかさむので、テンプレートを買わざるを得ない。
- テンプレートもやたらと多いので、選定の時点で一苦労する。
- 定期更新するサイトに向くが、作りきりのワンページャーをやると手間の方が大きくなってしまう。

---

#### Jekyll

ローカルマシンのデスクトップ上で、ひな形から静的サイトを生成してくれるrubyツール。

##### 【Jekyllのメリット】

- テンプレートさえあれば、HTMLを出力するのに手間が少ない。
- 記事を書いてGithubPagesなどにデプロイすると、簡単にサイトやブログが作れる。
- テンプレートが、GitHubで手に入る。

##### 【Jekyllのデメリット】

- ドキュメントがそれほど多くない。
- 動的なWebサービスは作れない。
- エディタとWebブラウザで完結するので、エンジニアでないと快適と感じにくい。

---

### 結論

ひと通り全部、ちゃんと使ってみた結果、今回の比較では、**Jekyllが最も使いやすかった**です。

##### 理由１． HTMLとCSSはわかるので、エディタで書けると楽

高機能なツールは、楽ができる一方で『HTMLでこう書きたいんだけどな』と感じてしまうので、あまり有難くない部分もある。本来書きたい事が隠蔽されるというか。

トータルコストでは、自分にとってGUIツールはベストではなさそう。

Jekyllの場合は、基本的にHTML、CSS、javascriptで完結しており、しかもHTMLのコードがコンポーネントに分かれているので、部品の再利用がしやすいです。

ブラウザのデバッグツールが今は高機能なので、エディタ側に頼る必要性が薄くなりました。

エディタはVimを使うので、ファイル単位の往復が苦になりません。

##### 理由２．コストが安い

複数のプロジェクトに応用したいので、コストに対する拡張性があってほしい。WordPressテーマを買う事や、有料サービスを利用する事じたいは問題ないけど、『これじゃないな』となった時にまた買うとか、別のサイトを作るときにライセンスを追加しなくてはならないとかだと、心理的にスケールしにくいです。

その点、Jekyllなら、テンプレートがGitHubで無償で手に入るので、構築までのコストが最安。

##### 理由３．スケールしやすい

自分で構築したサイトのひな形は、全てファイルになっているので、新しいサイトに応用するのも楽。

Jekyllひとつ覚えてしまえば、かなり楽ができる部分があります。

--- 

というわけで、あなたも一枚もののサイトが作りたいなら、Jekyllを覚えると楽ができますよ。
最も大きな決め手は、GitHubに高機能なテンプレートが公開されていることです。
前回の続きオブジェクト指向，オーバーロード

<h1>getData</h1>
今日はgetDataを使ってTaro (30)Hanako (24)というのを表示させました。
そもそもgetDataとは何ていう意味かというと
getData(string)とは、、、、指定したデータ形式に関連付けられているデータを取得します。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/249283/41437afd-65b6-f1f2-9bf1-fc4b012fb13c.png)
![image.png](https://qiita-image-store.s3.amazonaws.com/0/249283/e70616e9-5bf9-0904-dd54-9be3edb4a2e4.png)

stringのとこのgetDataのとこで指定したデータ形式に関連付けられているデータを読み取っているんだなと思いました。

Taro (30)
Hanako (24)
と表示されます。


<h1>オーバーロード</h1>
そもそもオーバーロードってどういう意味なのかオーバーロードとは、「引数や戻り値が異なるが名称が同一のメソッドを複数定義する」というオブジェクト指向プログラミングのテクニックである。

オーバーロードでは、引数の型が異なる同名のメソッドをあらかじめ複数定義しておくことで、メソッドが呼び出される時の引数や戻り値の型などに応じて適切なメソッドを呼び出すことができ、呼び出す際のチェックやメソッド内部での不要な条件分岐などを減らすことが可能になることです。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/249283/8d816cad-f012-972b-3406-747d894b6e18.png)
![image.png](https://qiita-image-store.s3.amazonaws.com/0/249283/a4beb6b0-cb36-e9f5-927f-df9276774ebf.png)
macのpowがLoadErrorを表示する

僕のmacで最後にpowが動いていたのは、2014年の事でした。  

それから3年間、『まあいいや』と放置していましたが、octopressのブログを真面目に書く事にしたので、直さないといけなくなりました。
とても今更な問題解決のエントリーですが、記録のために投稿します。

### やったこと

いったん、powderコマンドでpowをアップデートしました。

`
sudo powder install
powder respawn
powder cleanup
powder env_reset
`

octopressのフォルダに移動し、以下のコマンドを実行しました。
`
powder link
`

ファイアウォールがEl Capitanから変わったので、対応が必要、という事なので、以下のコマンドを実行しました。

```
sudo launchctl load -w /Library/LaunchDaemons/cx.pow.firewall.plist
```

これでも、まだ表示は変わりません。

```
sudo vim /etc/pf.anchors/com.pow
```

Vimでpowの設定ファイルを編集し、以下の設定を追記しました。

- rdr-anchor "com.apple/*" の次行

``` 
rdr-anchor "pow"
```

- load anchor "com.apple" from "/etc/pf.anchors/com.apple" の次行

``` 
load anchor "pow" from "/etc/pf.anchors/com.pow"
```

次に、以下のコマンドを実行しました。

```
sudo echo "rdr pass on lo0 inet proto tcp from any to any port 80 -> 127.0.0.1 port 20559" > /etc/pf.anchors/com.pow"
```

rbenvなので、~/.powconfigに、以下の通り追記しました。
 
```
export PATH=~/rbenv/shims:~/.rbenv/bin:$PATH
eval "$(rbenv init -)"
```

これで解決しました。
けっきょく、Octopressはやめて、Jekyllに移行することにしましたが。


### 参考資料：
“LoadError: cannot load such file — bundler/setup”と表示される場合

http://linuxserver.jp/%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9F%E3%83%B3%E3%82%B0/ruby/on-rails/pow



https://github.com/basecamp/pow/issues/452


https://github.com/basecamp/pow/issues/452
Google Document API の文書構造でハマった話

今回、Googleドキュメントの文書をスクリプトから編集する処理を書いていて、ハマったポイントがあるので共有します。

### やりたい事
- Googleドキュメントの本文をテンプレートとして使用し、テンプレートファイル内に、生成した本文を出力する

今回やろうとしたのは、文書を水平線(hr)で区切る構成です。

- 水平線以前がテンプレート
- 水平線以降に出力結果が表示される

という構成で、水平線以前／以降を判定する処理が必要でした。

### 水平線を取得する

水平線を取得するのは、
BodyオブジェクトのfindObjectメソッドで行います。

```
var firstHr = body.findElement(searchTypeHR);
```

こんな感じです。
これで取得できるのはRangeElementオブジェクトなので、さらにgetElement()メソッドで、中身のHorizontalRuleオブジェクトを取り出してあげます。

```
var theHr = firstHr.getElement();
```

これを基準に、段落（Paragraphオブジェクト）の位置を判定すれば、水平線以前と以降がわかるはずです。

### 水平線の前後要素が取れない

しかし、ここがハマりポイントとなりました。
すなわち、HorizontalRuleオブジェクトの、文書内の位置が取れません。

ここで読むべきものはドキュメントです。

<https://developers.google.com/apps-script/guides/docs#structure_of_a_document>

これによると、『水平線は、ListItemやParagraphの配下である』と書いてあります。
文書構造としては、このようになっているわけです。

```
Body
  ├ Paragraph
  │  ├ Text
  │  └ Text
  ├ Paragraph
  │  └ HorizontalRule
	.
	.
	.
```

### 解決法

HorizontalRuleオブジェクトはParagraphオブジェクトの子なので、文書内の位置を知るには、親要素となるParagraphオブジェクトを取得する必要がありました。

というわけで、以下のようにすると、文書内の位置が取れたのでした。

```
body.getChildIndex( theHr.getParent())
```

めでたし。
MacのターミナルでGitのブランチ名を表示 + 色付け

## brewでインストール
```
$ brew install git
```

## 下記ファイルを移動
```
$ cd /usr/local/Cellar/git/2.17.0/etc

$ mv git-prompt.sh /usr/local/git/contrib/completion/

$ mv git-completion.bash /usr/local/git/contrib/completion/
```

## .bashrcに記述
```
$ sudo vim ~/.bashrc

# git settings
source /usr/local/git/contrib/completion/git-prompt.sh
source /usr/local/git/contrib/completion/git-completion.bash
GIT_PS1_SHOWDIRTYSTATE=true
export PS1='\[\033[32m\]\u@\h\[\033[00m\]:\[\033[34m\]\w\[\033[31m\]$(__git_ps1)\[\033[00m\]\$ '
```

## .bashrcを再読み込み
```
$ source ~/.bashrc
```
Kotlin + android.animation で矢印をヒュンヒュン動かす

AnimatorSet とか android.animation とかを使ってKotlin で矢印を動かしてみました

## コード
```kotlin

import android.animation.AnimatorSet
import android.animation.ObjectAnimator
import android.view.animation.AccelerateDecelerateInterpolator
import android.view.animation.AnimationUtils
import android.widget.ImageView

fun setTranslateArrow(right: ImageView, left: ImageView): AnimatorSet {

    val moveCloser = AnimatorSet()
    val rightMove = ObjectAnimator
            .ofFloat( right, "translationX", -40f, 20f)
    val  leftMove = ObjectAnimator
            .ofFloat(  left, "translationX", 40f, -20f)

    rightMove.repeatCount  = ObjectAnimator.INFINITE
     leftMove.repeatCount  = ObjectAnimator.INFINITE
    rightMove.duration     = 700
     leftMove.duration     = 700
    rightMove.interpolator = AccelerateDecelerateInterpolator()
     leftMove.interpolator = AccelerateDecelerateInterpolator()
    rightMove.repeatMode   = ObjectAnimator.REVERSE
     leftMove.repeatMode   = ObjectAnimator.REVERSE

    moveCloser.playTogether(rightMove, leftMove)
    return moveCloser
}
```

```Kotlin

private val _moveCloser by lazy 
       { setTranslateArrow(_rightImageView, _leftImageView) }
...
_movecloser.start
```

## なぜAnimatorを使うのか

android.animator (Property Animator) は以下のような利点があります

 - 軽い
 - API Level 11 から使える(現実的)
 - 記述が簡単
 
デメリットとしては

 - 止めて表示など細かい制御が効かない
 - 既定のアニメーション以外は難しい

まあ使えるものを使えということですね。
使えるアニメーションとAPIは[Androidのアニメーション処理に関して - Qiita@glayash](https://qiita.com/glayash/items/1822a852ebaa7d26a53e)によくまとまっています。

## Kotlin だから難しかったこと

ありません。 むしろ`getter/setter` の記述簡素化と`by lazy` の利便性でコーディングがはかどること間違いなし
Xception-SSDLiteで遊んでみた~ssdkerasのその先5~

#対象
Faster-RCNN,SSD,Yoloなど物体検出手法についてある程度把握している方．
VGG16,VGG19,Resnetなどを組み込むときの参考が欲しい方．
自作のニューラルネットを作成している方．

とりあえず試してみたいという方は田中さんがコードを上げてくださっているので(ありがたき幸せ．．)，そちらを参考にされたい．
https://github.com/tanakataiki/ssd_kerasV2

余談．そろそろそのssdkerasのその先という表現はやめようかなと思っている．(笑)

# Xceptionとは
空間方向の畳み込みとチャンネル方向の畳み込みは完全に分離しても良いという仮説から成り立った究極のInceptionである.
![XceptionModule.JPG](https://qiita-image-store.s3.amazonaws.com/0/246406/902668da-2a5a-07fe-26fd-7d4af11ba28c.jpeg)
1)より引用

細かく見ていくと，それぞれ以下のような流れになっている．
![Xceptionflow.JPG](https://qiita-image-store.s3.amazonaws.com/0/246406/8dce82b3-6751-c8e2-2a16-d2126442ffb2.jpeg)
1)より引用
端的に言うとResnetをpointwise,depthwise畳み込みに変えたようなモデルである．


以下に@yu4uさんのXceptionの神説明があるので，参考にされたい．
https://qiita.com/yu4u/items/dc26d220e85279e76157
https://qiita.com/yu4u/items/34cd33b944d8bdca142d

# Xception-SSDLite

コンセプトは
#### 少ないリソースで最高の結果を

である．


# 実験
![Xception-SSDLite.gif](https://qiita-image-store.s3.amazonaws.com/0/246406/372242a9-37dc-80e6-f78f-da1878f1a980.gif)
まだ学習途中なので，もう少し早くなりそう．(DeepLearnerが出くわす謎の知見)


# 考察
Residualだけに学習途中でも割と精度がいい．
SSDLiteだけに学習途中でも比較的速い．
メモリーを食いすぎない(SSD512の学習は途中で放棄した)．
そして設計と学習がめちゃめちゃ大変だった．
↑もうこれに尽きる．
さすがExtremeInception

# 終わりに
アドバイスなどあればお願いします．(typoとかでも歓迎です！)
https://github.com/tanakataiki/ssd_kerasV2
SSDはガラス細工並みに繊細な構造で，職人技の数値設定が必要です．
上手くいった自作ネットワークがある方，プルリク待ってます．
筆者の環境
CPU:Xenon　GPU：GTX1080Ti×2


# 参考文献
1)https://arxiv.org/abs/1610.02357
C#のクラス

　"クラス" は C# の最も基本的な型です。 クラスは、状態 (フィールド) とアクション (メソッドおよびその他の関数メンバー) を 1 つの単位としてまとめたデータ構造です。 クラスは動的に作成された "インスタンス" の定義を提供し、"オブジェクト" とも呼ばれます。 クラスでは、"継承"と "ポリモーフィズム" をサポートします。これによって "派生クラス" が "基底クラス" を拡張して特殊化できます。

　クラスの内容は、静的メンバーまたはインスタンス メンバーです。 静的メンバーはクラスに属しており、インスタンス メンバーはオブジェクト (クラスのインスタンス) に属しています。
クラスに格納できるメンバーの種類の概要を次に示します。
ー　定数
ー　フィールド
ー　メソッド
ー　プロパティ
ー　インデクサー
ー　イベント
ー　演算子
ー　コンストラクター
ー　ファイナライザー
ー　種類


<pre>
class クラス名 {
    クラス内容
}
</pre>

例：
<pre>
class Person {
    public string name;
    public int age;
}
</pre>
VSCodeのLive ShareでFailed to create a collaboration session. となる場合の対処(Proxy環境下)

## はじめに
Visual Studio Live Share が先日パブリックプレビューとなりました。
https://code.visualstudio.com/visual-studio-live-share

早速 Visual Studio Code で試めそうと思い、Proxy 環境下で Share をおこなったところ以下のメッセージが

![image.png](https://qiita-image-store.s3.amazonaws.com/0/125105/695b68b2-ee73-bcd2-0d8d-8aafeef34001.png)

```
Failed to create a collaboration session. An error occurred while sending the request.
```

拡張機能のインストールもできているので、VSCode 自体の Proxy 設定は問題ないはず。。 

### 環境

* OS: Windows
* VSCode: 1.23.0 

## 対応方法

ユーザ環境変数またはシステム環境変数に HTTPS_PROXY を設定し、VSCode を再起動するだけでした。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/125105/6ed5b93a-a559-ed02-0b9b-712bd26539a9.png)

共有が成功し、招待リンクがクリップボードにコピーされました。 

## 補足
Live Share機能には複数のコネクションモードが用意されています。

**Connectivity requirements for Live Share**
https://docs.microsoft.com/en-us/visualstudio/liveshare/reference/connectivity

デフォルトは Auto で 自動的に Direct モードと Relay モードを切り替えて接続を試行します。
VSCode の場合、何れのモードでも以下のアウトバウントアクセスが必要です。

* download.microsoft.com:443
* download.visualstudio.microsoft.com:443

Relay モードはクラウド経由でホストマシンとゲストマシンを接続しますが、
更に以下のアウトバウントアクセスが必要です。

* *.servicebus.windows.net:443.

私の環境では VSCode の User Settings（settings.json）で http.proxy のみを設定していましたが、
上記の HTTPS 通信については Proxy を経由できていないため、エラーとなっていたようです。
環境変数に明示的に HTTP_PROXY/HTTPS_PROXY を設定すれば、
Visual Studio Live Share はそちらの設定を参照します。

以上です。
参考になれば幸いです。

## おまけ
### Live Share の準備
VSCode で Live Share 機能を使用するには以下が必要です。

* VSCode 1.22.0 以上
* 拡張機能のインストール

![image.png](https://qiita-image-store.s3.amazonaws.com/0/125105/83c6e42d-1340-7570-704a-00bb6400fbe7.png)

MARKETPLACEで live share と検索するか、こちらのページからインストールできます。
https://marketplace.visualstudio.com/items?itemName=MS-vsliveshare.vsliveshare

拡張機能をインストールし、再読込を行うと、画面下部に Sign in が表示されます。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/125105/1656fc8c-6a31-99c7-0ae9-55fd289f2b17.png)

こちらを選択すると、ブラウザでサインイン画面が開きます。
マイクロソフトアカウント または GitHubアカウントを使用してサインインします。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/125105/279b7063-9e67-262c-0f41-43bd84fd8ea9.png)

![image.png](https://qiita-image-store.s3.amazonaws.com/0/125105/6d2e5bf8-035e-6b49-295d-b0719d453af7.png)

サインインが成功し、Share ボタンが表示されれば準備完了です。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/125105/ba641b52-c7e8-c341-67aa-f0a6efd4ccb5.png)
Qiitaで記事を書くときの画像アップロードの容量制限について 

#概要
Qiitaで初めて記事を書くとき、最初の一記事目でアップロードできる容量は2MBでそれ以降は月間100MBまで可能となるらしいです。

##エラー内容
画像をアップロードするときに、右上の写真のアイコンをクリックして画像リンクを挿入すると思うのですが、2MBを超えたタイミングで![error]が表示されるようになりました。

#まとめと個人的な経験
本記事を投稿後、当初書いていた記事に2GB以上の画像をアップロードしたところ、上記エラーは表示されなくなりました。（本記事を最初の一記事目としてアカウントが認識したおかげ？）

説明しやすくするための画面キャプチャで2MBはすぐに食ってしまうので、できればもう少し画像アップロードに関して許容いただけるとありがたいです・・・。
Java6でテスティングフレームワーク揃えるのに苦労したお話

現場はJava6。

今までずっと手動テストでやってきたんだけど、やっぱ限界あるよね？
っことでテストコードを書くことになり、その見積もりを手伝った。

JUnitとかMockitoとかを集めるところから始めたんだけど、いかんせん
古すぎてぐぐってもなかなか情報にヒットしないので苦労した。

技術的負債がたまりすぎると死ぬよ？というケースとして忘備録。


# JUnit 4.11
Javaでテストコード書くと言えばJUnit。
最新はJUnit5があるけど、Java8以降じゃないと使えないので4系からチョイス。
後述の@Ruleアノテーション使うために 4.8以降じゃないとダメ。


# assertJ 1.7.1
アサーションライブラリ。

メソッドチェーンでつないで書いていくスタイルなので、
((((かっこ地獄))))になりにくいし、
Eclipseのサジェストにあわせてポンポンassert文が書ける。


# Mockito 1.9.5
テスト用のモックをかなり簡単に実装できるライブラリ。もひーと、と読むらしい。
JUit5系だとMockito 2.x.xとかあるけど、JUnit4系で安定は1.9.5の模様。

### モックって何？
Hogeクラスのhogehoge()メソッドをテストしたいとする。
hogehoge()メソッドが別のFugaクラスに依存している場合、
Fugaクラスも準備しないとテストできないことになる。

モックとはそういうとき、
「HogeクラスからFuga#fugafuga()を見たときは、とにかく3を返せ」
って設定できる。Javaでテストと言ったら必須。


# PowerMock 1.5.6
Mockitoはめっちゃ便利なんだけど、staticメソッドなんかはモックできない。
PowerMockはそこをいい感じにハックすることで
Mockitoと似た書き方でstaticメソッドのモックができる。
あとprivateメソッドなんかも。

古くからJava使ってる現場ではどーせstaticメソッドも
猛威をふるっている（偏見）のでこちらも必須。

このPowerMockと後述のEclemmaが相性が悪く苦労した。
（最新バージョンでは解決している）

1.5.6にしたのはMockito 1.9.xとPowerMock1.5.xが対応してるから。

#Javassist3.18.2
JavassistはJavaバイトコードをいじるときに使うライブラリ。
Javaバイトコードとは、僕らが書いたJavaソースを
コンパイルしてできるやつ。JVMで動くやつ。

PowerMockはこれを使っている。ソースじゃなくてJavaバイトコードの方を
うまく書き換えて、モックを実現させているらしい。
（詳しくは知らないし、この説明は厳密には間違っているかもしれない）

既存プロジェクトでJavassist3.4が入っていて、
優先度がそっちのが高かったので怒られたとき「え？入ってるよね？」ってハマった。


#QuickJUnit
JUnitを書くためのEclipseプラグイン。
いろんなショートカットとか雛形とかそろってる。


#Eclemma 3.0.1
**Ecl**ipse + **EMMA**ライブラリ。
テストのカバレッジを測るEMMAをEclipse上で動かすためのプラグイン。
Eclemmaはかなり前に更新止まっててほんとはJaCoCoとかを使いたかった。

EclemmaとPowerMock1.5.6は相性が非常に悪く、
PowerMockを用いたテストを実行するとカバレッジ0%とか表示される。

Eclemmaは先ほど説明したJavaバイトコードを見て、どこが実行されたかを
監視しているのだが、
PowerMockが（staticメソッドのモック実現のために）
そのバイトコード（のコピー）をJavassistで編集し、そっちが実行されてしまうため。

この問題はJava8、JUnit5系以降なら全部解決済みである。


#Ruleアノテーション
RunWithの変わりに使うことで、
上記の「カバレッジ0%問題」を回避することができる。

参考：<https://code.i-harness.com/ja/q/1647e8c>


#まとめ
これで一通りそろった（と思う）
試しに数メソッドのテストコード書いて、実行、カバレッジ測定までできた。

Javaだからまだいいよ、探すのに苦労するだけで、探せばなんとか出てくるんだから。


##なぜこんなに苦労したのか？

###①複数の問題が同時に発生した。
Javassistバージョン競合と、PowerMockとEclemmaの「カバレッジ0%問題」

間接的には、Eclipseのバージョンが古すぎ＆Maven無いという開発環境なので
プラグインやライブラリインストールが非常に面倒、って問題も重なった。

１つ１つなら大したことない問題でも、
複数発生すると途端に解決のためにかかる時間がハネあがる。


###②もう解決したから、情報が埋もれる

JUnit5系以降ならPowerMockとEclemmaの「カバレッジ0%」問題は解決している。

つまり、世間では２年前には解決済みなので、今その２つのキーワードでぐぐると、
Ruleアノテーションを使わないRunWithの書き方の方が多くヒットする。
（Ruleで書くとめんどくさいらしい）


##蛇足
苦労して手順化したんだけど、このテスティングフレームワーク群が
ぼくの提案どおり採用されるかわかんない。

何より「カバレッジ100%が必須」とか言われてるので嫌な予感がする。


##追記
結局、「テストを書くのは時間がかかるので手動テストをやろう」
という結論になりました。

どういう判断だ！
っていうか手動テストケース作るの俺じゃないか！
嫌だー！！
react js

##JSX
コードの見た目はHTMLにかなり似ている
jsx compiler がjsxをjavascriptに変換してくれる

##JSX element
変数やobjectに保存できる

```js

//変数の時
const name = <li> my name is </li>;

//objectの時
const myTeam = {
  member1: <li> A </li>,
  member2: <li> B </li>,
  member3: <li> C </li>
};
```

JSX element は属性(attribute)をもつ

```js
const p1 = <p id="large"> kan </p>;
const p2 = <p id="small"> fo </p>;
//値は""もしくは''でかこむ
//ひとつのelementで複数の属性を持つ子ができる
```

##Nested JSX

```js

const example = (
  <a href="http://www.example.com">
    <h1>
     Hello
    </h1>
  </a>
);
//<a></a>が<h1></h1>を囲んで(nest)いる
//JSXで複数の行を書きたいときは（）で囲む
```
Python 3 で　tkinter　がないと怒られたときの対処

環境: Ubuntu 14.04 の生python

グラフを書こうとしたらTkinterがないと怒られました。

'ImportError: No module named '_tkinter', please install the python3-tk package'

https://stackoverflow.com/questions/6084416/tkinter-module-not-found-on-ubuntu

このスレッドを参考にコンソールから

```$ sudo apt-get install python3-tk```

を実行したら解決しました。
C#プログラミング(基礎)三回目

※自分のメモ用に書いています
環境：Windows10 visual studio 2012

引数。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/249288/d195c171-a009-e342-6241-94944018c7c5.png)
動作結果。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/249288/30710673-b2c0-c178-6e42-937614e2756b.png)
今度は名前だけや数字だけを設定したものを用意。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/249288/2c8fb3de-eaad-215e-fa09-a7c19b2303b3.png)
設定どうりに名前だけなら名前のみや数字のみの表示になった。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/249288/07605fb6-3d72-bfd3-01c7-bb4d43c2f8db.png)
プロパティを利用するさっきと違い今度はマイナス値になったりしても大丈夫なようにifで設定
ここから1枚では収まらなくないほど長くなる。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/249288/1fdfa3b4-35f0-c1a8-b655-6f16cf799c2f.png)
![image.png](https://qiita-image-store.s3.amazonaws.com/0/249288/c1b4db69-5ed5-5c9f-b8f7-82e8352d04d6.png)
動作結果、名前がなければNoNameと表示し数字はマイナスだった場合0になるように設定してあり正しく動いた。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/249288/1b58a3f7-720b-3fbe-77a2-ea96c8eff8ad.png)
今度は継承を使ってみる、継承先には追加の情報も入れる。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/249288/65d60254-a7b5-a74e-6734-e1bd129be54d.png)
![image.png](https://qiita-image-store.s3.amazonaws.com/0/249288/a7a9b3c3-c570-eb68-5edf-d77ca9b42468.png)
動作結果。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/249288/813e9a5b-241a-3f03-5f6d-49f29896a62d.png)
次はOverRideを使ってみる。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/249288/bc095059-360c-4d81-bb8a-bc7f04912bcf.png)
![image.png](https://qiita-image-store.s3.amazonaws.com/0/249288/97df97f1-bd00-1314-f39b-5aa733c89f41.png)
動作結果、表示結果は見た目変わらない…
![image.png](https://qiita-image-store.s3.amazonaws.com/0/249288/f7fc5e0e-ed6a-82cf-50bf-06c6e77f4c60.png)
こっちはNewを使ったもの．．．
![image.png](https://qiita-image-store.s3.amazonaws.com/0/249288/0ee6472c-2995-3412-2a73-14dd00d7970b.png)
動作結果も見た目変わらない。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/249288/1e99fbf8-1aae-6f51-1d2b-95bc3b6e6d15.png)
今度はOverRideとNewを使って動作の違いを確認する。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/249288/1dc14fd4-e7d5-b5f5-4f6c-9d7e3094c875.png)
![image.png](https://qiita-image-store.s3.amazonaws.com/0/249288/4f7b8360-b31b-eb5d-9a62-fd16fe3e7906.png)
動作結果、OverRideでは表示は変わらないがNewでは変わった。
OverRideは上書きされるがNewは追加になる。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/249288/39427fb8-8ece-ebc0-f26b-9516399fd996.png)
最後に静的クラスを使ってみる。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/249288/1041f510-4b5b-a8d5-844f-0181e6ef87c6.png)
![image.png](https://qiita-image-store.s3.amazonaws.com/0/249288/8b8a446c-8f8c-90c1-1c90-03e84a5bab34.png)
動作結果。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/249288/1595ebea-cb02-1ec3-61e9-63854e415169.png)
Elasticsearchのプラグインの確認コマンド

Elasticsearchのプラグインの確認コマンド

```ruby:コマンド
curl -H "Content-Type: application/json"  -XGET 'https://aa.com/_nodes?plugin=true&pretty'
```
をうって、プラグインを確認しようとしたら、

```json:コマンド
curl -H "Content-Type: application/json"  -XGET 'https://aa.com/_nodes?plugin=true&pretty'
{
  "error" : {
    "root_cause" : [
      {
        "type" : "illegal_argument_exception",
        "reason" : "request [/_nodes] contains unrecognized parameter: [plugin]"
      }
    ],
    "type" : "illegal_argument_exception",
    "reason" : "request [/_nodes] contains unrecognized parameter: [plugin]"
  },
  "status" : 400
}
```
が表示された。

どうやら、6.0以降あたりからはコマンドが

```ruby:コマンド
curl -H "Content-Type: application/json"  -XGET 'https://aa.com/_nodes/plugins'
```
に代わったらしい、メモ代わりに書き込み
SkyWayのシグナリングサーバーだけを使用する

[SkyWay](https://webrtc.ecl.ntt.com/)は、シグナリングサーバーもサービス内で提供していますが、SDKにおいてはほぼ隠蔽されており、WebRTCを使用する分には気にする必要がありませんが、このシグナリングサーバーのみを使用したいとなった場合、どうすればいいか。


SkyWayのSDK(クライアント)はPeerJSがベースとなっており、WebSocketのライブラリにSocket.IOが使用されています。
Peerインスタンスのopenイベントは、シグナリングサーバーに接続が完了したイベントですので、openイベント後にSocket.IOのインスタンスを取得することができればいいわけです。
(SkyWay SDK内部においては、いったんdispatcherUrlにリクエストを投げ、レスポンスからシグナリングサーバーのURLを取得してから、シグナリングサーバーに接続しています。)

```js
const peer = new Peer({key:'---'});
peer.on('open', id => {
    const socket = peer.socket._io; // peer.socket._ioがSocket.IOインスタンス
});
```


シグナリング(WebSocket)サーバー側もPeerJSのサーバーをベースにしています。
PeerJSのサーバーは、特定のイベント名のメッセージ以外ははじく仕様となっています。
イベント名とは、Socket.IOのemit()で第1引数に指定する値のことです。
SkyWayでクライアントからサーバーにメッセージを送信するときに使用されているイベント名

|イベント名|
|:---:|
|'SEND_OFFER'|
|'SEND_ANSWER'|
|'SEND_CANDIDATE'|
|'SEND_LEAVE'|
|'ROOM_JOIN'|
|'ROOM_LEAVE'|
|'ROOM_GET_LOGS'|
|'ROOM_GET_USERS'|
|'ROOM_SEND_DATA'|
|'SFU_GET_OFFER'|
|'SFU_ANSWER'|
|'SFU_CANDIDATE'|
|'PING'|
|'UPDATE_CREDENTIAL'|

これら以外のイベント名でメッセージをクライアントから送信すると、サーバー側ではじかれます。
'SEND_'から始まらないイベント名は、サーバー側で処理されるメッセージですので、使用できません。
クライアントから別のクライアントにメッセージを送信するには、'SEND_'から始まるイベント名、
'SEND_OFFER'
'SEND_ANSWER'
'SEND_CANDIDATE'
'SEND_LEAVE'
のいずれかを使用します。
ただし、サーバーから別のクライアントへメッセージが送信されるときは、'SEND_'がないイベント名で送信されます。
また、特定の別クライアントにメッセージを送信したい場合は、送信データにdstプロパティを追加し値にpeerIdを設定することで、そのpeerIdへメッセージが送信されます。
ちなみに、srcプロパティで送信元のpeerIdを設定することができます。

```js
_io.emit('SEND_OFFER', {
    data: {},
    dst: destPeerId,
    src: sourcePeerId
});

|
V

<< Signaling Server >>

|
V

_io.on('OFFER', data => {
    //...
});
```

これにより、シグナリングサーバー経由で独自のメッセージの送受信が行えます。
call(MediaConnection)やconnection(DataConnection)を生成した場合、内部でシグナリングメッセージハンドラーが生成されるため、独自のメッセージを送受信する場合は、そのハンドラーを回避する必要があります。回避できなくはないですが、SDK内部を修正する必要があるため面倒になります。
ですので、シグナリングのみを使用するだけでしたら面倒なことは避けられますので、生のWebRTCの動作確認の用途等で使用することができます。
もちろん、独自のメッセージをシグナリングサーバー経由で送受信する方法は公式に公表されていませんので、使用には十分注意してください。
小数点のある数字をnumber_formatする(0を切り捨てる)

```php
 public static function floatNumberFormat(float $number)
    {
        $number = number_format($number,2);
        $number = rtrim(rtrim($number,'0'),'.');
        return $number;
    }
```

number_formatの第二引数は小数点の桁数


参考サイト
[SYSTEM238 / NOTES1 / PHP / 小数点以下０を削除する](http://www.sys238.jp/contents_notes1/php/php_non_display_0_of_decimals_md/)

こっちでも良さそう。
```
number_format(sprintf('%.1f',$number),1);
```
parsley.jsの2バイト文字判定

社内プロジェクトのフォームに使用しているバリデーション「parsley.js」ですが、どうもメールアドレスのバリデーションで、メールアドレス形式になっていれば２バイト文字が含まれていても通ってしまうようです。
※全角アットマークは通常でも弾かれます

例）aaあaa@.gmail.com

http://parsleyjs.org/doc/examples/simple.html

上記本家サンプルフォームでも通ってしまっています・・・。


そこでCustom Validators機能を使い、２バイト文字が含まれているかをチェックするバリデーションを追加することで対応しています。
そのコードが以下です

対象のINPUT要素にDATA属性「data-parsley-multibyte=''」を追加します。
もちろん、他の条件（data-parsley-type='email'など）と併用可能です。

```haml:sample.haml
= f.input :customer_email, placeholder: '例：hoge@hage.jp', label: false, input_html: {data: {parsley_required: true, parsley_required_message: 'メールアドレスを入力してください。', parsley_trigger: 'change', parsley_type: 'email', parsley_multibyte: ''}}, required: false
```
※追加したDATA属性の「multibyte」の部分は以下のJSコードと合わせて変更すれば任意なものでも大丈夫です。

```javascript:sample.js
window.Parsley.addValidator('multibyte', {
  validateString: function(value) {
    return value.match(/[^ -~｡-ﾟ\t]/) === null;
  },
  messages: {
    en: '半角で入力してください',
  }
});

```
上記JSコードは必ずparsley.jsの後で読み込まれる場所に記述してください。

en: '半角で入力してください'
ご自身が使用しているi18nのlocaleに合わせて適宜変更してください。

もっとスマートな方法があるかもしれませんのであしからず！！
BoxのExcel Onlineで、xlsxファイルが開けない時の対応方法


### 事象
下記メッセージが出る

<img width="406" alt="image.png" src="https://qiita-image-store.s3.amazonaws.com/0/148503/e8e8d8c3-ee4d-0c4e-6341-4b6efd63a12a.png">

We're sorry, we couldn't open your workbook. It's possibly corrupt or using a file format that's not supported.


### 対応方法
1. 対象ファイルをダウンロードする  
2. 対象ファイルをExcelで開いて、「.xlsm形式」で保存する
3. 上記の対象ファイルをExcelで開いて、「.xlsx形式」で保存し直す
4. 保存し直したファイルを再度アップロードする
【GCP】文字起こし


Uniteのシロちゃんの動画が為になったので文字起こししてみた。

基本こちらの記事をなぞる
[Google Cloud Speech API を使った音声の文字起こし手順](https://qiita.com/knyrc/items/7aab521edfc9bfb06625#8-%E5%AE%9F%E8%A1%8C%E7%B5%90%E6%9E%9C)



## FLACファイルを用意

日本語版：[【Unite Tokyo 2018】バーチャルYouTuber電脳少女シロがご紹介する「2018年の注目アセット100連発」](https://www.youtube.com/watch?v=2tOoN_uMVt0)
英語版：[【Unite Tokyo 2018】“100 Must-see Assets for 2018” by Virtual YouTuber, Cyber Girl Siro](https://www.youtube.com/watch?v=KYnCTlmVqMU)


youtube -> mp3
https://www.clipconverter.cc/

mp3 -> flac
https://audio.online-convert.com/convert-to-flac



## つまずきポイント

### ImportError

```
ImportError: cannot import name speech
```

`sudo pip install google-cloud-speech`で解決。



### 403 Cloud Speech API

```
google.api_core.exceptions.PermissionDenied: 403 Cloud Speech API has not been used in project 618104708054 before or it is disabled. Enable it by visiting https://console.developers.google.com/apis/api/speech.googleapis.com/overview?project=618104708054 then retry. If you enabled this API recently, wait a few minutes for the action to propagate to our systems and retry.
```

サービスアカウントの再取得で上手くいくときと、失敗するときがある。
失敗するときは、パケットごと作り直したら上手くいった。

### 文字化け

元のスクリプトがshift_jis設定なので正常なのだが。
Cloud Shell上部の鉛筆マークからコードエディタに移動。
文字起こししたテキストファイルを File > Export > Download
ローカルに持ってきた後に文字コードを変えたければ変えればいい。

> 参考
[超初心者でもgoogle-cloud-speechを使えるが、つまずいた所はある。](https://qiita.com/hanlio/items/875b91e0d4931a57e86b)



## 結果

[日本語](https://drive.google.com/file/d/1FApHckwZiN_ngbqhbSIEUoPLPYWg2iwK/view)
[英語](https://drive.google.com/file/d/1qrvVFbjgwvDjntNoaQM0D-9VAPJQKS42/view)

専門用語が多いからか、精度はよくない。
これは使えないなー。
Android Studioでアプリを作るための道筋（個人用）

#アプリの概要

FX資金管理アプリを作る。

##手順

1.メニューの実装,フローティングアクションボタンの実装

![68747470733a2f2f71696974612d696d6167652d73746f72652e73332e616d617a6f6e6177732e636f6d2f302f39363039312f36333736616130632d666433392d313563322d396332652d3463616166373238666530302e706e67.png](https://qiita-image-store.s3.amazonaws.com/0/251551/d3a523b3-ebca-1451-6e89-92aa7ec232aa.png)

実際にはAndroidStudiosのサンプルにあるのでそれを使えばよい。

以下ではコードを解説している
[自分でまとめたもの]()


2. スワイプでページ遷移できるようにする。


![viewpager-2.png](https://qiita-image-store.s3.amazonaws.com/0/251551/1edeb077-2e3d-7b37-d229-f051132e4da2.png)

android.support.v-4のviewpagerを用いる。
[参考サイト](https://qiita.com/naoi/items/59c01a2a6eb8420c351c)
[自分でまとめたもの viewpagerの実装方法](https://qiita.com/rui0930/items/d6df44b5f663f10871cd)
Vue.jsで連想配列を動的に変更させるときの注意点

Vue.jsで連想配列を動的に変更しようとした時に少しつまづいたので、備忘録として書きます。

# やりたかったこと
storeから取得した情報を連想配列に入れてチェックボックスに紐付け、動的に値を変更したかった。

```arrayTest.html
<div id="app">
  <div v-for="i in flagArray">
    <input type="checkbox" v-model="flagList[i]">
  </div>
</div>
```

```arrayTest.js
var app = new Vue({
  el: '#app',
  data: {
    flagList: {}
  },
  computed: {
    flagArray: {
      return this.$store.getters.flags;
    }
  },
  methods: {
    setFlag: function () {
      for (var i = 0; i < this.flagArray.length; i++) {
        this.flagList[i] = this.flagArray[i]; ←ここで代入
      }
    }
  }
})
```

ただ、これを実行してチェックボックスにチェックを入れても、Vue内部では値が変わってくれないという状態に陥っていました…


# 変更したところ
公式ドキュメントに載ってました。
[よくある初心者の落とし穴](https://jp.vuejs.org/2016/02/06/common-gotchas/)
[オブジェクトの変更検出の注意](https://jp.vuejs.org/v2/guide/list.html#%E3%82%AA%E3%83%96%E3%82%B8%E3%82%A7%E3%82%AF%E3%83%88%E3%81%AE%E5%A4%89%E6%9B%B4%E6%A4%9C%E5%87%BA%E3%81%AE%E6%B3%A8%E6%84%8F)

結局のところ、直接代入はNGみたいで、下の$set()を使った方法に変更すれば、動的に値を変更してくれました。

```arrayTest2.js
  methods: {
    setFlag: function () {
      for (var i = 0; i < this.flagArray.length; i++) {
        // this.$set(array, key, val);
        this.$set(this.flagList, i, this.flagArray[i]); ←これに変更
      }
    }
  }
```


# 結論
公式ドキュメントしっかりと読もう。
以上！
Sourcetreeでマージする時に競合を解決する方法（初心者向け）

##基本は右クリック＞競合を解決
警告マーク⚠️（三角にビックリマーク）が付いているコミットを右クリック＞競合を解決で以下の選択肢が出る。

- 自分の変更を使って解決
- 相手の変更を使って解決

マージする時には基本はmaster、develop、releaseブランチなどの元のブランチに自分の変更を加えて機能追加しているはずだから、基本は「自分の変更を使って解決」を選ぶことになるが、それによって該当コードが変になったり、自分のブランチのベースとなるコミットから、他のチームメンバーが別の変更を加えていて先にマージ済みの時にそれを壊してしまったりするので、右側ウィンドウのgitの差分表示（diff）でキチンと確認する必要がある。

```swift

<<<<<< HEAD
someMethod() {
  print("hoge")
}
=====
someMethod() {
  print("fuga")
}
master >>>>>> 
```
ここでいう`<<<<<< HEAD ~ ====`が自分の変更で、`==== ~ master >>>>>>`がマージ先である相手の変更となる。後の方で説明するリベース時も「上段（HEAD）が自分、下段が相手」という原則は変わらない。

##コード自体を修正したいとき
自分と相手、どっちかで解決するかではなく、そもそもコードを手動で修正したいときはSourcetreeのコミットをダブルクリックしてもその該当ファイルをエディタで開いてくれる。ここでコードを修正してその後（コミットをステージにあげて）コミットしようとすればOK。「マージの途中です」といったメッセージが出て「マージを続ける」を選択すれば無事にマージできるはずだ。

##リベースの時は自分と相手が逆になるので注意
ただ初心者エンジニアだとマージを担当することはほぼなくGitHubなどにPRを送って、上司や先輩エンジニアにマージしてもらうことになるだろう。なのでどちらかというとマージよりもリベースすることの方が圧倒的に多いはずだ。注意が必要なのはリベース時は上記の「自分」と「相手」が逆になってしまうことである。

```swift

<<<<<< HEAD
someMethod() {
  print("fuga")
}
=====
someMethod() {
  print("hoge")
}
hot-fix/print-fuga-to-hoge >>>>>> 
```
リベース、すなわちベースとなるコミットを変更するので、視覚的に例えるなら一度生やしてきたブランチの上を根元（木の幹から分岐したところ）まで歩いて戻って、幹の上の方にあるリベースしたいコミット（新しいベース）まで進んで、そこからこれまで変更してきたコミット（コード）を見る感じだ。なのでリベース時は「自分」はリベースしたいコミットであり、「相手」は自分が変更してきたコミットとなる。
CentOSとRHELのバージョン


|CentOS7|RHEL7|
|:---|:---|
|8 (1905)|8|
|7 (1908)|7.7|
|7 (1810)|7.6|
|7 (1804)|7.5|
|7 (1708)|7.4|
|7 (1611)|7.3|
|7 (1511)|7.2|
|7 (1503)|7.1|
|7 (1406)|7.0|
|6.9|6.9|
|6.8|6.8|
|6.7|6.7|
|6.6|6.6|
|6.5|6.5|
|6.4|6.4|
|6.3|6.3|
|6.2|6.2|
|6.1|6.1|
|6.0|6.0|
|5.11|5.11|
|5.10|5.10|
|5.9|5.9|
|5.8|5.8|
|5.7|5.7|
|5.6|5.6|
|5.5|5.5|
|5.4|5.4|
|5.3|5.3|
|5.2|5.2|
|5.1|5.1|
|5.0|5.0|
|4.9|4.9|
|4.8|4.8|
|4.7|4.7|
|4.6|4.6|
|4.5|4.5|
|4.4|4.4|
|4.3|4.3|
|4.2|4.2|
|4.1|4.1|
|4.0|4.0|
|3.9|3.9|
|3.8|3.8|
|3.7|3.7|
|3.6|3.6|
|3.5|3.5|
|3.4|3.4|
|3.3|3.3|
|3.1|3.1|
|2.1|2.1|