OmniAICreator/Qiita-1.07M huggingface dataset:
Entity Framework core関連の処理をIn Memory DBを利用してテストする

#環境
Asp.Net Core 2.0.8
.Net Core 2.0
Entity Framework core 2.0.2
mssqllocaldb
MSTest

#プロダクトコード
##DataModelを作成

```csharp:User.cs


    public partial class User
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public bool IsEnabled { get; set; }
    }

```

##DBContextを作成

```csharp:HogeDbContext.cs

    public partial class HogeDbContext : DbContext
    {
       public virtual DbSet<User> User { get; set; }
       
       public HogeDbContext(DbContextOptions<HogeDbContext> option) : base(option) { }
    }

```

##DB ContextをDIコンテナに登録

```csharp:Start.cs
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddDbContext<HogeDbContext>(options => options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));
            services.AddMvc();
        }
```

##appsettings.JsonにDB接続文字列を設定

```json:appsettings.json
{
  "ConnectionStrings": {
    "DefaultConnection": "Server=(localdb)\\mssqllocaldb;Database=Hoge;Trusted_Connection=True;"
  }
}
```

##テスト対象
```csharp:HogeLogic.cs
    public interface IUserlogic
    {
        IEnumerable<User> Get(); 
    }

    public class UserLogic
    {
        private HogeDbContext _dbContext;

        public UserLogic(HogeDbContext dbContext)
        {
            _dbContext = dbContext;
        }

        public IEnumerable<User> Get()
        {
            return _dbContext.User.Where(u => u.IsEnabled);
        }
    }
```

#テストコード
```csharp:UserLogicTests.cs
    [TestClass]
    public class UserLogicTests
    {

        [ClassInitialize]
        public static void ClassInitialize(TestContext testContext)
        {
            var options = new DbContextOptionsBuilder<HogeDbContext>()
                .UseInMemoryDatabase(databaseName: "Hoge")
                .EnableSensitiveDataLogging()
                .Options;
            using(var context = HogeDbContext(options))
            {
                context.User.Add(new User { Id = 1, Name="TestName1", IsEnabled = true});
                context.User.Add(new User { Id = 2, Name="TestName2", IsEnabled = false});
                context.SaveChanges();
            }
        }

        [TestMethod]
        public void 正常系_Get()
        {
            // arrange
            var options = new DbContextOptionsBuilder<HogeDbContext>()
                .UseInMemoryDatabase(databaseName: "Hoge")
                .EnableSensitiveDataLogging()
                .Options;

            
            using(var context = HogeDbContext(options))
            {
                // act
                var target = new UserLogic(context)
                var result = target.Get();                

                // assert
                Assert.IsNotNull(result);
                Assert.AreEqual(1, result.Count());
                Assert.IsTrue(result.Any(r => r.Id == 1 && r.Name == "TestName1"));
            }
        }
    }
```

In Memory DBを利用するように設定したDbContextOptionをコンスタントに渡すことで、
テスト時にIn Memory DBを利用できる。

DIコンテナ利用しない場合はDbContextのコンストラクタで良しなにすれば同様に
In Memory DBがテストで利用できる。
You may not change the shell for 'XXXXX'. でシェルの変更ができない場合

# 環境

* Amazon Lightsail
* Ubuntu16.04

デフォルトで存在するユーザー(ubuntu)とは別にユーザーを作成。
仮にユーザー名を `sample` とする。

# デフォルトのシェルを確認

```
$ echo $SHELL
/bin/sh
```

# シェルを変更しようとしたらできなかった

```
$ chsh -s /bin/bash
You may not change the shell for 'sample'.
```

# sudoの権限のあるユーザーで変更する

```
$ sudo usermod -s /bin/bash sample
```

# デフォルトのシェルを確認

一度、ログアウトしてから確認する

```
$ echo $SHELL
/bin/bash
```

# 参考URL

https://superuser.com/questions/119179/how-can-i-change-shell-in-ubuntu#answer-119216
ChainerCV YOLO 動かしてみた

# 要約
- ChainerCVでもYOLOを利用できるようになった
- 2018/05/16時点ではソースコードからインストールを行う必要がある
- YOLOv2・YOLOv3の2種類が準備されている

