OmniAICreator/Qiita-1.07M huggingface dataset:
Item 59: Know and use the libraries

# 59.ライブラリを知り、利用する
* ランダムな値を作るにおいて、下記の1番目のような実装では値の平均値がおかしくなる。ライブラリを使用することで正しくランダム値生成ができる。


```java
package tryAny.effectiveJava;

import java.util.Random;
import java.util.concurrent.ThreadLocalRandom;

import org.apache.commons.lang3.time.StopWatch;

public class RandomTest {
    public static void main(String[] args) {
        int n = 2 * (Integer.MAX_VALUE / 3);
        int low1 = 0;
        StopWatch sw1 = new StopWatch();
        sw1.start();
        for (int i = 0; i < 1000000; i++) {
            if (random(n) < n / 2) {
                low1++;
            }
        }
        sw1.stop();

        System.out.println(low1); // 500000位になると思いきやならない。666666位になる。
        System.out.println(sw1.getTime());

        int low2 = 0;
        StopWatch sw2 = new StopWatch();
        sw2.start();
        for (int i = 0; i < 1000000; i++) {
            if (tlr.nextInt(n) < n / 2) {
                low2++;
            }
        }
        sw2.stop();
        System.out.println(low2);// 500000位になる。
        System.out.println(sw2.getTime());// 速度はあまり変わらない
    }

    static Random rnd = new Random();

    static int random(int n) {
        return Math.abs(rnd.nextInt()) % n;
    }

    static ThreadLocalRandom tlr = ThreadLocalRandom.current();

}

```



* 自分で処理を書くのではなく、ライブラリを使用することで得られる利点は以下の5つ。

  * エキスパートが練りに練った実装を使える。

  * 時間を節約できる。

  * ライブラリ自体が進化していくので、恩恵にあずかれる。

  * ライブラリの機能がリリース事に増えるので、その恩恵にあずかれる。

  * 標準的なライブラリを使うことで、自身のコードが主流に則ったものとなり、読みやすく、つかいやすいものとなる。

* すべてのプログラマが、java.lang,java.util,java.ioとそれらのサブパッケージには親しくなっておくべき。
Item 58: Prefer for-each loops to traditional for loops

# 58.従来のforループより、for-eachのループを選択すべき

* 従来のfor文のほうが記述すべきことが多くて、ミスが発生する確率が上がる。
* 入れ子のイテレーションがあるときもfor-eachが使える。

```java
package tryAny.effectiveJava;

import java.util.Arrays;
import java.util.Collection;

public class NestedFor {
    enum Suit {
        CLUB, DIAMOND, HEART, SPADE
    };

    enum Rank {
        ACE, DEUCE, THREE, FOUR, FIVE, SIX, SEVEN, EIGHT, NINE, TEN, JACK, QUEEN, KING
    };

    public static void main(String[] args) {
        Collection<Suit> suits = Arrays.asList(Suit.values());
        Collection<Rank> ranks = Arrays.asList(Rank.values());

        for (Suit suit : suits) {
            for (Rank rank : ranks) {
                System.out.println("柄" + suit + "：数" + rank);
            }
        }
    }
}
```



* 一般的にfor-eachが使えない場面が3つある。

  * フィルタリングして特定の要素を削除する場合

  * 要素の値を変換する場合

  * 複数の要素集合を、並列で走査する場合

* Iterableをimplementsしているオブジェクトに対してfor-eachで要素を取り出すことができる。
Item 57: Minimize the scope of local variables

# 57.ローカル変数のスコープは最小にせよ
* ローカル変数のスコープを最小にする最も効果的なテクニックは、その変数を最初に用いる直前に宣言することである。
* ローカル変数は基本的に宣言時に初期化しておくべきである。
* ループ文においては、while文よりfor文を選択すべき。
  * なぜなら、for文は繰り返しに用いるその場限りの変数を定義できるのに対して、while文ではそれができないから。
  * for文のほうがコピペによるミスが起きにくい。（構文が割と定まっている）
* ローカル変数のスコープを最小にするためにメソッドを単位を小さくすべき。
Item 55: Return optionals judiciously

# 55.Optional を返す時は気を付けるべし
* 特定の条件下では値を返せないメソッドを考慮する際に、Java7以前では、exceptionをスローするか、nullを返すしかなかった。Java8からは、Optionalを返すという選択肢が生まれた。

```java
package tryAny.effectiveJava;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import java.util.NoSuchElementException;
import java.util.Objects;
import java.util.Optional;

public class OptionalTest {
    public static void main(String[] args) {
        List<String> l1 = Arrays.asList("paper", "strong", "java", "pepper");
        List<String> l2 = new ArrayList<>();

        System.out.println(max(l1).get());
        System.out.println(max(l2).orElse("no words"));
        try {
            max(l2).orElseThrow();
        } catch (NoSuchElementException e) {
            System.out.println(e.getMessage());
        }

        System.out.println(max(l1).filter(str -> str.length() == 6).map(str -> str.toUpperCase()).get());
    }

    public static <E extends Comparable<E>> Optional<E> max(Collection<E> c) {
        if (c.isEmpty()) {
            return Optional.empty();
        }

        E result = null;
        for (E ele : c) {
            if (result == null || ele.compareTo(result) > 0) {
                result = Objects.requireNonNull(ele);
            }
        }

        return Optional.of(result);
    }
}
```

* Optionalが戻り値であるメソッドからnullを返してはならない。これを行うと、Optionalを導入した意味がなくなる。
* nullを返したり、例外をスローする代わりに、Optionalを返すかを選択するにあたっては、検査例外をスローするか否かを決めるのと同じ考え（Item71）で選択する。
* コレクション、マップ、ストリーム、配列、Optionalといった何かを格納するものに対して、Optionalでラップすべきではない。例えば、Optional<List<T>>を返すよりは、空のList<T>を返すほうが良い。空のList<T>を返せるのであれば、そもそもOptionalを返す必要がないからである。
* メソッドの戻り値として、Optionalでラップした値を選択すべき時は、結果を返すことができない可能性があり、かつ、結果がnullである場合にメソッド呼び出し側で特別な考慮が必要な場合である。
* int,double,longのラッパークラスのOptionalを返してはならない。OptionalInt,OptionalDouble,OptionalLongが用意されているのでそちらを使う。
* コレクション、配列のキー、バリュー、要素としてOptionalを使ってはならない。
* インスタンスの必須ではないフィールド値として、Optionalを使用することはあり得る。（Item2で扱ったクラス参照）
Item 54: Return empty collections or arrays, not nulls

# 54.nullではなく、空のコレクション、配列を返すべし
* nullを返すとなると、呼び出し側でnullをチェックするためのコードが必要となり、煩わしい。空のコレクション、配列を返すべきである。

```java
//The right way to return a possibly empty collection
public List<Cheese> getCheeses() {
    return new ArrayList<>(cheesesInStock);
}
```

```java
//The right way to return a possibly empty array
public Cheese[] getCheeses() {
    return cheesesInStock.toArray(new Cheese[0]);
}
```

* 空のコレクション、配列を返すよりnullを返すほうが、メモリ割り当てがない分性能が良くなるという意見がある。これは以下2点で誤っている。
  * このレベルで性能が良くなるかは疑わしい。証明できている場合を除いたら、心配する必要はない。
  * メモリ割り当てをすることなく空のコレクション、配列を返すことは可能である。

```java
// Optimization - avoids allocating empty collections
public List<Cheese> getCheeses() {
    return cheesesInStock.isEmpty() ? Collections.emptyList()
        : new ArrayList<>(cheesesInStock);
}
```

```java
// Optimization - avoids allocating empty arrays
private static final Cheese[] EMPTY_CHEESE_ARRAY = new Cheese[0];
public Cheese[] getCheeses() {
    return cheesesInStock.toArray(EMPTY_CHEESE_ARRAY);
}
```
AndroidアプリをWiFi経由でデバッグ

USBデバッグ、とてもお手軽で良いのですが、USBデバイスをつなぐ必要がある場合、デバッグが困難になる。

Wifiを使ったデバッグが可能なので、試した。

## 前提

- 今回はWindowsで行う
- Android端末とデバッグ用PCが同一ネットワークに存在する必要がある
- Android端末を乗っ取ろうといった、悪意がある人はいないものとする

## 手順

SDKの場所を確認しておく。AndroidStudioならTools→SDK Managerから、SDKのパスを知ることができる。
今回は`%USERPROFILE%\AppData\Local\Android\Sdk`で統一する。（Android Studioを入れるとここに入るはず。）


1. USBケーブルでつなぐ
2. IPを得る

    端末上の情報から確認する。
    端末の操作が面倒な場合、これを流すと得られるかもしれない。(環境によってはうまくいかないかもしれない。)

        %USERPROFILE%\AppData\Local\Android\Sdk\platform-tools\adb.exe shell ip addr "|" grep inet "|" grep global  "|" cut -d "' '" -f 6 "|" cut -d "/" -f 1

3. `adb tcpip`でTCP接続を待ち受けるようにする。今回は5555番だが、5555番はあまりにも有名なので、もしネットワーク上に怪しい人がいそうで、少しでも隠したい場合はポート番号を変えるとかする。

        %USERPROFILE%\AppData\Local\Android\Sdk\platform-tools\adb.exe tcpip 5555
    なお、この時点でケーブルを抜いても良い。

4. `adb connect`で接続する。(2)で得たIPと(3)で指定したポートを使う。

        %USERPROFILE%\AppData\Local\Android\Sdk\platform-tools\adb.exe connect 192.168.xxx.xxx:5555

    `connected to 192.168.xxx.xxx:5555` と出ればOK。

