OmniAICreator/Qiita-1.07M huggingface dataset:
to_paramでURLにユーザーIDを表示する　初心者→中級者へのSTEP12/25

#to_paramでURLにユーザーIDを表示する
**はじめに**
今回解説するのは実際に僕が実装したもので、その時困ったこと、そしてどう対応したのかを紹介します。
このテーマについてはもっと良い方法がありそうなので、ご存知の方はご指摘いただけると幸いです。


##デフォルトのURL
Railsで`showアクション`にルートを通すと下記のようになる。
`http://localhost/users/1`
`http://localhost/users/2`
`http://localhost/users/3`
これだと「ん？もしかして会員数３人しかいない？」とか思われたり、何よりセンスがない。

なので、これを下記のようにユーザーIDを表示するようにしたい。
`http://localhost/users/＠kamo`
`http://localhost/users/＠buta`
`http://localhost/users/＠tanaka`

##to_param
実装は簡単で、`to_param`というメソッドをオーバーライドするだけ。

```User.rb
  def to_param
    user_id
  end
```
こうすると、モデルからパスを生成する時`:id`を使ってたのが、`:user_id`を使うようになってくれます。

to_paramの[ソース](https://github.com/rails/rails/blob/bb075e3839d9eea2be5cb0cbed50dafa2c14bb37/activemodel/lib/active_model/conversion.rb#L71)は下記のとおり。

```rb
  def to_key
    key = respond_to?(:id) && id
    key ? [key] : nil
  end

  def to_param 
    (persisted? && key = to_key) ? key.join('-') : nil
  end
```

上の`to_key`メソッドから見てみます。最初の１行で、`id`の有無、またメソッドとして呼び出せるかを確認しています。２行目で３項演算子を用いて、`id`を配列に格納しています。

そして次の`to_param`では、modelがDBに保存されていることを確認した後、`to_key`で得た`id` の配列を文字列化しています。

このto_paramはパスを生成する段階で呼ばれ、その時にパスに`id`を返す流れになっています。
それをオーバライドして、`user_id`が返ってくるようにしたわけです。

##問題が３点
上記のような`to_param`をオーバーライドの仕方だと問題が3点出てきました。

1,user_idに`index`,`new`など登録されると困る。
2,params[:id]に`user_id`が入るのでコントローラーでの修正が必要。
3,`omniauth`など、SNSの簡単認証などを使っていて、`user_id`が最初に登録されない場合、パスを生成できない。

##解決したコードがこちら

```User.rb
 def to_param
    user_id ? '@' + user_id : super()
 end
```
上記のコードでは`user_id`が存在するなら、＠を加えてます。
@が最初に加えられれば`index`だろうが、`new`だろうが怖くありません。また、super()は`user_id`を持ってないユーザーは元の`to_param`の振る舞いをするようにしてます。

```User_controller.rb

    def set_user
      if params[:id].chr == '@'
        user_id = params[:id].slice!(0)
        @user = User.find_by!(user_id: user_id)
      else
        @user = User.find(params[:id])
      end
    end
```
上記では加えた@を外してます。また`user_id`を登録してないユーザー用の分岐もかけています。
これでURLには`user_id`が表示され、かつちゃんとユーザーのデータも読み込めます。


##まとめ
この実装してて思ったのは、「Rails wayに反しているのでは...？」となりましたが、他に方法が見当たらないのでこの方法で実装しました。（当時）
今回調べてたら、実はgemで`friendly_id`てのがあり、それでも実装できるらしいです。でもまあ、せっかく`to_param`覚えたし、gemの仕組みを理解するよりこっちの方が仕組みを理解するのが簡単そうだったのでこっちを採用します。


##参考にしたの

【Rails】to_paramでURLをUser.nameにする
https://remonote.jp/rails-to-param-url-user-name
horovodのTensorflow eager対応(PR中)

# horovod
horovodはuberが開発しているDeep Learningの分散学習向けのフレームワークです．
現在,Tensorflow, pytorch, kerasに対応しています．([現在MXNetのPR](https://github.com/uber/horovod/pull/542)が出ているのでもうじき対応するかもしれません．)
詳しくは[紹介記事](https://qiita.com/kurosawa1/items/5aeb9efb2eceeb9c8206)があるので，horovodに関する説明はそちらを見てほしいです．

現状のhorovodはgraphモードのみに対応していて、sessionを使う前提になっています。eagerには対応していません．
eagerモードはtensorflow2.0でdefaultになる予定など今後重要度が増してくるので対応した方が良いなと思ったのが動機です．
今回の記事はhorovodに対してeager向けのPRで自分がした変更について軽く書いていこうと思います．
(あまり大した変更してないのと，まだPRの段階なのでmergeされるとは限りません．．．．．)
実際に出した[PR](https://github.com/uber/horovod/pull/670)です
<img width="637" alt="hvd_eager.PNG" src="https://qiita-image-store.s3.amazonaws.com/0/135030/d3498785-c843-34b9-867e-d540f9dea5cc.png">

# 基本方針
horovodはTensorflowや各Deep Learning向けフレームワークとうまく分離できていて，データ取得は各フレームワークごとに実装されていて，核となるncclやmpiを使った分散処理はフレームワークに依存しない形で実装されています．実際の集合演算処理はTensorflowとは別thread，別streamで動作します。なのでeagerモードの対応もinterfaceのみの変更で対応しています．

# 対応内容
以下簡単に対応内容を書きます．
最近[Contributed.md](https://github.com/uber/horovod/blob/master/CONTRIBUTING.md)が追加されて，GPU,CPUのテストのunittestを追加する必要があることが明記されました．

## broadcast(初期値の共有)
horovodでは各GPUごとに初期化した初期値を統一するために，rootが初期化したvariablesを各GPUにばらまきます.（MPIのbroadcastを利用しています．）
従来の方法はsessionにhookさせる形でsessionが作成された後に1回だけ実行されます．eagerだとsessionは使用しないので新たに関数を定義してあげました．

## allreduce(gradientsの平均化)
allreduceはtf.train.Optimizerをwrapする形で実装されていて，compute_gradientsで計算を行ったgradientsを受け取ってhorovodでallreduceを実行しています．
eager modeでbackwardを実行するためには```tf.GradientTape```のgradient関数を利用します．eager対応も従来同様，tf.GradientTapeをwrapするclassを実装する形で実現しました．

```python
        with tf.GradientTape() as tape:
            logits = mnist_model(images, training=True)
            loss_value = tf.losses.sparse_softmax_cross_entropy(labels, logits)

        # Horovod: broadcast initial variable states
        # from rank 0 to all other processes. This is necessary to ensure consistent
        # initialization of all workers when training is started with random weights
        # or restored from a checkpoint.
        hvd.bcast(0, mnist_model.variables) if batch == 0 else None

        # Horovod: add Horovod Distributed GradientTape.
        tape = hvd.DistributedGradientTape(tape)
        grads = tape.gradient(loss_value, mnist_model.variables)
```

## unit test

horovodはTensorflowのtf.test.TestCaseを利用してunit testを書いています.
tf.test.TestCaseはpythonのunittestを継承して作られているので使い方はほとんど同じですが,
tf.test.TestCaseを利用するとsessionの管理が簡単になったり
eagerのテストもgraphモードのテストと同一のTest関数内に定義することができました.

```python
    def test_horovod_allreduce_cpu_fused(self):
...

         with self.eager_mode:
            tests = graph_and_eager()
            with self.subTest(msg='eager mode'):
                self.assertTrue(tf.reduce_all(tests),
                                "hvd.allreduce produces incorrect results")

        with self.test_session(config=self.config) as session:
            tests = graph_and_eager()
            with self.subTest(msg='graph mode'):
                self.assertTrue(session.run(tf.reduce_all(tests)),
                                "hvd.allreduce produces incorrect results")

```

# まとめ
今回初めてOSSに対してPRを出したので、その内容に関して簡単に書きました.
アドバイス、ご感想などありましたらお気軽にコメントお願いします.
シクシク素数列 Advent Calendar 2018 C#編

[「シクシク素数列 Advent Calendar 2018」](https://qiita.com/advent-calendar/2018/4949prime-series)の16日目の記事になります。問題詳細は当該アドベントカレンダーのページを参照していただくとして、ごく簡単にまとめておくと「100以下の自然数nが与えられたとき、n番目までの"シクシク素数"を求めて、カンマ区切りで出力しなさい」というものになります。なお"シクシク素数"とは数値として4または9を含む素数を指します。

本記事ではこの"シクシク素数"問題をC#で解答しています。解答コードは次の通りです。

```csharp
using System;
using System.Collections.Generic;
using System.Linq;

namespace Prime4949
{
    class Program
    {
        static void Main(string[] args)
        {
            int n = 100;
            var answer = string.Join(",", Primes().Where(Program.HasFourOrNine).Take(n));
            Console.WriteLine(answer);
        }

        /// <summary>
        /// 数値に4か9を含むかどうかを判定する。
        /// </summary>
        /// <param name="x">自然数</param>
        /// <returns>xが4か9を含む場合true</returns>
        static bool HasFourOrNine(int x)
        {
            while (x > 0)
            {
                int mod = x % 10;
                if (mod == 4 || mod == 9)
                {
                    return true;
                }
                x /= 10;
            }
            return false;
        }

        /// <summary>
        /// 素数を次々に生成する。
        /// 
        /// 注意: 
        ///     任意の素数をxとすると、x+1..x^2に1つ以上の素数が含まれていることを前提にしています。
        ///     そのほか、説明のためにもろもろの検査をすっ飛ばしています。
        ///     クリティカルな場面では利用しないことをおすすめします。
        /// </summary>
        /// <returns>素数</returns>
        static IEnumerable<int> Primes()
        {
            var primes = new List<int> { 2, 3, 5 };
            for (int index = 0; ; index++)
            {
                if (index == primes.Count)
                {
                    var min = primes.Last() + 1;
                    var max = min * min;
                    var integers = Enumerable.Range(min, max - min + 1).ToList();
                    foreach (var prime in primes)
                    {
                        int sieving = integers.FindIndex(digit => digit % prime == 0);
                        while (sieving < integers.Count)
                        {
                            integers[sieving] = -1;
                            sieving += prime;
                        }
                    }
                    primes.AddRange(integers.Where(integer => integer != -1));
                }

                yield return primes[index];
            }
        }
    }
}
```

---

シンプルな問題なので解答方法はいろいろあると思いますが、今回は次のような方針を採用してみます:「素数列から4949性を満たすものをフィルタリングする」。まず素数列の生成ですが、今回はいわゆる[エラトステネスのふるい](https://ja.wikipedia.org/wiki/%E3%82%A8%E3%83%A9%E3%83%88%E3%82%B9%E3%83%86%E3%83%8D%E3%82%B9%E3%81%AE%E7%AF%A9)を利用することにしました。エラトステネスのふるいは素数判定法のひとつで、指定された整数以下の素数を単純かつ効率的に求めることができ、プログラミングの教材にもよく利用されます。「指定された整数以下の素数を求める」という記述を見ると、今回のように「無限に素数を作りたい」という要件にマッチしないようにも思えますが、工夫次第ではなんとでもなり、それを実装したものが`Primes`メソッドになります。

4949性を満たすかどうか--すなわち与えられた整数が数値として4または9を含むかの判定を行っているのがメソッド`HasFourOrNine`で、除法をうまく利用して整数xを各桁ごとにばらしています。
IntelliJ IDEAを利用して、コメントからソースコードにある問題のありそうな箇所を見つける


ソフトウェアテスト Advent Calendar 2018 - Qiita の12日目の記事です。

IntelliJ IDEAを利用して、コメントからソースコードにある問題のありそうな箇所を見つける方法について，紹介します．

## TODOコメント
TODOコメントは，下記のような例です．

``` Java
//TODO:処理速度を早くするために，アルゴリズムを改善する
```
よくありますよね．

このようなコメントは，TODOコメントと呼ばれたり，開発中のコメントと呼ばれたり，
Self-Admitted Technical Debtと呼ばれたりします．
日本語でいうならば、技術負債を表すコメントといってもよいでしょう．

このようなコメントの周辺には，ソースコードに問題が存在しています．
このようなコメントを見つけることで，ソースコードにある問題のありそうな箇所を見つけることができます．

統合開発環境の一つであるIntelliJ IDEAには，TODOコメントを見つける機能があります。
https://pleiades.io/help/idea/using-todo.html

TODOとFixmeのタグのついたコメントであれば，そのままでも見つけることができます．
しかし，TODOの他にも，XXXやHACKやOPTIMIZEなどのタグが使われて記述されます．
また，知識不足により開発者によっては，コメントにタグを付けない人がいます．
他にも，自分独自の言葉でタグを付けていることがあります．
これらのコメントを見つけるためには，カスタマイズしたパターンを追加する必要があります．

## パターンの追加方法

IntelliJ IDEAでは，カスタマイズしたパターンを追加する機能があります．
https://pleiades.io/help/idea/using-todo.html

パターンには，正規表現を利用して追加できます．
正規表現については，以下をご覧になってください．
https://pleiades.io/help/idea/regular-expression-syntax-reference.html

日本語で検出したいパターンは，下記のようなものがあると思います．

``` Java
//これ必要?
//これいる？
//今は使ってない
//なぜか動く？
//暫定的な処理
//今後対応する
//将来対応する
//改善すべき
//暫定的な処理
//仮の処理
//修正開始
//修正完了
```
このようなコメントを見つけるパターンを，記述して追加しましょう．
以下は例です．

``` Java
必要\?
いる\?
今\?
今後\?
使っていない
なぜか
暫定的な
将来
改善
仮の
修正の
？
```
これくらいのであれば，正規表現を利用せずとも引っかかりますね．
ゴミも出てきたりするので，正規表現を工夫する必要があります．

このように，見つけてきてくれますね．

<img width="766" alt="スクリーンショット 2018-12-12 23.29.24.png" src="https://qiita-image-store.s3.amazonaws.com/0/42567/8ff69d82-527c-492a-e634-ed9699096a04.png">


## 最後に

他のIDEでも同様な機能があるため，同様にパターンを追加すると，コメントを見つけることができます．
ただし，正規表現の記述方法は，IDEごとに違うので，IDEごとの正規表現を調べて従う必要があります．

grepコマンドを利用しても，正規表現を利用して見つけることはできます．
また，それなりに工夫が必要です．grepを利用した方法については，そのうち書くかもしれません．

チームでよく書かれるような，このようなコメントのパターンを追加してみてください．
正規表現を工夫するとゴミが減っていきます．
Docker の基本コマンド


## Dockerのインストール
1. [Docker Desktop (Mac)](https://store.docker.com/editions/community/docker-ce-desktop-mac) の「Get Docker」から
Stable（安定版）または edge（最新版）を選択してダウンロードする

2. ダウンロードした「Docker.dmg」をダブルクリックしてインストールする

## コンテナを一覧表示（実行中のコンテナのみ）

```
$ docker ps
//または
$ docker container ls
```


## すべてのコンテナを一覧表示（停止中のコンテナを含む）

```
$ docker ps -a
//または
$ docker container ls -a
```

## イメージ取得（pull）、コンテナ生成（create）、コンテナ起動（start）を一度に行う


```
$ docker run イメージ名

//例
$ docker run hello-world
```
ローカルに該当するイメージがみつからない場合は、Docker が Docker Hub から自動的にイメージを取得してくる

## イメージを取得

```
$ docker pull リポジトリ:タグ

//例
$ docker pull alpine
$ docker pull centos:7
```
※[Alpine（Linux軽量OS）](https://hub.docker.com/_/alpine/)
※タグなしの場合は自動的にlatestタグが付与される

## 今までpullしたホスト上のイメージを一覧表示

```
$ docker images オプション
```
イメージはリポジトリ単位で管理されている

## コンテナ生成

```
$ docker create -it alpine
```

　=>コンテナID表示
　オプション	内容
　-i	アタッチしていなくても、STDINを開き続ける。STDIN：standard input 
　-t	疑似ターミナル（pseudo-TTY）を割り当てる。 　
　--name	コンテナに名前を割り当てる。


## コンテナ起動（startコマンド ＋ コンテナID）
コンテナ識別子（コンテナID）はすべてコピーでも頭の３文字程度でも可

```
$ docker start [コンテナ識別子]
```


## コンテナ停止

```
$ docker stop [コンテナ識別子]
```



## イメージの詳細を表示する
```
$ docker inspect リポジトリ

//例
$ docker inspect mysql
```

## コンテナ削除

```
$ docker rm コンテナ識別子
```

## コンテナの名前変更

```
$ docker rename 新コンテナ名 旧コンテナ名
```

## alpineを生成し、中に入る場合

```
$ docker run -it alpine bin/sh
```
ディレクトリの中のファイルやフォルダを一覧表示する

```
$ ls
```

alpine から出る

```
Ctrl + P → Q 
```

## 参考

- [The base command for the Docker CLI.](https://docs.docker.com/engine/reference/commandline/docker/)
- [#マンガでわかるDocker ① 〜概念・基本コマンド編〜 PDFダウンロード（改訂版） #技術書典 4](https://note.mu/llminatoll/n/n4f419db0effc)
- [Software Design 2017年2月号](https://gihyo.jp/magazine/SD/archive/2017/201702)
CakePHP 2 から CakePHP3 ORM を使ったテスト

さて、まず [kunit](https://qiita.com/kunit) さんの記事 「[CakePHP2 から CakePHP3 ORM を使ってみる](https://qiita.com/kunit/items/f00d232baead413ba223)」 を読ませていただいて、
「既存のコードは、製品コードの他にテストのコードがあるのだけれど、どうすればいいのかな？」
という疑問がわきました。
さて、どこまでできるかわからないのですが、試してみることにしました。

kunit さんがもともと用意していたリポジトリが使えるのでとても楽に進めることができました。ありがとうございます！

今回、私の方で手を加えたソースの差分は、[こちら](https://github.com/okinaka/cakephp2-with-cakephp3-orm/compare/develop...support-testing)。

テストを動かすためにつまずいた点や思いついたことを並べてみます。

## phpunit は何を使えば良い？

とりあえず、今回は CakePHP 2 と 3 の両方でサポートしている 5.7.* にしました。
ただ、php 7.2 を使うのであれば、phpunit 6 以上が必要らしいのですが、
6 は来年２月１日でサポート終了なので 7.x 系がいい?

https://phpunit.de/supported-versions.html

## ORM へのテストデータベースへの接続方法

CakePHP では、テスト実行時にテストデータベースへ接続します。どうやって接続先を切り替えたらいいのでしょう？
現状では、それぞれ別々の設定を持っていて全く連携していないので、何か手を打つ必要がありそうです。

調べた結果、接続先は Cake\Datasource\ConnectionManager で制御していました。

https://github.com/okinaka/cakephp2-with-cakephp3-orm/blob/develop/app/Config/bootstrap.php#L118-L121

```php
 \Cake\Datasource\ConnectionManager::setConfig( 
     \Cake\Core\Configure::consume('Datasources')
);
```

として、 `test` もデータソースとして設定した後、

```php
 ConnectionManager::alias('test', 'default');
```

をテスト実行時に設定します。
今回は、 `app/Test/bootstrap.php` に上のコードを書くだけにしてます。
これで、 テストデータベースへ接続するようになりました。

この処理は CakePHP 3 の場合は、 FixtureManager 内でやってくれるみたいだけれど、
CakePHP 2 のフィクスチャしかないので、ORM の部分は自前で FixtureManager を実装することになるはず。

## TestCase::getMockForModel() の実装

モデルをモックしたい場合もあると思います。
これも、 ORM 部分の実装は、 3 から取ってこないとダメっぽい。

真面目に実装するとなると [こちら](https://api.cakephp.org/3.7/source-class-Cake.TestSuite.TestCase.html#732-777) をコピって動くようにするわけだけど、
面倒臭そうなので、今回はパスかな。

以上、雑に調べてみましたが、意外といけるかも？という感触は得られて満足です。
scrapyのインストールでエラーになった際の対処法(Ubuntu18.04)

## 1.この記事の目的
scrapyをubuntu 18.04にインストールしようとした所、少々エラーが発生したので、
その解決方法を共有することを目的とした投稿です。

```error.py
error: invalid command 'bdist_wheel'##wheelが無い！
  
  ----------------------------------------
  Failed building wheel for PyDispatcher
  Running setup.py clean for PyDispatcher
  Running setup.py bdist_wheel for Twisted ... error
  Complete output from command /home/yoshida/pyProject/breadData/bin/python3 -u -c "import setuptools, tokenize;__file__='/tmp/pip-build-imm_816d/Twisted/setup.py';f=getattr(tokenize, 'open', open)(__file__);code=f.read().replace('\r\n', '\n');f.close();exec(compile(code, __file__, 'exec'))" bdist_wheel -d /tmp/tmpsiymix5ypip-wheel- --python-tag cp36:
  usage: -c [global_opts] cmd1 [cmd1_opts] [cmd2 [cmd2_opts] ...]
     or: -c --help [cmd1 cmd2 ...]
     or: -c --help-commands
     or: -c cmd --help
  
  error: invalid command 'bdist_wheel'
  
  ----------------------------------------
  Failed building wheel for Twisted#Twistedも無い！
  Running setup.py clean for Twisted
Failed to build PyDispatcher Twisted
Installing collected packages: cssselect, w3lib, parsel, PyDispatcher, queuelib, pyasn1, pyasn1-modules, service-identity, Twisted, scrapy
  Running setup.py install for PyDispatcher ... done
  Running setup.py install for Twisted ... error
    Complete output from command /home/yoshida/pyProject/breadData/bin/python3 -u -c "import setuptools, tokenize;__file__='/tmp/pip-build-imm_816d/Twisted/setup.py';f=getattr(tokenize, 'open', open)(__file__);code=f.read().replace('\r\n', '\n');f.close();exec(compile(code, __file__, 'exec'))" install --record /tmp/pip-jlw00lig-record/install-record.txt --single-version-externally-managed --compile --install-headers /home/yoshida/pyProject/breadData/include/site/python3.6/Twisted:

```

## 2.環境
ubuntu 18.04
再インストールしたばかりの状況です。

## 3.発生したエラー群まとめ
* wheelが無い。
* 開発環境（gcc）が無い。
* python3-devが無い。
* Twistedが無い。

## 4.エラーに対する対処
1. wheelが無い。　`$ pip install wheel`
1. 開発環境（gcc）が無い。　`$ sudo apt install build-essential`
1. python3-devが無い。　`$ sudo apt install python3-dev`
1. Twistedが無い。　`$ pip install Twisted`

## 5.ようやくscrapy
```install.py
$ pip install scrapy 
...
Installing collected packages: scrapy
Successfully installed scrapy-1.5.1

```
以上です。
64bitアプリでの WM_DROPFILESメッセージのバグについて

Win32API アプリのGUIでD&Dを簡単に扱う方法の一つとして WM_DROPFILESメッセージを利用するというのがあります。
しかし、32bitアプリからファイルをD&Dして64bitアプリ上でそのメッセージを処理しようとしても上手く行かないようです（他のパターンなら問題は無いようです）。それについて調べてみたら以下のURL（英語）にて質問と回答があったのでそれについてまとめてみました。

https://stackoverflow.com/questions/39612616/drag-and-drop-from-32-to-64-bit


32bitアプリと64bitアプリ間でのD&Dとそれを受け取るWM_DROPFILESメッセージのやりとりについて、
32bitアプリからD&Dして64bitアプリでWM_DROPFILESメッセージを受け取った場合に正しく動作しない問題がある。
どのような問題かというとWM_DROPFILESメッセージのパラメータWPARAMで受け取るHDROPの上位32bitが破壊されていて正しく動作しないとのこと。

対処法としては複数ある

- WM_DROPFILESメッセージの使用を止めてIDropTargetインターフェースを使用する
  - インターフェースをごっそり変えるので面倒だが、正しい対処法と言える。
- 破壊された上位32bitを復元する。
  - 具体的にはGlobalAlloc関数を利用して得られたポインタの上位32bitが破壊されたポインタと同じとする
  - 危険な方法だと言えるが、修正は楽。
- high entropy ASLR を無効にする。
  - セキュリティリスクがあるみたい。
  - ごめんなさい。自分にはよくわかりませんでした。

自分がこのバグに遭遇した時は、一時的なアプリであった為破壊された上位32bitを復元する方法を以下のコードで対処した。

```C++
// HDROP drop
LONG_PTR p = (LONG_PTR)::GlobalAlloc(GMEM_MOVEABLE, 0);
drop = (HDROP)((0xFFFFFFFF00000000 & p) | (0x00000000FFFFFFFF & ((LONG_PTR)drop)));
::GlobalFree( (HGLOBAL)p );
```
最近知った便利なGitのコマンド・オプションたち

最近知った便利なGitコマンド・オプションを使い所と併せて紹介します。

## ファイル内の特定の編集だけステージしたい
```sh
$ git add --patch
```

addコマンドに`--patch(もしくは-p)`オプションをつけると修正した塊(ハンク)ごとにステージするかどうかを選択できます

```sh
$ git add --patch

diff --git a/nvim/dein.toml b/nvim/dein.toml
index 964ebe1..69af6f8 100644
--- a/nvim/dein.toml
+++ b/nvim/dein.toml
@@ -621,9 +621,6 @@ 

+[[plugins]]
+repo = 'Shougo/dein.vim'

Stage this hunk [y,n,q,a,d,e,?]?
```

基本的にはy(es), n(o)でステージするハンクを選んでいくだけです(?を実行すれば各コマンドの内容が表示されます)

自分の想定していない修正が入っていないかステージする前に必ず確認したいのでaddコマンドは必ずこのオプションとともに実行するようにしています

## ちょっとした修正を前のコミットに含めてしまいたい
```sh
$ git commit --amend --no-edit
```

ちょっとした修正を`git add`したあとに↑のコマンドを実行することで前のコミットに修正を取り入れることができます
直前のコミットをリモートにpushしてしまった場合は使えません
また, コミットメッセージも修正したい場合は`--no-edit`コマンドなしで実行したらできます

## 新規作成したファイルが間違ってignoreされてないか確認する
```sh
$ git status --ignored | grep searching_file
```

新しく作成したファイルがなぜかignoreされていてコミットに含めるのを忘れてしまうことってあると思います(ないですかね)
`git status`に`--ignored`オプションをつけるとignoreされているファイルも合わせて表示してくれるので簡単に確認できます
そのまま実行するとignoreされているファイルが多いときは探すのがめんどくさいのでgrepしてもよいです

## 作業ディレクトリから不要なファイルを削除したい
```sh
$ git clean --interactive
```

一時的に何かしらのテスト用ファイルを作ったりすること、あると思います。その後必要なくなったので削除したい, そんなときは`git clean`を実行することで綺麗な状態にできます。`--interactive(もしくは-i)`オプションをつけることで以下のように対話形式で削除するファイルを選択できるので誤って必要なファイルを削除することを防げます。

```sh

$ git clean --interactive
Would remove the following items:
  .DS_Store test.py
*** Commands ***
    1: clean  2: filter by pattern  3: select by numbers  4: ask each  5: quit  6: help
What now>
```

なお`git clean`するとファイルが完全に削除されるので一応ファイルの変更を残しておきたいときは`git stash --all`します

## 割り込み作業が入って別ブランチを切らないといけない
```sh
$ git worktree add -b hotfix/fatal-bug hotfix
```

何かしらの作業中に別の作業をする必要が出たとき`git stash`して`git checkout -b hotfix/fatal-bug`のようにするのはちょっとめんどくさいですね
同じワーキングツリーでbranchを切り分けるのではなくワーキングツリー自体を新しく追加することで簡単に作業branchを切り替えることができます
`git worktree add -b ブランチ名 パス名`とすることで新しくワーキングツリーが指定したパスに追加されます
↑の例だとhotfixディレクトリが新規に作成されるので`cd hotfix`して実際に作業を行なうことができます
作業が終わりpushまでしてしまったらルートディレクトリに戻って`rm -rf hotfix`で作成されたhotfixディレクトリを削除して`git worktree remove`もしくは`git worktree prune`するだけです

## まとめ
↑で紹介したコマンドを利用することで雑なコミットをしてしまったり作業ディレクトリが汚れるのをある程度防げるような気がします
あとはbranchの切り方にも気をつけて綺麗なバージョン管理をしていきたいです:muscle:
MIME TYPE application/octet-streamを返すときブラウザでは通信結果をダウンロードさせる

# MIMEタイプとは
返却するコンテンツの種類を表す識別子。

これによってブラウザはファイルを受け取ったときの挙動が決まる。

# nginxでの設定例
nginx.confのhttpディレクトリでは以下のような指定がされてある。

```
http  {
  include /etc/nginx/mime.types;
  default_type application/octet-stream;
}
```

`/etc/nginx/mime.types`には拡張子ごとに設定するMIMEタイプが定義されている。

# octet-streamを返すケース
どれにもマッチしなかった場合、`application/octet-stream`となる。

curlでみるとこういう値が表示されている。

```
< HTTP/2 200
< server: nginx
< date: Wed, 12 Dec 2018 14:00:34 GMT
< content-type: application/octet-stream
< content-length: 303
```

ブラウザでアクセスすると、結果がダウンロードさせられてしまう。

RFCを見てみると、octet-streamは任意のバイナリコードを意味し、ブラウザでは実行したりせず、単にダウンロードする挙動をとる。

http://www.t-net.ne.jp/~cyfis/rfc/mime/rfc2046_ja-2.html#INDEX_4_5_1

ちなみに適当にドキュメントルートを指定して、index.htmlを返すようにすると、ちゃんとcontents typeはtext/htmlになった。

# おわり
勉強になった。
NiCOLAについて


### はじめに
記事の投稿が遅れてしまい、申し訳ありません。

簡単に自己紹介をさせていただきます！
teamサイゼリア主催の @yoshixj さんが働いているNiCOLAで
インターン生としてマーケティングを担当させてもらっている者です。

何を書こうか悩みに悩みましたが、、ここ最近を振り返るとNiCOLAのことしか頭に浮かばなかったので、NiCOLAについて書こうと思います。笑
NiCOLAというチームに入って思ったことを書きます！

### NiCOLAのいいところ
- 常にwe思考であること。
”私”ではなく”私たち”を基準にチーム全体が行動している。

- 自分がしている作業の目標や、それに対しての進捗状況などを全体で共有することでチーム内の共通理解を深めている。チーム全体のレベルアップに繋がる。

- 信頼関係
これはNiCOLAに入って一番強く思ったことです。
信頼関係を築き、親密になることでメンバー内のやりとりが増えます、これもまたチーム全体のレベルアップに繋がると言えます。

他にもたくさんありますが、、
１ヶ月経って感じたチームのいいところをまとめると、こんな感じです！

### 自分の成長とチームの成長

よく、社長のみつやさんに
”本多の成長がそのまま会社の成長に繋がる”と言われます。

自分が成長してアウトプットを出すことで、自分の成長にも、会社の成長にも繋がるし、
そのノウハウを言語化し、再現性のあるものにすれば、これから新しく入るメンバーが同じアウトプットを出すことができる。
結果としてチーム全体のレベルアップの底上げになる。

成長できる環境というのはまさにNiCOLAそのもので、このチームのメンバーの一員になれたことに感謝して、アウトプットという形で感謝の気持ちを伝えていきたいな、、と。


### 最後に

薄い内容ではありますが、、、
NiCOLAのいいところが少しでも伝わったら嬉しいです。

こうして読み返してみると、NiCOLAに愛着が湧いているのだな。と、改めて思います。笑

読んでいただきありがとうございました！
cloud9でメンバーと開発画面及びコードの共有する方法とチャット機能

cloud9への登録が完了していることを前提とした記事になります。

※　前準備として「参加するメンバーの、AWSに登録している名前およびID」が必要となりますので事前に取得しておいてください。
手順の大まかな流れとしては、共有のために必要な「ロールの作成」と、開発画面（IDE)へ移ってから行う「Share（シェア）」の2段階に分かれた操作になります。

手順「ロールの作成」
１.　cloud9のI AMマネジメントコンソールページをひらく。（場所がわからなければAWSトップページの黒帯の部分にある「サービス」をクリックし、検索フォームに「I　AM」と入力・決定すればI AMページがひらく。
左側にある表から「ロール」を選択、「ロールの作成」をクリック。（ここでいうロールとはチームのようなもので、ロールに参加させたいメンバーを登録することで自分のcloud9にメンバーを認識させることができます。）

２.　信頼されたエンティティの種類を選択の画面で「別のAWSアカウント」を選択、オプションはチェックしなくてOK。
参加するメンバーの12桁のアカウントIDを入力。

３.　画面右下の「次のステップ：アクセス権限」をクリック。
Attach アクセス権限ポリシーの表が出たら、表の中から「AWSCloud9EnvironmentMember」を見つけて、左のボックスにチェックを入れる。
（探すの大変なので、検索フォームにmemberと入力すればすぐ見つけられます。）
また、表の枠外下に「アクセス権限の境界設定」がありますが、ロール完成後にでも変更できるので、ここでは無視します。

４.　画面右下の「次のステップ：タグ」をクリック。ここも後で変更できるので無視で問題ありません。

５.　画面右下の「次のステップ：確認」をクリック。各項目を入力。
ロール名（チームの名前のようなもの。好きにつけて構いませんが、あとでチーム名を入力することになりますので簡潔で覚えやすいのがよろしいです。）
ロールの説明（そのままの意味です。入力しなくてもOKです。）
「ロールの作成」をクリックすればロールが完成します。
作成済のロールの表からロールにつけた名前をクリックすれば、先ほど無視したアクセス権限やタグを設定できます。
ここまでが「ロールの作成」になります。


ここからは「Share」の手順です。
１.　AWSのマネジメントコンソール（トップページ）からcloud9をクリック、そこから開発画面を開く。（OPEN IDEをクリック）
２.　画面右上の「Share」をクリック。
３.　メニューが出るので、invite Membersの欄に次の内容を入力してください。
```
arn:aws:sts::自分の12桁のアカウントID：assumed-role/先程決めたロール名/参加するメンバーのAWSに登録している名前
```
さらに分かりやすく書くと
```
arn:aws:sts::123456789100：assumed-role/hogehoge-team/kohya
```
となります。
一言でも間違うと成功しないため、注意が必要です。
また、混同しやすい注意としてロール名をクリックしたときに出る「ロールのARN」（arn:aws:iam::888888888888:role/sampleのような記述）とは内容が違うので勘違いしないようにしましょう。

４.　「Environment member added」と表示されれば成功です。
Who has accessに参加させたメンバーが表示されます。
※　青いボタンでR/RWと表示されているのはR（READ読む・閲覧することができる）　RW(Read読むこともWrite書き込むこともできる）という参加したメンバーによる自分の開発画面への干渉権限を示しています。
RWとすると書き込みを許可できる分、ファイルの消去などもできてしまうので注意が必要です。

これでチャットでのメッセージも送信できるようになっているので、SHAREの下側にあるGroup Chatも使用できます。

問題点が1つ。
本来であれば参加させたメンバーの「メンバー名」がWho has accessおよびSHAREボタンの下のEnvironment Membersには表示されるはずが、長い「arn:aws・・・」が表示されるため、メンバーが増えると誰なのかわからなくなってしまいます。
解決方法を模索中です。
Chatbase のススメ

#Chatbase とは
Chatbase とは対話型アシスタント（チャットボット)用のアナリティクスツールです。
作成したボットのログをプラットフォーム横断で確認することが出来ます。
<img width="1394" alt="chatbase_home" src="https://qiita-image-store.s3.amazonaws.com/0/40524/fe42693a-96ab-02d9-b3ee-b20ba3fee2a7.png">

#アクション作ったはいいものの、どう分析すればいいか
Google Assistant のアクションや Alexa のスキルを作成する際に問題となるのが、
「会話データの分析をどのようにすればいいかわからない」ということです。

Chatbase は、その問題の解決策の一つです。
この記事では、 Chatbase の使い方を、満月のことを教えてくれる「[満月博士](https://assistant.google.com/services/a/uid/0000006e9c5bdc27?hl=ja)」というアプリを例を紹介します。
#設定方法
設定チュートリアルは以下のドキュメントを読んでいただければと思います。

https://chatbase.com/documentation/quickstart

#できること
###処理出来なかったメッセージの確認
<img width="652" alt="chatbase_messages" src="https://qiita-image-store.s3.amazonaws.com/0/40524/69a85e4b-6b66-eace-9d1e-ea5e30b4b916.png">
「Message」 タブでは、どのようなメッセージを受け取っているか確認出来ます。
この例では、全体の 5 % の発話がきちんと理解出来ていない、ということになります。

また、View Transcripts をクリックすることで、実際に聞き取れなかった発話が確認出来ます。

例：
<img width="308" alt="chatbase_dialog_example" src="https://qiita-image-store.s3.amazonaws.com/0/40524/6f6615e3-029b-a3e7-dd19-47a01e3dec4b.png">

この例では、「明日の予定」 という言葉が満月博士には理解出来なかったことがわかります。

###セッションフロー
<img width="783" alt="chatbase_session_flow" src="https://qiita-image-store.s3.amazonaws.com/0/40524/d39f5f9e-c573-6c19-0e24-b03e59d8f138.png">
ユーザーがどのようなフローで会話を行っているかも確認出来ます。
満月博士は、 全体の 92.3% が Default Welcome Intent （通常のアクセス）からの流入で、 7.5% が その他の [Implicit Invocation](https://qiita.com/iwao_akiba/items/63e7b0f4e8d79f8fddff) からの流入になっていることがわかります。

また、Default Welcome Intent から流入したユーザーの 95 % がなにも会話せず離脱している、ということもデータでわかります。
今回の例では、満月博士にはじめて入ってきた人が話しやすいように「Default Welcome Intent」を変更する必要がある、ということがわかります。

###コホート
<img width="1004" alt="chatbase_cohorts" src="https://qiita-image-store.s3.amazonaws.com/0/40524/8c747d10-6c92-4242-c2a8-255c9202134a.png">
再来訪者/リターンユーザーのデータも確認出来ます。
残念ながらほとんどのユーザーは 1 回使って二度と返ってこない、ということがわかります。

#まとめ
Chatbase を利用することで、各プラットフォームに存在するアナリティクスでは見られない細かいデータが確認することが出来ます。
これらを利用することで、問題がどこに存在しているのか、改善する点はどこなのか、ということが明確にわかります。

ぜひ利用してみてください。
今年やった技術書の読書会のやり方

弊社ではよく技術書の読書会・勉強会が開かれます。
以下は今年私が会社内の読書会・勉強会で読んだ本です。

* Linuxのしくみ ～実験と図解で学ぶOSとハードウェアの基礎知識
* nginx実践入門
* データベース実践講義
* Real World HTTP
* スーパーエンジニアへの道―技術リーダーシップの人間学
* オブジェクト指向設計実践ガイド
* Clean Architecture

集まって読むことで、締切ができたり、ゆっくりとではあっても読み進められ、積読が減るので良かったです。

## 読み方いろいろ

### 輪読

* nginx実践入門
* スーパーエンジニアへの道―技術リーダーシップの人間学
* データベース実践講義
* Real World HTTP

nginx実践入門では、意外とみんなバラバラに読んでいるLinuxコマンドやオプションの読み方などを確認できてよかったです。
その他の本は、どこがわからないとかこの部分の具体例はなんなのかなどを話し合いながら読み進めました。


### ワールドカフェ
* オブジェクト指向設計実践ガイド
* Clean Architecture

[ワールドカフェ](http://world-cafe.net/about/)風にして、事前に決められた範囲を読んでおいて、疑問に思ったことを書きとどめておき、その後集まって話す形式でした。
わからなかった部分や内容を発展させる会話ができることで、より内容が定着したと思います。
また、どちらかといえば特定の言語やフレームワーク、ツールなどの技術書よりは、設計法など明確な答えの無い内容の本を対象とすると良いと思いました。

### 写経
* Real World HTTP
* Linuxのしくみ ～実験と図解で学ぶOSとハードウェアの基礎知識

実際にコードが出てくる本は、写経しながら読みました。
全員でその場でコーディングするので、環境のセットアップなども含めて、間違えたときに教え合えるのが良かったです。

## まとめ
読みたかったけど読み進められなかった本をワイワイやりながら読めるのは楽しいですね。
また来年もやっていきたいと思います。
C++で文字列を分割する方法

```split_string.cpp
#include <iostream>
#include <string>
#include <sstream>
#include <vector>
#include <boost/algorithm/string.hpp>
using std::cin;
using std::cout;
using std::endl;
using std::getline;
using std::string;
using std::stringstream;
using std::vector;

void method1();
void method2();

int main(int argc, char **argv) {
  return 0;
}

// 方法1: getlineを使う方法
void method1() {
  string line;
  cin >> line;
  string token;
  stringstream ss(line);
  char delim = ';';
  while (getline(ss, token, delim)) {
    cout << token << endl;
  }
}

// 方法2: boostのsplitを使う方法
void method2() {
  string line;
  cin >> line;
  vector<string> tokens;
  string delim = ";";
  boost::split(tokens, line, boost::is_any_of(delim));
  for (auto token : tokens) {
    cout << token << endl;
  }
}
```
自分のPC（mac）で、秘密鍵と公開鍵を作る方法

①真っ黒なターミナル画面にてsshのディレクトリを作成
`mkdir ~/.ssh`

②`cd ~/.ssh`
③`ssh-keygen -t rsa`
何回かエンターキーを押すと
　<img width="138" alt="スクリーンショット 2018-12-12 22.33.54.png" src="https://qiita-image-store.s3.amazonaws.com/0/204239/59c89f36-2f06-000b-0ad3-5e3c56449372.png"> 
のような表示が出てくるので、

④`ls`
id_rsa	　秘密鍵　（絶対誰にも教えない！）
id_rsa.pub　　公開鍵

⑤`cat id_rsa`
ズラズラ出てくる文字が秘密鍵　（絶対誰にも教えない！）

⑥`cat id_rsa.pub`
ssh-rsa から始まるズラズラ文字が秘密鍵

⑦`pbcopy < ~/.ssh/id_rsa.pub`
クリップボードにid_rsa.pub（公開鍵）がコピーされた

⑧Gitlab サイトにもどって、、、、、
右上のアイコンマークからsettingsへ
![image.png](https://qiita-image-store.s3.amazonaws.com/0/204239/dd779e6b-ea9b-5ca4-8d2a-712d30781d3c.png)

⑨左サイドバーにある鍵マーク!をクリック
![image.png](https://qiita-image-store.s3.amazonaws.com/0/204239/773fe1ac-e9c2-36ce-6217-ecc06de38ebe.png)

⑩
![image.png](https://qiita-image-store.s3.amazonaws.com/0/204239/758068fc-3ac2-63a7-514e-2864d87ec334.png)

Keyの欄にそのまま　⌘＋V　で貼り付け
Titleには、自分のPCの愛称をつけておく（例：MacBook Air2019）

最後にAdd keyボタンを押す

これで、自分のPCとGitlabの通信接続準備が出来た！
Ruby GOLDを受けに行って不合格だった話


みなさんは、Rubyに資格があることをご存知でしょうか。
Rubyアソシエーションが開催しているRuby技術者認定試験です。
そのレベルにSilverとGoldがあります。

私は知っていたのですが、値段が高い(16000円ぐらい)ことで敬遠しておりましたが、一念発起してGOLDを受けてみました。

結果、
落ちました。:innocent:

心がつらいですが、「試験にうけようかな」と思っている方向けに、体験談を書きました。
読み物としてアンチパターンにしてもらえればと思います。

# 自分について
コンピュータに触った経歴は長く、20年以上でしょうか。perlでちょっとしたスクリプトを組んで喜ぶ年少期を過ごしました。

現在は、半年前ぐらいにwebエンジニアに転向しまして、渋谷の会社さんでお世話になっております。

それまでは、ユーザ系Sierで6年間システムエンジニアをしていました。
夜間バッチがこけないことを祈りつつ毎日眠りにつく、精神のデスマーチをくらっていました。
一度こければ、復旧対処、再発防止、上司・ユーザへの報告、と大変で・・・。
そして、毎日フルタイムで打合せの日々・・・かっこいいプログラマーを目指したかったのに、

なぜか進捗管理と見積のエキスパートみたいになってるし・・・。

でもそのおかげで、大半の事には動じない（驚かない）強い心を持てたと思います。

今は、プログラミングができて楽しい日々をおくっています。

# 受けたきっかけ
「Rubyを業務で使って、半年ほど経つ。どれぐらい理解できてるのか客観的に知りたい」
「コミュニティで知り合った人が、10月ごろ取得した。負けられない。」

 といった気持ちからです。

# 試験対策

公式教科書 基礎問題、模擬問題 合計 80問を1周
ITトレメ 60問を2周

時間にすると5,6時間でしょうか。

# 問題の傾向

キーワードで表すと、
・モジュール
・クラス
・定数
・self
・可変長引数
・Fiber
・その他(rubyコマンドオプション、組み込みライブラリ）

当然単純な問題ではなく、深い理解を要するものばかりでした。

例えば可変長引数だったら

``` ruby:question
def hoge(*args)
 p args
end

hoge([1,2,3,4])
```

回答

```
1. [1,2,3,4]
2. [[1,2,3,4]]
3. エラー
```

などなど。

正解はどれでしょう？！。答えは試してみてくださいｗ

私のように、初心者じゃないんだけど中級者でもないよなー、ぐらいの方には理解が深まりいい感じだと思います。

# 受験の申し込み

ここからは、私の申し込み～受験終了の体験談を書こうかと思います。

まずは、申し込み。
プロメトリックからオンラインで予約＆支払いが可能です。
受験地と日付も指定できます。国家資格の試験と違って自分の都合で受けられるのがいいですね。
私が住んでいる多摩地区でも府中市や立川市に試験会場がありました。
ちなみに、今回は府中で受けてきました。

ただし、簡単に申し込みできる分、「本当にうけようかどうしようか」という葛藤が数日続きました笑。
1万6000円・・・私の収入では大金なのです。

# 当日まで

公式教科書を購入。アマゾンでも売っていたのでkindleにしました。
それと、受験された方のブログ記事を拝読。
ITトレメで無料で問題が公開されていることを知りました。

隙間時間を使いながら、問題を解いていきます。

# 受験当日

問題の傾向を把握し始めた段階で試験当日になってしまいました。

## 受付
必要なものは、身分証明証と申し込み時の確認書(ネット画面プリント)ぐらいです。
試験会場にいくと、6畳ぐらいの部屋にパイプイス、ロッカー、受付の窓口があり、3,4人待っている方がいます。
おそらく別の試験を受ける方だと思いますが、結構受験する人いるんだなーと感じました。
スーツで来てる人もいたので、仕事の合間をぬってきたのかな。

受付を済ませると、腕時計からなにやらなにまでロッカーに仕舞えといわれたので、指示に従います。

時間になると受付の方が試験手順を説明してくれます。
説明後、別部屋に通され、自習室みたいにセパレートされたブースで受けました。
各ブースの天井には監視カメラが配置されておりましたが、違和感なかったです。

## 試験

いざ試験を開始するんですが、感じたことが二点。

1. 試験用パソコンの解像度が低い。
 普段なれている大きさのソースコードが表示されないため、戸惑いました。

2. 試験開始は自分のタイミングで始められる。
 これまで受けてきた試験だと試験官が「開始！」と言ってから全員スタートだったんですが、自分でボタンをクリックして開始でした。
また、イヤーマフとマジックペンで書けるホワイトボードペーパーが使えました。

そんなこんなで開始してから60分、すべての問題を解き終わります。

## 試験後

解き終わると、アンケートと結果がその場で画面に表示されます(すごい)。

結果、75点以上で合格のところ70点でした。泣

なにを間違えたのかはわかりません。
おそらく、Moduleの`included append_features`のところかな。

ガックシしながら、受付の部屋にもどり、A4用紙一枚の不合格ペーパーをいただきました。

# 反省

1. 計画をおろそかにした

もうこれに尽きるとおもいます。

試験申し込み～試験当日が1週間程度でした。

「彼を知り己を知れば百戦殆うからず」

敵(問題)をリサーチせずに一週間後と決め打つ愚策。
結果、今回は問題の傾向を把握した段階で試験に臨むことになってしまいました。

まずは、模擬問題を一通り解き、
自分の実力と問題にどれぐらいギャップがあるのか見定めて
計画を立てましょう。

# 今後
サンクコストにするわけにはいかないのです！。
2,3ヵ月後にお金がたまったら、再チャレンジしたいです。

# 参考リンク

参考にさせていただいたサイト

[Ruby技術者認定試験Goldに1ヶ月で合格するまでにやったこと](https://qiita.com/pepepki/items/62a3d54d8416eeb56265)
プロに聞きながらGitlabを初体験　            ①登録から自分のPCとの紐付けまで

まずは、Gitlabをググって、サインアップ
登録メールアドレスで認証して
本格的に使用開始できる

#create project
###①Project name 　に　開発プロジェクト名を記入
###②Visibility Level（ココ重要！）　
　自分だけで開発する場合は、privateのままでOK！ 
　ここで、privateにしていても、アクセス権限はあとから変更可能

###③create projectボタンを押す

#自分のPCのターミナルとの紐づけ
『自分のPCのテキストエディタで書いたコード、変更点が自動的にGitlab に反映してくれると楽だな〜〜。』
（実は、後から気づくと結構コワイ事かも。。。）

###①右上のアイコン（変な絵）へ
　→Settingsへ
　　→左側メニュバーの鍵マーク　SSH keys　へ
　なにやら、public key を記入することころがあったりする。
　
　これはどういうことかというと、
　自分のPCに秘密鍵、Gitlabに公開鍵　を置いて、
　公開鍵暗号方式で、２つの環境が１対１で通信できるようにするわけだ

###②自分のPCで秘密鍵・公開鍵を作る
　長くなりそうなので、別途まとめた

###③SSH keysのページ
　公開鍵を記入
　Add keyボタンを押す


以上で、自分のPCと　Gitlabが通信できるようになった。。。
初心者向けPython入門講座の開催入門（準備編）

Pythonの活用分野は、事務作業から人工知能・Web開発まで幅広い分野で活用されています。そのため、様々な利用目的を持った初学者に対してどのような入門講座が良いか整理しました。
本記事では初心者向けのPython入門講座の講師経験から学んだ事を中心に記載しました。

#入門講座のタイトルを決める

入門講座講師メンバーと初めに検討した事は、入門講座のタイトルです。
タイトルをしっかりと決める事で、受講者はどのような入門講座であるか理解してもらい、講師は作成する教材の方針を決めやすくなります。

講師メンバーと検討し、サンプルプログラムを動かし、プログラミング初心者でも楽しんで学べる講座である事が最も伝わる下記タイトルを採用する事に決定しました。

**タイトル：動かして学ぶ、はじめてのPython**


また、他のタイトル案は下記に記載します。

- 実務で使うPython入門　〜〜初めの一歩〜〜
- 実践！Python入門 〜実務で使う第一歩を踏み出そう〜
- 段階的に学ぶPython入門　～実践力をつけるPythonプログラミング講座～

最終的には実務利用が出来るようになってもらう目標でもあったため、実践的な講座である事を訴えかけるタイトルです。
但し、少し難しい印象を受けるタイトルになってしまうため、「実務」「実践」より「動かして学ぶ」と「はじめての」で初心者向けである事がタイトルで理解できる上記タイトル案が採用されました。


#実施内容と時間配分を決める

次に講師メンバーと議論した事は、実施内容と時間配分です。
まったくプログラムミングを今まで経験された事の無い方でもステップを踏んで理解出来るように「基礎編」「応用編」「発展編」と３部構成にしました。

プログラミングが初めての方でも理解出来るように「基礎編」で構文とデータ構造を理解して頂き、「応用編」では少し長いプログラミングに挑戦してデバッグ方法やユニットテストをしてもらいます。
「発展編」はサンプルのチャットボットを使って「基礎編」「応用編」の学んだ事を試してもらう事を前提としています。

各講座の詳細と時間配分は下記のようにしました。

- 基礎編　2時間（１０分）
    - データ構造・制御の基本的な構文を理解します
    - コレクション（リスト・辞書）について理解します
    - 関数・クラスについて理解します
    - エラー処理について理解します
    - ファイル入出力について理解します
    - リスト内包表記・ジェネレータについて理解します

- 応用編　２時間（１０分）
    - PEP８スタイルガイドについて理解します。
    - クラス・関数のドキュメンテーションの書き方について理解します。
    - ユニットテストとデバッグ方法について理解します。
    - 標準ライブラリに含まれるsqlite3を使ったDBアクセス方法について理解します。
    - 外部サイトの情報を取得してみます。

- 発展編　２時間（１０分）
    - Slackとbotについて理解します。
    - 開発環境を構築します。
    - botを動かします。
    - 課題にチャレンジします。
    

「基礎編」の前半では、講座の全体像の説明や、環境設定とPythonが他の言語と違いどのような優位点があるかなどの説明もしているため、実際は１時間ほどで説明できる内容となっています。
それには理由があり、講師陣でロールプレイング（講義の練習）をした結果、座学に近い講義になり退屈すぎるため「基礎編」は１時間で説明出来る内容にしています。
本来であれば、マルチスレッドやマルチプロセスの説明や位置引数・キーワード引数など細かな内容についても「基礎編」に加える予定でした。

「応用編」では、「外部サイトの情報を取得」するで、自分自身でプログラムをカスタマイズしたりするためテストやデバッグ方法を中心に課題を含めて学習して頂きました。
前半の１時間は「基礎編」と同様に座学に近い内容ですが、後半の１時間を「外部サイトの情報を取得」のサンプルプログラムの説明とカスタマイズしてみる時間としました。

「発展編」は、２時間すべてをサンプルプログラムを元に自分自身でbotをカスタマイズする時間にしました。
講師は受講生の方々から、質問を受けたりする事に翻弄します。
また、「発展編」では自由に興味のある事をしてもらったため、「応用編」で学んだ「外部サイトの情報を取得してみます。」で学んだ事を引き続きやってもらってもよしとしました。

# サンプルコードの作成


Pythonはコードの構文が表情に読みやすく作られているため初学者でも理解しやすく、入門者にとっては良質のサンプルを動かして学んで頂く事が一番だとおもいました。

サンプルを作る際に注意した事は、下記です。（今回の講座では実践できてるところと出来てないところがあります）

-  動かさなくても全体を見渡せるようにする事
    -  読みやすく変数名など略語は避けるコードの方が良いです
-  Python らしい、シンプルで読みやすいコードの書き方を説明する前に、それ以外の書き方もサンプルコードに含める事
    -  今回は講座の時間の都合で対応する事ができませんでしたが、受講者より「こんな書き方も出来るのですが？」と質問があったので次回は対応できるようにしたいです。
-  オブジェクト指向は強力なツールですが、なるべくクラスを作らないで説明する事
    -  講座でクラスについて簡単に説明しましたが、Pythonの話ではなく設計の話になってしまいます。また、Pythonはクラスに頼らなくても強力な言語機能を持っているため大抵の事は対応できるようになっています。
-  デバッグ・テストをしやすいコードにする
    -  今回の講座では簡単なデバック方法とテスト方法しか書けませんでしたが、動かしながら学ぶためにテスト方法はもう少しボリュームがあった方が良かったかもしれません
-  サンプルで楽しめるコードを作る
    -  スクレイピングや　botなど後半で説明をしましたが、もしかしたら先に動かし方だけでも説明し、基礎編の退屈な構文をそのサンプルで試せるようにした方が良かったかもしれません

本講座のソースコード
[PyConTutorialSampleCode](https://github.com/BrainPad/PyConTutorialSampleCode)

# 準備編まとめ
まだまだ、実際の各講座で注意すべき点や・終わった後の反省など本記事では書きたい事が沢山ありますが、都合（Advent Calendarの掲載日の締切）から準備までの話とさせて頂きます。
（別のページで講座実施と事後について記載します。）

準備編では、淡々と書いて順調に進んだように書きましたが。実際はかなり時間的にも入門者用の説明方法等で苦労しました。


# 参考書籍

プログラマ以外の方がどのような用途で使うか調べる参考にしまいた。
[退屈なことはPythonにやらせよう](https://www.oreilly.co.jp/books/9784873117782/)

初学者に教えるための説明方法を参考にしました。
[わかるPython](https://www.python.jp/news/wakarupython.html)
ChromiumとEdgeでベンチマーク

先日マイクロソフトのウェブブラウザ「Edge」が、「Google Chrome」と同じオープンソースのレンダリングエンジン「Edge」に、「Google Chrome」と同じオープンソースのレンダリングエンジン「Chromium」を採用すると発表され話題となりましたが、実際にEdgeから変更になると、どのくらい処理が早くなるかを比較してみました。
#Speedometer2.0でテスト
Speedometer 2.0(https://browserbench.org/Speedometer2.0/ )のテスト結果です。
![001.png](https://qiita-image-store.s3.amazonaws.com/0/150944/bb3084e6-2a9e-221e-2882-d570208e8974.png)
![002.png](https://qiita-image-store.s3.amazonaws.com/0/150944/e096f484-b72f-edce-6969-64ac3033bece.png)
上がChromium、下がEdgeになります。
Speedometer2.0では数値が大きい方がより性能が良いそうなので、Chromiumに軍配が上がりました。

#basemarkでテスト
basemark WEB3.0(https://web.basemark.com/ )のテスト結果です。
![004.png](https://qiita-image-store.s3.amazonaws.com/0/150944/4d7d9706-c007-757f-7ede-273d00e5037d.png)
![003.png](https://qiita-image-store.s3.amazonaws.com/0/150944/25f18d5a-66d1-7850-252f-316732c91eb3.png)
上がChromium、下がEdgeになります。
basemarkも数値が大きい方がより性能が良いそうなので、Chromiumに軍配が上がりました。

#ChromiumをWindowsFormsで使用してみる
C#でChromiumをアプリケーションへ組み込むためのフレームワークにCefSharpがあります。今回こちらを使用し、WindowsFormsへ組み込んでいきたいと思います。

##はじめに
VisualStudioで適当なWindowsFormsのプロジェクトを作成し
【ツール】→【NuGetパッケージマネージャー】→【ソリューションのNuGetパッケージの管理 】を選択します。

|![005.png](https://qiita-image-store.s3.amazonaws.com/0/150944/48a960cd-02a3-277c-4349-5155eb0a28a1.png)|
|:-:|

NuGetのパッケージ管理が開きますので、CefSharp.WinFormsを選択し、イントールを行います。


```C#:MainForm.cs
using System.Windows.Forms;
using CefSharp.WinForms;
using CefSharp;
using System.IO;

namespace CefSharpTest
{
	public partial class MainForm : Form
	{
		ChromiumWebBrowser browser;

		public MainForm()
		{
			InitializeComponent();
			CefSharp();
		}

		public void CefSharp()
		{
			var settings = new CefSettings
			{
				IgnoreCertificateErrors = true,
				CachePath = Path.Combine(Application.StartupPath, "Cache"),
				LogSeverity = LogSeverity.Info,
				LogFile = Path.Combine(Application.StartupPath, "log.txt")
			};
			Cef.Initialize(settings);
			CefSharpSettings.LegacyJavascriptBindingEnabled = true;

			//初回起動時のURLを指定
			browser = new ChromiumWebBrowser("https://web.basemark.com/")
			{
				Dock = DockStyle.None
			};

			Controls.Add(browser);
			browser.Dock = DockStyle.Fill;
		}
	}
}

```

最後にプラットフォームをx86またはx64に変更すれば、指定したURLをChromiumで閲覧することができます。
podのlogが確認したい

#はじめに
この記事は[ユニークビジョン株式会社 Advent Calendar 2018](https://qiita.com/advent-calendar/2018/uniquevision)の15日目の記事です。
最近始まった開発でk8sを利用することとなり、その際にrailsのログを見る方法がわかららず苦労していました。というかそもそもpodって何だろうっというレベルだったので、簡単にpodの説明をしたのちに掲題の内容に移りたいと思います。

#podとは
公式(https://kubernetes.io/docs/concepts/workloads/pods/pod/) によると、「podは共有ストレージ/ネットワークと1つ以上のグループ、およびコンテナを実行する方法の仕様です。(google翻訳)」とあります。docker(鯨)の群がpodというそうで、コンテナ群とでもいうのか、何か一つの機能を持つ集合というの認識です。
では、実際に起動しているminikubeをみていきたいと思います。


#logを確認する
まず、起動しているpodの一覧を取得します。一覧を取得するには「kubectl get pods」コマンドを利用します。

```iTerm
$ kubectl get pods
NAME                       READY   STATUS    RESTARTS   AGE
postgres-d4447dbd5   1/1     Running   0          2h
rails-7bf5585b55     1/1     Running   0          4h
```
一覧が取得できました。現在はpostgresとrailsのpodが起動しています。ここからrailsのpod内のログを確認してみます。特定のpodのログを確認するためには、「kubectl logs pod名」コマンドを利用します。
pod名は先ほど取得した名前で今回はrailsの方を利用します。

```iTerm
$ kubectl logs rails-7bf5585b55
 // ・・・（中略
  Rendering admin/companies/new.html.erb within layouts/application
  Rendered admin/common/_errors.html.erb (1.3ms)
  Rendered admin/companies/_form.html.erb (10.9ms)
  Rendered admin/companies/new.html.erb within layouts/application (12.7ms)
Completed 200 OK in 117ms (Views: 97.9ms | ActiveRecord: 9.3ms)

```
取れました！これで、railsログを追ったり、printデバッグで呼ばれた順番を確認したりと開発が捗ります。

#まとめ
k8sのpodのログを確認する方法をまとめました。さらなるpodの詳細は「kubectl get pod pod名 -o json」でpodのコンテナ名を調べて、「kubectl log pod名 コンテナ名」でコンテナごとのログを出力したりとまだまだできることが多そうです。

次回は[@toba_さん](https://qiita.com/toba_)です！
Springのlogbackにハマった件

講習中、logbackされなくて一日費やしたので、備忘録として。
改善してから、再度エラーの状況を再現しようとしたけれど、再現できなかったので、文字ばっかりになるのは許してほしいです。

##当時の状況
![sts-console.PNG](https://qiita-image-store.s3.amazonaws.com/0/318745/755fe1d2-e937-7b4a-58b3-f3bb12d5baac.png)
普通はSpring Bootさせたらこんな感じのログが出ます。

しかし私は1か月ほど前から、こんな感じ。
![sts-console2.png](https://qiita-image-store.s3.amazonaws.com/0/318745/e01a73cc-7077-a7d7-6d77-2264e1686cb4.png)
実際はこの「SPRING」のAAも崩れてるんだけど、まったくログが出ない状況でした。
ただまぁ、SpringBoot自体は起動してたし、localhostとかも普通に使えていたので、気にはしていなかったです。

ただこれからlogbackを利用してlogを出そうとしたときに、どんなに工夫してもコンソールにlogは出ないし、代わりにFileを作成しても、作成されるだけで何も出力されないという状況でした。

、、、ということで、同期と講師陣にお願いして解決を図りました。

##解決策
私のSTSではログが出なかったので、同期と共有して、同期のSTSで実行してもらうと、
logback-classicとslf4jがBindingしてるよ、とのこと。
私のSTSではエラーのログもはかれないから、何も分かんなかったけど、ありがたい。

slf4j ⇒　DBUnit実施するために入れてた。
logback ⇒　今回ログを出すために入れた。

試しにjarのslf4j-api,nop,simpleの3つを抜くときれいに動作しました。
DBUnitのテスト自体も、slf4jなくても動いたので、とりあえず解決。

logback-classicにslf4jが自動的にくっついてるって認識しました。
普通のログも出るようになったので、たぶんslf4jを入れると、何かしら起きて、ログが出力されなくなるんでしょうねぇ。

とりあえず備忘録として残します。
またキャプチャ取れたら追記しときます。
Pythonで競プロに挑む日誌 vol.25 ~Pythonの罠：リスト編~

どうも. こないだ初めて ABC の C 問題を時間内に解けて狂喜乱舞していたのですが, フタを開けてみたらレート下がってました...けどいいんです. 私にとっては大きな一歩でした. めげずに今週の AGC をがんばります.

# 現在の目標
* 2018年内に茶色になる**←イマココ. 現レート 364**
 * [ABC](
https://kenkoooo.com/atcoder/?user=&rivals=&kind=category) の A, B 問題を全部解く
* 2018年度内に緑色を取得する
 * [ABC](
https://kenkoooo.com/atcoder/?user=&rivals=&kind=category) の C 問題を全部解く
* (水色になったら, [APG4b](https://beta.atcoder.jp/contests/apg4b) で C++ にも手を出す)

# 今日のおはなし
## 結論
Python のリストをラクしてつくると痛い目に遭う.

### 解いた問題
[B - Minesweeper](https://beta.atcoder.jp/contests/abc075/tasks/abc075_b)

### 考え方はあってると思うんだけど通らない
1. 入力から四角形の配列を作り, 周囲を "." でパディングする. これを lst と呼ぶ.
2. ↑と同じサイズで, 要素がすべて 0 の配列（リスト）を用意する. これを lst2 と呼ぶ.
3. lst のパディングされてない要素を中心とした 3x3 の窓で探索する. 中心が "." の場合, 周囲 8 マスのうち何個 "#" が含まれるか数える. 数えた "#" の個数を lst2 の同じ場所の要素に割り当てる. 中心が "#" の場合は, lst2 の同じ場所の要素を "#" とする.
4. lst のパディングされてない部分に対して, 3 を繰り返す.
 

```WA.py
# coding: utf-8
H, W = map(int, input().split())

# 一回り大きい並びになるように、"." をパディングする
lst = ["."*(W+2)] + ["." + input() + "." for _ in range(H)] + ["."*(W+2)]
# print(lst)

# lst と同じ形で、要素が全部 0 のリスト
lst2 = [[0]*(W+2)] * (H+2)  # ←この作り方, 要注意

# パディングの内側を3x3の窓で、「. の周囲に # があるか」探索する
for i in range(1, H+1):
    for j in range(1, W+1):
        cnt = 0
        if lst[i][j] == ".":
            cnt += lst[i-1][j-1:j+2].count("#")
            cnt += lst[i][j-1:j+2].count("#")
            cnt += lst[i+1][j-1:j+2].count("#")
            lst2[i][j] = str(cnt)
        else:
            lst2[i][j] = "#"

for i in range(1, H+1):
    print("".join(lst2[i][1:W+1]))
```
考え方自体は割とすぐ浮かんだのですが, そこからが長かった...2日くらいなんで通らないかわからず悩みました.

### lst2 が原因だった

```AC.py
# coding: utf-8
H, W = map(int, input().split())

# 一回り大きい並びになるように、"." をパディングする
lst = ["."*(W+2)] + ["." + input() + "." for _ in range(H)] + ["."*(W+2)]
# print(lst)

# lst と同じ形で、要素が全部 0 のリスト(★)
lst2 = []
for _ in range(H+2):
    lst2.append([0 for _ in range(W+2)])

# パディングの内側を3x3の窓で、「. の周囲に # があるか」探索する
for i in range(1, H+1):
    for j in range(1, W+1):
        cnt = 0
        if lst[i][j] == ".":
            cnt += lst[i-1][j-1:j+2].count("#")
            cnt += lst[i][j-1:j+2].count("#")
            cnt += lst[i+1][j-1:j+2].count("#")
            lst2[i][j] = str(cnt)
        else:
            lst2[i][j] = "#"

for i in range(1, H+1):
    print("".join(lst2[i][1:W+1]))
```
http://delta114514.hatenablog.jp/entry/2018/01/02/233002 に書いてある通り, 単純な掛け算でリストを作成すると, どこか一つの要素に変更を加えると, ほかの要素もすべて同じ変更が反映されてしまうとのことでした. 

この方法で作ったリストは, 各要素が各々独立したデータではないんですね. リストの各要素が一か所のデータを参照しているだけなので, リストの要素をいじると参照先が変わってしまう, ということのようです. 有名な話らしいし, Python あるあるのようですが, 知れてよかったです.

# むすび
ハマって初めて知る罠が, そこにはある
Laravelのローカルサーバーに他のデバイスからアクセスする方法

#実行方法
まずは、**プライベートIPアドレス**の検索

```
$ ifconfig
```

```
$ php artisan serve --host 192.168.*.*
```

--hostの後ろに先程、検索した**プライベートIPアドレス**を入れる。

```
http://192.168.*.*:8000
```

これで検索すればアクセスできる。
Google App Makerとスプレッドシートを駆使してシステムを構築する(スプレッドシートのデータを表示する)

#やること
Google App Makerがイケてるツールなのかを知るために、簡易なシステムを作ってみる。
(スプレッドシートをDB代わりにする)

#前提
・もともとはAppMakerでスプレッドシートをDB代わりに使えていたようだけと、どこかのアップデートのタイミングで機能が廃止された
・Google App Makerにはデータを格納するものとして、Cloud SQLがきっと推奨されている
・だけど、Cloud SQLは別途費用かかったり、学習コストがかかったり、利用までに少し壁があるので、SpreadSheet APIを駆使して何とかDB代わりにできないか頑張る

#目次
- スプレッドシートのデータを表示する　←今ココ
- [データを変更する](https://qiita.com/kanametunes/items/bb2a449c9206f1a8c812)
- データを新規登録する
- 検索する

#やってみる
- スプレッドシートを用意

![image.png](https://qiita-image-store.s3.amazonaws.com/0/87715/440dffc0-0a30-d47f-9cd2-f7a3ab4c6dc6.png)


次AppMakerなんですが、ログインとかは割愛。
- 下のDATAの右側の「＋」をクリック

![image.png](https://qiita-image-store.s3.amazonaws.com/0/87715/fc0fa095-d29b-08fd-b22a-1c3e34763441.png)

- Calculatedを選択しNEXT

![image.png](https://qiita-image-store.s3.amazonaws.com/0/87715/43705303-325e-e2ae-e366-9ebee0f2ce7b.png)

- 適当に名前つけてください。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/87715/b8e92186-0de4-8e02-c29f-aa29365b57ea.png)

- 「ADD FIELD」からFieldを追加。(データが記載されたスプレッドシートと揃える)
![image.png](https://qiita-image-store.s3.amazonaws.com/0/87715/5bdff88c-3d40-7d50-b2b0-c559f88607ed.png)

- データを取得するコードを下記へ書いていきます。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/87715/4d381844-a062-659e-4908-cfd069d57d21.png)

```javascript:test.js
//スプレッドシートのデータを取得する。
var sheets = SpreadsheetApp.openById('ここに基になるスプレッドシートのIDを記載');
var sheet = sheets.getSheetByName('そのスプレッドシートのシート名を記載');
var records = [];
var values = sheet.getDataRange().getValues();
//タイトル行いらないので削除
values.splice(0,1);

//AppMakerのテーブル用に整形
values.forEach(function(value){
  var record = app.models.GSuiteGroup.newRecord();
　//AppMakerで作ったFIELDと揃える。
  record.id = value[0];
  record.name = value[1];
  record.mail = value[2];
  records.push(record);  
});
//最後に結果を返す
return records;  
```


#結果
こんな感じで表示される
![image.png](https://qiita-image-store.s3.amazonaws.com/0/87715/a74e9a9a-3bfb-331a-39f6-808740f002d9.png)


次回は「データを変更する」をやろうかと思います。

- スプレッドシートのデータを表示する　←今ココ
- [データを変更する](https://qiita.com/kanametunes/items/bb2a449c9206f1a8c812)
- データを新規登録する
- 検索する
手抜きのjavascript -var編-

[富士通ソーシアルサイエンスラボラトリ Advent Calendar](https://qiita.com/advent-calendar/2018/ssl) 13日目！

#はじめに
javascriptで、どのような変数宣言でもついつい「var」を使いますよね。
使いますよね？
そのようなアナタのために、なるべくvarを利用してみる方法をご紹介・・・
しているようで、varのみ利用はめんどくさいという記事。

#結論
まぁ、普通に「let」や「const」を使い分けた方がいいっす。
letやconstの詳しい説明は、[ES6の新機能: 「let」「const」宣言を調べてみた](https://qiita.com/niisan-tokyo/items/bacb5ed98ea10831eeba)とか、
[letとvarの違い](https://qiita.com/y-temp4/items/289686fbdde896d22b5e)とかみてみてください。
（こうやって手を抜いていくスタイル）

#手を抜きたい
javascriptでは、変数宣言には長らくvarが使われてきました。
が、ES6にてletやconstが追加され、変数を安全に利用することが可能となりました。
（ES6ってなに？という方は、[ES2015(ES6) 入門](https://qiita.com/soarflat/items/b251caf9cb59b72beb9b)とかみるとよいかも）

しかし、長年varを打ってきた手は、なかなかletとは打ってくれません。
癖を治すのはめんどくさい。
なので、プログラムの書き方の工夫による解決方法を無駄に探ってみました。

#その１：とにかく即時関数をつかう
varというのは、関数スコープです。
関数スコープとは、その名の通り関数（function）内で有効となります。
例えば、ありがちなのが

```javascript
function sample(){
  var rtn = "";
  var lenA = 1;
  var lenB = 2;
  for (var i = 0; i <= lenA; i++){
    rtn += "[" + i + "]";
    for (var i = 0; i <= lenB; i++){
      rtn += (i===0 ? i : ","+i);
    }
  }
  return rtn;
}
```
というのを書いてしまう場合。
期待する結果は「[0]0,1,2[1]0,1,2」なのですが、iをダブって使っているため
「[0]0,1,2」という結果が返ってきてしまいます。
関数内のコードが長く、複数のループを利用している場合にやりがちなミスです。

このような場合、即時関数を利用してこう書いてしまいましょう。

```javascript
function sample(){
  var rtn = "";
  var lenA = 1;
  var lenB = 2;
  (function(){
    for (var i = 0; i <= lenA; i++){
      rtn += "[" + i + "]";
      (function(){
        for (var i = 0; i <= lenB; i++){
          rtn += (i===0 ? i : ","+i);
        }
      })();
    }
  })();
  return rtn;
}
```

即時関数って何？ってかたは、[JavaScript基礎 即時関数](https://qiita.com/_neekoko/items/b89bac48fa526f0b14a5)とかみてみてください。
varは関数スコープなので、ループ部分を即時変数化してしまえば問題ないのです！
みなさん、varのみで変数指定したい場合は、forやifなどのブロックを見たら
とにかく即時関数化していきましょう！
（注：みなさんお気づきと思いますが、頭の悪い発想です。マネしてはいけません）

#その２：prototypeを利用してみる
いっそ、prototype宣言を利用してみるというのも手です。

```javascript
function sample(){
  this.rtn = "";
  this.lenA = 1;
  this.lenB = 2;
}

sample.prototype.itemA = function() {
    for (var i = 0; i <= this.lenA; i++){
        this.rtn += "[" + i + "]";
        this.itemB();
    }
};

sample.prototype.itemB = function() {
    for (var i = 0; i <= this.lenB; i++){
        this.rtn += (i===0 ? i : ","+i);
    }
};

var s = new sample();
s.itemA();  //これで、s.rtnは「[0]0,1,2[1]0,1,2」となる
```
prototypeの場合はnewした単位で変数が保持されるので、
似たような処理が複数ある場合に有効です。
さらにprototype宣言で記載しようとすると関数内の処理は単機能となりがちなので、
varによる変数設定ミスが起きにくくなります。
（注：みなさんお気づきと思いますが以下略）

なお、ちゃんとしたprototype宣言の詳細は、
[JavaScriptのプロトタイプからオブジェクト指向を学ぶ](https://qiita.com/takeharu/items/809114f943208aaf55b3)とかをご参照ください。

#結局
varの利用であれこれ考えるよりは、用途に応じてletやconstを利用したほうが良いです。
当たり前ですが。
ついついvarと打ってしまう方は、ちょっと注意してみましょう。

しかし、javascriptはいろいろな書き方がありますね。



ちなみに今回マークダウン初めてだったので、[Qiita Markdown 書き方 まとめ](https://qiita.com/shizuma/items/8616bbe3ebe8ab0b6ca1)を参照しました。
ありがとうございます。（あまり活かせていませんけど）
MacでBoostをインストールして使えるようにする方法

コマンドラインにてboostをインストール

```
brew install boost
```

.bashrcにてg++のオプションに`-I/usr/local/include`を追記してboostへのパスを通す

```
alias gpp='g++ -Wall -O3 -std=c++17 -I/usr/local/include'
```

コマンドラインにて以下を実行してエイリアスを更新

```
. ~/.bashrc
```