# 概要
- [ChainerCV](http://chainercv.readthedocs.io/en/stable)([github](https://github.com/chainer/chainercv))にてYOLOが利用できるようになったらしいので動かしてみた

# 環境
- OS: Windows 10 1803 WSL Ubuntu18.04
- python: 3.6.5
- pip: 10.0.1

# 準備
- 2018/05/16時点の最新バージョンである0.9.0にはまだ組み込まれていなかった
- リポジトリでは[YOLOのモデル](https://github.com/chainer/chainercv/tree/master/chainercv/links/model/yolo)を見つけられたのでソースコードからのインストールを試みた

```shell
$ git clone https://github.com/chainer/chainercv
$ cd chainercv
$ pip install -e .
```

# 認識
- どこかで見たことのある以下の画像を認識させた

![sample.jpg](https://qiita-image-store.s3.amazonaws.com/0/240076/b7cac0af-bb9a-de8d-fd16-dcc40c557351.jpeg)

- 認識は[公式のサンプルコード](https://github.com/chainer/chainercv/blob/master/examples/yolo/demo.py)(わずか46行!!)により行った

## YOLOv2
```shell
$ python examples/yolo/demo.py sample.jpg
```
![sample_yolov2.jpeg](https://qiita-image-store.s3.amazonaws.com/0/240076/d87557f9-4337-d40c-fa69-3f1be8065b43.jpeg)

## YOLOv3

```shell
$ python examples/yolo/demo.py sample.jpg --model yolo_v3
```
![sample_yolov3.jpeg](https://qiita-image-store.s3.amazonaws.com/0/240076/267b4c0c-502a-55bc-1476-b380fb2ad528.jpeg)
devise_token_authでunauthenticatedなエラー時のレスポンスをカスタマイズする

devise_token_authのgemでアクセストークンなどをヘッダーに送る際、それがエラーになった場合のレスポンスは動的に、`render_authenticate_error`メソッドによって作られている。

https://github.com/lynndylanhurley/devise_token_auth/blob/v0.1.43/lib/devise_token_auth/controllers/helpers.rb#L134-L137

一番手っ取り早いのは該当するControllerでoverrideしてあげればとりあえずカスタマイズできる。

```ruby
class Api::ApplicationController < ActionController::API
  include DeviseTokenAuth::Concerns::SetUserByToken

  def render_authenticate_error
    render json: {
        errors: [{
          title: I18n.t('devise.failure.unauthenticated')
        }]
    }, status: 401
  end
end
```
AlexaSkillのnode.js(V2)で類義語を固定で取得する

`alexa-skills-kit-sdk-for-nodejs(ask-sdk)`にて`スロット`を取得しようとした時、基本的には以下のようにとってた

```js
const request = handlerInput.requestEnvelope.request; 
var slots = request.intent.slots.slotsName.value; // slotsNameというスロットを取得
```

しかし、これはユーザーが発したスロットをアレクサが聞き取った単語をそのまま取得する方法である。
しかし、ASKのスロットには`類義語`と`ID`を設定することができる。

例えば、`fruit`スロットが`オレンジ`で設定しているものがあった時、以下のような類義語とIDを設定したりできる。

```
fruitスロット
オレンジ

[類義語]
おれんじ
みかん
ミカン
蜜柑

[id]
orange
```

この時、ユーザーがfruitスロットのところに`蜜柑`と言った時、上記のコードでは`蜜柑`と取得する。
しかし、スロットを固定で取得したかったり、idで取得したかったりする場合は以下のうように取得できる

```js
const request = handlerInput.requestEnvelope.request; 

var slotsValue = request.intent.slots.fruit.resolutions.resolutionsPerAuthority[0].values[0].value.name; // 蜜柑
var slotsId = request.intent.slots.fruit.resolutions.resolutionsPerAuthority[0].values[0].value.id; // orange
```
preseed.cfgでraid設定

preseed.cfgのUEFI環境RAID設定での備忘録です。
一見、冗長に見える項目も以下のように全て設定しないとセットアップに失敗します。

```text:preseed_debian_raid.cfg
# == Partitioning =============================================================
  d-i partman-efi/non_efi_system boolean true
  d-i partman/confirm_nooverwrite boolean true
  d-i partman/confirm boolean true
  d-i partman/choose_partition select finish
  d-i partman-partitioning/confirm_write_new_label boolean true
  d-i partman-md/device_remove_md boolean true
  d-i partman-md/confirm boolean true
  d-i partman-lvm/device_remove_lvm boolean true
  d-i partman-lvm/confirm_nooverwrite boolean true
  d-i partman-lvm/confirm boolean true
  d-i mdadm/boot_degraded boolean true
# -- raid / uefi / lvm / hdd * 4 ----------------------------------------------
  d-i partman-auto/method string raid
  d-i partman-auto/disk string /dev/sda /dev/sdb /dev/sdc /dev/sdd
# -----------------------------------------------------------------------------
  d-i partman-auto/expert_recipe string multiraid :: \
      256 1 1024 fat32 $gptonly{ } $primary{ } $lvmignore{ } method{ efi }    format{ } . \
      256 2 1024 raid              $primary{ } $lvmignore{ } method{ raid } . \
      512 3   -1 raid              $primary{ } $lvmignore{ } method{ raid } . \
     100% 4 300% linux-swap  $defaultignore{ } $lvmok{ }     method{ swap }   format{ } lv_name{ swap } . \
    20480 5   -1 ext4        $defaultignore{ } $lvmok{ }     method{ format } format{ } lv_name{ root } use_filesystem{ } filesystem{ ext4 } mountpoint{ / } . 
# -----------------------------------------------------------------------------
  d-i partman-auto-raid/recipe string \
    1 4 0 ext4 /boot /dev/sda2#/dev/sdb2#/dev/sdc2#/dev/sdd2 . \
    5 4 0 lvm  -     /dev/sda3#/dev/sdb3#/dev/sdc3#/dev/sdd3 .
```
Activityのインスタンス破棄対策ライブラリFridge

#Fridgeとは

AndroidのActivityの破棄復元対策のライブラリです。
AndroidのActivityやFragmentはシステムによって破棄-復元されるのでプログラマは必要に応じて値を退避・復元します。
自前で書くと `onSavedInstanceState` で退避処理をして `onCreate` などで復元処理をしますが、対象のフィールドが多いと似たような処理を大量に書く必要があって面倒なので、ライブラリを導入して楽をします。

有名なライブラリに [Icepick](https://github.com/frankiesardo/icepick) があります。

## Icepickとの違い
Icepickはアノテーションプロセッサで退避復元のためのコードを生成しますが、Fridgeはランタイムでアノテーションを解析して退避復元処理をします。

Icepickはサイズが大きいですが、Fridgeはたったの3ファイルですので軽量です。

##名前の由来
大昔のActivityの破棄・復元に関するBundleの変数名は`savedInstanceState`でなく、`icicle`(つらら)でした。
有名なライブラリも`Icepick`（アイスピック）でしたので、このライブラリは冷蔵庫を意味する `Fridge` としました。

#導入

##Gradle
###プロジェクトのbuild.gradle
jitpackで配布しているので以下を追加

```
allprojects {
    repositories {
        maven { url 'https://jitpack.io' }
    }
}
```
###モジュールのbuild.gradle
appなどのモジュールのdependenciesにライブラリを指定

```
dependencies {
    implementation 'com.github.SaikoRobot:Fridge:0.2.0'
}
```
## 使い方
基本的に Icepickと同じです

```MainActivity.java
public class MainActivity extends Activity {

    private int nonStateValue;

    @State
    private int stateValue;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Fridge.restoreInstanceState(this, savedInstanceState);
    }

    @Override
    protected void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        Fridge.saveInstanceState(this, outState);
    }
}

```
#source
[Fridge](https://github.com/SaikoRobot/Fridge)
vueでv-modelをネストして使いたい

```vuejs:親Component
<template>
  <child-component
    v-model="text"
  />
</template>

<script>
export default {
  data() {
    return {    
      text: ''
    }
  }
}
</script>
```

```vuejs:child-component
<template>
  <mago-component
    v-model="localValue"
  />
</template>

<script>
export default {
  props: {
    value: {
      type: String
    }
  },
  computed: {
    localValue: {
      get() {
        return this.value
      },
      set(value) {
        this.$emit('input', value)
      }
    }
  }
}
</script>
```

子Componentでgetterとsetterを指定してあげればよかった。

これで無限にネストできる。

参考
[コンポーネントで-v-model-を使う](https://jp.vuejs.org/v2/guide/components.html#%E3%82%B3%E3%83%B3%E3%83%9D%E3%83%BC%E3%83%8D%E3%83%B3%E3%83%88%E3%81%A7-v-model-%E3%82%92%E4%BD%BF%E3%81%86)
catapult-server 構築奮闘記（未完成）

#速報

こちらのdockerファイルでビルドが通ったとのことです！
https://github.com/daoka/catapult-docker

以下の記事はお忘れください。



catapult-server をインストールするための奮闘記（未完成）
AWS EC2 amazon linuxターゲットです。
依存ライブラリのインストールは終了しています。
パスの通し方がよく解りません。どなたか！

https://github.com/nemtech/catapult-server

思い出しながら書いてるので順序が逆の場所があるかも。
あとcdは省略してる場所があるので要注意。完成版にはちゃんと書きます。

#お約束
```
sudo yum update -y
sudo yum install gcc -y
sudo yum install gcc-c++ -y
sudo yum install git
```
#zlib
```
sudo yum install zlib
 ```
#libarchive
```
sudo yum install libarchive libarchive-devel
```
#jsoncpp
```
sudo yum install cmake
```
(jsoncppを通すためにあえて古いcmakeをインストールする。少々トリッキー)

```
wget https://github.com/open-source-parsers/jsoncpp/archive/1.7.5.tar.gz
tar zxvf 1.7.5.tar.gz
 cd jsoncpp-1.7.5/
mkdir build
cd build
cmake ..
```
#cmake
(yumで入るcmakeではmongodbで詰まるので最新のcmakeを入れる)

```
wget https://cmake.org/files/v3.6/cmake-3.6.1.tar.gz
(最新を取ったほうがいいかも https://cmake.org/download/)
tar zxvf cmake-3.6.1.tar.gz
cd cmake-3.6.1
$ ./bootstrap --prefix=/usr \
        --system-libs \
        --mandir=/share/man \
        --docdir=/share/doc/cmake-3.6.1
make 
sudo make install
```

参考：[Amazon Linuxに最新のclangをインストールする - Qiita](https://qiita.com/yohei1126@github/items/476c6b6d002944236139)

#curl
```
sudo yum install curl
sudo yum install curl-devel
```
(sudo yum install curl-devel xz-devel expat-devel -y) いらんかも

#python3
```
sudo yum install python36*
sudo update-alternatives --config python
```
[2] enter でpython3.6に切り替える

#boost
```
sudo yum install boost
```
#gtest
```
sudo yum install gtest
```
#mongodb
```
sudo vi /etc/yum.repos.d/mongodb-org-3.6.repo
[mongodb-org-3.6]
name=MongoDB Repository
baseurl=https://repo.mongodb.org/yum/amazon/2013.03/mongodb-org/3.6/x86_64/
gpgcheck=1
enabled=1
gpgkey=https://www.mongodb.org/static/pgp/server-3.6.asc

sudo yum install -y mongodb-org
```

参考：[Install MongoDB Community Edition on Amazon Linux — MongoDB Manual 3.6](https://docs.mongodb.com/manual/tutorial/install-mongodb-on-amazon/)

#libbson
```
wget https://github.com/mongodb/libbson/releases/download/1.9.5/libbson-1.9.5.tar.gz
./configure
make 
sudo make install
```

#mongo-c-driver
(これがないとmongo-cxx-driverが入らない)

```
git clone --depth 1 https://github.com/mongodb/mongo-c-driver.git
cmake .
make
sudo make install
```

参考：https://github.com/mongodb/mongo-c-driver/

#mongo-cxx-driver

```
git clone https://github.com/mongodb/mongo-cxx-driver.git     --branch releases/stable --depth 1
cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=/usr/local ..

sudo make EP_mnmlstc_core
make 
sudo make install 
```

参考：[Installing the mongocxx driver](http://mongodb.github.io/mongo-cxx-driver/mongocxx-v3/installation/)

#zmq
```
git clone https://github.com/zeromq/libzmq
sudo yum install autogen
sudo yum install libtool

./autogen.sh && ./configure && make -j 4
make check
sudo make install
sudo ldconfig
```
#rocksdb
(makeが超遅いので要注意 jオプションとか要検討)

```
git clone --depth 1 https://github.com/facebook/rocksdb.git
cd rocksdb
mkdir build
cd build
cmake ..
make
sudo make install
```
Netflix製fast_jsonapiのTips

※ 2020/03時点でforkされた下記プロジェクトで開発が進行しているようです.PRやissueはこちらにあげたほうが良いかもしれません.
https://github.com/fast-jsonapi/fast_jsonapi

※ 2019/12時点でかなり雲行きが怪しくなっているので別のシリアライザの導入の検討をおすすめします.
https://github.com/Netflix/fast_jsonapi/issues/433

# はじめに
RailsAPIでjsonでレスポンス返す場合に候補となるライブラリはいくつかあるのですがjbuilderはいわずもがなAMS(ActiveModel::Serializer)でもレコード数が多かったりするとわりとjson作るのに時間がかかる場合があります。
他に候補ないかなと思ったところNetflixOSSのfast_jsonapiが速いとのこと、基本的にAMSの思想を踏襲しているようでAMSを使ったことがある人であればわりと感覚的に書けるのですが公開されてまだ間もないこともありドキュメントもあまり充実していなかったのでまとめたいと思います。

[fast_jsonapi](https://github.com/Netflix/fast_jsonapi/tree/master)
# Tips
## attributeをカスタマイズする

AMS的にいうと`def hoge` みたいにプロパティを作りたいケース。
公式にも書いてあるのであえて書くまでもないのですが一応。
下記`name_with_year` というカスタムプロパティを作る場合です。

```MovieSerializer.rb
class MovieSerializer
  include FastJsonapi::ObjectSerializer
  attributes :name, :year
  
  attribute :name_with_year do |object|
    "#{object.name} (#{object.year})"
  end
end
```

## serializerにパラメーターを渡す

AMSでいうscope的な機能を使いたいケースです。
こちらまだmasterブランチには機能として存在しないようですが、下記PRでdevのほうにはマージされているので2018/05/10現在利用したい場合はdevブランチを利用することになります。
https://github.com/Netflix/fast_jsonapi/tree/dev

```Gemfile.
gem 'fast_jsonapi', git: 'https://github.com/Netflix/fast_jsonapi', branch: 'dev'
```
Serializerの第2引数がoptionsになるのでparamsというkeyに対してobjectをセットします。

```MovieController.rb
MovieSerializer.new(@movies, {params: {user: current_user}})
```
attributeメソッドでブロックと引数としてobject+paramsが受け取れます。

```MovieSerializer.rb
class MovieSerializer
  include FastJsonapi::ObjectSerializer
 
  attribute :name_with_year do |object, params|
    current_user = params[:user]
  end
end
```

## hashをcacheする

謎に韻を踏んでしまいました、とはいえもっと早くしたいのでcacheしたいパターンです。

```MovieSerializer.rb
class MovieSerializer
  include FastJsonapi::ObjectSerializer
  cache_options enabled: true, cache_length: 12.hours, race_condition_ttl: 10.seconds
end
```

### cache_keyが設定できない?
cache_optionsとしては`enable` `cache_length` `race_condition_ttl` の3つが設定できますが、これだとuserに紐付いたデータはキャッシュできないように思えます。
ドキュメントをよく読むとしれっと`Requires a cache_key method be defined on model`と書いてあるので例えば以下のようにモデルにcache_keyメソッドを定義することでカスタマイズ可能です。

```Movie.rb
class Movie < ApplicationRecord
  def cache_key
    "#{id}_#{user.id}
  end
end
```

# おわりに
以上PR・issueみたりコード読まないとわかりにくかったりしたところをあげてみました。リリース間もないライブラリということで今後の動向を注視しつつ何かあったら更新していきたいと思います。

## ref
https://medium.com/netflix-techblog/fast-json-api-serialization-with-ruby-on-rails-7c06578ad17f
https://github.com/Netflix/fast_jsonapi/pull/49
https://github.com/Netflix/fast_jsonapi/pull/205
Google Compute EngineにLightGBMをインストールする

# はじめに
Google Compute EngineにLightGBMをインストールする手順を記載します．

# 環境
Python version: Python 3.6.5 :: Anaconda custom (64-bit)
OS: CentOS Linux release 7.5.1804 (Core)

# インストール
## Open MPIのインストール
Lightgbmのビルドには分散処理を可能にする[Build MPI Version](https://lightgbm.readthedocs.io/en/latest/Installation-Guide.html#build-mpi-version) が存在する.
これを利用するため，まずOpen MPIをインストールする．

```sh:
cd /usr/local
curl -O https://download.open-mpi.org/release/open-mpi/v3.1/openmpi-3.1.0.tar.gz
tar xvf openmpi-3.1.0.tar.gz
cd openmpi-3.1.0
./configure --prefix=/usr/local/openmpi-3.1.0  CC=gcc CXX=g++
make -j 4 all 2>&1 | tee make.log
make -j 4 install 2>&1 | tee install.log
```

PATHを通す．

```sh:~/.bash_profile
MPIROOT=/usr/local/openmpi-3.0.1
export PATH=$MPIROOT/bin:$PATH
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$MPIROOT/lib
export MANPATH=$MANPATH:$MPIROOT/share/man
```
適用

```sh:
source ~/.bash_profile
```

## LightGBMのインストール
前述した通り，MPI versionでのビルドを行う．

```sh:
sudo yum install cmake
git clone --recursive https://github.com/Microsoft/LightGBM ; cd LightGBM
mkdir build ; cd build
cmake -DUSE_MPI=ON ..
make -j4
```

## python-packageのセットアップ

```sh:
cd LightGBM/python-package
python setup.py install
```

これでpythonからLightGBMを使用可能になる．

```python:
import lightgbm
```
Vault: 検証用に非 Dev モードでサーバを起動する

## はじめに

Vault サーバを検証用途で利用目的で簡易的にサーバを立ち上げる Dev モードが容易されていますが、Dev モードでは TLS が無効になっています。それはそれで都合がよいのですが、TLS を利用して検証したいときには不便です。

自己証明書の作成からコンテナを利用して非 Dev モードで Vault サーバを起動する手順を残します。

## 手順

```
$ brew install cfssl
$ echo '{"CN":"CA","key":{"algo":"rsa","size":2048}}' | cfssl gencert -initca - | cfssljson -bare ca -
$ echo '{"signing":{"default":{"expiry":"43800h","usages":["signing","key encipherment","server auth","client auth"]}}}' > ca-config.json
$ export ADDRESS=127.0.0.1,localhost
$ export NAME=server
$ echo '{"CN":"'$NAME'","hosts":[""],"key":{"algo":"rsa","size":2048}}' | cfssl gencert -config=ca-config.json -ca=ca.pem -ca-key=ca-key.pem -hostname="$ADDRESS" - | cfssljson -bare $NAME
$ cat <<EOL > config.hcl
storage "inmem" {}

listener "tcp" {
    address = "0.0.0.0:8200"
    tls_cert_file = "/data/server.pem"
    tls_key_file  = "/data/server-key.pem"
}
EOL
$ docker run --name vault -d -p 8200:8200 -v $(pwd):/data --cap-add=IPC_LOCK vault server -config /data/config.hcl
$ export VAULT_CACERT=$(pwd)/ca.pem
$ vault operator init -key-shares=1 -key-threshold=1
$ vault operator unseal $UNSEAL_KEY
$ vault login $ROOT_TOKEN
$ vault kv put secret/password -value=mypassword
$ vault kv get secret/password
$ docker kill vault
```

## 参照

- [Dev Server Mode \- Vault by HashiCorp](https://www.vaultproject.io/docs/concepts/dev-server.html)
VSCode の Cmd + D を case-sensitive にしたい時のコマンド

毎回忘れるのでメモ。

## やりかた

`Option+Cmd+c` で使うたびに case-sensitive が切り替わる。
Windows の場合は `Alt+c` の様子。

[![https://gyazo.com/36fe919b3eae4a3ff968c7175d5536ca](https://i.gyazo.com/36fe919b3eae4a3ff968c7175d5536ca.gif)](https://gyazo.com/36fe919b3eae4a3ff968c7175d5536ca)

## Refs

`vscode cmd d case-sensitive` みたいなワードでググるといくらでも出てくるけど毎回忘れる。

- https://github.com/Microsoft/vscode/issues/4309
- https://github.com/Microsoft/vscode/issues/34548
- https://github.com/Microsoft/vscode/issues/18239
Google Analytics API v2をPHPで使う

# Google Analytics APIをPHPで使おうとして、苦労した

Google Analytcs APIを使う必要があった、Amazon AWSのEC2からPHPで使おうと思いたって、調べた。

で、見つけたのがこことか、
https://syncer.jp/google-analytics-api-tutorial
こちら。
https://www.spiceworks.co.jp/blog/?p=10825

こちらを使うために、いろいろ苦労したので、メモを残しておく。

## 環境の準備

### PHPのバージョンアップ

Amazon Linuxのインスタンスはすでにあったが、PHPを使おうと決めたので、まずはComposerのインストールをしなければならない。

Amazon LinuxのデフォルトのPHPのバージョンは要件に合わないので、最初5.4.0をYum経由でインストールした。
しかし、進めていたら5.5.0以上が必要とのことだったので、再度yumで5.5.0をインストールした。

### httpdのバージョンアップ

Amazon AWSのデフォルトのhttpdのバージョンは2.2.34のようで、Composerで必要な2．4.xにバージョンアっプした。

### インスタンスのアップグレード

上記準備をして、composerをインストールしようとしたところ、メモリ不足！
SWAPを増やそうにもディスクもフル、ということで、EC2のインスタンスをアップグレード、ディスク容量も増やした。

## APIの利用準備

環境は整ったので、APIの利用準備はリンク先の情報にしたがって進めた。

## APIの利用

最終的にAPIを利用してみようと、書いてあることそのままを実行した。しかしPHPのエラーで動かない。

> PHP Fatal error:  Class 'Google_Auth_AssertionCredentials' not found in /var/www/html/api/index.php on line 35

調べてみると、Google Analytics API for PHPはv2になっており、ソースをかなり修正しなければいけないことがわかった。要修正点の詳細はこちら。

https://github.com/google/google-api-php-client/blob/master/UPGRADING.md

diffはこちら

```
*** index.php.orig    2018-05-15 09:24:57.610308228 +0000
--- index.php.v2      2018-05-15 09:52:56.098575392 +0000
***************
*** 19,49 ****
  define('CSV_DIR', __DIR__.'/csv');

  // google-api-php-clientを呼び出します。
! require_once __DIR__.'/google-api-php-client-master/src/Google/autoload.php';
  // 念のためタイムゾーンの設定をします。
  date_default_timezone_set('Asia/Tokyo');

  $ymd = sprintf("%s01", $target_yyyymm);

- $json = file_get_contents(JSON_PATH);
- $json = json_decode($json, true);
-
- $client_email = $json['client_email'];
- $private_key  = $json['private_key'];
-
  $scopes = array(Google_Service_Analytics::ANALYTICS);
- $credentials = new Google_Auth_AssertionCredentials(
-     $client_email,
-     $scopes,
-     $private_key
- );

  $client = new Google_Client();
  $client->setApplicationName("Google Analytics PHP API");
- $client->setAssertionCredentials($credentials);
- if ($client->getAuth()->isAccessTokenExpired()) {
-     $client->getAuth()->refreshTokenWithAssertion();
- }
  $analytics = new Google_Service_Analytics($client);

  $date1 = date('Y-m-01', strtotime($ymd));
--- 19,36 ----
  define('CSV_DIR', __DIR__.'/csv');

  // google-api-php-clientを呼び出します。
! require_once __DIR__.'/google-api-php-client-master/vendor/autoload.php';
  // 念のためタイムゾーンの設定をします。
  date_default_timezone_set('Asia/Tokyo');

  $ymd = sprintf("%s01", $target_yyyymm);

  $scopes = array(Google_Service_Analytics::ANALYTICS);


  $client = new Google_Client();
+ $client->setAuthConfig(JSON_PATH);
+ $client->setScopes($scopes);
  $client->setApplicationName("Google Analytics PHP API");
  $analytics = new Google_Service_Analytics($client);

  $date1 = date('Y-m-01', strtotime($ymd));
```

## 感想

- ここには書いていないが、gitとか、いろいろなツールを使わないと目的が達成できず、なかなか素人さんには難しい
- APIのバージョンアップって、旧バージョンの使い方はいきなり切っちゃうのがGoogle流なのだろうか？
- 当然ではあるが、サンプルコードはエラーが起こった際のメッセージが不親切なので、なかなかなぜ動かないのか分からないだろうなぁ。
mysqlコマンド早見表

## 準備系
|　　項目  　　　   |　　コマンド 　　　　　　　　　　|　　例     　　　　　　　　　　　|
|:-----------|:-----|:------------------|
| mysqlに接続　　　　|mysql -u root　　|　-  　　 |
| DB一覧を表示      　 |  show databases; 　|　-      |
| DB作成          　　　　| create database 〇〇;| CREATE DATABASE users(birth_day:int, email,varchar(255))   |     
| DB選択            | use　〇〇;　　　　|        USE users;         |

## データ登録/更新/削除
|　　項目  　　　　　　　　|コマンド　　　　　　　　　　　　　　　　　　　|　例    |
|:---------|:------------------|:------------------|
| 登録<br>（カラム全て）  | insert into 〇〇　values （値1,2,3...） 　　　| insert into users values （19930111,example@gmail.com,tanaka masashi,）      |　 登録（一部）
| 登録<br>（カラム一部）           | insert into 〇〇　（カラム1,カラム2）<br> value（値1,値2） |    insert into users (name, email) <br>　value (tanaka masashi, example@gmail.com)      |
| 変更            |update 〇〇 set 変更内容 where 条件; |  update users set name = "suzuki masashi" where name = "tanaka masashi"       |
| 削除               | delete from 〇〇 where 条件 |  delete from users where birth_day = 19930111        |


## データ検索系
| 項目   　　　　　　　　　　　　　　|コマンド       |    例    |
|:-------------|:--------------|:------------------:|
| カラム選択     　|select 　　　　　　　　　　　　　| select name from users;        |
| 文字列合体           |concat| concat(family_name,first_name)from users;|
| カラムに命名             |as| concat(family_name,first_name) as "名前" from users   |
| レコード数取得               |count カラム名|   select * from users count(*)       |
| 重複除外             |distinct| （中間テーブルなどで）select distinct user_id;       |
| グループ化          | group by| （中間テーブルなどで）seelct user_id from posts group_by user_id      |
| カラムの一致するデータ結合         |join|  （中間テーブルなどで）select user_id, count(*)"投稿数" from posts p join users u on p.user_id = u.id group by user_id      |
CakePHP(3.x) 優先するテンプレートディレクトリを条件によって変える

特定の条件でのみCakephpのテンプレートディレクトリを変更したいという要望があり、わりと変態じみた実装をしたのでメモ。

```php:cakephp/config/app.php
    'App' => [
         // ～中略～
        'paths' => [
            'plugins' => [ROOT . DS . 'plugins' . DS],
            //GETパラメータhogeがある場合には/home/fuga/Template/からを優先してctpファイルを探す
            'templates' => isset($_GET['hoge'])
                ? [DS . 'home' . DS . 'fuga' . DS . 'Template' . DS, APP . 'Template' . DS]
                : [APP . 'Template' . DS],
            'locales' => [APP . 'Locale' . DS],
        ],
    ],
```

設定項目templatesにはテンプレートディレクトリの絶対パスを配列で記述する。

このときに先に記述したディレクトリからマッチするctp(テンプレート)ファイルを探してくれる。

```php
'templates' => [
    DS . 'home' . DS . 'fuga' . DS . 'Template' . DS, # /home/fuga/Template/が優先される
    APP . 'Template' . DS
]
```

なので特定条件の場合にのみ/home/fuga/Template/の中のctpを優先して見たい場合には、三項演算子で設定する配列を切り替える。

```php
'templates' => (条件) ? [条件がtrueの場合の配列] : [条件がfalseの場合の配列]
```

+ 設定ファイルの配列内で条件分岐をさせる
+ さらに優先ディレクトリからテンプレート有無を判断するという条件分岐が起こる

と、なんだか書いていてモヤっとする気分になる実装でした。

コントローラ内でテンプレートディレクトリを絶対パスで指定する方法はあるのだろうか。

（[シンボリックリンクを使った方法](https://qiita.com/ito_gen/items/9678db816566d415473e)だとsvn管理に不都合が生じるためにボツとなった。）
micro:bit用パッケージの言語リソースの命名ルール

micro:bit用のプログラミング環境である[ブロックエディタ(MakeCode)](https://makecode.microbit.org/)では、自作のブロックを追加できる機能があるのですが、パッケージを複数の言語に対応（ローカライズ）するためのルールで、公式のドキュメントに書かれていないことを補足する記事です。

公式のドキュメントの方にもPRを送るつもりですが、英語なのでとりあえずこちらに日本語でメモとして。

## micro:bit用拡張パッケージの開発方法
micro:bit用拡張パッケージの開発方法については、[公式のドキュメント](https://makecode.com/packages)がありますのでそちらをご覧ください。ただ、なにかと情報不足な点は否めません...。

## ローカライズ用言語リソースの置き方
このドキュメントの中に[言語対応（localization）](https://makecode.com/packages/localization)の説明があり（元々無かったけれど質問したら追加されたようだ）、基本的にはここに書いてある通りなのですが、言語リソースファイル名の命名ルールの説明がありません。

言語リソースファイルは以下のルールに従ってください。
1. "_locales"ディレクトリを作成する。
2. その下に各言語ごとのディレクトリを作成する。ディレクトリ名には[ISO 3166-1 alpha-2](https://ja.wikipedia.org/wiki/ISO_3166-1)を小文字で使用します。日本の場合は"ja"となります。
3. 各言語のディレクトリの中に「{pxt.jsonの"name"で指定した名前}-strings.json」のファイル名で言語リソースファイルを置きます。

```
"ExternalPackages"の日本語リソースの場合。
"_locales/ja/ExternalPackages-strings.json"
```

ツールチップの言語リソースの場合は、「{pxt.jsonの"name"で指定した名前}-jsdoc-strings.json」となります。

## 言語リソースの書き方
言語リソースの書き方については、実際にパッケージを開発されている方なら、公開されているパッケージを参考にすればわかると思いますので、省略します。

- [neopixelのパッケージ](https://github.com/Microsoft/pxt-neopixel)

## 最後に
めっちゃ走り書きで申し訳ありませんが、もし困っている方の参考になればと思い取り急ぎシェアしました。
wp_link_pages()で得られるリンクのURLを配列形式で得る

# やりたいこと
```html
<ol>
  <li><a href="http://hoge.com/blog/">1</a></li>
  <li><a href="http://hoge.com/blog/2/">2</a></li>
  <li><a href="http://hoge.com/blog/3/">3</a></li>
</ol>
```
WPで改ページのある記事に、こんな感じの一般的なページネーションを作りたい。

# 普通にやる
```php:single.php
<?php
  $args = array(
    'before'           = '<ol>',
    'after'            = '</ol>',
    'link_before'      = '<li>',
    'link_after'       = '</li>',
  );

  wp_link_pages($args);
?>
```
```html:出力結果
<ol>
  <a href="http://hoge.com/blog/1"><li>1</li></a>
  <a href="http://hoge.com/blog/1/2/"><li>2</li></a>
  <a href="http://hoge.com/blog/1/3/"><li>3</li></a>
</ol>
```
違う、そうじゃない

# 対策
改ページのURLを配列形式で返す自作関数を定義。

```php:functions.php
// 改ページのURLを配列形式で返す
function wp_link_pages_uri() {
  global $page, $numpages;

  $result = array();
  for ($i = 1; $i < $numpages+1; $i++) {
		$result[] = preg_replace('/<a href="(.+)">/', '$1', _wp_link_page($i));
	}

  return $result;
}
```

```php:single.php
<?php
  echo "<pre>";
  print_r(get_wp_link_pages_uri());
  echo "</pre>";

  // Array
  // (
  //     [0] => http://hoge.com/blog/
  //     [1] => http://hoge.com/blog/1/2
  //     [2] => http://hoge.com/blog/1/3
  // )
?>
```
あとはforeachなりで成型して完成！
Port forwarding Setting for teraterm

# 設定手順

サーバ側

1. サーバを用意。Privoxyをインストール。
1. ポートは8123としておく。
1. 起動しておく。

クライアント側

1. ssh 接続。
1. 設定-SSH転送を開く。
1. 追加 → ローカルポートを選択、ポート番号を設定（例：8882。これがProxyポートになる）
1. ポートに8123を設定。後は空白でOK。
1. インターネット設定のプロキシサーバのアドレスにLocalhost、ポートに8882を設定する。

以上で設定完了。
Unityエディターをサクッと日本語化する方法

# はじめに
Unity 2018.1以降からメニュー表示等が日本語化対応しました。
その手順を説明します。

# POファイルのダウンロード
まず、日本語化に必要な翻訳ファイルを以下のURLからダウンロードします。

http://editor-localization.s3-website-ap-northeast-1.amazonaws.com/2018.1/ja.po

次にダウンロードしたPOファイルを、指定のフォルダに格納します。

Macの場合で説明します。

/Applicaitons -> Unity -> Unity.appを右クリック

![0b7f464b4f19b4c1f3132360ce011ca8.gif](https://qiita-image-store.s3.amazonaws.com/0/34936/9b81c6e6-6e3e-6571-6180-7146d7b0f9da.gif)

# Localizationフォルダの作成

![b22056f27bd5535580abf13b66df67de.gif](https://qiita-image-store.s3.amazonaws.com/0/34936/c2dde608-2007-8c0a-7916-577419ee2b57.gif)

# POファイルを配置
* Localizationフォルダに先程ダウンロードしたja.poファイルをドラッグ・アンド・ドロップします

![06e25f2422f4efbf18c1e3042d8b6841.gif](https://qiita-image-store.s3.amazonaws.com/0/34936/da564b4e-4421-6245-c238-72b3a2273792.gif)

# Preferenceの設定
* メニューからUnity -> Preferencesを選択
* Editor languageでJapaneseを選択します

![dea207ef069fc499780b45d027ff1bf4.gif](https://qiita-image-store.s3.amazonaws.com/0/34936/1690dd11-c814-9f7b-5ff3-b17d7d82d0ee.gif)

Unityを再起動したら完了です！
Headless Chromeでにっちもさっちもいかないとき

Selenium + Headless Chromeでクローラを実装したけど途中で落ちてしまって原因もわからないとき、期待した結果が取得できないときの対策。

## ログを出す

出力できるログは全て取る。

```Ruby
# Seleniumのデバッグログ (情報は少ない)
Selenium::WebDriver.logger.level = :debug
Selenium::WebDriver.logger.output = 'selenium.log'

# Chromeのログ (UserProfileに下に作成される。Linuxだと /tmp/.org.chromium.Chromium.AAAAA あたり) 
options = Selenium::WebDriver::Chrome::Options.new({
  args: ['log-level=0', 'enable-logging'],
})
# chromedriverのログ (find_element の実行結果とか全て記録されるので便利)
@driver = Selenium::WebDriver.for(:chrome, options: options, driver_opts: {
  log_path: 'chromedrive.log',
})
```

## スクリーンショットを取る

エラーが発生したときの画面の状態をあとから確認する。

```ruby
def save_screenshot(path)
  @driver.save_screenshot(path)
end
```

## ソースを保存する

エラーが発生したときのソースをあとから確認する。

```ruby
def dump_source
  filename = Digest::MD5.hexdigest(@driver.current_url)
  png_path = './log/%s.png' % filename
  html_path = './log/%s.html' % filename
  save_screenshot(png_path) # スクリーンショットとHTMLを同じファイル名にしておく
  File.open html_path, "w" do |writer|
    writer.puts @driver.current_url # 一緒にURLも出力しておくと便利
    writer.puts @driver.page_source
  end
end
```

## ウインドウサイズを大きくする

ウインドウサイズが小さいとHTMLが崩れたりDOM要素が重なったりして意図しない結果になることがある。

```ruby
options = Selenium::WebDriver::Chrome::Options.new({
  args: ['headless', 'start-maximized', 'window-size=1920,1080'],
})
```

## 日本語フォントを入れる

日本語フォントをインストールしておかないと文字化けする。たまにエラーで落ちたりする。

```bash
$ sudo yum install -y google-chrome-stable libOSMesa google-noto-cjk-fonts ipa-gothic-fonts.noarch ipa-mincho-fonts.noarch
```

## タブの状態をログに出力する

実装が悪いとエラー発生時にタブが残ってしまい動作が不安定になるので、ちゃんとタブが閉じられているかチェックするためにログに出力しておく。

```ruby
logger.info('タブ: %d' % @driver.window_handles.size)
```
[AWS]boto3でEC2のインスタンス料金を取得する

# python boto3でec2の料金を取得する
インスタンスの料金を自動で取れたら便利だなーと思っていたら、
料金取得APIがあるようなので叩いてみました。

## コード
pricingクライアント生成と、APIを実行しレスポンス取得

```python:api実行.py
import boto3

# pricingを指定
pricing = boto3.client("pricing",
                          aws_access_key_id='access_key',
                          aws_secret_access_key='secret_key',
                          region_name='us-east-1')

response = pricing.get_products(
            ServiceCode='AmazonEC2',
            # フィルタ条件。
            Filters=[
              {
                'Type': 'TERM_MATCH',
                'Field': 'instanceType',
                'Value': 't2.micro'
              },
              {
                  'Type': 'TERM_MATCH',
                  'Field': 'termType',
                  'Value': 'OnDemand'
              },
              {
                  'Type': 'TERM_MATCH',
                  'Field': 'location',
                  'Value': 'Asia Pacific (Tokyo)'
              },
              {
                  'Type': 'TERM_MATCH',
                  'Field': 'operatingSystem',
                  'Value': 'Linux'
              }
            ]
        )
```
### ※注意事項
- 東京リージョンには存在しないAPIなのでregion_nameの指定には注意
- フィルタ条件を指定しないと全料金が返却されるので量がとんでもないです。

私の場合は、インスタンスサイズの料金が1件のみ返却されるようにフィルタ条件を調整しています。
フィルタ条件の属性等については、参考のリンク先を参照してください。

以下、レスポンスから1時間当たりの値段を取得するコード。

```python:responseから料金取得.py
import json

response = json.loads(response['PriceList'][0])

# 1時間当たりの料金を取得する
hour_fee = 0
for v in response['terms']['OnDemand'].values():
  for v2 in v['priceDimensions'].values():
    hour_fee = float(v2['pricePerUnit']['USD'])

print('1時間あたりの料金:', hour_fee)
```
取得できるオンデマンドのインスタンス料金は時間単位です。

## その他
`response['terms']['OnDemand']`の`OnDemand`を`Reserved`にするとリザーブドインスタンスの料金も取得できます。

稼働中のインスタンス取得のAPIと組み合わせると稼働中のインスタンスの料金を計算できるようになります。

また、同様の方法で他サービスの料金も取得できます。


## 参考
[AWS 料金表 API の更新 – 新しいクエリとメタデータ関数](https://aws.amazon.com/jp/blogs/news/aws-price-list-api-update-new-query-and-metadata-functions/)
Spring Initializr を IntelliJ IDEA から利用できることに気づいた

Spring Initializr(https://start.spring.io/) を IntelliJ IDEA から利用できる。
しかも IntelliJ IDEA の方が使いやすいと思う。
今後はこっちからプロジェクト生成しようと思います。

## IntelliJ IDEA version
2018.1.2 Ultimate

## New Project にある
File -> New Project -> Spring Initializr
![image.png](https://qiita-image-store.s3.amazonaws.com/0/218706/d42d0dd2-0fa0-f316-daee-c35ffdde1a0c.png)

## dependencies が Web より見やすいと思う
![image.png](https://qiita-image-store.s3.amazonaws.com/0/218706/6b9c965d-051f-0613-c522-0b86d6d8afce.png)
大事なファイルを消したいときのgit filter-branch

大事なファイルをリモートリポジトリにpushしてしまっていた時に使える`git filter-branch`。

`git filter-branch -f --index-filter 'git rm -rf --ignore-unmatch [ファイル名]' HEAD`
で消したいファイル名を指定し該当の削除して

`git gc --aggressive --prune=now`
で過去のcommitした上記ファイルを消して最適化して

`git push -f`
`-f`オプションをつけて強制的に`push`。　(強制的に上書きされるので注意が必要です)
NuGetに広がっていた 表©鷗字㌍ 汚染が収束したみたい

( ﾟ∀ﾟ) < **表©鷗字㌍!!**

![スクリーンショット (75).png](https://qiita-image-store.s3.amazonaws.com/0/199750/6bb51782-dd89-0ed2-c20b-f244b4949814.png)

3ヶ月ぐらい前からasp.net あたりのNuGetのロケールパッケージに突如広がりだした謎の**表©鷗字㌍**が 5/12ぐらいに修正されたようだ。

手元のソリューションで使われてる範囲だと

- Microsoft.AspNet.Mvc.ja
- Microsoft.AspNet.Razor.ja
- Microsoft.AspNet.WebPages.ja

あたりが影響受けていたみたい。

NuGetのCopyrightも悲しいことになってた。
![スクリーンショット (76).png](https://qiita-image-store.s3.amazonaws.com/0/199750/f4d10090-7138-884a-835b-eea3c3c85655.png)

パッケージをアップデートしよう。
New Relic INFRASTRUCTUREによるKubernets環境のモニタリング

# はじめに
New Relic INFRASTRUCTUREの機能、"on-host integrations"にKubernetes(K8S) Integrationが追加されました！現在まだβ版ではありますが、Kubernetesのアドオンとして提供されているkube-state-metricsと連携することで、下記コンテナオーケストレーションレイヤのメトリクスをモニタリングすることができます。

- K8Sノード
- ネームスペース
- デプロイメント
- レプリカセット
- ポッド
- コンテナ

# 機能概要
New Relic INFRASTRUCTUREのK8Sインテグレーションでは、INFRASTRUCTUREのAgentを介し、kube-state-metricsで取得したK8SのメトリクスをNew Relic INSIGHTに送信することができます。これにより、下記の機能を提供します。

- K8Sメトリクスをまとめたダッシュボード(New Relic INSIGHTS)の自動作成
- K8Sに関するアラートを作成可能

# 要件
New RelicとK8SのIntegrationには下記のコンポーネントが必要です。

- New Relic INFRASTRUCTURE Pro、もしくはトライアル(無料トライアルは[こちら](https://newrelic.nissho-ele.co.jp/)から)
- New Relic INFRASTRUCTUREと互換性のあるLinuxディストリビューション
- 起動中のK8Sクラスタ
- クラスタにインストールされ、実行中のkube-state-metricsバージョン1.1.0

# インストール手順
## 1. kube-state-metricsのインストールと設定
下記コマンドにより、kube-state-metrics用のpodやserviceを作成

```
kubectl create -f https://raw.githubusercontent.com/kubernetes/kops/master/addons/kube-state-metrics/v1.1.0-rc.0.yaml
```

kube-state-metricsがインストールされ、"kube-system"ネームスペース内に"kube-state-metrics"が作成されていることを確認

```
$ kubectl get po,svc -n kube-system | grep metrics
pod/kube-state-metrics-5c556c8657-467tl                                      1/2       CrashLoopBackOff   4          3m

service/kube-state-metrics     ClusterIP   100.70.246.43    <none>        8080/TCP        3m
```

## 2. Integration設定ファイルのインストールと設定
設定ファイルをインストールします。

```
$ curl -O https://download.newrelic.com/infrastructure_agent/integrations/kubernetes/newrelic-infrastructure-k8s-1.0.0-beta2.1.yaml
```

次に、設定ファイルにNew Relicライセンスキー及びK8Sクラスタ名を追記します。

```
$ vi newrelic-infrastructure-k8s-1.0.0-beta2.1.yaml
env:
  - name: NRIA_LICENSE_KEY
    value: YOUR_LICENSE_KEY
  - name: CLUSTER_NAME
    value: YOUR_CLUSTER_NAME
```


下記コマンドでデーモンセットを作成します。

```
$ kubectl create -f newrelic-infrastructure-k8s-1.0.0-beta2.1.yaml
```

## 3. INFRASTRUCTURE on-host Integrationで確認
INFRASTRUCTUREの画面から、下記番号順にクリックし、自動作成されたINSIGHTSのダッシュボードを開きます。

![SnapCrab_NoName_2018-5-8_17-33-59_No-00.png](https://qiita-image-store.s3.amazonaws.com/0/150903/1b1e4a84-4c0f-2f78-7553-9288affdc754.png)

ダッシュボードを開くと下記各種K8Sクラスタの情報が表示されます。クラスタ内のノードの全リソース使用率やノード数、クラスタ数やポッド数をはじめ、各コンテナのCPUやメモリ利用率などを確認することができます。K8Sのon-host Integrationでは、こうしたダッシュボードを全て自動で生成してくれます！

![SnapCrab_NoName_2018-5-8_17-32-49_No-00.png](https://qiita-image-store.s3.amazonaws.com/0/150903/ca87547c-07a0-a41b-3edc-8e08859922db.png)

取得した各種K8Sのメトリクスに対して、アラームを設定することも可能です。もちろんK8S上のコンテナで起動するアプリケーションに対して、APMをインストールすることも可能です(詳しくはこちらのBlogを参照)。各種New Relicサービスを組み合わせることで、K8S環境をまとめてNew Relicで監視することができるようになりましたので、是非お試しください！
開集合，閉集合，コンパクトのイメージ

今回は，集合がopen, closed, そしてcompactであるとはどういうことなのかを自分なりに理解したので，メモしておく．Qiitaに書くことではないのかもしれないが，書くのが楽なのでここに書く．こういうのは定義だけ書いてある本が多いですが，イメージが大事だと思うので，そういう感じで書きたいと思います．もし，皆様のお役に立てれば幸いです．

## 数学的な「開いている（あいている）」のイメージ

まずは，数学的な「開いている」というイメージをつかむことにする．言葉からはなんとなく開放的な感じがする．数学ではこれをおなじみの記号である$<$で表現する（$x < b$みたいな感じで使う）．$<$をみたら，「開いている感」が出てきたらもうイメージはつかめているんだと思う（自分的に）．
さて，なんで$<$が「開いている」に繋がるのかを考えよう．例として，aからbまでの実数の空間を考えよう．ここで，**aやbを含めるのかは非常に大事**．aもbも含める場合は$[a, b]$，aもbも含めない場合は$(a, b)$，aは含めてbは含めない場合は$[a, b)$と書いたりする．
$[a, b]$と$[a, b)$の違いはなんだろうか？僕的には，前者は壁が中にあって，後者は壁が外にあるみたいなイメージで捉えている．例えば，僕たちがとある世界に住んでいて，その世界のものしか見えないのだとしたら，前者の場合，壁である$b$は見えて，後者の場合は$b$は見えない，つまり壁がないように思える．これが僕なりの数学的な「開いている」のイメージ．$x \in [a, b]$は，$a \leq x \leq b$で，$y \in [a, b)$は，$a \leq y < b$である．こう見ると，住人$x$は壁$b$が見えていることを$x \leq b$で表現し，住人$y$は壁$b$が見えていないことを$y<b$で表現しているように見える．まとめると，後者の世界は，その住人からみたら，「開放的」に見えて，これが数学的な「開いている」というイメージ（自分流）．

## open ball
ここまでで，$<$が「開いている」を表現しているのをイメージできただろうか．上に書いたのはあくまでも僕なりのイメージなので，自分なりにイメージできるまで考えてみて欲しいと思う．こういうのはとにかく自分なりに消化するのが大事だと思う．

さて，ここで急に，open ballというものを考えよう．それを考えるには距離空間を導入しないといけないが，ここでは省略して，$d$を距離としよう．ある集合に距離が定義されていれば，その集合の要素同士がどれだけ離れているか（近いか）を表現することができる．余談だが，極限とかで出てくる「近づける」という言葉の数学的な表現も，距離を使って書かれる．こういうのは本にはあまり出てこない辛い．

ボールというのは，丸い．中心と半径があればなんとなく表現できそう．中心を$x$，半径を$\epsilon$とすると，open ballという集合は，

```math
B(x, \epsilon) = \{y \ | \ d(x, y) < \epsilon \}
```

で定義される．ボールの端っこが含まれていないので，openなボールだ．この定義をみて，直感的に「ああ，確かにopenなボールだわ」と思えたら勝ち．

## openな集合（開集合）
open ballを飲み込むと，openな集合を考えることができる．openな集合は「開いている」集合で，端っこが含まれていない集合である．端っこが含まれていないのを表現するのは結構大変で，open ballを使う．集合の中のボールを考えよう．端っこが含まれていると，なんとなく「ボールがはみ出そう」な感じがしないだろうか．このイメージを伝えるのは結構難しい...．openな集合の中の世界の人は，壁が見えないので，そもそも「やべえ，はみ出た」というのがわからない．そんなイメージ．
きちんと数学的に書くと，ある集合$X$を考える．その部分集合$O \subset X$がopenであるとは，全ての$x \in O$に対して，$B(x, \epsilon) \subset O$となる$\epsilon$が存在することである．
こういうのはかなりわかりにくい．僕的には，何が与えられてるのかをまず考える．この例だと$X$が与えられている（実際には距離$d$も）．その上で，その部分集合の性質を考えている．

## closedな集合 (閉集合)
これは割とわかりやすい．$X$の部分集合$A \subset X$が閉集合であるとは，その補集合$X \setminus A$がopenであることをいう．全体の世界$X$の中に２つの世界$A$と$X \setminus A$があって，$X \setminus A$がopenなら片方$A$はclosedであることは多分直感的に理解できるはず．はず．はず...．

## compactな集合
これはなんか「包むことができる」というイメージ．コンパクトなら包めるだろ，という感じ．
例のごとく集合$X$を考えよう．
適当な$X$のopenな部分集合たち$(O_i)_{i \in I}$を考えよう．

$I$は適当なインデックス．そして，$A \subset X$の性質をみていこう．
ここで気になるのは，適当に用意した$(O_i)_{i \in I}$で$A$を包めるのかということ．

包めるなら，$i_1, \ldots, i_n \in I$が存在して，$A \subset \cup_{j=1}^n O_{i_j}$となるだろう．伝わるかわからないが...．

「存在する」というのは結構わかりにくいかもしれない．でも，そう書かざるを得ない．何かを用意して，それで表現できるみたいな論法は結構使われる．極限とかもそうだ．

## まとめ
今回はopen, closed, compactという概念の自分なりのイメージを書いてみた．最後らへんが適当になってしまった感が否めないが，お役に立てれば幸いです．
Web3.jsでUTF8文字列と16進数データの相互変換

* Web3.js 1.0.0 を使用した例です。

# Web3.js のインストール

```bash
 $ npm install web3 --save
```

# サンプルコード

```js
let Web3 = require('Web3');

console.log(Web3.version);
// => 1.0.0-beta.34

// UTF8String to HexData
let data = Web3.utils.utf8ToHex('piyo');
console.log(data);
// => 0x7069796f

// HexData to UTF8String
let string = Web3.utils.hexToUtf8(data);
console.log(string);
// => piyo
```

# Note
- Ethereum 関連の情報は https://scrapbox.io/sushiether/ に集約することにしました。
- この記事の内容に変更・更新がある場合は、以下の URL を更新します。
- https://scrapbox.io/sushiether/Web3.jsでUTF8文字列と16進数データの相互変換
bitnami Redmineでview customizeプラグインを入れる

# ハマったこと
view customizeをインストールしても、redmineを再起動後、internal errorが表示されて正しく動かない。

# 正しいインストール方法
ディレクトリ名は『view_customize』とする。
素直にgit cloneなどをすると、『redmine-view-customize』となり、ディレクトリ名がダメらしい。
正しいディレクトリ名にして再起動したら動き出した。

# やったこと
1. プロジェクト一覧の表示が崩れるのを直す
    [https://teratail.com/questions/96853](https://teratail.com/questions/96853)
    ここの『対処法2』

2. チケット作成時に担当者のデフォルトを設定、チケット編集時のエンターキー誤送信防止
https://qiita.com/wfigo7/items/f13a89e1d3522f4a73b6
エンターキー誤送信は、実際はtype="date", "type="checkbox"もあったので、それら全部制御する用に変更した。

    ```js
    /*
    チケット編集時のエンターキー誤送信防止
    Path pattern: /issues
    Type: JavaScript
    */
    $(function(){
    
        // form内のエンターキー入力を無視
        // トラッカー・ステータス操作時のDOM操作で破棄されないようdocumentにイベントを設定
        $(document).on('keypress', 'input', function(event) {
            if(event.keyCode == 13) {
                return false;
            }
        });
    });
    ```
Fisherの線形判別法で手書き文字を認識してみた

タイトルの通りです。
ソースコードを[GitHub](https://github.com/be-kan/handwriting_fisher)にアップしています。

MNISTではだいたい80%、自分で用意した手書き文字セットで80%台後半くらいの精度でした。

ざっくり説明すると、フィッシャーの線形判別法とは、各カテゴリの共通の共分散行列を求め、それぞれの事後確率から判別する方法です。
Unity3D Japanチャンネルの動画をレビューしてみた

YouTubeの[Unity3D Japan](https://www.youtube.com/channel/UCCdskievdAtH6AtPeEfTqEg)チャンネルで公開されている動画に関する備忘録という名のレビュー記事です。
投稿が新しいものから順に遡って観ています。

動画の内容から次に学ぶべき内容、興味を引く内容が見つかればと考えています。


# [Unite Tokyo 2018 Made with Unity Reel](https://www.youtube.com/watch?v=O-YAXKcQqG8)
Unity製のゲーム紹介動画です。
>★★★★★
どうぶつの森やCupheadがUnity製だと初めて知りました。
処理落ちしそうなアカとブルー(弾幕STG)やオープンワールドのVaneなど
初心者レベルの私には、どうやって作成されているか理解できませんが
Unityの可能性を見せつけてくれる良動画です！
[2018/05/24追記]


# [【Unite Tokyo 2018】バーチャルYouTuber電脳少女シロがご紹介する「2018年の注目アセット100連発」](https://www.youtube.com/watch?v=2tOoN_uMVt0)
自身にバーチャルYouTuberの耐性が無いことが判明しました。
ギブアップ!!!
>★★★★☆
内容は有用なので、いつかリベンジします……。


# [【Unite Tokyo 2018】基調講演スペシャルゲスト キズナアイ](https://www.youtube.com/watch?v=ZOwd8GB3uOQ)
同上
>★☆☆☆☆
Uniteで上映された賑やかし動画なのでスルーしても問題ありません。

# [ProBuilderでモデリング入門](https://www.youtube.com/watch?v=IeUNvMAA84k)
Unity version:2018.1.0以降から標準搭載されたモデリングツールと関連するアセットの使用方法について、建物、タル、キノコなどのモデルの作成を通して初歩的な知識を学べます。

>★★★★★
ProBuilderについて、まだ日本語での記事や資料が少ないため最初の一歩としてお勧めです。
見栄えが良いものを作成するためには、公式ドキュメントを読みこみ、更なる理解を深める必要があります。
[Unity](https://www.youtube.com/channel/UCG08EqOAXJk_YXPDsAvReSg)チャンネルの方でもProBuilderに関する動画が上がっているの閲覧する予定です。

# [【 Unity道場 XRスペシャル in Panasonic（社内セミナー）】初めてのVR/AR開発をUnityで](https://www.youtube.com/watch?v=_KBT0ZMoBo0)
動画の最初に断りがありますが、ほぼUnity初心者向けの用語や基本操作の説明で、
VR/AR開発については5分ほどしか言及されません。

>★☆☆☆☆
VR/AR開発の要素はUnityなら簡単にVR端末向けにビルドできる（が実際には端末性能差や各プラットフォーム毎の規約などで個別に対応する必要がありますよ）という内容でした。

# [【Unity道場 XRスペシャル in Panasonic （社内セミナー）】こんなに違う！Unityアプリケーション講座](https://www.youtube.com/watch?v=VP_d3p_6v50)
Unityでの実装上の注意点（C#の動作、実行タイムライン、入力の扱い、ブロック関数の対応など）について解説されています。
この動画を閲覧しただけで○○ができるようになる！という訳ではありませんが
中級者以上（他の言語、フレームワーク経験者でUnityの基礎を理解した方）にお勧めです。
少し複雑なことをスクリプトで実現するようになったら、いずれ必要になる知識だと思います。
>★★★★★
Unityの内部処理に一歩踏み込んでいるので初心者には理解は難しいですが
Unityの実行タイムライン（Main threadにおいて1フレームの間にどんな処理がどの順番で行われているか）の説明だけでも一見の価値があります。<br>
講演者の方もプレゼンに手馴れており解説が分かりやすいのも○です。

# [【Unity道場仙台スペシャル2】失敗から学ぶ小規模開発アプリで収益を出す方法](https://www.youtube.com/watch?v=EM0dhlM2rNo)
実際にリリースされたゲームの開発過程、リリース後の施策などをダウンロード数などのKPIの推移を交え説明されています。
>★★★★☆
YouTuberへのプロモーション依頼といった興味深い施策について言及されていたのですが、
どの程度DL数が増えたのか解析する手段を用意されていなかったため効果が不透明だったことが残念です。
（動画を見た人に無料アイテムのコードを配布するようにして流入元を解析するなどの手法が必要だったのではないでしょうか）

# [【Unity道場 2017】スマートフォンゲームでお金を稼ぐときにやっておくべきいくつかのこと](https://www.youtube.com/watch?v=O7Xv-fyr7bA)
スマホゲーにおけるマネタイズやプロモーションの種類、方法に関する講演です。
プランナー、ディレクター、プロデューサーなど運営側に向けた内容ですが
個人やインディーズ開発者も知っていて損はない内容になっています。
>★★☆☆☆
内容的に視聴対象が限られている点、実例はあるものの具体的な効果や数字が測れないところから評価は控えめです。

随時更新予定です。
GolangでAtCoderの問題を解くためのスニペット集

最近Goの練習も兼ねて[AtCoder](https://atcoder.jp/)のコンテストに参加していたりするのですが、毎回同じようなことを書いているなーと感じたのでまとめておきます。
普通に考えたらパッケージ化しろという話なんですが、競プロでは単一のソースファイルにする必要があるため古き良きスニペットという形で用意しておきます。
AtCoderと書きましたが他の競技プログラミングサイトでもおそらく使えると思います。

以下`import`は省略してます。

## 入出力系

単一の数値入力

```go
var N int
fmt.Scan(&N)
```

単一の文字列入力

```go
var s string
fmt.Scan(&s)
```

指定の要素数の数列を読み込んでスライスで返す関数

```go
func scanNums(len int) (nums []int) {
	var num int
	for i := 0; i < len; i++ {
		fmt.Scan(&num)
		nums = append(nums, num)
	}
	return
}
```


指定の要素数の文字列群を読み込んでスライスで返す関数

```go
func scanStrings(len int) (strings []string) {
	var str string
	for i := 0; i < len; i++ {
		fmt.Scanf("%s", &str)
		strings = append(strings, str)
	}
	return
}
```

出力はだいたいこれで

```go
fmt.Println(result)
```


## 計算系

競プロでは整数の計算をよくするんですが、Go標準のmathパッケージは`float64`でしか計算してくれないんですよね。なので、毎回書くのも面倒なので、各関数を`int`で使えるようにラップしておきます。

```go
func abs(a int) int {
	return int(math.Abs(float64(a)))
}

func pow(p, q int) int {
	return int(math.Pow(float64(p), float64(q)))
}
```

minとmaxはちょっと拡張して任意の要素数を渡せるようにしています。

```go
func min(nums ...int) int {
	if len(nums) == 0 {
		panic("funciton min() requires at least one argument.")
	}
	res := nums[0]
	for i := 0; i < len(nums); i++ {
		res = int(math.Min(float64(res), float64(nums[i])))
	}
	return res
}

func max(nums ...int) int {
	if len(nums) == 0 {
		panic("funciton max() requires at least one argument.")
	}
	res := nums[0]
	for i := 0; i < len(nums); i++ {
		res = int(math.Max(float64(res), float64(nums[i])))
	}
	return res
}

```

わざわざ`float64`にキャストしてパッケージに投げるよりこのくらいの計算自分で実装したほうがメモリも食わんし速く実行できるみたいな考え方もあるのですが、車輪の再発明をするのもなー、という気持ちがあって今回はこのようにしています。(どうにかならないんですかね、これ)


## 文字列系

文字列群`a`の中に文字列`b`が含まれるかどうかを判定する。

```go
func strSearch(a []string, b string) bool {
	for i := 0; i < len(a); i++ {
		if a[i] == b {
			return true
		}
	}
	return false
}
```

また何かあれば追加していきます。
[Review] Custom On-Device ML Models with Learn2Compress

This post follows this google's amazing blog.
https://ai.googleblog.com/

## Introduction
These days we have seen explosive evolution of Deep Learning techniques all over the world. Some people posted their achievement on their blog or summarised in research papers. However, when it comes to actually utilise it. You might face the issue in the size of that model. As we assume, deeper it is designed, more accurate it becomes. So in this post I would like to talk about the solution from Google to inevitable issue.

## On-Device Machine Learning
Over the last decade, google provides many amazing technologies, in fact they have already given us the solution for the issue we have seen in previous section.
MobileNet and ProjectionNets can actually reduce the size of given model by removing the unnecessary weights and activations. So it allows us to run inference directly on the devices, such as Arduino or Raspberry pi-like IoT devices so called. However, Google has still questioned themselves what if an user wants custom on-device learning model. So at the latest Google I/O 2018, they have announced the innovative learning strategy, **Learn2Compress** which is able to compress our model using [TF Lite](https://www.tensorflow.org/mobile/tflite/).

## How it works?
Now, enough of flirting, and let's see how actually it works.
Learn2Compress literally compresses our NN models taking as input a large TF model and automatically generates the ready-to-use on-device models.

***Architecture Image***
<img width="668" alt="Screen Shot 2018-05-16 at 9.11.43.png" src="https://qiita-image-store.s3.amazonaws.com/0/240801/152c3a1a-ab48-2145-3c5f-8b5bb1079f06.png">

If we look at the key essence in this techniques, they have proposed three points as below.

1. <font color='red'> **Pruning** </font color> reduces the model size by removing meaningless weights and activations.
2. <font color='red'> **Quantisation** </font color> techniques are particularly effective when applied during training and can improve inference speed by reducing the number of bits used in the model.
3. <font color='red'> **Joint Training** </font color> and <font color='red'> **Distillation** </font color> approaches follow a **Teacher-Student** learning strategy. Ofcourse, in this case, teacher is a given model and a student is the compressed one with minimal loss in accuracy. Also, we can train several students with different size in parallel.

<img width="571" alt="Screen Shot 2018-05-16 at 9.19.48.png" src="https://qiita-image-store.s3.amazonaws.com/0/240801/f75d047d-ac4f-765d-446e-5723185f15dc.png">

## Result
Indeed, it results very well, and sometimes it outperforms the given models.
Learn2Compress can generate the model way faster and smaller!

<img width="659" alt="Screen Shot 2018-05-16 at 9.20.05.png" src="https://qiita-image-store.s3.amazonaws.com/0/240801/0b12c274-2bfd-304c-1c19-734ad55bca95.png">
<img width="650" alt="Screen Shot 2018-05-16 at 9.20.21.png" src="https://qiita-image-store.s3.amazonaws.com/0/240801/586afd13-5956-0ad7-9066-b91ec1b4b719.png">
file_put_contentsでfailed to open stream: No such file or directory

画像アップロードの処理を作成して、ローカルでは動いてたのが本番で動かず、ナンデ！？ってなってました。

```bash:
ErrorException (E_WARNING)
file_put_contents(/home/XXXXX/XXXXX.xsrv.jp/public_html/img/upload/Pqg063R5Q4iX7r7A3yJ5.jpg): failed to open stream: No such file or directory

```

見ての通りですがパスが間違ってます。

**変に疑わずにパスを確認しまくりましょう。**

100回くらい。

それでも足りなければ１０００回くらい。

自分の場合はLaravelのドキュメントルートとかを指定していい感じにパスを指定してくれるようにしてたんですが。
本番環境ではディレクトリ構成が異なるので存在しないパスを参照するようになってしまってました。

初歩的すぎて愕然としています。