後はUSBの時と同じように、いい感じに認識するはず。デバッガもちゃんと機能する。


デバッグ作業を終えたらTCP接続を受け付けない形に戻す。

```
 %USERPROFILE%\AppData\Local\Android\Sdk\platform-tools\adb.exe usb
```

## トラブルシューティング


```
unable to connect to 192.168.xxx.xxx:5555: cannot connect to 192.168.xxx.xxx:5555: 接続済みの呼び出し先が一定の時間を過ぎても正しく応答しなかったため、接続できませんでした。または接続済みのホストが応答しなかったため、確立された接続は失敗しました。 (10060)
```

- ネットワーク的に到達できていない。IPが正しいか、IPが同じネットワーク内に存在するか確認する。
- 私の端末の不具合？らしく、WiFiを一度オフにし、再度オンにした後、(3)のtcpipコマンドからやり直す。（WiFiを1度オフにしないとダメ。理由は不明。）


```
unable to connect to 192.168.xxx.xxx:5555: cannot connect to 192.168.xxx.xxx:5555: 対象のコンピューターによって拒否されたため、接続できませんでした。 (10061)
```

- tcpipコマンドを忘れている。一度、USB接続しなおして、コマンドを打つ。
- IPを間違えている。（ただし、こっちのエラーの場合は存在する。）


## おまけ: 便利ツール

Unityでアプリログを見たい場合はSDKについてくるmonitorを使うとよい。

```
%USERPROFILE%\AppData\Local\Android\Sdk\tools\monitor
```
Item 53: Use varargs judiciously

# 53.可変長引数は気を付けて使うべし
* 0個以上の引数を取る場合に、個数のチェック等が入って美しくない作りになるときがある。そういった場合は、取るべき引数を、以下のように2つに分解してやる。

```java
package tryAny.effectiveJava;

public class Varargs {
    public static void main(String[] args) {
        System.out.println(min1(99));
        System.out.println(min2(1, 2, 3));

    }

    // ugly
    static int min1(int... args) {
        if (args.length == 0)
            throw new IllegalArgumentException("Too few arguments");
        int min = args[0];
        for (int i = 1; i < args.length; i++)
            if (args[i] < min)
                min = args[i];
        return min;
    }

    // better
    static int min2(int firstArg, int... remainingArgs) {
        int min = firstArg;
        for (int arg : remainingArgs) {
            if (arg < min) {
                min = arg;
            }
        }
        return min;
    }
}
```

* 可変長引数を用いる場合には、配列のメモリ割り当てと初期化が必要となり、コストがかかる。もし、コストを減らす必要があり、引数の個数が3つ以下の場合が大多数であるとわかっている場合には、あらかじめ引数が0,1,2,3個の場合を作って対応するのがよい。

```java
public void foo() { }
public void foo(int a1) { }
public void foo(int a1, int a2) { }
public void foo(int a1, int a2, int a3) { }
public void foo(int a1, int a2, int a3, int... rest) { }
```
Unity TestRunner（PlayMode）のアセンブリ参照問題

あまり触れてる人はいないが、Unity2018における「Unity TestRunner」は、アセンブリの観点から3つの設定がある。

- デフォルト状態
- Test Assemblies を有効にした Assembly Definition を配置したフォルダ以下にテストスクリプトを置いた状態
- TestRunnerの右上の設定で、「Enable play tests for all assemblies」を設定した状態（Assembly Definion不要）

まず、デフォルト状態は、そもそも必要なテストライブラリが読まれないので使えない

