OmniAICreator/Qiita-1.07M huggingface dataset:
Tinker Board S (Tinker OS) で GrovePi+を動かす

Raspberry Pi (以下 RPi) で Grove システムのモジュールが使えるようになる [GrovePi+](https://www.switch-science.com/catalog/2129/) を RPi 互換な Tinker Board S (というか Tinker OS) で動かすのに少々手間がかかったので、記録しておきます。

## 手順

```console
$ sudo apt update ; sudo apt upgrade -y ; sudo apt autoremove --purge -y
$ sudo apt install nodejs \
     git libi2c-dev i2c-tools \
     python-setuptools python-pip python-smbus python-dev python-serial \ 
     python-numpy python-scipy python3-setuptools python3-pip python3-smbus \
     python3-dev python3-serial python3-numpy python3-scipy
$ git clone https://github.com/TinkerBoard/gpio_lib_python.git
$ pushd gpio_lib_python/
$ sudo python setup.py install
$ sudo python3 setup.py install
$ popd
$ sudo apt install libffi-dev
$ sudo rm /home/pi
$ sudo useradd -m -d /home/pi -s /bin/bash -G sudo pi
$ sudo -s -u pi
$ curl -kL dexterindustries.com/update_grovepi | \
  bash -s -- --no-update-aptget --no-dependencies --bypass-gui-installation \
     --bypass-python-rfrtools
$ sudo systemctl reboot
```

### 解説

Tinker OS 用の GPIO ライブラリ(gpio_lib_python)をインストールする必要があります。
また、セットアップスクリプト(dexterindustries.com/update_grovepi) が `pi` というユーザや `/home/pi` を決め打ちでインストールしようとするので、その環境を構築する必要があります。

### ついでに入れておくと幸せになるパッケージなど

この辺は入れておいた方がいいでしょう。

* screen
* avahi-daemon

また、[USB型ドングル](https://soracom.jp/products/module/)でインターネットに接続したいなら、このスクリプトでつなげられるようになります (半分CMでスミマセン)

```
$ curl -kL https://soracom-files.s3.amazonaws.com/setup_air.sh | sudo bash
```

## ちなみに：Raspbian なら

https://www.dexterindustries.com/GrovePi/get-started-with-the-grovepi/setting-software/ に書いてある通りの手順で OK です。

```console
$ sudo curl -kL dexterindustries.com/update_grovepi | bash
$ sudo systemctl reboot
```

## ちなみに：音声出力

Tinker Board S 上の 3.5 イヤホンジャックから音声出力したい場合は以下のようにします。
(必要なパッケージは `aplay open_talk` だったような気がする...)

```console
$ aplay -D plughw:CARD=OnBoard,DEV=2 /usr/share/sounds/alsa/Front_Center.wav
$ echo "こんにちはこんにちわ" | \
  open_jtalk -m /usr/share/hts-voice/nitech-jp-atr503-m001/nitech_jp_atr503_m001.htsvoice -x /var/lib/mecab/dic/open-jtalk/naist-jdic/ -ow /dev/stdout /dev/stdin | \
$  aplay -D plughw:CARD=OnBoard,DEV=2
```

## あとがき

現場からは以上です。

EoT
Go で IPアドレスから逆引きするには

検索しても意外とぱっとは出てこなかったので。お役に立てば幸いです・・・

# net.LookupAddr を使う

引数にIPアドレスを指定することで、host が slice で返却されます。

```go
package main
 
import (
    "fmt"
    "log"
    "net"
)
 
func main() {
    addr, err := net.LookupAddr("127.0.0.1")
    if err != nil {
        log.Fatal(err)
        return
    }
    fmt.Println(addr)
}
```
```:実行結果
[localhost]
```
Beautifulsoupを使って、簡単に今期（２０１９年冬）アニメランキングを作ってみた

###はじめに###
巷ではよく今期アニメランキングを発表していますが、どうも納得がいかないことが多いと聞きます。例えば、このサイトでは、
１位　バーチャルさんはみている
２位　転生したらスライムだった件
３位　けものフレンズ２
４位　かぐや様は告らせたい
５位　五等分の花嫁
（https://anime.nicovideo.jp/ranking/view-total.html?from=nanime_rank-view-daily_rank
）

![LXUsI0mUYlobBX61548023770_1548023789.png](https://qiita-image-store.s3.amazonaws.com/0/335630/ec3beee5-dcc5-b43e-73f5-57082d65292a.png)


他のアニメは「まあまあ正しいのかな」としても、「バーチャルさんはみている」が１位というのは、おかしいような気もします。

勿論、アクセス数で測っているので有料枠などはアクセス数が低くなることは必然でしょう。アニメをインターネットで生配信しているか否かもアクセス数が違う原因になります。現に今期人気アニメの「約束のネバーランド」は３０～１４位をウロウロしています。

よってこのランキングを参考に、「どのアニメが人気なのか」を判断することは出来ません。このランキングは、あくまで「このサイトで、どれくらいアクセス数があったのか」ということでしかないのです。

よって<b>とりあえず今期は何が人気なのかを判断して、３話ぐらい見てから切るか考えよう</b>という人にとっては、このランキングはあまり役に立たないでしょう。

そこで色々調べたところ、このサイトがランキングとして使えそうだと考えました。
MyAnimeList 　https://myanimelist.net/anime/season

理由としては、レヴュー数が5万~16万と圧倒的に多く、ランキングの基準を「アクセス数」ではなく、「作品の評価」（１０段階）で決めているからです。１０段階であれば、より作品の面白さで点数に差がつくので、繊細なランキングができることでしょう。欠点は外国人がレビューしていることですが、見たところ、日本で人気なものは、大体海外でも人気なようなので、大丈夫だと判断しました。

（補足：Crunchyrollも考えましたが、作品数がいくつか欠けており、５段階評価で、レヴュー数も少なかった（50~600ぐらい）で少なかったので辞めました。）
https://www.crunchyroll.com/videos/anime/seasons/winter-2019


###実際にやってみる###

ウェブスクレイピングは初めてだったので、このくらいの難易度は丁度良かったように思えます。
（2019/01/25　shiracamusさんのご指摘でコードをアップデートしました。）

```py
from urllib.request import urlopen
from bs4 import BeautifulSoup as soup


def download(url='https://myanimelist.net/anime/season'):
    http = urlopen(url)
    html = soup(http, 'html.parser')

    # 今期のアニメだけを取るためにhtmlの「今期」の部分だけを抽出
    containers = html.find("div", class_="seasonal-anime-list js-seasonal-anime-list js-seasonal-anime-list-key-1 clearfix")

    # スコアとタイトルを抽出・産出
    titles = containers.findAll("a", class_="link-title")
    scores = containers.findAll("span", class_="score")
    for title, score in zip(titles, scores):
        title = title.text
        score = score.text.strip()
        score = float(score if score != 'N/A' else '0')  # 無評価(N/A)は0.0
        yield score, title


def show_ranking(score_titles):
    ranking = sorted(score_titles, reverse=True)
    for rank, (score, title) in enumerate(ranking, 1):
        line = ' {:<2}  {:<60}  {:<3}'.format(rank, title, score)
        print(line)

if __name__ == '__main__':
    show_ranking(download())
```

結果
![9EecRuYTHrgHIWX1548023398_1548023416.png](https://qiita-image-store.s3.amazonaws.com/0/335630/6cf15738-397d-be73-caa3-b2a4b1250598.png)

１位　モブサイコ100 二期
１位　約束のネバーランド　（２位と書いてあるが同率１位）
３位　盾の勇者の成り上がり
４位　どろろ
５位　かぐや様は告らせたい

結果、小点数第２位まで表しているのにも関わらず、なんとモブサイコ100の２期と約束のネバーランドが、同点になりました！１位であった「バーチャルさんはみている」は36位へ（好きな人、侮辱しているわけではないです。すみません。）

その他のアニメもかなり違う結果となりました。（ちなみに転スラ等、前から続いているアニメは入っていません。評価が無かったアニメも0点としています。）

他にも同点が２つあり、「五等分の花嫁」と「ドメスティックな彼女」は0.03の違いでかなり近い結果となりました。

勿論、このランキングは殆ど外国人が付けているので、「日本人だけに通じるネタは外国人には分からない」など懸念も多々ありますが、アニメを多く見ている人なら、このランキングを見て納得する方も多いのではないでしょうか。

<b>これだったら、一、二話での評価をサクッと見て、人気が無いアニメを捨てて人気が高いものに絞って見ることができます。</b>
ScalaでGoogle SpreadSheetAPI使って以下エラーが表示された場合

# 問題
google-api-clientを使用しGoogleのSpreadSheetのクライアントをscalaで作ったが、アクセス時に403になった。ハマったのでメモ

```
com.google.api.client.googleapis.json.GoogleJsonResponseException: 403 Forbidden
{
  "code" : 403,
  "errors" : [ {
    "domain" : "global",
    "message" : "The caller does not have permission",
    "reason" : "forbidden"
  } ],
  "message" : "The caller does not have permission",
  "status" : "PERMISSION_DENIED"
}
```

# 原因と解決
今回service accountを使用してアクセスしようとしたが、アクセスしたいファイルに当該service accountのアクセス権限がなかったが原因。

1. google sheet編集画面の右上の「共有」ボタンを押して出るダイアログに、service accountのメアドを入力。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/30677/c9ba0c63-9809-9350-eb35-4be8b08a8083.png)

2. 送信ボタンで権限設定が完了する
scalatestでFutureをテストする方法３通り

# 問題
Futureを使用したテストがかけない。
単純にFutureの値のmapで以下のように書こうとしても、map内のassertの実行前にテストが終了してしまう

```scala
    HelloFuture.hello().map { s =>
      assert(s == "hello!")
    }
```

例としてこちらの単純なクラスのhello()をテストする。


```scala
import scala.concurrent.Future
import scala.concurrent.ExecutionContext.Implicits.global

object HelloFuture {

  def hello(): Future[String] = {
    Future {
      "hello!"
    }
  }
}
```

## Await.resultを使用

```scala
import scala.concurrent.Await
import scala.concurrent.duration._

class HelloFutureWithAwaitSpec extends FlatSpec {
  "hello method" should "return string 'hello!'" in {
    val result = Await.result(HelloFuture.hello(), 500 millis)
    assert(result == "hello!")
  }
}

```

参考：[Futures and Promises | Scala Documentation](https://docs.scala-lang.org/overviews/core/futures.html)

## ScalaFuturesを使用
scalatestに付属している、テスト専用のメソッドであるfutureValueを使用して値を取り出す。
Await.resultよりコードの見通しがよい。

```scala
import org.scalatest.FlatSpec
import org.scalatest.concurrent.ScalaFutures

class HelloFutureWithFutureValueSpec extends FlatSpec with ScalaFutures {
  "hello method with futureValue" should "return string 'hello!'" in {
    assert(HelloFuture.hello().futureValue == "hello!")
  }
}

```

ちなみに、org.scalatest.concurrent.ScalaFuturesのwhenReadyを使用してもテストがかける。

```scala
import org.scalatest.FlatSpec
import org.scalatest.concurrent.ScalaFutures

class HelloFutureWithWhenReadySpec extends FlatSpec with ScalaFutures {
  "hello method with whenReady" should "return string 'hello!'" in {
    whenReady(HelloFuture.hello()) { result =>
      assert(result == "hello!")
    }
  }
}
```

いずれも、timeout時間と再実行までの間隔intervalを設定できるようなので、Await.resultと同じようにある程度待たないとFutureの処理が終わらない場合も使える。

参考: [ScalaTest 3.0.1 - org.scalatest.concurrent.ScalaFutures](http://doc.scalatest.org/3.0.1-2.12/org/scalatest/concurrent/ScalaFutures.html)

## Async系のSuiteを使用
scalatest3.xから登場。Future型のmapのブロック内でassertを実行しても、正常に実行可能。

例ではAsyncFlatSpecだが、FlatSpec以外のscalatestが提供している各種suiteのAsync版がある。

```scala
import org.scalatest.AsyncFlatSpec

class HelloFutureWithAsyncSpec extends AsyncFlatSpec {
  "hello method with async assert" should "return string 'hello!'" in {
    HelloFuture.hello() map { result =>
      assert(result == "hello!")
    }
  }
}
```
ThreadSleepを仕込んで１０秒またせたが、終了まできちんと待ってからassertを実行してくれていた。
Future特有のメソッドをわざわざ使わないので実装コードと同じ感覚でかけるのがよい。

参考：[ScalaTest](http://www.scalatest.org/user_guide/async_testing)
2019 年 3 月以降の iOS アプリ申請について

2019 年 3 月以降からは、 App Store に提出されるすべての iOS アプリは、iOS 12.1 以降の SDK でビルドする必要があります。

詳しくは、[App StoreにiOS Appを提出する](https://developer.apple.com/jp/ios/submit/)を参照してください。

現在、iOS 11 系のバージョンでビルドしている場合は、下記のようなメッセージが表示されているようです。

```
SDK Version Issue - This app was built with the iOS 11.2 SDK. Starting March 2019, all iOS apps submitted to the App Store must be built with the iOS 12.1 SDK or later, included in Xcode 10.1 or later.
```

# ビルド環境設定

Monaca では、Cordova 7.1 プロジェクトで iOS 12.1 以降の SDK でビルドを行うために、新たに `ビルド環境設定` 項目が追加されました。

<img width="289" alt="メニュー.png" src="https://qiita-image-store.s3.amazonaws.com/0/113550/90912032-2141-3fa0-687e-d3e0ba3d2cd9.png">

この「ビルド環境設定」から `Xcode 10.1` を選択し、`保存` ボタンをクリックすることで、対象プロジェクトを iOS  12.1 以降の SDK でビルドすることが可能になります。

<img width="557" alt="ビルド環境設定.png" src="https://qiita-image-store.s3.amazonaws.com/0/113550/a390eeac-75de-01d9-5248-0664028f9467.png">

# おわりに

App Store へ iOS アプリを提出する際の SDK バージョン要件については、定期的に更新されます。

App Store Connect へ アプリをアップロードした際に、SDK バージョンに関するメッセージが表示された場合は、「ビルド環境設定」から適切な Xcode を選択して利用してください。
bashの基本コマンド

#使用したコマンドの一覧
|コマンド名|動作|
|-------|---|
|ls|ディレクトリ（フォルダ）内のファイル一覧を表示|
|cd|操作対象ディレクトリ（フォルダ）を移動|
|mkdir|ディレクトリ（フォルダ）を作成|
|cp|ファイルをコピー|
|mv|ファイルを移動|
|rm|ファイルを削除|
|less|ファイルの内容を表示|
|touch|ファイルを更新、または作成|
|nano|ファイルをエディタで表示|

#環境
windows 10
![image.png](https://qiita-image-store.s3.amazonaws.com/0/253014/e7d76da9-be92-c503-3e50-01c6490cfa20.png)

```bash
$ bash --version
bash --version
GNU bash, version 4.4.19(2)-release (x86_64-pc-msys)
Copyright (C) 2016 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>

This is free software; you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
```

#公式のユーザーズガイド
https://cygwin.com/cygwin-ug-net/cygwin-ug-net.html

#基本コマンド（一通り試して、正常に動作確認済み）
http://polymer.apphy.u-fukui.ac.jp/~aplabo3/PC/cygwin-command.html

#実際の例
**フォルダの呼び方はディレクトリで統一します**

###ls
- ディレクトリ（フォルダ）内のファイル一覧を見る
- -l、-aといったオプションがある（google検索で-l -aを検索すると、検索結果から除外されてしまうので、"-l","-a"などで検索してください。）

```bash:ls
ls #コマンドを実行したディレクトリ内のファイル一覧が見れる
```

###cd ディレクトリ名
- ディレクトリに移動する。

```bash:cd
cd ディレクトリ名
```


###mkdir ディレクトリ名
- ディレクトリを作成する。

```bash:mkdir
mkdir ディレクトリ名
```

###cp コピー元 コピー後の名称
- ファイルをコピーする。

```bash:cp
cp コピー元ファイル名 コピー後のファイル名
```

###mv 移動させたいファイル名 移動先のディレクトリ名
- ファイル名を変更する。ファイルを移動する。

```bash:mv
mv 移動元ファイル名 移動先ディレクトリ名
```
###rm 削除したいファイル名
- ファイルを削除する。
- -r オプションをつけるとディレクトリを削除できる

```bash:rm
rm ファイル名
```

###less 表示させたいファイル名
- ファイルの内容を，画面１ページずつ表示する。

```bash:less
less ファイル名
```

###touch 更新したいファイル名
- タイムスタンプを更新します
- ファイル名が存在していないものだと、新規作成コマンドになります

```bash:touch
touch ファイル名
```

###nano エディタで表示したいファイル名
- エディタで表示します

```bash:nano
nano ファイル名
```
Streamで九九を出力する

##1年前入社前に未経験としてJavaを学んだ僕はこんなコードを書いた
　for文を2重にし、内部で掛け算したものを改行なしで出力し、内部のforが終わる度に改行を出力することで、九九表を出力する定番のあれ

```Kuku.java
public class Kuku { 
    public static void main(String[] args) {
 
        for (int i = 1; i <= 9; i++) { 
            for (int j = 1; j <= 9; j++) { 
                System.out.print(i * j + " "); 
            } 
            System.out.println(""); 
        } 
    }
}

/************************************************
1 2 3 4 5 6 7 8 9 
2 4 6 8 10 12 14 16 18 
3 6 9 12 15 18 21 24 27 
4 8 12 16 20 24 28 32 36 
5 10 15 20 25 30 35 40 45 
6 12 18 24 30 36 42 48 54 
7 14 21 28 35 42 49 56 63 
8 16 24 32 40 48 56 64 72 
9 18 27 36 45 54 63 72 81 
*************************************************/
```

##1年経ってStreamAPIを勉強している今同じことをやってみる
できた

```Kuku.java
import java.util.stream.IntStream;

public class Kuku { 
    public static void main(String[] args) { 
  
        IntStream.rangeClosed(1, 9).forEach(i -> {
            IntStream.rangeClosed(1, 9).forEach(j -> System.out.print(i * j + " "));
            System.out.println("");
        });
    }
} 

/************************************************
1 2 3 4 5 6 7 8 9 
2 4 6 8 10 12 14 16 18 
3 6 9 12 15 18 21 24 27 
4 8 12 16 20 24 28 32 36 
5 10 15 20 25 30 35 40 45 
6 12 18 24 30 36 42 48 54 
7 14 21 28 35 42 49 56 63 
8 16 24 32 40 48 56 64 72 
9 18 27 36 45 54 63 72 81 
*************************************************/
```
[Keras]ImageDataGeneratorのchannel_shift_rangeの仕様について

## 概要
`ImageDataGenerator`の`channel_shift_range`について調べたメモです。

## バージョン

```
>>> keras.__version__
'2.1.6-tf'
```

## 出力される画像について

<img width="341" alt="channel_shift.PNG" src="https://qiita-image-store.s3.amazonaws.com/0/42193/cc30c6e3-9164-34df-e199-f641b027c242.png">

こんな感じの画像が出力されます。
最初の三つが元々の画像でその後の画像が生成された画像です。
画像全体が白か黒方向に色が変わっています。
(あれ、googleで調べたときに出てきたのと違う気がする:thinking:)

## 実装

[image_data_generator.py#L772](https://github.com/keras-team/keras-preprocessing/blob/master/keras_preprocessing/image/image_data_generator.py#L772)

```python:image_data_generator.pyより引用
channel_shift_intensity = None
if self.channel_shift_range != 0:
    channel_shift_intensity = np.random.uniform(-self.channel_shift_range,
                                                self.channel_shift_range)
```

`channel_shift_range`の値は`-channel_shift_range`から`channel_shift_range`の間の乱数として使用されているようです。
この乱数`channel_shift_intensity`は以下のような形で使用されています。

[image_data_generator.py#L836](https://github.com/keras-team/keras-preprocessing/blob/master/keras_preprocessing/image/image_data_generator.py#L836)

```python:image_data_generator.pyより引用
if transform_parameters.get('channel_shift_intensity') is not None:
    x = apply_channel_shift(x,
                            transform_parameters['channel_shift_intensity'],
                            img_channel_axis)
```

`apply_channel_shift`の実装は以下のようになっています。

[affine_transformations.py#L162](https://github.com/keras-team/keras-preprocessing/blob/master/keras_preprocessing/image/affine_transformations.py#L162)

```python:affine_transformations.pyより引用
def apply_channel_shift(x, intensity, channel_axis=0):
    """Performs a channel shift.
    # Arguments
        x: Input tensor. Must be 3D.
        intensity: Transformation intensity.
        channel_axis: Index of axis for channels in the input tensor.
    # Returns
        Numpy image tensor.
    """
    x = np.rollaxis(x, channel_axis, 0)
    min_x, max_x = np.min(x), np.max(x)
    channel_images = [
        np.clip(x_channel + intensity,
                min_x,
                max_x)
        for x_channel in x]
    x = np.stack(channel_images, axis=0)
    x = np.rollaxis(x, 0, channel_axis + 1)
    return x
```

単純に各チャンネルに`intensity`を足してクリップしているだけのように見えます。

## 感想

あまり画像処理に詳しくないのでわかりませんが、これってチャンネルシフトなのでしょうか。

これに関して興味深いissueがありました。
[Which one is expected by channel_shift?](https://github.com/keras-team/keras-preprocessing/issues/17)

バグとかではなく意図してこうなっているようです。
マルチプルパイプラインは便利！

logstash 6.3から簡単にパイプラインのプロセスを分けることが可能となった。

kibana6.xで提供されているモニタリングでは
logstash,elasticsearch,kibanaのリソースが確認できる。
初期状態のパイプラインは「main」のみとなっている。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/253680/1f901941-8530-416f-eed1-e9879176c159.png)

これを複数のパイプラインに分けてみたい。
設定は簡単

```
# ls /etc/logstash/
conf.d/              log4j2.properties    logstash.yml.rpmnew  startup.options
jvm.options          logstash.yml         pipelines.yml        test.conf.d/
```

etc配下にある[pipelines.yml]を編集する。
初期configは下記の通り。

```
cat /etc/logstash/pipelines.yml
# This file is where you define your pipelines. You can define multiple.
# For more information on multiple pipelines, see the documentation:
#   https://www.elastic.co/guide/en/logstash/current/multiple-pipelines.html

- pipeline.id: main
  path.config: "/etc/logstash/conf.d/*.conf"
```

モニタリングで確認できるmainという名前のパイプラインのコンフィグファイルがあるディレクトリが記載されている。
新しいパイプラインを追加するには同じように追加すればよい。
今回は[test]を追加してみる。

```
cat /etc/logstash/pipelines.yml
# This file is where you define your pipelines. You can define multiple.
# For more information on multiple pipelines, see the documentation:
#   https://www.elastic.co/guide/en/logstash/current/multiple-pipelines.html

- pipeline.id: main
  path.config: "/etc/logstash/conf.d/*.conf"
  pipeline.workers: 1
- pipeline.id: test
  path.config: "/etc/logstash/test.conf.d/*.conf"
  pipeline.workers: 1
```
新しくコンフィグを格納するディレクトリを作成し、
その配下を指定した[test]パイプラインを作成した。
また。「pipeline.workers: 1」は利用するCPU？コア？を指定できるらしい。

logstashを起動した際にこの「pipelines.yml」から読み込ませる必要がある。
初期設定では

```
cat /etc/logstash/logstash.yml
～
# ------------ Pipeline Configuration Settings --------------
#
# Where to fetch the pipeline configuration for the main pipeline
#
path.config: /etc/logstash/conf.d ★ここ
#
```

mainに設定されているディレクトリが指定されている。
pipeline.ymlの設定を読み込ませるには★ここをコメントアウトすればよい。

あとは
`systemctl restart logstash`

そうするとモニタリングで下記の通り表示される。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/253680/926ad67d-e2f8-e601-a183-4b77a3a4b49d.png)

管理がしやすい
パイプラインごとにリスタート、停止などの操作が可能なはずなため大変便利であるのは間違いない。
【JavaScript】アロー関数の書き方とthisを使う場合の注意点

#アロー関数とは？

[アロー関数 | MDN](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Functions/Arrow_functions)

>アロー関数式 は、その名のとおり矢印を使って記述し、function 式より短い構文で同様な内容を記述することができます。なおthis, arguments, super, new.target を束縛しません。また、アロー関数式は、メソッドでない関数に最適で、コンストラクタとして使うことはできません。

アロー関数とは通常の関数を省略した記法です。
しかし完全に同じという訳ではないため間違いを生んでしまうこともあります。
この記事ではアロー関数の書き方と、関数内でthisを使う場合の注意点について書きました。

## アロー関数の書き方
一例として、数値を受け取り倍にして返す関数を書いて比較してみましょう。
アロー関数では引数を（）で囲った後、=>（アロー）を使って記述します。

```javascript:通常の関数とアロー関数

// 通常の関数
const func = function(number) {
  return number * 2;
};

// アロー関数
const arrowFunc = (number) => {
  return number * 2;
};
```

また、アロー関数はいくつかの条件が揃えばさらに記法を省略することができます。
- 引数が1つであれば（）を省略できる
- 本体が一文の場合ブロックスコープとreturnを省略できる

さきほどのアロー関数もこの条件を満たしているため省略してみましょう。

```javascript:省略したアロー関数

const arrowFunc = number => number * 2;
```
このように短縮することができました。

## アロー関数内でthisを使用する
通常の関数ではthisの値は呼び出される時に決まりますが、アロー関数では関数が宣言された時に決まります。

試しに2つの関数内でthisを使った比較を見てみましょう。

```javascript:通常の関数とアロー関数のthisを比較

const person = {
  age: 20,
  func: function() {
    return this.age;
  },
  arrowFunc: () => {
    return this.age;
  },
};

console.log(person.func()); // 20
console.log(person.arrowFunc()); // undefined
```

上記の場合、アロー関数内のthisはグローバルオブジェクトを参照しているためageがundefinedになってしまいました。
アロー関数は単純な省略記法ではないので注意が必要です。
キャンペーンへの反応予測の閾値の最適化

kaggleの「データセットのローンキャンペーンへの応答」データを使って、ロジスティック回帰のモデルから算出した予測確率の閾値の最適化をします。
https://www.kaggle.com/dineshmk594/loan-campaign

要は、ロジスティック回帰に当てはめたときに、算出された応答確率がいくつ以上のユーザーをキャンペーンの対象にするべきかを最適化します。

データセットを準備していきます。

```python
df = pd.read_csv('PL_XSELL.csv', index_col = 0)
Y = df.TARGET
x = df.drop('TARGET', axis=1）
```

数値ではない値を、OneHotEncodingします。

```python
from sklearn.preprocessing import OneHotEncoder

enc = OneHotEncoder()
x_gender = pd.DataFrame(enc.fit_transform([[g] for g in x.GENDER]).A, columns=['F', 'M', 'O'], index=x.index)
x_occupation = pd.DataFrame(enc.fit_transform([[oc] for oc in x.OCCUPATION]).A, columns=set(x.OCCUPATION), index=x.index)
x_acc_type = pd.DataFrame(enc.fit_transform([[at] for at in x.ACC_TYPE]).A, columns=set(x.ACC_TYPE), index=x.index)
```

`Account Open Date`を今日までの経過日時に変更します。

```python
from datetime import datetime

now = datetime.now()

acc_days = x.ACC_OP_DATE.apply(lambda x : x.replace('-', '/')).apply(lambda x: (now - datetime.strptime(x, '%m/%d/%Y')).days)
x_acc_days = pd.DataFrame(acc_days)
x_acc_days.columns = ['ACC_DAYS']
```

`AGE`列があるので、`AGE_BKT`列はdropします。
上記で前処理したデータを合わせます。

```python
x_ = x.drop(columns=['GENDER', 'OCCUPATION', 'ACC_TYPE', 'AGE_BKT','ACC_OP_DATE'], axis=1)

new_x = pd.concat([x_, x_gender, x_occupation, x_acc_type, x_acc_days], axis=1)
```

モデルに当てはめるために、標準化します。
（本当ならトレーニングセット・テストセットに分けるべきですが、デモで行なっているので、分けずにやります。）

```python
from sklearn.preprocessing import StandardScaler
std = StandardScaler()
X_std = std.fit_transform(new_x)
```

ロジスティック回帰を使って、モデルを学習させます。

```python
from sklearn.linear_model import LogisticRegression
clf = LogisticRegression()
clf.fit(y=Y, X=X_std)
```

1. 閾値を変化させて、`confusion　matrix`作成。
2. 閾値を超えたユーザーを対象にキャンペーンを行うとして、一人当たりのコスト（今回は仮定で`10`）を掛け合わせて総コストを計算。
3. `true　positive`がキャンペーンに応答するので、応答した時の期待値（今回は仮定で`100`）を`true　positive`のサンプル数に掛け合わせて総収入を計算する。
4. 収入とコストの差が利益となる

```python
from sklearn.metrics import confusion_matrix

def generate_confusion_matrix(threshold, y_true, y_prob):
    y_pred = [pred[1] for pred in np.where(y_prob > threshold, 1, 0)]
    return confusion_matrix(y_pred=y_pred, y_true=y_true)

def calculate_profit(c_mat, gain, cost):
    sum_gain = gain * c_mat[1,1]
    sum_cost = cost * sum(c_mat[:,1])
    return sum_gain - sum_cost

y_prob = clf.predict_proba(X_std)
thresholds = np.linspace(0,1)
profits = []
gain = 100
cost = 10
for threshold in thresholds:
    c_mat = generate_confusion_matrix(threshold, y_true=Y, y_prob=y_prob)
    profit = calculate_profit(c_mat, gain, cost)
    profits.append(profit)
```

結果をプロットします。

```python
pd.DataFrame(profits, index=thresholds, columns=['profit']).plot()
```
![ダウンロード.png](https://qiita-image-store.s3.amazonaws.com/0/344470/bbf29d28-5b7f-3ef3-3512-15033899c9af.png)

だいたい0.1くらいが最適な閾値という結果となりました。
メモ：Android Emulatorのブラウザでホストマシンで起動しているサイトのチェックをする場合

javascriptの挙動がPCとスマフォブラウザで違うことはよくある。
PCブラウザで正常に動作しても、デプロイしてスマフォの実機で確認したらちゃんと動かない。。。とか。
とはいえ、こういったことはサーバにデプロイせずともローカルマシンだけで確認したい。

androidの場合は、android emulatorを使えばかなり高い精度で確認ができるのだが、完全にローカルマシンで確認するならAndroid emulatorを起動していPCでnginxなどを起動して確認したい。

anrdroid emulatorから、起動しているPCにアクセスする場合、予約されているIPアドレスを使えばアクセスができる。
マニュアルにはこの辺りに記載されている→[Set up Android Emulator networking  |  Android Developers](https://developer.android.com/studio/run/emulator-networking)

一番よく使いそうなのは、エミュレータが起動しているPCのIPアドレスで、`10.0.2.2`でアクセス可能だ。
SCNTechniqueが[SceneKit] Error: can not render without programs, using defaultと言われて適用できないとき。

SCNTechniqueをSCNViewにセットすると、次のようなエラーが出て真っ暗な画面になる事がある。
 
`[SceneKit] Error: can not render without programs, using default`

？？？という感じでめっちゃハマった。
これはSCNViewのRendering APIがOpenGLESなのにMetalのシェーダを適用しようとしていたり、逆にMetalなのにOpenGL ESのシェーダを適用しようとするとなる。


コードでRenderingAPIを指定する場合は初期化時に指定

```swift
SCNView(frame: .zero, options: [SCNView.Option.preferredRenderingAPI.rawValue: NSNumber(value: SCNRenderingAPI.openGLES2.rawValue)])
```

Storyboardで指定する場合はインスペクタから選択する事ができる。

<img width="260" alt="スクリーンショット 2019-01-21 1.43.30.png" src="https://qiita-image-store.s3.amazonaws.com/0/24979/0313adff-c635-5d45-f53c-89005ead78c8.png">
shopify：商品に付与された tag の有無で要素を出し分ける

商品詳細ページでタグの有無で要素を出し分けたい。

product.tags.sizeでtagsのサイズが0以上ならばtagが存在している。
なので、そいつを使って出し分ける

```
{% if product.tags.size > 0 %}
  // 要素
{% endif %}

```
デフォルトのテンプレート内を見るとサムネイルの出し分けに同じようなコードがあった。

```
 {% if product.images.size > 1 %}
```
画像は１つ以上登録されて入ればサムネイルの一覧を出すという事です。
なるほど。
添付ファイルの後に送られてくるパスワードの意味

#要約
1.メールでパスワード付きzipファイルが送られてきて、後でパスワードを書いたメールが届く、よくあるうんざりした習慣には、エンジニアの直観とはまた違う効果がある。という主張がある。
2.でも、それだったらもっとうまい方法があるだろう？と思う。
3.それ以前にファイルを送る方法としてパスワード付きのzipファイルというのはどうなのか？
#添付ファイルとパスワードを別々に送って来る文化
これは皆様経験していると思う。

1.zipファイルの添付されたメールが飛んでくる。
2.zipファイルのパスワードが書かれたメールが届く。

よく言われるのは、「1のメールが盗まれる場合、2のメールも盗まれるはず」という主張で、これはごもっともだと思う。あえて言うならば、付け加えて「メールが盗まれるような状況なら、他にもっと大事なものを盗まれていないか」心配になるくらいである。

ところが、世の中には、この方式にはちゃんと意味がある。という主張があることに気が付いた。外部サイトの悪口を言う趣味はないので、詳しくは適当にググって欲しい。

※会社の都合でやらされている。って方は、とりあえず「お疲れさまです」とだけ言っておきたいと思います。

#別々に送信することの効果（と主張されるもの）
こういうことのようだ。

1.zipファイルの添付されたメールを送る。
**2.送信先を間違えたことに気が付く。**
3.zipファイルのパスワードを送らなければ、ファイルの中身を見られることはない。

**…いや、これ本当にそういう目的だったのか？**

パスワードがなくとも、肝心のファイルそのものはもはや相手の手元にある。
zipファイルのパスワードなんて、「忘れたときのために解析する」なんてツールが出回っている。ブルートフォースをかけたところで、手元にあるzipファイルなら短時間に大量に試行できるため、非常に効率よくパスワードを破ることができる。
それどころか、zipファイルにパスワードをかけても、**zipファイルの中身にどんなファイルが入っているかは隠蔽されない**という問題がある。ファイル名に重要な文言が付けられている場合、中身が見えなくとも、誤送信された相手はどんなファイルが送られたのか、確認できてしまう。

#いっそのことこうしたらいいのでは
もちろん、これでうまく行くとは思っていないのですが…

1.これから送るファイルのパスワードをメールで送信する。
2.先にパスワードを伝えたファイルをメールで送信する。

このようにした場合、何が起きるだろう？

1.これから送るファイルのパスワードをメールで送信する。
**2.送信先を間違えたことに気が付く。**
3.zipファイルを送らなければ、ファイルの中身を見られることはない。

つまり、逆の手順を使うのだ。

この方が、安全性はずっと高いと思う。相手の手元にファイルを送らなければ、相手はパスワードを破ることも、ファイル名から中身を推測することもできない。

そして大抵の場合、**パスワードを送るメールには大した内容は書いていない。**
少なくとも、「ファイル⇒パスワード」の順よりは「パスワード⇒ファイル」の順の方が、送信のシーケンスが途中で止められた場合、安全であることは間違いない。

**途中で誤送信に気付くケースというのがどれだけあるのかは、ちょっとよくわからないけど。**
#そもそもの話
パスワードをかけたzipファイルがそこまで安全かというと、そんなことはないと思う。
pgpでも使うとか、ファイル交換用のストレージサービスを使うとか[^storage-pass]、もっとマシな方法はいくらでもある。

しかし、どんな手を使ったところで、**どれだけ防護されていても、防護されたリソースが意図しない相手に渡っている時点で、既に重大な流出案件である。**という事実は変わらないと思う。

本当に、このおかしな文化はこれからどうなっていくんだろうか。
[^storage-pass]: 相手とファイルの交換が必要な関係ができた時点、例えばプロジェクト開始時点とかでパスワードを先渡しして使う。という使い方をしたことがある。
[.NET] コードを見直したくなる「値型」等価判定の思わぬ落とし穴（一般編）

値型の等価判定には気をつけるべき点があります。
以下の例で、Assert.IsTrue なら () 内が 真、Assert.IsFalse なら () 内が 偽です。
★印の箇所は注意が必要です。

# ボックス化した値の比較

```c#
int i = 1;
object o1 = i;
object o2 = i;

// Object.Equals が int の Equals を呼び出すので値で比較されます。
Assert.IsTrue(o1.Equals(o2));

// o1 != o2 かつ o1 != null なら上の o1.Equals(o2) と同じ結果となります。
Assert.IsTrue(Object.Equals(o1, o2));
```

ここまではいいでしょう。
次は少し注意が必要です。

```c#
// ★ボックス化（値型 → object）すると参照比較になるので一致しません。
Assert.IsFalse(o1 == o2);

// ★引数として渡されるときにボックス化されるので一致しません。
Assert.IsFalse(Object.ReferenceEquals(1, 1));
Assert.IsFalse(Object.ReferenceEquals(i, i));
```
DataRow の各フィールド値（インデクサ／Itemプロパティ）なども Object 型なので、比較の際は注意しましょう。

# 異なる型の比較
```c#
int i = 1;
long l = 1;

// 比較演算子では、int が long に暗黙的に型変換され、long 同士として比較されます。
Assert.IsTrue(i == l);
Assert.IsTrue(l == i);

// 暗黙の型変換ができるなら Equals で比較できます。
Assert.IsTrue(l.Equals(i));
```

ここまではいいでしょう。
以降は注意が必要です。

```c#
// ★暗黙の型変換ができないと Equals は false を返します。
// コンパイルは通り、例外も発生しないので見逃しがちです。
Assert.IsFalse(i.Equals(l));

// ★異なる型へのボックス化解除は失敗します。
object iBoxed = i;
try
{
   // int 型をボックス化しているので long 型に戻すことはできません。（InvalidCastException が発生）
   bool b = (l == (long)iBoxed);
   Assert.Fail();
}
catch (InvalidCastException) {}
```

おまけです。

```c#
// 実行されるのは Object.Equals です。
// 字面だけ見ると true を期待してしまいそう(?)です。
Assert.IsFalse(Type.Equals(1, 2));
```

# 値型を自作する場合の注意点
値型（struct/Structure）の Equals メソッドは、既定ではリフレクションを使用して全フィールド（自動実装プロパティのバッキングフィールドを含む）を定義された型の Equals メソッドで比較します。
値型を自分で作成する場合、Equals メソッドをオーバーライドすることで、この比較処理をカスタマイズすることができます。

等価演算子（==）を使用するためには、「==」「!=」のオーバーロードを定義する必要があります。

値型を定義する場合には、Equals メソッドのオーバーライドと等価演算子のオーバーロードが推奨されています。

《参考》コード分析（FxCop）
[CA1815: equals および operator equals を値型でオーバーライドします](http://msdn.microsoft.com/ja-jp/library/ms182276.aspx)

---

[.NET] 値型 等価判定の思わぬ落とし穴（一般編）
[[.NET] 値型 等価判定の思わぬ落とし穴（特殊編）](https://qiita.com/CodeOne/items/4e22a1aa1b4d8c90e435)
[[.NET] 参照型 等価判定の思わぬ落とし穴（一般編）](https://qiita.com/CodeOne/items/c0f593c28c08f72d67ad)
[[.NET] 参照型 等価判定の思わぬ落とし穴（特殊編）](https://qiita.com/CodeOne/items/e9ff4d797a19c84231a1)
機械学習勉強会をした後悔より、しなかった後悔の方がきっと大きい

# はじめに

機械学習の知識ゼロベースの自社の社員の方々に対して、機械学習の勉強会をしました。
実際やってみて感じたことをつらつらと語ります。

これから勉強会を開こうかなと考えている方の役に立てたら幸いです。
勉強会で使用した資料はSlideShareに載せてます。自由にパクってもらって構いません。
https://www.slideshare.net/hiroyukikageyama2/machine-learning-128571053

# 勉強会の資料を作る時に気を付けたこと
## ①目標を低めに設定する。
勉強会１回で人間が学べる事など、たかが知れています。
初学者には<strong>「機械学習の大まかなイメージを掴む」</strong>くらいがちょうどいいかなと思ったので
今回はその目標でやってみることにしました。

## ②目標に沿った内容にする。
「機械学習の大まかなイメージを掴む」という初心者向けの目標を設定したのに
パーセプトロンやら誤差逆伝搬法やら、<strong>本で読んででウンザリするような内容</strong>を詳しく取り上げるとかえってややこしくなってしまいます。
そういった内容はなるべく省くか、文脈上どうしても必要な場合は言葉だけ出して簡単に説明してあっさり流すようにしました。

## ③難しい数式は絶対に出さない。
機械学習の勉強になかなか踏み出せないという理由の多くに、数式への苦手意識があると思います。
確かに、機械学習を深く学んでいく上で数学的な理解は必要となってきますが、
初学者にわざわざ数式を見せつけて、ハードルを高く感じさせるのはやめようと思いました。
~~そもそも、私もあまりわかってない。~~

## ④必ず実践を見せる。
SlideShareでは動画を省いていますが、実際には<strong>MNISTの学習処理を実行する様子の動画と、
学習結果を使用して手書き文字を認識させている動画</strong>を参加者に見せています。
実践動画を見せることで、勉強会の中での緩急がつきますし、より食いつきが良かったです。

## ⑤実践で使ったコードを見せる。
実践動画をみせると、<strong>プログラマなら当然プログラムの中身が見たくなります。</strong>
ちゃんと見せられるように準備するとよいでしょう。
実際の機械学習の実装はフレームワークに任せられる部分が多いため、シンプルにコードをまとめていくと
<strong>「これなら私でもできそうだな。」</strong>と感じてもらえるかもしれません。

# 後の酒会にて
勉強会後、酒会にて参加者の方に「勉強会どうでしたか？」と恐る恐る聞いてみたところ、なかなか感触は上々でした。
内容に関しては、気を利かしてくれたのかダメ出しはなく、良かった点だけ教えてもらえました。

<strong>【良かった点】</strong>
・実践動画後にコードを見せてもらえたのが良かった。
→実際にコードを見ることで、実装に対するハードルが少し下がったそうです。

・住宅価格の例で、簡単なパラメータ調整の例（スライドP.11~13）を先に挙げてくれていたこと。
→先に簡単な例を挙げてから、ニューラルネットワークの説明で「さっきの住宅価格でいうと...」、という風に簡単な例に立ち返りながら説明したのが分かりやすかったそうです。

# 最後に
いろいろと準備は大変でしたが、苦労に見合う価値はあったと思います。
<strong>タイトル通り、やるかどうか迷ってるならやっちゃいましょう。</strong>
というか、自分の作ったプレゼンを公開するのってかなり勇気がいるよ（；´Д｀）
Array.prototype.indexOf(NaN)は利用できない。

## indexOfの処理詳細

`Array.prototype.indexOf()`は、配列について与えられた要素と一致する（最初の）添字を返却する。

```
let array = [1,3,5,7,9];
console.log(array.indexOf(5)); // -> 2
```

処理の仕組みとしては、配列内の各要素について`===`で比較したときに一致するものを返却している。

## NaNの一致

上記の仕様を頭に入れたとき、ひとつ注意しないといけないことがある。それがNaNだ。

[NaNの判定について](https://qiita.com/south37/items/e400a3a698957ab4aa7a)でも触れられているように、NaNはNaNと一致しない。
つまり`indexOf`ではNaNを見つけることはできない。

```
console.log(NaN === NaN); // -> false

let array = [1,3,NaN,7,9];
console.log(array.indexOf(NaN)); // -> -1
```

## 結論

`indexOf`の引数がNaNになりそうな場合は要注意。

## 備考

コメント欄で教えていただいたように、Array.prototype.includes(NaN)はtrueになる。
こっちは`===`による比較ではなさそう。

```
let array = [1,3,NaN,7,9];
console.log(array.includes(NaN)); // -> true
```
仮想マシンとは？

ローカル環境を構築するとき、仮想マシンを設定する必要があります。
では、その「仮想マシン」とは一体何でしょうか？

#「仮想化」とは？
「仮想化」とは、物理的な環境にとらわれず、仮想的な環境を作り出すことです。
例えば、サーバーの仮想化は仮想的に作り上げたサーバーを複数稼働させます。
すると、動いているサーバーは一つだけに見えても、実際は複数動いているように見えることを指します。


#「仮想マシン」とは？
では、「仮想マシン」とは一体何でしょうか？
それは、「仮想的に作られたハードウェア」のことを言います。
つまり、先ほどの仮想サーバーのことを表します。
【Ubuntu16.04.5】PythonのFlaskをHTTPS化

# はじめに
WebRTCとOpenCVを使ってリアルタイム映像処理を行おうとしていたところ、PythonのFlaskというフレームワークが便利そうなので使ってみることに。
ただWebRTC用にSSL化するのにちょっと手間取ったので備忘録の意味も含めて。

## 開発環境
- Ubuntu16.04.5(AWS)
- Python3.5.2

## 注意点
あくまで自分で遊ぶ用なので、セキュリティ等は一切考慮しておりません。そのため使う証明書もオレオレ証明書になります。


# 証明書作成
以下のコマンドからopensslのインストールとサーバ証明書と鍵を作成をします。
一応これで10年持つ証明書の完了です。どうせ無料期間終わったら解約するので関係ないですが。

```bash
$ sudo apt install openssl
$ openssl genrsa 2048 > server.key
$ openssl req -new -key server.key > server.csr
$ openssl x509 -days 3650 -req -signkey server.key < server.csr > server.crt
```

これらのファイルは全て`~/openssl`下に置いてあるものとします。

# ソースコード
あとは以下のソースをホームディレクトリに設置して、実行したらhttps化されているはずです。portはお好きに。
ただし実行はroot権限で行ってください。

```python:app.py
# coding: UTF-8

from flask import Flask, render_template, request, redirect, url_for, Response

@api.route("/")
def index():
    return "test\n"

if __name__ == '__main__':
    api.run(host='0.0.0.0', port=334, ssl_context=('openssl/server.crt', 'openssl/server.key'), threaded=True, debug=True)
```

もしかしたらopensslが入ってないと怒られるかもしれないのでその時は
`sudo apt install python3-openssl`
でインストールしてください。

# ハマったところ
## 1.証明書の読み込み
この件について調べてみると大体以下のようなソースが出てくると思います。


```python
from flask import Flask, render_template, request, redirect, url_for, Response
import ssl

context = ssl.SSLContext(ssl.PROTOCOL_TLSv1_2)
context.load_cert_chain('openssl/server.crt', 'openssl/server.key')

@api.route("/")
def index():
    return "test\n"

if __name__ == '__main__':
    api.run(host='0.0.0.0', port=334, ssl_context=context, threaded=True, debug=True)
```

で、これをいざ実行してみようとすると
`Traceback (most recent call last):
  File "app.py", line 14, in <module>
    context.load_cert_chain('openssl/sever.crt', 'openssl/server.key')
FileNotFoundError: [Errno 2] No such file or directory
`
って怒られるんですよね・・・絶対パスに変えてみてもダメ。バージョンで引数変わったのだろうか。ちゃんとファイルはあるのに。
権限とかその辺も全部確認しました。というかそもそも`ssl_context=('openssl/server.crt', 'openssl/server.key')`で読み込めるんだから読めるはずだし。

## 2.Flaskの外部公開
AWSのサーバを使ってるのでサーバを外部公開する必要があります。
それでそこそこ詰まりました。以下を参考にしてください。

[Flaskのサーバーはデフォルトだと公開されてない - Qiita](https://qiita.com/tomboyboy/items/122dfdb41188176e45b5)

#おわりに
これで気兼ねなくWebRTCで遊べます。
そっちの方に関してもまたいつか書こうと思います。

#参考文献
[【flask】Webサーバーをhttps対応する方法 【お家IT#4】 - MotoJapan's Tech-Memo]
(http://motojapan.hateblo.jp/entry/2017/12/14/083635)
[Running Your Flask Application Over HTTPS - miguelgrinberg.com]
(https://blog.miguelgrinberg.com/post/running-your-flask-application-over-https)
AndroidStudio3.3 環境構築メモ

Android Studioの環境構築手順メモ。

尚、各ツールや用語等の説明はありません。
本当にただ構築するためだけのメモ。

### 前提
・初回インストール
・バージョンは3.3
・OSはWin10

## Android Studio環境構築手順

### 1.インストーラをDL
[公式](https://developer.android.com/studio/?hl=ja)からDLする。

### 2.事前準備
1でDLしたインストーラを実行……**する前に、
VT-xを有効にする**。
理由としては、後工程において
Intel x86 Emulator Accelerator(HAXM installer)を正しくインストールするため。
通常であればVT-xが無効化されているとHAXMのインストールに失敗するのだが、
何故か無効化していても**不完全にインストールされてしまう**模様。
不完全にHAXMをインストールすると、AVD実行時に以下のログが出力されて失敗する。

```
emulator: ERROR: x86 emulation currently requires hardware acceleration!
```
その場合はHAXMをアンインストール&再インストールすることになる。

### 3.インストール
1でDLしたインストーラを実行する。
**コンポーネントの選択画面が出たら、
Android Virtual Deviceにもチェックを入れる**。
後は全部デフォルトのまま、画面の流れ通りにNextとInstallを押していく。

### 4.初期設定
インストールが終わったら、
Android Studioを起動する。
初回起動時は、設定のインポート画面が表示される。
デフォルトの「Do not import settings」を選択して
OKを押下すると、セットアップウィザードが表示される。
再びデフォルトのまま、画面の流れに沿ってNextとInstallを押していく。

### 5.初期設定終了
コンポーネントのDL完了画面でFinishを押下すると、
ウェルカム画面が表示される。
これで初期設定は終了。

### 6.SDKを追加DL
以下手順により、SDK PlatformとSDK Toolsを追加DLする。

#### 6-1.SDK Manager起動
ウェルカム画面右下のConfigureをクリック。
開いたメニューからSDK Managerを選択して開く。

#### 6-2.DLするSDK Platformを選択
SDK Platformタブを開いた状態で、
右下のShow Package Detailsにチェックを入れる。
使用したいAPIレベルの以下のチェックボックスを選択する。
・Android SDK Platform
・Sources for Android
・Google APIs Intel x86 Atom System Image

例）APIレベル26-APIレベル28を使用したい場合
![20190120_01.png](https://qiita-image-store.s3.amazonaws.com/0/331751/4eed4751-07cf-fae3-1eae-0b0f204fe490.png)
![20190120_02.png](https://qiita-image-store.s3.amazonaws.com/0/331751/94a5130c-89e5-708a-28c2-fc062f93df40.png)

#### 6-3.DLするSDK Toolsを選択
次はSDK Toolsタブを開き、
右下のShow Package Detailsにチェックを入れる。
以下のチェックボックスを選択する。
・Android SDK Build-Tools
・Android Emulator
・Android SDK Platform-Tools
・Android SDK Tools
・Intel x86 Emulator Accelerator(HAXM installer)
・ConstraintLayout for Android
・Solver for ConstraintLayout
・Android Support Repository
・Google Repository

#### 6-4.DL
OKを押下すると、DLが開始する。

### 7.終了
環境構築は以上で終了。

初回ビルドは時間がかかるため、動作確認はお時間がある時にでも。
お疲れさまでした。
Arduino Uno 互換品を使おうとした際に、Mac(OS:Siera)上のArduino IDEからシリアルデバイスが見つからない問題を解決した件について

# 概要
Arduino Uno 互換品を使おうとした際に、Mac(OS:Siera)上のArduino IDEからシリアルデバイスが見つからない問題を解決した件について記載します。

Arduino Uno 互換品は下記を使用しました。
HiLetgo® 2個セット NEWバーション UNO R3 ATmega328P USB CH340G Arduinoと互換性 + USB ケーブル
https://www.amazon.co.jp/gp/product/B013QV28CW/ref=ppx_yo_dt_b_asin_title_o05__o00_s01?ie=UTF8&psc=1

# 問題発生時の状況
Arduino Uno 互換品をMac(OS:Siera)に接続しましたが、Arduino IDEからシリアルポートが見つかりませんでした。

<img width="540" alt="001.png" src="https://qiita-image-store.s3.amazonaws.com/0/344880/d6ebfe31-330c-94ab-2717-785566402c0a.png">

# 解決策
下記にあるドライバをインストールして解決しました。
（Arduino互換品のUSB接続に使われているCH340チップのドライバを手動で導入する必要があるようです。）

Signed Mac OS Driver for Winchiphead CH340 serial bridge – Björn’s Techblog
https://blog.sengotta.net/signed-mac-os-driver-for-winchiphead-ch340-serial-bridge/

→上記サイトの下記リンクからドライバをインストール
CH341SER_MAC-1.4


# インストール手順
前述のサイトへ移動してドライバをダウンロード
![002.png](https://qiita-image-store.s3.amazonaws.com/0/344880/1bf03d3a-422c-501d-969d-d232de503511.png)
pkgファイルを実行
![003.png](https://qiita-image-store.s3.amazonaws.com/0/344880/1ab4e1e6-b9ae-bc1c-c6cb-d02a1b83b539.png)
続ける
![004.png](https://qiita-image-store.s3.amazonaws.com/0/344880/38a9b32f-aa94-533c-da28-41bb9050698e.png)
インストール
![005.png](https://qiita-image-store.s3.amazonaws.com/0/344880/1a1a51b1-0f62-cc95-1196-5f5e106b8797.png)
インストール完了を待つ
![006.png](https://qiita-image-store.s3.amazonaws.com/0/344880/b01ea8d8-4940-05a2-360f-b91ab332335c.png)
もし読み込みがブロックされた場合は、許可を行ってインストール継続
![007.png](https://qiita-image-store.s3.amazonaws.com/0/344880/2df94430-0e9f-60d9-42e9-97cedbb7ae10.png)
再起動後にArduino IDEを起動すると、シリアルデバイスを見つけることができました。
<img width="540" alt="009.png" src="https://qiita-image-store.s3.amazonaws.com/0/344880/807746ab-0948-bff2-2d2c-1896b257a82d.png">



# まとめ
Arduino Uno 互換品を使おうとしたにも関わらず、
Arduino IDEからシリアルデバイスが見つからない問題の解決策について記載しました。
（本件は、Arduino Uno 互換品を使いましたがUno 互換品だけの問題ではなさそうです）

# 参考
下記を参考にさせて頂きました。
- Signed Mac OS Driver for Winchiphead CH340 serial bridge – Björn’s Techblog
https://blog.sengotta.net/signed-mac-os-driver-for-winchiphead-ch340-serial-bridge/
- 激安ArduinoをMac(Sierra)で使ってハマったこと
https://qiita.com/dobnezmi/items/c5beebab7cb6bb42f606
- Arduino互換品がMacで認識されない問題の解決
https://qiita.com/malta/items/3b9f7c77ab7ab834723e

# 環境
OS：Siera
バージョン：10.13.6
Arduino IDE：1.8.7
レジスタ指定でアドレスジャンプさせてみる

Windows 10(64bit版)のClangでアセンブラコードを書いてみましたという話です。

# Clangにおけるアセンブラコード

GCC互換です。つまりclangにGASのソースコードを渡すとコンパイルすることができます。また、clangに`clang -S hoge.c`などと書いてコンパイルするとclangでディスアセンブルしたコード(.s)が得られます。つまりこいつに適当なCの関数を与えてやってGASの書き方を学べばClang用アセンブラコードを書くことができます。

# アセンブラプログラミングはそんなに楽じゃない

- ~~ラベルの値をレジスタに代入することができません。ラベルの値はアドレス値ですが、アドレス値はプログラムがロードされるときに決定されるのでラベルのアドレス値を静的領域に置いてやる必要があります。レジスタにラベルの値を読ませるときは、代わりに静的領域のデータを読んでやります。~~ (2019.1.24 追記 RIPレジスタ(プログラムカウンタ)の間接アドレッシングを使えば簡単に実現できます。これは@fujitanozomuさんの再帰的な関数`hoge`のディスアセンブルによって示されていますが私はすぐにそのことに気が付くことができませんでした)

- ~~ラベル同士の引き算ができない。なぜ！？すれよ！！！なぜか分かりませんがGASだとできないようです(NASMだとできるのかも…)。ラベル同士の引き算をしてくれると64bitのアドレス値を16bit以内に圧縮することができます。今回はそれを試みましたが失敗しました。~~ 16bitイミディエイトへの代入はできないが16bitの静的領域への代入は可能 (2019.1.23 @fujitanozomuさんのご指摘により修正)

# 作成したコード

作成したコードを示します。

```test1.c
#include <stdio.h>

extern void proc1(void); // proc1.sで定義されている
extern long long int debug;

int main() {
    printf("start program\n");
    proc1();
    printf("end program\n");
    return 0;
}
```

```proc1.s
#
# proc1.s
#

	.text
	.intel_syntax noprefix

# proc1
	.globl proc1
	.p2align	4, 0x90
proc1:
.seh_proc proc1
	push	rax
	push	rbx
	sub	rsp, 40
	.seh_stackalloc 40
	.seh_endprologue
	xor	rax, rax
	mov	ax, word ptr [rip + toOffset]
	add	rax, qword ptr [rip + fromAddress]
	jmp	rax
from:

	.p2align 8, 0x00 # 失敗する命令列
to:
	add	rsp, 40
	pop	rbx
	pop	rax
	ret
	.seh_handlerdata
	.text
	.seh_endproc
	
	.bss
	.data
fromAddress:
	.quad	from
toOffset:
	.word	to - from
```

## ビルドコマンド

```
clang test1.c proc1.s -o test1.exe
```

## 実行結果

```
start program
end program

```

# より簡約したバージョン (2019.1.24 追記)

下記コメントの`hoge`関数を`-masm=intel`オプションでディスアセンブルすると`lea [rip + hoge]`が得られます。従って`proc1.s`のコードは`proc1b.s`のように簡約することができます。

```proc1b.s
#
# proc1b.s
#

	.text
	.intel_syntax noprefix

# proc1
	.globl proc1
	.p2align	4, 0x90
proc1:
.seh_proc proc1
	push	rax
	sub	rsp, 40
	.seh_stackalloc 40
	.seh_endprologue
	lea	rax, [rip + to]
	jmp	rax

	.p2align 8, 0x00 # 失敗する命令列
to:
	add	rsp, 40
	pop	rax
	ret
	.seh_handlerdata
	.text
	.seh_endproc
	
	.bss
	.data
```

静的領域ではラベル同士の演算を行うことはできるのですが、オペランドにではできないようです。たとえば`lea rax, [rip + to - from]`はエラーになります。
laravel開発向けのdocker全部入りのlaradockのメモ

### laradockとは？
[laradock](https://laradock.io/)

laravelだけじゃなくて、開発のときに利用する周りのリソースDB,キャッシュとかのDockerfileの詰め合わせみたいなものです。
docker-composeコマンドだけで開発環境ができてしまって便利。
とりあえずPHPで何か開発しようかー。ってときに自分で環境を準備するんではなくて、これをベースに始めるのがいい感じ。


### 対応しているもの
公式ドキュメントのSupported Software (Images)に書いてあるんですが、おそらくこれだけあれば開発目的には足りるだろうという感じです。

```
Supported Software (Images)
In adhering to the separation of concerns principle as promoted by Docker, Laradock runs each software on its own Container. You can turn On/Off as many instances of as any container without worrying about the configurations, everything works like a charm.

Database Engines: MySQL - MariaDB - Percona - MongoDB - Neo4j - RethinkDB - MSSQL - PostgreSQL - Postgres-PostGIS.
Database Management: PhpMyAdmin - Adminer - PgAdmin
Cache Engines: Redis - Memcached - Aerospike
PHP Servers: NGINX - Apache2 - Caddy
PHP Compilers: PHP FPM - HHVM
Message Queueing: Beanstalkd - RabbitMQ - PHP Worker
Queueing Management: Beanstalkd Console - RabbitMQ Console
```


### はじめかた
```
$ git clone https://github.com/laradock/laradock.git
$ cd laradock
$ cp env-example .env
$ docker-compose up -d nginx mysql phpmyadmin redis workspace
```

これをするだけで、nginx, mysql, phpmyadmin, redis, workspace(開発用のphpunitとか入ってくるやつ)のイメージが起動します。


### PHP-CLIのバージョンを変更する
イメージの設定を変えたい場合は直接docker-compose.ymlを編集することはせずに、.envファイルを修正します。
例えばPHP-CLIのバージョンを変えたい場合は、

```
1. .envファイルを開く
2. PHP_VERSIONを探す
3. 指定のバージョンへ変更
  PHP_VERSION = 7.2
4. buildし直す
  docker-compose build workspace
```

の流れになります。また、各イメージのDockerfileの下に設定ファイル用のディレクトリが置いてあって、DockerImageとVolumeで共有されていて、
設定ファイルなどはそこに配置するようになってます。

PHPの環境がサクッとできてしまうのも便利なのですが、これを使っていくとDockerの使い方の理解も深まっていく感じでとてもよかったです。
ページ内リンクが固定ヘッダーに被るのをJavaScript(not jQuery)で解決する

よくこういう記事の目次とかページ内の見出しに飛ぶようなリンクありますよね？
<a href="https://hotokami.jp/articles/10/"><img width="1680" alt="スクリーンショット 2019-01-20 23.50.32.png" src="https://qiita-image-store.s3.amazonaws.com/0/169644/afc795ed-9e3a-576b-7c81-736b779b3e99.png"></a>
こういうhrefに飛びたい位置の要素のid名を指定したリンクを「アンカーリンク」と呼ぶそうです。

ただこのリンク、ページ上部にfixedなどで固定したヘッダーがあるとうまく飛ばないことがよく起きます。
<img width="1146" alt="スクリーンショット 2019-01-20 23.53.05.png" src="https://qiita-image-store.s3.amazonaws.com/0/169644/b8679421-a0a4-8580-2d74-1088d9207dca.png">
巷では、スムーススクロールと併せてjQueryで解決する例が溢れているので、今回はこれをJavaScriptで解決してみます。

# JavaScriptを使わなくても解決できる
「今回はこれをJavaScriptで解決してみます。」と言いましたが、基本的にはJavaScriptを使わなくても解決できます。

```css
padding-top: 50px;
margin-top: -50px;
```
これを飛びたい先の要素(見出しなど)に指定すればいいわけですが、デザインなどの都合でどうしてもこれを適用できないとか、CSS調整するのめんどくさい時とかあると思います。
そういう時にCSS・jQueryなしで使えるコードを作ってみました。

# 実際のコード

```JavaScript
document.addEventListener('window.onload', () => {
    let headH = document.getElementsByTagName('header')[0].offsetHeight + 10;  //ヘッダーの高さを取得
    mokujiLink(headH);
});
function mokujiLink(headH = 0) {
    for (let i = 0; i < document.querySelectorAll('a[href^="#"]').length; i++) {
        let lect = window.pageYOffset + document.getElementById(document.querySelectorAll('a[href^="#"]')[i].getAttribute("href").replace('#', '')).getBoundingClientRect().top - headH;
        document.querySelectorAll('a[href^="#"]')[i].setAttribute("onClick", 'window.scrollTo(0,'+lect+')');
        document.querySelectorAll('a[href^="#"]')[i].removeAttribute("href")
    }
}
```
`document.querySelectorAll('a[href^="#"]')`でページ内の全てのアンカーリンクを取得します。

飛ぶ位置を、ヘッダー要素の高さ分引いて調整することで被らないようにしています。

アンカーリンクの数だけfor文で「所定のid要素にscrollするonclick」をaddしているわけです。

シンプルですね。

ただ、TurbolinksやService Workerなど、ページの読み込みをXHRで行なっている場合は正しい動作をしないことがあるので、注意してください。

また、もっといいやり方があったら、ぜひコメント欄で教えてください。

ありがとうございました。
Kibana(Amazon Elasticsearch Service)へApache2.4でProxy接続

作業メモベースですがどなたかのお役に立てば。

## やりたいこと
・Amazon Elasticsearch Serviceに同梱されているKibanaに認証をつけたい
・上記認証にcognitoは利用しない
・経路はhttpd2.4をProxyとして利用portベースのvirtualhostで受ける
・ApacheのBasic認証で受ける

## 環境
・Red Hat Enterprise Linux Server release 7.6 (Maipo)
・Server version: Apache/2.4.6 (Red Hat Enterprise Linux)

### 認証とProxy経路の確保

・準備

```bash
yum install mod_ssl　-y
mkdir /var/www/px/_plugin/kibana
```

・認証

```bash
htpasswd -c /etc/httpd/conf/.htpasswd aaa
# New password:
# Re-type new password:
# Adding password for user aaa
```
・Proxy

```apache:/etc/httpd/conf.d/es.conf

Listen 8090
<VirtualHost *:8090>
  DocumentRoot /var/www/px
  SSLEngine on
  SSLProtocol all -SSLv3
  SSLCipherSuite HIGH:MEDIUM:!aNULL:!MD5
  SSLCertificateFile /etc/pki/certs/server.crt
  SSLCertificateKeyFile /etc/pki/private/server.key

  <Directory "/var/www/px/_plugin/kibana">
        AuthUserFile /etc/httpd/conf/.htpasswd
        AuthGroupFile /dev/null
        AuthName "auth"
        AuthType Basic
        Require valid-user
  </Directory>

RewriteEngine On
RequestHeader unset Authorization
RewriteCond %{LA-U:REMOTE_USER} !^$
# RewriteCond %{QUERY_STRING} !method=PUT
# QueryでDELETE methodを発行するものはブロック
RewriteCond %{QUERY_STRING} !method=DELETE
RewriteRule  ^/_plugin/kibana(.*)$ http://{Es-Vpc-Endpoint}/_plugin/kibana$1 [P]

</VirtualHost>
```
PyWaveletを使ったDWTへの入り口（1）

#PyWaveletについての備忘録
- 音声信号に離散ウェーブレット変換をかけたくなったのでとりあえず調査
- 今回使いたいマザーウェーブレットはDaubechiesウェーブレット
- DaubechiesウェーブレットObjectを作成するまで

##Waveletオブジェクトのビルド
Pywaveletではウェーブレットをオブジェクトとして作成する。
使えるウェーブレットはpywt.familiesの中に入ってる。

```python
import pywt
pywt.families()
#['haar', 'db', 'sym', 'coif', 'bior', 'rbio', 'dmey', 'gaus', 'mexh', 'morl', 'cgau', 'shan', 'fbsp', 'cmor']

for family in pywt.families():
    print ("%s family:" %family + ",".join(pywt.wavelist(family)))
# haar family:haar
# db family:db1,db2,db3,db4,db5,db6,db7,db8,db9,db10,db11,db12,db13,db14,db15,db16,db17,db18,db19,db20,db21,db22,db23,db24,db25,db26,db27,db28,db29,db30,db31,db32,db33,db34,db35,db36,db37,db38
# sym family:sym2,sym3,sym4,sym5,sym6,sym7,sym8,sym9,sym10,sym11,sym12,sym13,sym14,sym15,sym16,sym17,sym18,sym19,sym20
# coif family:coif1,coif2,coif3,coif4,coif5,coif6,coif7,coif8,coif9,coif10,coif11,coif12,coif13,coif14,coif15,coif16,coif17
# bior family:bior1.1,bior1.3,bior1.5,bior2.2,bior2.4,bior2.6,bior2.8,bior3.1,bior3.3,bior3.5,bior3.7,bior3.9,bior4.4,bior5.5,bior6.8
# rbio family:rbio1.1,rbio1.3,rbio1.5,rbio2.2,rbio2.4,rbio2.6,rbio2.8,rbio3.1,rbio3.3,rbio3.5,rbio3.7,rbio3.9,rbio4.4,rbio5.5,rbio6.8
# dmey family:dmey
# gaus family:gaus1,gaus2,gaus3,gaus4,gaus5,gaus6,gaus7,gaus8
# mexh family:mexh
# morl family:morl
# cgau family:cgau1,cgau2,cgau3,cgau4,cgau5,cgau6,cgau7,cgau8
# shan family:shan
# fbsp family:fbsp
# cmor family:cmor
```
各familyには数種類のウェーブレットが存在（おそらく長さが違う）。
試しにdb3のウェーブレットObjectを作ってみる。
printを実行すると作成したウェーブレットObjectの名称や特性などが出力される。

```python
w = pywt.Wavelet("db3")
print w
# Wavelet db3
#   Family name:    Daubechies
#   Short name:     db
#   Filters length: 6
#   Orthogonal:     True
#   Biorthogonal:   True
#   Symmetry:       asymmetric
#   DWT:            True
#   CWT:            False
```
同様にdb5を作ってみる。

```python
w = pywt.Wavelet("db5")
print w
# Wavelet db5
#   Family name:    Daubechies
#   Short name:     db
#   Filters length: 10
#   Orthogonal:     True
#   Biorthogonal:   True
#   Symmetry:       asymmetric
#   DWT:            True
#   CWT:            False
```
Filter lengthが名前の数字の2倍になるらしい。

各要素の説明
- Family name: ウェーブレットの種類
- Short name: ウェーブレットの略称
- Filter length:展開の次数らしい。いまいち良くわからない。*
- Orthogonal:直交性を持つか否か。
- Biorthogonal:双直交性を持つか否か。
- Symmetry:対称性を持つか否か。
- DWT:DWTに使えるか否か。（明記されてないため間違ってるかも）
- CWT:CWTに使えるか否か。（DWTと同様に明記されていない）

*追記：次数の大きいものほど変化率の大きな部分のみを抽出できるらしい
##まとめ

- PywaveletのAPIドキュメントをとりあえず和訳
- ウェーブレットObjectの生成ができたらしい

書いてる途中に色々わからないことが出てきて、調べるうちにさらにわからなくなった。
とりあえず今回はここら辺で。。
VuetifyをStorybookで動かすための設定

vue-cliを使ってサクッとお試しで触ろうと思ったのにハマってしまったのでまとめておきます。

環境はvue-cli uiを使ってインストールしました。

## 環境

| CLI Or CLI-PLUGIN | インストールされたライブラリ | バージョン  |
|---|---|---|
|vue-cli(3.4.0)  | vue | 2.6.2  |
|vue-cli-plugin-storybook(0.5.1)  | @storybook/vue | 4.1.11  |
|vue-cli-plugin-vuetify(0.4.6)  | vuetify | 1.5.0  |

## 設定

```js:config/storybook/config.js
// 以下のコードを追加する
import Vue from 'vue';
// webpackで読み込めるように、ビルドされたmin.jsとmin.cssを読み込む
import Vuetify from 'vuetify/dist/vuetify.min';
import 'vuetify/dist/vuetify.min.css';

// Themeの設定を行っている場合は同様の設定を行う。
Vue.use(Vuetify, {
  iconfont: 'md',
});
```

```html:config/storybook/config.js
<head>
  <link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto:100,300,400,500,700,900">
  <link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Material+Icons">
</head>

```

## 補足
vue-cli-plugin-vuetifyを使ってインストールすると、下記のような`src/plugins/vuetify.ts`が作成される

```ts:vuetify.ts
import Vue from 'vue';
import Vuetify from 'vuetify/lib';
import 'vuetify/src/stylus/app.styl';

Vue.use(Vuetify, {
  iconfont: 'md',
});
```

TypeScriptプロジェクトの場合、storybookのwebpackでビルドできないので、Vuetifyが使用できない。ビルド後のjs, cssを読み込むことで回避可能。

## 最後に
storybookの4系だとwebpackのデフォルトを上書きしたいのに、webpack.configがどこにあるかわからない...:cry:
picoCTF 2018 HEEEEEEERE'S Johnny! - Points: 100

#問題

https://2018game.picoctf.com/problems

![image.png](https://qiita-image-store.s3.amazonaws.com/0/17681/85e5adcb-b594-bda4-0dc0-5af40d98836d.png)

#解いてみた

ncで接続してみます。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/17681/626371a4-a65f-51ea-6371-c1c7991739a6.png)

アクセスするとログインを求められます。
shadowファイルからjohnしてみます。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/17681/32bac555-5719-7201-0bbc-be641004932f.png)

ということで、パスワードはhellokittyです。
これでログインしてみます。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/17681/48558d8d-490d-182b-7387-81578fd3d33a.png)

できた。