![スクリーンショット 2018-09-06 21.06.32.png](https://qiita-image-store.s3.amazonaws.com/0/6047/05bab32c-ea02-e86d-5689-b7fd567e3e8d.png)

これ、何も知らないと、コンパイルエラーでNUnit参照がないとか言われるのなんでだー？
で小一時間悩むことに...

故に、実質 2つ目 or 3つ目 になるわけだが、2つ目は小規模なプロジェクトやライブラリ開発以外では辛くなることが多く、どうせ採用するのは 3つ目の案 になる。

ちなみに 2つ目 がなぜ辛いかと言うと、Assembly分割（ = DLL分割）と同じ制約を受けるからである。
すなわち、__Assembly-CSharp.dllに含まれる実装をテストコード側から参照できない。__
テストする実装は全て、独自のAssemblyに分割し、それをテストのAssemblyから参照させる必要があると言う、理想主義のソレ。

ただ、3つ目も問題点がないわけではなく、__テストコードがAssembly-CSahrp.dllに含まれてしまうという点が問題。__
なんらかのマクロ定義などで、リリースビルドでストリップさせる仕組みをちゃんと入れなくてはいけない。
まぁでも普通にデバッグコードをストリップしたりは出来るようにしてる筈なので、その流れで普通の人はできるよなぁ！？

![スクリーンショット 2018-09-06 21.11.57.png](https://qiita-image-store.s3.amazonaws.com/0/6047/e312e4d8-d8c6-1243-b773-93d16416f164.png)

ちなみに右上の設定ってここ。なんでこんな重要な設定メニューがここにあるんだ...

----------

ということで、プロジェクトを作ったら、TestRunnerのパネルから、設定を忘れずにしよう & ストリップする仕組みをいれたテストスケルトンを用意しておこう。

あと、TestRunnnerの詳しい話は変にセンセーショナルな記事を読むくらいなら、本家をあたった方がよいです。
https://docs.unity3d.com/2018.1/Documentation/Manual/testing-editortestsrunner.html
Item 51: Design method signatures carefully

# 51.メソッドのシグニチャは注意深く設計せよ
* メソッドの名前は注意深く決めるべき。理解しやすく、同パッケージ内の他の名前と矛盾しないようにする。また、広く一般的に合意を得ている名前を付ける。迷ったらガイダンスとして、JavaライブラリAPIを見てみる（良くないのもあるが、良いのがたくさんある）。
* 便利なメソッドを過度に提供すべきでない。あまりに多いメソッドがあると、学習、利用、ドキュメント作成、テスト、保守が大変になる。頻繁に使われる場合にのみ、記述の省略化ができるようなメソッドの提供を考慮すべき。迷ったら作らないほうが良い。
* 引数の数を多くとるべきでない。引数の数は4つ以下に抑えるべきである。利用者は多くの引数を覚えることができないので、リファレンスをみながら使用しなければならない。特に、同じ型で多くの引数がある場合は避けたい。なぜなら、引数の順番を間違えたとしても、コンパイルエラーとならず、意図したものと違う処理がなされる可能性があるから。引数の数を減らすテクニックは以下の3つ。
   * 1つのメソッドを複数のメソッドに分割する。（**Listのsublist、indexOf、lastIndexOfの例をあげていたがいまいちわからず**）
   * ヘルパークラスを作る。例えば、トランプの柄と数を引数に取るものがあるならば、柄と数をまとめたEntityを作成し、それを引数に取るようにする。
   * ビルダーパターンを使う。（Item2）
* 引数の型は具象クラスよりもインターフェースに優先すべき。具象クラスにした場合には、メソッドの使用者に特定の実装を強いることになり、時にはコストの高いコピーを強いるときがある。
* boolean 引数よりも、2値のenumとすべき。なぜなら、enumの方は後に拡張することが容易であるから（要素を2つから3つにする）。また、enumはその中にメソッドを持つこともできる。（Item34）
Reactで改行込みのデータを表示させたい時

コンテナにスタイルを当てればOK。
CSSだけで完結するのでReact以外でも使える。

```jsx
import React from 'react';
import ReactDOM from 'react-dom';

const data = "hoge\nfuga";
const styles = { whiteSpace: 'pre-line' }; // CSSで書く場合は { white-space: pre-line }

const App = ({ children }) => (
  <div style={styles}>{children}</div>
);

ReactDOM.render(<App>{data}</App>, document.getElementById('root'));
```

[デモ](https://codesandbox.io/s/54kj44qv6k)
Item 50: Make defensive copies when needed

# 50.必要に応じて防御的コピー（defensive copies）を作るべし
* JavaはCやC++のようなメモリに手を加えて起こる脆弱性（バッファオーバラン等）がない、という意味で安全な言語であるが、自分でクラスを実装するにあたっては、攻撃者が不変条件（invariant）を破ってくる、というつもりで実装をすべき。
* 以下のクラスは一見immutableに見える。

```java
// Broken "immutable" time period class
public final class Period {
    private final Date start;
    private final Date end;
 /**
     * @param  start the beginning of the period
     * @param  end the end of the period; must not precede start
     * @throws IllegalArgumentException if start is after end
     * @throws NullPointerException if start or end is null
     */
    public Period(Date start, Date end) {
        if (start.compareTo(end) > 0)
            throw new IllegalArgumentException(
                start + " after " + end);
        this.start = start;
        this.end   = end;
    }
    public Date start() {
        return start;
    }
    public Date end() {
        return end;
    }
 ...    // Remainder omitted
}
```
* しかし、Dateクラスはmutableなので、以下のように簡単に、「startはend以後にはならない」という条件を破れる。

```java
// Attack the internals of a Period instance
Date start = new Date();
Date end = new Date();
Period p = new Period(start, end);
end.setYear(78);  // Modifies internals of p!
```

* 日付のクラスに関しては、Dateはもはや時代遅れであり、Java8以降は Instant クラス等を使うべきである。
* mutable な引数を持つコンストラクタに defensive　copy を使用して、脆弱性をなくす。defensive copyを使って上のコードのコンストラクタを書き直すと以下のようになる。

```java
// Repaired constructor - makes defensive copies of parameters
public Period(Date start, Date end) {
    this.start = new Date(start.getTime());
    this.end   = new Date(end.getTime());
 if (this.start.compareTo(this.end) > 0)
      throw new IllegalArgumentException(
        this.start + " after " + this.end);
}
```
* defensive copy を採用した際の引数のバリデーションチェックは、引数で渡ってきたオリジナルのものではなく、コピー側に対して行う。これは、バリデーションチェックを行ってから、コピーを行うまでの間に、別スレッドから攻撃を受ける可能性（TOCTOUというらしい）を考慮してのことである。
* 引数で受けるオブジェクトがfinalでない、つまり、継承が可能であるクラスである場合は、defensive copy の作成に当たって、cloneを用いてはならない。なぜなら、受け取った引数が悪意のあるサブクラスである可能性があるため。
* アクセサを用いて、不変条件を壊すことも可能。

```java
// Second attack on the internals of a Period instance
Date start = new Date();
Date end = new Date();
Period p = new Period(start, end);
p.end().setYear(78);  // Modifies internals of p!
```
* 上の攻撃を防ぐため、アクセサにおいてもdefensive copyを作って対応する。

```java
// Repaired accessors - make defensive copies of internal fields
public Date start() {
    return new Date(start.getTime());
}
 public Date end() {
    return new Date(end.getTime());
}
```
* その他のdefensive copyの用途として、フィールドの配列変数をクライアントに返す際に用いる。配列は必ず mutable なので、このような対応を取る必要がある。（Item15でも言及）
* そもそもmutableなものをクライアントに返す設計にしないようにすべきである。
* defensive copyのコストがとても高く、かつ、クラスの利用者が不適切にmutableなフィールドを変更ないと確信できる場合は、defensive copyの代わりに、ドキュメントで注意を書く。
Item 49: Check parameters for validity

# 49.引数のバリデーションチェックをすべし
* 引数のバリデーションチェックをすることなく、誤った引数の値が先の処理にわたった場合、直接的な原因が分かりにくいエラーが出たり、最悪の場合、エラーにはならないが、誤った処理がなされることがある。
* 引数の制限はJavadocに書くべき。
* Nullチェックに際して、Java7からは Objects.requireNonNull でできるようになった。
* rangeのチェックに際しては、Java9からは Objects の checkFromIndexSize, checkFromToIndex, checkIndex が使えるようになった。（closed rangeには使えない）
* 外に公開しない、ヘルパーメソッドにおける引数チェックではアサーションを用いるべき。通常のバリデーションと異なり、影響がなく、javaコマンドに-aeをつけない限りコストもかからない。（**理由がピンとこない**）

```java
// Private helper function for a recursive sort
private static void sort(long a[], int offset, int length) {
    assert a != null;
    assert offset >= 0 && offset <= a.length;
    assert length >= 0 && length <= a.length - offset;
    ... // Do the computation
}
```

* メソッドで使う引数でなく、後々の利用のために溜めておく引数は特にバリデーションチェックすることが重要（コンストラクタとかの話）。そこで誤った値を落としておかないと、後の処理でエラーになったときにデバッグが難しいため。
* バリデーションチェックを明示的にすべきでないときもあって、それは、バリデーションチェックのコストが高く、非現実的で、かつ、チェックが処理の中に内包されているとき。例えば、Collections.sort(List)において、Listに内包される値は互いに比較可能なものでなければならないが、それはキャストするときにチェックされる。
* 内包的チェックがなされた時に、出力されたエラーが適切なものでない場合には、適切なエラーへの変換処理を行う。
* ここでの指南は、引数の恣意的な制限が良いというわけではなく、メソッドの設計をより汎用的なものに対応できるようにすることを目指すべきであり、制限は少ないほうがよい。
Arduinoでquaternionを使って３次元角度を計算する

# arduinoでquaternionを計算する。
[quaternionのライブラリのgithub](https://github.com/takashiAg/Quaternion_for_arduino)を作ったので、arduino IDEで使ってください。
quaternionの勉強不足でエラーハンドルが足りないと思います。githubのissueに投げてもらえると、頑張ります。　

# コード
```
#include <Quaternion.h>

void setup() {
  Serial.begin(115200);

  //初期化したらx,y,z,wは全て0後からx,y,z,wを代入しても良い
  Quaternion a;
  a.x=1.0f;
  a.y=0.0f;
  a.z=1.0f;
  a.w=1.0f;
  

  //quaternionの初期化ではx,y,z,wの順番で入れても良い
  float x = 1.0f;
  float y = 0.0f;
  float z = 1.0f;
  float w = 0.0f;
  Quaternion b(x, y, z, w);

  //inverseを求める
  Quaternion inv = a.inverse();

  //掛け算を求める。
  Quaternion product = a.multiple(b);

  //大きさを求める
  float norm = a.norm();

  //角度差を求める
  Quaternion diff = a.Angular_difference(b);

  Serial.print("a[x,y,z,w] = [");
  Serial.print(a.toString());
  Serial.println("]");
  
  Serial.print("b[x,y,z,w] = [");
  Serial.print(b.toString());
  Serial.println("]");
  
  Serial.print("inv[x,y,z,w] = [");
  Serial.print(inv.toString());
  Serial.println("]");
  
  Serial.print("product[x,y,z,w] = [");
  Serial.print(product.toString());
  Serial.println("]");
  
  Serial.print("norm = ");
  Serial.print(norm);
  Serial.println("");
  
  Serial.print("diff[x,y,z,w] = [");
  Serial.print(diff.toString());
  Serial.println("]");

  delay(1000);

}

void loop() {
}

```


# 参考資料
1. [quaternionの角度差について](https://qiita.com/chiepomme/items/a91de616d746b6653a4a)
2. [quaternion計算ノート](http://www.mss.co.jp/technology/report/pdf/18-07.pdf)

を参考にしました
PlayModeのTestからのScriptableObject参照

結論から言うと、ScriptableObject.Instantiate({生成済みのSOへの参照}) するしかない感じ。

そしてそのための参照は、ResourcesかABで取得しなくてはいけない...
Resources汚染したくない。でもこのためだけにABは...という気もしているが、テストから参照したい場合にどうするのが最適なのか。。

メモ： ScriptableObjectの参照方法あれこれ
https://indie-du.com/entry/2017/04/29/134827
【JavaScript】Array.prototype.filter()で条件に一致した配列の要素を削除する方法

厳密に言うと、条件に一致しない配列の要素を取得しない処理になる。

例えば配列から偶数を削除する処理を書くとき。
奇数を取得したいのなら条件を`val % 2 == 1`と書くべきだが、今回は偶数を取得したくないので不等価演算子`!`を使って`val % 2 != 0`と書くことでこの処理が偶数の値を取得したくないという意図を読み取ることができる。

```delete_even.js
const array = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
const odd = array.filter(val => val % 2 != 0);

console.log(odd); //[1, 3, 5, 7, 9]
```

条件が`val % 2 == 1`も`val % 2 != 0`も結果は一緒だけど処理の目的が分かりやすいのは後者だと思う。
【Rails】バルクインサート・バルクアップデートがvalidationにひっかかった時の対処法


##バルクインサートとは
`INSERT`するとき、一個一個保存していると、それに応じてsqlも発行されてしまいます。

```rb
User.each do |user|
  user.name = "hoge"
  user.save
end
```


そこで、一括で`INSERT `してDBに対する負担を減らそうとするときに使うのがバルクインサート。

```rb
users = []
User.each do |user|
  user.name = "hoge"
  users << user
end
User.import users
```

これでクエリを一個で済ますことができます。

##バルクアップデート

以下のように、更新させる値を指定してアップデートすることも可能.

```rb
users = []
User.each do |user|
  user.name = "hoge"
  users << user
end
User.import users, on_duplicate_key_update: [:name, :age]
```


便利なものですが、　今回,validationに引っかかり保存できなくてハマったので共有します。
##バリデーションで引っかかっている

単純にUserモデルと、それに属するPostモデルがあるとする.

```rb

#  name   :string
#  age    :integer
User < < ActiveRecord::Base
  has_many :posts
end
```

```rb
#  title   :string
#  content :text
User < < ActiveRecord::Base
  belongs_to :user
end
```

今回は**Userと、それに紐づくPostの値を更新**するために以下のように実装するわけだが、ここに落とし穴がある。


```rb
users = []
posts = []
User.each do |user|
  user.name = "taro"
  user.age  = 20
  users << user
  post = user.posts.build(title: "テスト", content: "テストテキスト")
  posts << post
end
User.import! users, on_duplicate_key_update: [:name, :age]
Post.import posts
```
**実行**

```rb

Parent.import! users, on_duplicate_key_update: [:name, :age]
ActiveRecord::RecordInvalid: バリデーションに失敗しました。 Postsの値が不正です。
```


userが持っていたpostモデルも同時に作っていたので、そのpostモデルのバリデーションに引っかかってしまった。

とりあえず、postが保存されればuserも保存されることを確認する。

```rb
user = users.first
post = user.posts.first
post.save
true
user.save
true
```

やはり、子モデル(post)が正常に保存されていない状態ではuserは保存できない。
今回のミスとして、一つのモデルに対して、二つのモデルを二重に保存させようとしていたことがわかる。
つまり、どちらか一方を正常に保存させてからでないと、どちらか一方のバリデーションに引っかかり保存できないということ。

なのでuserを保存させてからpostのみバルクインサートさせるという仕様に変えた。


```rb

posts = []
User.each do |user|
  user.name = "taro"
  user.age  = 20
  user.save
  post = user.posts.build(title: "テスト", content: "テストテキスト")
  posts << post
end
Post.import posts
```

##validateオプションを使う
特にvalidatenを外すことに抵抗がなければ、以下のように`validate: false` を使うことでimportに成功させることもできる。

```rb
User.import users, on_duplicate_key_update: [:name, :age], validate: false
```

最初からこれを使えばいいわけだが, これでは子モデル(post)にユニーク制限があった場合でも全て保存されてしまうので注意したいところ。
【MATLAB】通信の勉強をする前の練習問題【問題編⑤グラフの出力】

#【第5章】BERグラフを出力する
信号検出性能を見るためにはBERを縦軸に、SNR[dB]を横軸にとったグラフを出力することが多いということをいつか述べました。
次の諸元でシミュレーションを行った時のBERグラフを出力しましょう。
・変調方式：QPSK
・通信路：AWGN
・送信bit数：$10^6$bit
・送受信アンテナ数：2本
・SNR：0[dB]～12[dB]
そろそろMATLABについて調べるのも慣れてきたころかと思いますので、グラフ出力の方法などは調べながらノーヒントでやってみましょう。
また、<font color = "Deeppink">今回だけはfor文を使います。</font>

#解答
```matlab
% おまじない
clear all

N = 10^6;
SNRdB = 0:12;
BER = zeros(1,length(SNRdB));

for count = 1:length(SNRdB)

    % 雑音の生成
    SNR = 10^(SNRdB(count)/10);
    No = 1/SNR;
    noise_comp = sqrt(No/2) * randn(2,N/2) + 1j*sqrt(No/2) * randn(2,N/2);

    % 送信bit生成　～　QPSK変調
    TX_bit = randi([0,1],2,N);
    TX_BPSK = zeros(size(TX_bit));
    TX_BPSK(TX_bit == 0) = -1;
    TX_BPSK(TX_bit == 1) = 1;
    TX_QPSK = (TX_BPSK(:,1:2:end) + 1j*TX_BPSK(:,2:2:end))/sqrt(2);

    %受信
    RX_QPSK = TX_QPSK + noise_comp;

    % QPSK復調
    RX_BPSK1 = zeros(2,N/2);
    RX_BPSK1(real(RX_QPSK) > 0) = 1;
    RX_BPSK1(real(RX_QPSK) < 0) = -1;
    
    RX_BPSK2 = zeros(2,N/2);
    RX_BPSK2(imag(RX_QPSK) > 0) = 1;
    RX_BPSK2(imag(RX_QPSK) < 0) = -1;
    
    RX_BPSK = zeros(size(TX_bit));
    RX_BPSK(:,1:2:end) = RX_BPSK1;
    RX_BPSK(:,2:2:end) = RX_BPSK2;
    
    % BPSK復調
    RX_bit = zeros(size(TX_bit));
    RX_bit(RX_BPSK == -1) = 0;
    RX_bit(RX_BPSK == 1) = 1;

    %BERの計算
    BER(count) = sum(abs(TX_bit(:) - RX_bit(:)))/(2*N);
end

figure
semilogy(SNRdB,BER);
grid on
```
モテる”ITエンジニア”

この記事は [リンク情報システム](https://www.lis.co.jp/) が主催するイベント「[Tech Connect! Autumn](https://qiita.com/dgkz/items/4c3a449f3168d6c787cf)」のリレー記事です。
「[Tech Connect! Autumn](https://qiita.com/dgkz/items/4c3a449f3168d6c787cf)」は engineer.hanzomon のグループメンバによってリレーされます。
(リンク情報システムのFacebookは[こちらから](https://ja-jp.facebook.com/lis.co.jp/))

#はじめまして！
8日目担当の@huraです。

タイトルを見て、
「あれ？今回はいつもと雰囲気違うなぁ」
「もっと技術的な事を知りたいのに･･･」なんて思った方はごめんなさい。

ワタシハギジュツシャデハアリマセン。

IT企業の人事担当としてこの記事を書かせていただきました。
技術的な記事の中の、“箸休め”的感覚で読んでもらえるとうれしいです。

ITエンジニアの市場価値ってどのくらいでしょうか？色々な指標はあるとは思いますが、
人事担当ならではの目線で探っていきたいと思います！


#「有効求人倍率」って聞いた事あります？
![はてな猫.jpg](https://qiita-image-store.s3.amazonaws.com/0/284556/0f4fbc3f-8eb4-68f3-e74c-2510da9a7160.jpeg)
転職を経験した人なら、ご存知かもしれませんね。
知らない人のためにちょっと解説･･･

有効求人倍率とは、
厚生労働省が毎月発表している“求職者に対する求人数の割合”のことです。
つまりは、（ハローワークで募集中の求人数）÷（ハローワーク登録の求職者数）で
出てくる数値のことなんです。

例えば･･･
100件の求人に対して、求職者200人だと→　0.5倍（1人に0.5件の仕事がある）
100件の求人に対して、求職者50人だと→　2倍（1人に2件の仕事がある）

っていう考え方で、人事やHR企業の担当者が市況感を把握する為の数字の一つです。


#現在はどのくらいなの？
![上昇.jpg](https://qiita-image-store.s3.amazonaws.com/0/284556/cbdce7fc-83cc-b31c-821e-d9c3210abffe.jpeg)
2018年7月の数値は、なんと1.63倍！東京都は2倍を超えています。

･･･で？･･･それが何？なんていう声が聞こえてきそうですが。
そうなんです。初めて聞く人はそうなりますよ。
普段から気にしていないと、この数値が良いのか悪いのか分からないんです。
そこで、分かりやすい指標を･･･

・2008年リーマンショック。その翌年2009年の有効求人倍率は0.47倍。
・有効求人倍率が1.6倍を超えたのは1974年以来44年ぶり。

どうです？ちょっとイメージが沸きませんか？
この数値は、企業側（採用担当者）からは脅威ですね。求職者側にはうれしい限りですけどね。

#ここからが本題です。
全体の市況感は分かったところで、IT業界で働くSEやプログラマーといったITエンジニアを見てみましょう！

おや？
あれれ？

どうやら、厚生労働省のデータでは、職種毎の数値は出してないっぽいデス。

そこで、多くのHR企業は、「転職求人倍率」なる有効求人倍率と似て非なる数値を発表していますので、
そちらを参考とします。（多少強引ですが、この際やむなしです。）

考え方は基本的には同じで、（各社にオーダーのある求人数）÷（各社に登録している求職者数）ということになります。

ではいよいよ。
いったいどのくらいなのかな～？ちょっと高めなんだろうな～。
って軽い気持ちで覗いてみると･･･

A社　6.88倍
B社　5.60倍
･･･以下省略

なんと、（各社バラつきがあるが･･･）だいたい5倍～7倍！

Oh･･･予想の斜め上をいってました。なんとも恐ろしい数字を見た気がします。

#ITエンジニアは”モテモテ”
![モテモテ.jpg](https://qiita-image-store.s3.amazonaws.com/0/284556/2082d825-12d3-92cd-556f-698257ee4be8.jpeg)

ITエンジニアが仕事を探す際には、5～7件の求人から選ぶことができるようです。
逆に考えると、5～7社のIT企業が、1人のITエンジニアを取り合っている。ってことになりますね。

また、一言でITエンジニアといっても、経験値やレベルは人それぞれのはず。
高い技術を持ったITエンジニアと出会うには、5～7社どころじゃないでしょう。
正確な数字は分かりませんが、10社以上のライバルがいると言っても大袈裟ではなさそうです。


もう、アレですね。
････
･･･
･･
伝説のポ○モンと出会うより難しいんじゃないですか？

という事でまとめると、求人倍率から見るITエンジニアの価値は！
今ならその技術力を買いたい！欲しい！っていう企業が少なくとも5社以上あるってことでした。
うーん。IT企業の人事の苦難は、当分続きそうですね。はぁ･･･。



さて、明日の投稿からはこれまで通り技術的な内容に戻ります。ご安心を♪
それでは、また！
【MATLAB】通信の勉強をする前の練習問題【問題編④BERの計算】

#【第4章】通信の実行とBERの計算
ここから一気にBERの計算まで行きます。

##(1)受信信号を計算する
第3章の問5，第2章の問2を参考にして、QPSK変調された送信シンボルがAWGNの影響を受けた時の受信シンボルを表現してみましょう。
SNRや送信bit数は自由に決めてください。
###ヒント
$y_k,x_k,z_k$をそれぞれ時刻kにおける受信シンボル、送信シンボル、雑音ベクトルだとしたとき、それらは
$y_k = x_k + z_k$という関係にあります。
##(2) 奇数bit目の復調
まずは受信シンボル$y_k$から奇数bit目を復調しましょう。「どのような変調が施されたことにより$x_k$が作られたのか」を思い出せば，$y_k$のうちどこが奇数bit目に対応するのかが見えてくると思います。復調結果は{-1,1}から構成される行列で出力してください
###ヒント
$y_k$は$x_k$と違って雑音が足されていることに注意しましょう。
##(3) 偶数bit目の復調
上と同じです。「どのような変調によりそれが作られたのか」を思い出しましょう。
##(4) (2),(3)の結果の結合
結合結果は、もし雑音がなければ「送信信号をBPSK変調したもの」と全く同じになるはずです。
###ヒント
```matlab
A(:,1:2:end) = B
```
このような操作によってAの(2*n-1)行目にBのn行目を代入することができます。(n=1,2,...)
##(5) BPSK復調
(4)の結果得られたビット列に対してBPSK復調をしましょう。
###ヒント
BPSK変調のときには、0を-1にしたんでしたね。では逆操作である復調は…。
##(6) BERの計算
BERの定義とは、「(誤って判定されたbitの個数)/(送信したbitの個数)」です。

#解答
```matlab

% おまじない
clear all

% 今までの復習
N = 10^6;
SNRdB = 10;
SNR = 10^(SNRdB/10);
No = 1/SNR;
noise_comp = sqrt(No/2) * randn(2,N/2) + 1j*sqrt(No/2) * randn(2,N/2);

TX_bit = randi([0,1],2,N);
TX_BPSK = zeros(size(TX_bit));
TX_BPSK(TX_bit == 0) = -1;
TX_BPSK(TX_bit == 1) = 1;
%TX_QPSKの実部は奇数番目の送信bit、虚部は偶数番目の送信bitに対応することに着目
TX_QPSK = (TX_BPSK(:,1:2:end) + 1j*TX_BPSK(:,2:2:end))/sqrt(2);

%問(1) 受信信号の表現
RX_QPSK = TX_QPSK + noise_comp;

%問(2) 奇数bitの復調
RX_BPSK1 = zeros(2,N/2);
RX_BPSK1(real(RX_QPSK) > 0) = 1;
RX_BPSK1(real(RX_QPSK) < 0) = -1;

%問(3) 偶数bitの復調
RX_BPSK2 = zeros(2,N/2);
RX_BPSK2(imag(RX_QPSK) > 0) = 1;
RX_BPSK2(imag(RX_QPSK) < 0) = -1;

%問(4) (2),(3)の結果の結合
RX_BPSK = zeros(size(TX_bit));
RX_BPSK(:,1:2:end) = RX_BPSK1;
RX_BPSK(:,2:2:end) = RX_BPSK2;

%問(5) BPSK復調
RX_bit = zeros(size(TX_bit));
RX_bit(RX_BPSK == -1) = 0;
RX_bit(RX_BPSK == 1) = 1;

%問(6) BERの算出
BER = sum(abs(TX_bit(:) - RX_bit(:)))/(2*N);
```
nuxt.js, vuetify ダイアログコンポーネント化サンプル

# 概要 
- 【目的】手軽にダイアログヲコンポーネント化したい
- - 環境
    - Windows10, VSCode
    - Node v8.11.3
    - Nuxt v1.4
    - vuetify
- 参考
    - [ Vuetify Confirm Dialog component that can be used locally or globally ](https://gist.github.com/eolant/ba0f8a5c9135d1a146e1db575276177d)


# components
 components/Confirm.vueを作成
引用：https://gist.github.com/eolant/ba0f8a5c9135d1a146e1db575276177d

```vuejs:Confirm.vue
<template>
  <v-dialog v-model="dialog" :max-width="options.width" @keydown.esc="cancel">
    <v-card>
      <v-toolbar dark :color="options.color" dense flat>
        <v-toolbar-title class="white--text">{{ title }}</v-toolbar-title>
      </v-toolbar>
      <v-card-text v-show="!!message">{{ message }}</v-card-text>
      <v-card-actions class="pt-0">
        <v-spacer></v-spacer>
        <v-btn color="primary darken-1" flat="flat" @click.native="agree">Yes</v-btn>
        <v-btn color="grey" flat="flat" @click.native="cancel">Cancel</v-btn>
      </v-card-actions>
    </v-card>
  </v-dialog>
</template>
<script>
  export default {
    data: () => ({
      dialog: false,
      resolve: null,
      reject: null,
      message: null,
      title: null,
      options: {
        color: 'primary',
        width: 290
      }
    }),
    methods: {
      open(title, message, options) {
        this.dialog = true
        this.title = title
        this.message = message
        this.options = Object.assign(this.options, options)
        return new Promise((resolve, reject) => {
          this.resolve = resolve
          this.reject = reject
        })
      },
      agree() {
        this.resolve(true)
        this.dialog = false
      },
      cancel() {
        this.resolve(false)
        this.dialog = false
      }
    }
  }
</script>
```
# 呼び出し側 page
 page/以下に呼び出し側Vue作成

```vuejs:dialog2

<template>
<div>
  <v-btn color="success" @click="onClickOpen">OpenConfirm</v-btn> 
  <confirm ref="confirm"></confirm>
</div>
  
</template>

<script>
import confirm from '@/components/Confirm.vue'
export default {
  components:{
    confirm
  },
  methods:{
    async onClickOpen(){
      console.log('--onClickOpen')
      if (await this.$refs.confirm.open('Delete', 'Are you sure?', { color: 'red' })) {
        console.log('--yes')
      }else{
        console.log('--no')
      }
    }
  }
}
</script>

<style>

</style>
```
動作テスト
![image.png](https://qiita-image-store.s3.amazonaws.com/0/158724/3030539d-b5e1-7636-a22c-8fe4c65484d8.png)
![image.png](https://qiita-image-store.s3.amazonaws.com/0/158724/c76d9a35-7d46-4195-9a37-44bd5a6d1afc.png)
DLL 'XXX.dll' を読み込めません:指定されたモジュールが見つかりません。 (HRESULT からの例外:0x8007007E)

# 発生状況

研究室の自作 C# ラッパーを使おうとした時に起きたエラー

# 解決

**Visual Studio の C++ 開発環境を追加する**

自作ラッパーは C++ のライブラリをラップしたもので、
C++ 関連の必要なモジュールが足りていなかった。

# あとがき

通常、exeと同じフォルダに、dllを置けば解決できるもので、
「あれ？dllはおいてあるし、パスは通ってるぞ…？」と同じことをぐるぐると繰り返してしまった。
Visual Studioのインストールで得られるようなモジュールには考えが及ばなかった。
Status bar could not  find cached  time string image. Rending in-process というエラーの解消法

今回アプリを作成し、実機でビルドした際にコンソール部分に
Status bar could not find cached time string image. Rendering in-process.
というエラーが表示されました。


Deployment Infoの欄のHide status barにチェックを入れることで解消できました。

<img width="432" alt="スクリーンショット 2018-09-06 19.31.53.png" src="https://qiita-image-store.s3.amazonaws.com/0/282860/159edda3-0a94-a522-1dde-5e825b47367a.png">


こちらを参考にしました！https://stackoverflow.com/questions/49586341/status-bar-could-not-find-cached-time-string-image-rendering-in-process
VScodeでAWS Cloud9の操作

![図1.png](https://qiita-image-store.s3.amazonaws.com/0/266140/611cc121-e193-dded-402b-835d9c1723e9.png)

### はじめに
AWSをVScodeでいじれないかなーと思っていたら、[**Live Sync for AWS Cloud9**](https://marketplace.visualstudio.com/items?itemName=iann0036.live-share-for-aws-cloud9)というAWS Cloud9と同期して、編集が行える。VScodeの拡張機能がありました！

![image.png](https://qiita-image-store.s3.amazonaws.com/0/266140/c72649a6-d1ec-43b2-12b0-9ad708583c20.png)


* 前提として、EC2インスタンスでCloud9の環境構築が完了しているとします。これからCloud9の環境を作る方は以下の記事を参考にしてください。
* [AWS Cloud9を動かしてみた](https://qiita.com/icck/items/7705ef6871e261d6535e)

### 導入方法
**グループの作成**
1. AWSのコンソール画面から[**IAM**], [**グループ**], [**新しいグループを作成**]を順に選択。
2. 適当なグループ名を入力し、[**次のステップ**]を選択。
3. [**AmazonEC2FullAccess**]と[**AWACloud9Administrator**]の２つにチェックを入れ、[**次のステップ**]を選択。
4. [**グループの作成**]を選択。

---
**IAMユーザーの作成**
1. 続いて、コンソール画面から[**ユーザー**], [**ユーザーを追加**]を順に選択。
2. ユーザー名を適当に入力し、アクセス種類を[**プログラムによるアクセス**], [**AWSマネジメントコンソールへのアクセス**]の両方にチェックを入れる。
3. コンソールのパスワードは[**カスタムパスワード**]を選択し、[**パスワードのリセット**]は今回は不要にしました。
4. 先程、作成したグループをチェックし、[**次のステップ:確認**]を選択。
5. [**ユーザーの作成**]を選択し、[**Access key ID**]と[**Secret access key**]を取得。

---
**VScodeでIAMユーザーの認証**
1. [**F1**]、[**Cloud Sync: Setup**]を選択。
2. [**Access key ID**]、[**Secret access key**]、[**region**]を順に入力。

* regionは以下を参考

| Region Name      |       Region      |
|:-----------------|------------------:|
| 米国東部 (オハイオ)  |              us-east-2 |    
| 米国東部 (バージニア北部) |            us-east-1 |       
| 米国西部 (オレゴン) |              us-west-2 |        
| アジアパシフィック (シンガポール)  |                ap-southeast-1 |        
| 欧州 (アイルランド)  |             eu-west-1 |              

あとは、VScodeを再起動し、VScode側のCloud９から[**Environments**]の接続したい環境上で右クリックで[**Add to Workspace**]を選択すれば完了です。
ということで、個人的に使い慣れた、VScodeがAWSで使えるのは画期的だったのでシェアさせていただきました！
XGBoost(eXtreme Gradient Boosting)について

#はじめに
最近Kaggleでよく使われるXGBoostについてまとめました。
一体どのような学習法であり、どのような特徴があるのかを紹介していきます。

#XGBoostとは ?
- ***Gradient Boosting(勾配ブースティング)***と***Random Forest***を組み合わせたアンサンブル学習(複数の分類器を集めて構成される分類器)
- 勾配ブースティングをC++で実装し高速化したものであり、Gradient Boosted Tree(GBT)より10倍くらいは高速に処理すると言われている。
- 複数のパラメータ調整によるチューニングが必要であり，最適化はグリッドサーチやCross Validationを複数行う
- 汎化能力を上げるために，学習率(XGBoostパッケージではパラメータeta)を下げていき，その都度最適化を行う

---
### Gradient Boosting(勾配ブースティング)とは？
- 弱学習器を1つずつ順番に構築していく手法。新しい弱学習器を構築する際に，それまでに構築されたすべての弱学習器の結果を利用する。
- すべての弱学習器が独立に学習されるバギングと比べ，計算を並列化できず学習に時間がかかる。

※バギングとは、ブートストラップサンプリングで得られた学習データを使って、識別器を複数作り、それらの識別器の多数決をとることによって、一つの識別器よりも性能の高いモデルを作ること。

###Random Forest(ランダムフォレスト)とは？
- アンサンブル学習法の一つ。
- 決定木を複数集めて使うので、木が集まってフォレスト（森）と言われている。
- 複数集めた各決定木の予測結果を多数決することによって結果を得る。

####Random Forestのアルゴリズム
    1. ランダムにデータを抽出する
    2. 決定木を成長させる
    3. 1,2ステップを指定回繰り返す
    4. 予測結果を多数決することによって分類閾値(ラベル)を決定する
  
####Random Forestのメリット
- 特徴量のスケーリングが必要ない(SVMなどの分類手法では必要になる)
- 考慮するパラメータが少ない
- 並列化が容易
- どの特徴量が重要かを知ることができる

####Random Forestのデメリット
- 複雑なデータではSVM(サポートベクターマシン)などの分類手法に比べて汎化性能が下がる

---

##XGBoostのメリット
- 欠損値が多いなどのスパースなデータに対して、事前に木の分岐の方向を決めるアルゴリズムを採用している。
- 並列分散処理により、モデルの探索を高速化している。
- CPU外でも学習が回せるため、大規模なデータも処理できる。

##XGBoostのハイパーパラメタ
XGBoostの公式ドキュメントから、チューニングすべきであろう主なハイパーパラメータは以下のとおりです。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/277948/7b2510e9-8aaf-bc34-45dc-37419c09a6e3.png)

---
###参考文献
[Kaggleで大人気！XGBoostに関する備忘録](https://qiita.com/aaatsushi_bb/items/0b605c0f27493f005c88)
[xgboost公式ドキュメント](https://xgboost.readthedocs.io/en/latest/)
[機械学習アルゴリズム〜XGboost〜](http://rtokei.tech/machine-learning/%E6%A9%9F%E6%A2%B0%E5%AD%A6%E7%BF%92%E3%82%A2%E3%83%AB%E3%82%B4%E3%83%AA%E3%82%BA%E3%83%A0%E3%80%9Cxgboost%E3%80%9C/)
[決定木とランダムフォレスト](https://qiita.com/yshi12/items/6d30010b353b084b3749)
[XGBoostの主な特徴と理論の概要](https://qiita.com/yh0sh/items/1df89b12a8dcd15bd5aa)
【MATLAB 通信 入門】練習問題まとめ

2018/09/06 追加

【MATLAB】通信の勉強をする前の練習問題【問題編①乱数の生成】
https://qiita.com/Seiji_Tanaka/items/cd70a8c8fa406a26f73b

【MATLAB】通信の勉強をする前の練習問題【問題編②変調】
https://qiita.com/Seiji_Tanaka/items/82fd01c82a22d09e6961

【MATLAB】通信の勉強をする前の練習問題【問題編③SNRと雑音の生成】
https://qiita.com/Seiji_Tanaka/items/4286395a708cc0a65cac

【MATLAB】通信の勉強をする前の練習問題【問題編④BERの計算】
https://qiita.com/Seiji_Tanaka/items/0562e6bca12989ac1be6

【MATLAB】通信の勉強をする前の練習問題【問題編⑤グラフの出力】
https://qiita.com/Seiji_Tanaka/items/e51e38fb458febc526f5
Sketchでフォルダ分けして書き出す（sketchtoolを使っても同じ）

# はじめに
Photoshopなら最初からできることができないのが悔しかったので
`gulp-sketch`で組んでみたり試したら、標準機能としてあった。でおちです。

## 参考にしていた
sketch、png、書き出しとググるとgulpがヒットして、かつてはスタンダードだったみたいです。
https://whiskers.nukos.kitchen/2014/12/19/gulp-sketch.html

# 書き出し素材

![スクリーンショット 2018-09-06 18.08.49.png](https://qiita-image-store.s3.amazonaws.com/0/12362/7d4b0c87-77fd-3b61-5563-4fdd9c510fd3.png)

こちらから利用させてもらいました
https://www.sketchappsources.com/
https://www.sketchappsources.com/search_ios.html

# スライス上での命名
## アートボード

![スクリーンショット 2018-09-06 18.10.53.png](https://qiita-image-store.s3.amazonaws.com/0/12362/a72de3c7-ee6b-bdfd-6b7d-db97aa06e8bc.png)

- art/Car-Type
- artboard/Car-Tyres

## シンボル
共通部品として流用の多いものはアートボードで出すよりもシンボルで書き出す方がいいです。

![スクリーンショット 2018-09-06 19.05.46.png](https://qiita-image-store.s3.amazonaws.com/0/12362/76d8d751-4826-3d74-5605-090e650cc328.png)

## 記載部
https://sketchapp.com/docs/exporting/slices/

# 書き出し

## Sketchアプリから
![スクリーンショット 2018-09-06 19.08.19.png](https://qiita-image-store.s3.amazonaws.com/0/12362/40a18ca1-2f8b-7c9e-50f4-7f37f8398924.png)

## sketchtoolから
sketchという名前のフォルダに入れたsketchのファイルからoutフォルダへ素材を書き出します。

> $ sketchtool export slices sketch/hogehoge.sketch --output="./out/"

## 書き出しファイル
![スクリーンショット 2018-09-06 19.11.50.png](https://qiita-image-store.s3.amazonaws.com/0/12362/4dfcf9e4-e567-33d1-ea0e-5db023f0d4cf.png)

![スクリーンショット 2018-09-06 19.12.07.png](https://qiita-image-store.s3.amazonaws.com/0/12362/48e9541c-dde7-ca2d-3348-dff25e6e5527.png)

# さいごに
サイズ別にだす、とかはgulpで調整・・・になるかもですが、PhotoShopのGeneratorに負けない程度に便利になった気がします。
to doの管理をslack内で完結！

こんにちは。オズビジョンで採用広報インターンをしている[たけぶち](https://twitter.com/k_takebuchii)です。

今日は、
<strong>（課題）to do管理で複数の媒体を行き来するストレス
（解決策）to doの管理をslack内で完結！</strong>
を共有したいと思います！

<h3><strong>（課題）to do管理で複数の媒体を行き来するストレス</strong></h3>

先日、オズビジョン採用広報の[まさよふ](https://twitter.com/masayofff)さんと、

<strong>to doを整理して、今後の計画を立てよ～</strong>

と話していて、とりあえずbacklogを使って整理することに。

で、実際使ってみたら、

<strong>正直めんどくさいな、、</strong>

ってなりました＿|￣|○

slackで話したことをbacklogに登録・共有
→進捗毎にbacklogを更新（しかもslackで話は進んでいく）
→完了したらbacklogを更新、slackで共有

これは結構ストレス溜まりそうだなと、、

どうせslackでコミュニケーションを取っているなら、

<strong>to doの管理もslack内で完結したい！！</strong>

と思い、方法考えてみました～

```注：今回は「自分のto doを整理したい」という目的とマッチしないためbacklogの使用を見送りましたが、「600人規模のプロジェクト管理と業務の引き継ぎ」などではbacklogの方が有用だといえます。ケースバイケースということですね。```



<h3><strong>（解決策）to doの管理をslack内で完結！</strong></h3>

<h4><strong>①まず「親課題」を設定します。</strong></h4>

例：記事「to doの管理をSlack内で完結！」の投稿

<img width="501" alt="①.png" src="https://qiita-image-store.s3.amazonaws.com/0/287202/4b5cf926-e677-a20b-9985-ff50fde0b13f.png">

<h4><strong>②次に親課題を解決するための「子課題」を設定します。</strong></h4>

例：to doの管理をSlack内で完結！検証

<img width="791" alt="②.png" src="https://qiita-image-store.s3.amazonaws.com/0/287202/e4fb4bfd-f127-9e5b-546d-9846171284a6.png">

<h4><strong>③それぞれに「未処理」を示す特定のリアクションをしておきます。</strong></h4>

例：リアクション「着手」

<img width="786" alt="③.png" src="https://qiita-image-store.s3.amazonaws.com/0/287202/84d7ecaa-f4fc-d86e-f9a5-f7ac95482514.png">

<h4><strong>④右上の検索窓で、「in:#部屋名 has::リアクション:」で検索します。</strong></h4>

例：「in:#todoテスト has::start:」

<img width="500" alt="④.png" src="https://qiita-image-store.s3.amazonaws.com/0/287202/063a7b1e-7a62-844f-9138-bd900eca1a76.png">

「未処理」のto doが時系列で出てきます！

<h4><strong>⑤解決したものは、リアクションを外し、代わりに「済」を示すリアクションをつけます。</strong></h4>

例：リアクション「チェックマーク大」

<img width="789" alt="⑤.png" src="https://qiita-image-store.s3.amazonaws.com/0/287202/b445dda1-f7fa-0dd5-f07d-0218d392e9b6.png">

<h4><strong>⑥再度検索すると、「未処理」のto doだけが出てきます。</strong></h4>

<img width="501" alt="⑥.png" src="https://qiita-image-store.s3.amazonaws.com/0/287202/b38ed430-4148-da13-7fad-aa0818510f02.png">

思いついたばかりなので、粗削りの部分もありますが、

・<strong>to doの共有が簡単</strong>（「in:#部屋名 has::リアクション:」で検索かければ、誰でも見れる）
・スレッドを利用することで、<strong>「親課題」と複数の「子課題」を簡単に設定</strong>できる。
・リアクションによって<strong>「未処理」「処理中」「済」のような進捗管理</strong>もできる。

など、可能性を感じる使い方だと思います！！

今後改良しながら、しばらく使ってみて、また試用結果を共有します！
GASを使って、スプレッドシートにMySQLのテーブル定義書を作成する

OSSなどを使う場合、ドキュメントがなかったり、マニュアルがあってもテーブル定義書がなかったりすることが
ありましたので、DBから直接テーブル定義書を作成するスクリプトを作りました。

# ソースコード

https://github.com/kumanizm/table_spec_at_spreadsheet
READMEとか何も書いてない・・・

# 経緯

前述の通り、OSSを使うことが増えてきた背景もあり、
DBから直接、ドキュメントを作成したかったので。

# 完成品

![スクリーンショット 2018-09-06 18.20.43.png](https://qiita-image-store.s3.amazonaws.com/0/103/d20f319e-25c3-54c5-6868-614e5fbb85be.png)

![スクリーンショット 2018-09-06 18.20.56.png](https://qiita-image-store.s3.amazonaws.com/0/103/85784739-ee5e-2e40-3748-4073b22db9d2.png)

# 使い方

![スクリーンショット 2018-09-06 18.23.54.png](https://qiita-image-store.s3.amazonaws.com/0/103/ec407701-c2e8-d2e4-b450-5d9b78aac295.png)
↑シート名を「テーブル定義書」に書き換えてください

![スクリーンショット 2018-09-06 18.24.26.png](https://qiita-image-store.s3.amazonaws.com/0/103/8520b84b-3870-a13d-ef10-781f8a26ff64.png)
↑スプレッドエディタを開く

![スクリーンショット 2018-09-06 18.25.20.png](https://qiita-image-store.s3.amazonaws.com/0/103/e28a254e-3879-2c11-9787-f1d7d8f4db12.png)
↑githubからcloneしてきたcode.gsを貼り付けてください。
↑_configのMySQLの接続情報とスプレッドシートのファイルIDを適切な値に書き換えてください

![スクリーンショット 2018-09-06 18.25.42.png](https://qiita-image-store.s3.amazonaws.com/0/103/7e0f0cd1-ba82-5817-6690-adf0e0b331c6.png)
↑set_table_list()という関数を実行すると、スプレッドシート上にテーブル定義書が作成されます。
※テーブル数によって若干時間がかかります。

# ソースの中身説明

## 関数の概要
set_table_list()：実行する関数
get_list_() : テーブルを配列に突っ込む
set_table_sheet_() : テーブル定義をシート別に作成する
set_list_sheet_() : テーブル一覧のシートを作成する


## MySQLへの接続

``` js
  // 変数定義
  var con_str = 'jdbc:mysql://' + _config['DB_HOST'] + ':' + _config['DB_PORT'] + '/' + _config['DB_NAME'];
  var user_id = _config['DB_USER'];
  var user_pass = _config['DB_PASS'];

 　　// DBに接続
  var conn = Jdbc.getConnection(con_str, user_id, user_pass);
  var stmt = conn.createStatement();
  // 最大row数
  stmt.setMaxRows(1000);

```

## SQL実行

``` js
  var str_query = "show table status like '" + TABLE + "'";
  var rs = stmt.executeQuery(str_query);
  while(rs.next()) {
    //getStringで列名を指定して取得
    table_ss.getRange("A"+(j+1)).setValue(rs.getString("Comment")).setBorder(true, true, true, true, true, true);
    
    j++;
    k++;
  }
  rs.close();
```

## 利用したSQL

・・・はソースの中をご確認ください。

# 注意点

スプレッドシートの仕様上、セルが200万個以上出来るとエラーになるようです。
そのため、不要なセルは削除する方が良いと思われます。

``` js
  if (table_ss.getMaxRows()==1000) {    
    table_ss.deleteColumns(11, table_ss.getMaxColumns()-11);
    table_ss.deleteRows(j, (table_ss.getMaxRows()-j));
  }
```
デフォルトは1000行あるので、デフォルトの状態の時には必要な分のみ残して行・列ともに削除する

# 感想

最近、スプレッドシートを使ってドキュメントを書くことが増えてきたので、出来ることはバシバシ自動化していきたい。
一括でinnodbテーブルを圧縮するAlterコマンドを生成するSQL

Mysql運用し始めて、DISK容量が足らなくなった時に使ってみてください。
大体テーブル容量が半分になるので、

```sql:
SELECT
`TABLES`.TABLE_SCHEMA,
`TABLES`.TABLE_NAME,
`TABLES`.ROW_FORMAT,
CONCAT("ALTER TABLE `",`TABLES`.TABLE_SCHEMA,"`.`",`TABLES`.TABLE_NAME,"` ROW_FORMAT = COMPRESSED;"),
`TABLES`.*
FROM
information_schema.`TABLES`
WHERE
`TABLES`.ROW_FORMAT != "Compressed"
AND
`TABLES`.TABLE_SCHEMA NOT IN ("information_schema","performance_schema","mysql","sys")
AND
`TABLES`.ENGINE = "InnoDB"
AND
`TABLES`.CREATE_OPTIONS not like "%COMPRESSION%"
```

system schema とmyisamは除外してます。
pt-online-schema-changeとかとセットに使うとよいかも。

pt-online-schema-changeを安全につかう
http://strsk.hatenablog.com/entry/2014/12/19/003044
Qiitaイイネやフォロワーを社内メンバーでウォッチして盛り上がる

# 背景
- 社内エンジニアメンバーで積極的にQiita記事を投稿していこうという取組を始めた。（品質向上＆教育＆認知拡大の狙い）
- 書くだけでなく、より多くの人に良い影響を与えられるかを狙いたいため、（もちろんそれ自体が目的ではないにせよ）イイネ数やフォロワー数をKPIとしてウォッチしたい。
- どうせなら楽しくやって盛り上がりたい。

# アウトプット
![Clipboard02.png](https://qiita-image-store.s3.amazonaws.com/0/89255/7a07a17b-415c-55af-2316-d13e72cfa05d.png)

# 出している指標
共通ルールとして、チームメンバー間のフォロワーやイイネはカウントしない。
イイネをもらった日時期間を絞ることができる。
#### フォロワー数
チーム全体で何人のフォロワーが居るか。
#### イイネユーザ数
チーム全体で指定期間に何人からイイネをもらったか。
#### イイネ総数
チーム全体で指定期間に何回イイネをもらったか。
#### メンバー別イイネ数ランキング
チームメンバごとに指定期間に何人からイイネをもらったか。
#### メンバー別フォロワー数ランキング
チームメンバごとに何人のフォロワーがいるか。
#### 記事別ランキング
記事ごとに指定期間に何人からイイネをもらったか。
#### 累積イイネ数
指定期間にもらったイイネ数の積み上げ範囲グラフ。メンバーで色分け。
#### 累積記事数
投稿した記事数の積み上げ範囲グラフ。メンバーで色分け。

# 作り方
1. APIを用いてイイネ情報取得
 1. チームメンバーユーザID毎に、API:itemsで記事一覧を収集
 2. その記事ごとにAPI:likesでイイネしてくれたユーザ情報を収集
 3. 「メンバーuserid / 記事ID / 記事作成日時 / 記事タイトル / 記事URL / イイネuserid / イイネ日時」 のファイルを作成
2. APIを用いてフォロワー情報取得
 1. チームメンバーユーザID毎に、API:followersでフォロワー一覧を収集
 2. 「メンバーuserid / フォロワーuserid」 のファイルを作成
3. 2つのファイルを用いてTableauで可視化

※イイネ情報はAPIで累積データ自体が取得できるが、フォロワー情報は断面情報になるので扱いが異なる。
※現状週1回API取得して作成。

# 諸注意等
- API発行時にヘッダにトークンを入れれば、API発行上限はユーザ毎に1000回/hとなる。記事ごとに発行が必要なのでこれは必須。（でないと、IP毎に60回/hとなり不足）
- そのうえで、急激に投げすぎないよう、1分間あたりの発行数を16回までに制御して取得。
- チームメンバーからのイイネを除外するために、likes_countは使わず、イイネユーザ一覧を取得してユーザ精査する。

# 今後改善するとしたら
- 記事一覧取得(API:items)は一度に100記事までなので、101記事以上投稿したメンバーが出てきたら要考慮。（その日が来ることを祈る）
- もっと記事数増えてきたら平均値や中央値を出しても。
- ファイルベースでTableauDesktopに渡すのではなく、DBを介してTableauServerに渡せば完全自動化が可能。
- 自動化すればフォロワー数などの断面情報も自前で蓄積することで時系列変化を追える。
- 記事のPV数は他ユーザのものは取得できないようなので、アクセスはGAで見ている。PV見れるようになったら統一したい。
- （Tableau見た目素敵化）

# 所感
- こんなことでもやってみるとけっこう盛り上がる。エンジニアという種族はゲーム感覚が好きなのだろう。
- イイネ自体が目的ではないものの、より「良い思ってもらえる記事を書こう」という意識醸成につながる。
Web Bluetoothを実戦投入すると意外と使えたメモ

普段はIoTな製品開発をメインにしているため、JSも王道の斜め横くらいの使い方で楽しんでいる今日このごろ。そんななかで、なかなか触る機会がないであろう`Web Bluetooth`をゴリゴリいじくり倒して実戦投入すると意外と使えたので、そのときにわかったことのメモをまとめておきます。Android Chromeがサポート環境だったため、そっち寄りのまとめになります。

なかなかチュートリアル以上のネタがネット上になかったので、他に同じ心境の方が出てきたときの助けになれば...:innocent:

# Web Bluetoothの仕様とか参考にしたところ

- [W3C Document](https://webbluetoothcg.github.io/web-bluetooth/)
- [GitHub: WebBluetoothCG / web-bluetooth](https://github.com/WebBluetoothCG/web-bluetooth)
- [GitHub: WebBluetoothCG / Demos](https://github.com/WebBluetoothCG/demos)

ドキュメントは意外と更新頻度高いので、実装時期によっては意外とできなかったことができてたりします。

# 対応ブラウザ

- Chrome
  - Mac
  - Windows
      - 要フラグ設定 `chrome://flags/#enable-experimental-web-platform-features`
  - Android

![スクリーンショット 2018-09-06 17.57.05.png](https://qiita-image-store.s3.amazonaws.com/0/55103/f9789bc3-9572-3b50-e8fe-4be75de6dd75.png)

※2018/09/06現在

- [Can I use](https://caniuse.com/#feat=web-bluetooth) 
- [Implementation Status](https://github.com/WebBluetoothCG/web-bluetooth/blob/gh-pages/implementation-status.md)

Windowsはフラグが必要だったりサポート状況が芳しくなかったりするので、開発するアプリのサポート環境からは外したい。Android Chromeは、Mac Chromeとサポート状況が変わらないので、意外と使えました。

# Web Bluetoothが動く条件

- HTTPS環境下のみ実行可
- ユーザーアクション（クリックやキーボード操作など）をトリガーにして実行すること
- Service Workerを使ったオフライン起動も:ok:

# 実戦投入してわかったWeb Bluetoothの癖

## Advertisingは今の所未サポート（2018/09/06現在）

AndroidやiOSのネイティブアプリなら、Scan時にAdvertisingでデータを見ることもあると思いますが、Web Bluetoothには今の所サポートされていないため要注意。

## `readValue`と`startNotification`を複数実行したいときに同時に実行できない

アプリ起動時に、複数のCharacteristicに対して`readValue`や`startNotification`でデータを吸い上げることになりますが、同じタイミングで複数個を実行するとAndroid Chromeでエラーを吐いた（Macでは問題なかった）。端末のスペックが影響しているのかな？ と憶測... どうしても複数個を実行する必要がある場合、Stackに貯めて1一つずつ実行する処理を自前で実装する必要がある。

## Android Chromeで設定できるNotificationは15本まで

Web Bluetoothの問題ではなく、Android OSのバージョンに依存する（Android 4.4は7本、8.0は15本）。たくさんデータのやり取りが必要な場合（BLEでそこまで送らないで..というのは思いつつ）、Notificationは必要最低限の数にして、残りはReadで補うという工夫が必要になりそうです（ちゃんと数えていませんがMacでは15本以上も問題なく設定できた）。

- 参考記事: [BLE視点でまとめるAndroid OSの違い](https://qiita.com/ozyozyo/items/351babdf2160d733a306)

## Android端末によって転送速度が全然違う

開発は手元のXperiaで進めていたので転送速度も特に気にせずやれていたのですが、検証端末で使った海外製のAndroidだと悲しくなるほど劇遅に... 端末もある程度絞ったほうがよさそう。

# ネイティブアプリに比べたらやれること限られるけど、JSでも意外とよかった

「そんなんネイティブでやりゃ〜いいじゃん」と言われそう:sweat_smile:だけども、ストアへの申請の面倒くささや更新の頻度、ユーザーの端末への導入しやすさで考えると意外とありなのかなと思いました。Service Workerのオフライン起動やApplication Manifestを使ってネイティブアプリっぽく見せるのもありかなと（そのあたりも実戦投入したのでどこかのタイミングでまとめます）。

Web Bluetoothでもっと何か作りたいな:muscle:
NginxとuWSGIでHelloWorld

Nginx上でuWSGIを動かしてHelloWorldするのに苦労したのでメモしておきます。
各種インストールは終わっているものとします。

環境は以下です。

- CentOS7
- Nginx
- uWSGI 2.0.17.1


# 目次
- [とりあえずhttpでuWSGIを動かす](#とりあえずhttpでuwsgiを動かす)
- [NginxからuWSGIにsocketでつなぐ](#nginxからuwsgiにsocketでつなぐ)
- [uWSGIをiniファイルで起動できるようにする](#uwsgiをiniファイルで起動できるようにする)
- [uWSGIをsystemctlで起動できるようにする](#uwsgiをsystemctlで起動できるようにする)

ではいきましょう！

# とりあえずhttpでuWSGIを動かす
uWSGIに直接httpで接続できるようにします。
まずは表示用のpythonファイルをつくります。
ディレクトリは何でもいいですが、とりあえず/var/www/uwsgi/にindex.pyを置くようにしました。

```index.py
def application(env, start_response):
    start_response('200 OK', [('Content-Type','text/html')])
    return [b"Hello World"]
```

では早速、以下のコマンドでつないでみます。

```
uwsgi --http 127.0.0.1:3031 --wsgi-file /var/www/uwsgi/index.py
```
ブラウザでlocalhost:3031にアクセスすると、'HelloWorld'が出力されるのを確認できます。

uwsgiを停止して抜けるにはctrl+cを使います。
なお、上述のコマンドだとuwsgiの起動中はコマンドを叩けなくなってしまいます。

```
uwsgi --http 127.0.0.1:3031 --wsgi-file /var/www/uwsgi/index.py &
```
として、最後尾に'&'をつけることで、ctrl+cで抜けた後もプロセスを実行し続けることができます。
この場合、プロセスを停止するには

```
killall -9 uwsgi 
```
として、強制終了してしまいます。
また、実行時にpidファイルを設定している場合は、これを指定して停止させることができます。

```
uwsgi --stop [好きなディレクトリ]/uwsgi.pid
```

# NginxからuWSGIにsocketでつなぐ
とりあえずuWSGIに直接httpでつなぎましたが、実際はNginxを通してuWSGIに接続するような形になります。
今回は/var/www//uwsgi/に80番ポートでアクセスしたときにuWSGIに接続するような設定にしましょう。

まずはNginx側の設定ファイルをいじります。

```/etc/nginx/conf.d/default.conf
server {
    listen       80;
    server_name  hoge;

    location / {
        root   /var/www;
        index  index.html index.htm;
    }

    #--------------------------------------------
    #ここを追記
    location /uwsgi {
        include uwsgi_params;
        uwsgi_pass unix:///[好きなディレクトリ]/uwsgi.sock;
    }
    #--------------------------------------------
}
```
uwsgi.sockはソケットファイルです。勝手に作られるので特に用意しておく必要はありません。

# uWSGIをiniファイルで起動できるようにする
uWSGIをiniファイルを使って起動できるようにします。
uwsgi.iniを好きなディレクトリにつくりましょう。

```uwsgi.ini
[uwsgi]
module = index
master = true
socket = [好きなディレクトリ]/uwsgi.sock
chmod-socket = 666
wsgi-file = /var/www/uwsgi/index.py
pidfile = [好きなディレクトリ]/uwsgi.pid
logto = [好きなディレクトリ]/uwsgi.log
```
uwsgi.sockのディレクトリはNginx側の設定と合わせるようにします。
ここまで設定すると、80番ポートからNginxを通してuwsgiにアクセスできるようになります。

```
systemctl restart nginx
uwsgi --ini [好きなディレクトリ]/uwsgi.ini
```
ブラウザでlocalhost/uwsgiにアクセスすると、index.pyが動いて'HelloWorld'が出力されるのを確認できます。
今回はpidファイルを指定して起動しているので、終了には以下のコマンドが使えます。

```
uwsgi --stop [好きなディレクトリ]/uwsgi.pid
```

# uWSGIをsystemctlで起動できるようにする
以上でHelloWorldまではできましたが、ついでにsystemctlに登録して自動起動もできるようにしてしまいます。
systemctlに登録するために、/etc/systemd/system/内にuwsgi.serviceファイルをつくりましょう。

```/etc/systemd/system/uwsgi.service
[Unit]
Description = uWSGI
After = syslog.target

[Service]
ExecStart = /usr/bin/uwsgi --ini [好きなディレクトリ]/uwsgi.ini
Restart=always
KillSignal=SIGQUIT
Type=notify
StandardError=syslog
NotifyAccess=all

[Install]
WantedBy=multi-user.target
```
これでsystemctlが使えるようになっているはずなので確認しましょう。

```
systemctl status uwsgi
```
ついでに自動起動の設定もしておきます。

```
systemctl enable uwsgi
```
Git の使い方　超入門

# Gitの使い方
## Branchの切り方
- GitのWebページ
    - Project⇒Branches⇒New branch
    - Brance name を入力すればOK
- ローカル環境（tortoiseGitを使う)
    - クローンを作って
    - 右クリック⇒切換え
    -