OmniAICreator/Qiita-1.07M huggingface dataset:
じゃんけんの勝敗を手っ取り早く処理する表

# じゃんけんの勝敗を手っ取り早く処理する表

## はじめに

本書は、プログラミング初心者向けに、表の実装を紹介するものである。
例として、じゃんけんの勝敗を処理する。

## じゃんけんの仕様

まず、じゃんけんの仕様を考える。

- 対戦者は2人とする。
- 対戦者はそれぞれ「グー✊」「チョキ✌」「パー✋」の3つの手から1つ選んで出す。
- 「グー✊」は「チョキ✌」に勝つ。
- 「チョキ✌」は「パー✋」に勝つ。
- 「パー✋」は「グー✊」に勝つ。
- 同じ手はあいこ（引き分け）となる。

今回は「対戦者は2人とする」という点だけ留意してもらいたい。

## じゃんけん関数

今回用意したじゃんけん関数（JavaScript）は以下の通りである。
尚、引数のエラーチェックはしていない。

このじゃんけん関数を使う場合、対戦者2人の出す手を事前に決定しておく必要がある。
ユーザーから入力を受け付けても良いし、乱数を得ても良い。
また、処理結果（勝敗）の表示もこの関数を使う側で行う事になる。

このじゃんけん関数の肝要は、勝敗表を2次元配列で表現している点である。
2次元配列とは、配列のデータの中身がさらに配列になっている物である。
これにより、表を表現する事が出来る。
記述方法の詳細は省くので、以下のソースコードから読み取ってもらいたい。

```javascript
// じゃんけん関数
// janken(you, opponent)
//
// 引数に0～2の値を入れる。
// 0：グー
// 1：チョキ
// 2：パー
//
// 戻り値
// -1：あなたの負け
//  0：あいこ
//  1：あなたの勝ち

var janken = function(you, opponent) {
    // ↓you / opp→  rock    scissors    paper
    // rock         draw    win         lose
    // scissors     lose    draw        win
    // paper        win     lose        draw
    var game = [[ 0,  1, -1],
                [-1,  0,  1],
                [ 1, -1,  0]];

    return game[you][opponent];
};
```

## おわりに

このように、答えが決まっていて将来的にも変更がないデータは、配列や2次元配列でデータを持っておくと良い。

以上。
Java の Vector がなぜ使われないのか

# はじめに
C++ だと可変長配列で `std::vector` を使いますが、Java では普通 `java.util.ArrayList` を使い、同じような機能を持つ（らしい） `java.util.Vector` は使われません。

- 同期をとるため遅いらしい
- 同期リストが欲しい場合は `java.util.Collections.synchronizedList()` を使った方がいいらしい
 
みたいな話を昔聞いてそうなのかーと思いこれまで気にしてきませんでしたが、ふとに気になったので OpenJDK のソースを見てみました。

# Vector のメソッド
確かに各メソッドに synchronized 句がついています。同期が必要ない場面では間違いなく `ArrayList` を使うべきそうです。

```Vector.java
...
    public synchronized E get(int index) {
        if (index >= elementCount)
            throw new ArrayIndexOutOfBoundsException(index);

        return elementData(index);
    }
...
    public synchronized boolean add(E e) {
        modCount++;
        add(e, elementData, elementCount);
        return true;
    }
...
```

# Collections.SynchronizedList との違い
では、`Collections.SynchronizedList(new ArrayList<>())` とし `ArrayList` をラップしたものと Vector はどう違うのか？
パッと見て違うのは、Iterator の挙動です。`Vector` では Iterator のメソッドでもほかのメソッド同様、ロックを取得しています。

```Vector.java
    private class Itr implements Iterator<E> {
...
        public E next() {
            synchronized (Vector.this) {
                checkForComodification();
                int i = cursor;
                if (i >= elementCount)
                    throw new NoSuchElementException();
                cursor = i + 1;
                return elementData(lastRet = i);
            }
        }
...
```

SyncronizedList が継承している SynchronizedCollection の場合、Iterator() はラップしている型のものをそのまま返しています。

```Collections.java
    static class SynchronizedCollection<E> implements Collection<E>, Serializable {
        private static final long serialVersionUID = 3053995032091335093L;

        final Collection<E> c;  // Backing Collection
        final Object mutex;     // Object on which to synchronize
...
        public Iterator<E> iterator() {
            return c.iterator(); // Must be manually synched by user!
        }
```

リストへの繰り返し処理を行う場合には、単一のメソッド内でのみでのロック取得では不十分で、結局繰り返し処理全体でロックする必要があり、それは自分でやってね（"Must be manually synched by user!"） ということなのでしょうたぶん。

# まとめ
- `Vector` は各メソッドに synchronized がついている
- SynchronizedList とは iterator の挙動が異なる
WITH句について

こちらの記事から
https://docs.aws.amazon.com/ja_jp/redshift/latest/dg/r_WITH_clause.html

## WITH句とは
サブクエリでテーブルを定義するもの

- SELECTより先に評価される
- 各サブクエリは、ビュー定義に似ている一時テーブルを定義する
- 一時テーブルはFROM句内で参照可能

## 構文
```sql
WITH テーブル名 AS (サブクエリ)
```

## 使用可能なSQLステートメント
- SELECT (SELECT ステートメント内のサブクエリを含む)
- SELECT INTO
- CREATE TABLE AS
- CREATE VIEW
- DECLARE
- EXPLAIN
- INSERT INTO...SELECT
- PREPARE
- (WHERE 句サブクエリ内の) UPDATE

## 例
```sql
WITH tmp_table AS (SELECT * FROM exist_table)
SELECT * FROM tmp_table;
```

## ポイント
- 固有の目的に合わせたテーブル構造のデータから更にデータを抽出したい時などに使える
- 抽出した結果を別テーブルとして作成したい時などに使える
- WITH句のサブクエリ内で、別のWITH句を指定することはできない

## 参考URL
https://docs.aws.amazon.com/ja_jp/redshift/latest/dg/r_WITH_clause.html

## 雑感
MySQLは8から使える
エントリーの編集画面でフィールドのhundleをすぐ確認する

フィールドのhundleをすぐ確認できる

> CP Field Inspect
> https://plugins.craftcms.com/cp-field-inspect

編集画面へもいけるので使い勝手が良さそう。

表示するロールを制限できるといいのかも？だけどどうなってるのかは後で見てみる。
phpenvでphpの実行エラーがあり、バージョンチェックでもエラーが出てしまう場合の対処法


## 該当エラー
dyld: Library not loaded: /usr/local/opt/icu4c/lib/libicui18n.62.dylib error running php

## 原因
ライブラリを参照しているが、ライブラリがない。
おそらく最新版にアップデートした時にこのバージョンが消えてしまうため発生する。

## 解決方法

```shell
$ cd /usr/local/Homebrew/Library/Taps/homebrew/homebrew-core/Formula/
$ git fetch --unshallow
$ brew log icu4c
```
エラーが出ているバージョンがある履歴にチェックアウトします。
libicui18n.62.dylib
なので、このバージョンを指定してチェックアウト。

```shell
$ git checkout c179a064276d698d66953898ff9e02d6e0664b2a icu4c.rb
$ brew uninstall icu4c
$ HOMEBREW_NO_AUTO_UPDATE=1 brew install icu4c
```

とすることで、必要なバージョンがインストールされ実行できるようになりました。

## 参考サイト
https://codechord.com/2018/09/solution_for_php_error_after_upgrade_homebrew/

と書いたのだが、brew updateして、phpenvで該当のPHPを入れ直したら動作したとさ。
[Mac] Goのアンインストール

公式の**macOSパッケージインストーラ**を使ってぶち込んだGoをアンインストールするメモ
といってもこれだけ

1. `/usr/local/go`を削除
2. `/etc/paths.d/go`を削除

※間違えて消しちゃいけないとこ消さないように注意

# `/usr/local/go`ディレクトリを削除する

普通にインストールしてれば`/usr/local/go`にGoが入ってるはず
このフォルダをまるっと削除する

```bash
sudo rm -rf /usr/local/go
```

# `/etc/paths.d/go`を削除する

`/etc/paths.d/go`を消すと環境変数のPATHからGoの`bin`へのパスを消せる。

```bash
sudo rm -rf /etc/paths.d/go
```

# 終わり

最初公式のマニュアルを適当に読み飛ばしてたので
PATHから`/usr/local/go/bin`が消せずどうなってるんだと奮闘。

あれこれ調べて解決できたものの
公式見たら普通に`/etc/paths.d/go`も消してねと書いてあった。

マニュアルはちゃんと読めと(\`ω`)
Jupyter NotebookでMeCabとNEologdをインポートするまで（Mac）


##AnacondaではMeCabをインストールできない？
普段は「$conda install ~」でインストールを行っているが

```
$ conda install mecab-python3
```

Macのターミナルで上記コマンドを実行すると・・・

```
WARNING: The conda.compat module is deprecated and will be removed in a future release.
Collecting package metadata: done
Solving environment: failed

PackagesNotFoundError: The following packages are not available from current channels:

  - mecab-python3

Current channels:

  - https://repo.anaconda.com/pkgs/main/osx-64
  - https://repo.anaconda.com/pkgs/main/noarch
  - https://repo.anaconda.com/pkgs/free/osx-64
  - https://repo.anaconda.com/pkgs/free/noarch
  - https://repo.anaconda.com/pkgs/r/osx-64
  - https://repo.anaconda.com/pkgs/r/noarch

To search for alternate channels that may provide the conda package you're
looking for, navigate to

    https://anaconda.org

and use the search bar at the top of the page.
```

( ´ω` ):


##$pip install を使う

色々調べた結果、AnacondaではMeCabをインストールできないらしく、
pip install で実行しろとのことでした。。。

```
$ pip install mecab-python3
```

この方法でも上手くいかない場合はjupyter notebookに直接下記コードを入力します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/401957/bf1714e3-ba18-182b-eda7-c7f494cf9e99.png)

すると。。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/401957/0730b638-6608-2de3-0e3d-072fcaa9dcfb.png)

とりあえずMeCabは使えるようになりました( ◜ω◝ )
（Pythonの初期構築で色々苦労したのでcondaコマンド以外でのインストールはあまりしたくないのです。。）


##NEologdのインストール

NEologdをインストールするには「git clone」コマンドを使うそうで・・・

とりあえず、MeCabのディレクトリまで移動して。。

```
$ cd [めかぶディレクトリ]
```


```
$git clone --depth 1 https://github.com/neologd/mecab-ipadic-neologd.git
$cd mecab-ipadic-neologd
$./bin/install-mecab-ipadic-neologd
```

```
[install-mecab-ipadic-NEologd] : Start..
[install-mecab-ipadic-NEologd] : Check the existance of libraries
[install-mecab-ipadic-NEologd] :     find => ok
[install-mecab-ipadic-NEologd] :     sort => ok
[install-mecab-ipadic-NEologd] :     head => ok
[install-mecab-ipadic-NEologd] :     cut => ok
[install-mecab-ipadic-NEologd] :     egrep => ok
[install-mecab-ipadic-NEologd] :     mecab is not found.
```
_(-ω-`_)⌒)_

もしかして。。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/401957/47d6fe6e-7dee-c3e9-aa66-51e06afb26f6.png)

あ、同じ方法でいけました笑

終わり。
AtomのパッケージのViewがスクロールできない時

AtomのパッケージのViewがスクロールできない問題を（一応)解決したのでメモ
[ここ](https://discuss.atom.io/t/how-to-get-panel-to-scroll-on-overflow-without-scrollview/29176)参照

## 解決方法

Viewの`getElement()`のHTMLElementに以下のスタイルをcssや`element.style`から追加する。

```
overflow: auto;
```

## そうじゃないやり方もありそう

[atom-space-pen-views](https://github.com/atom/atom-space-pen-views)のScrollViewや[markdown-preview](https://github.com/atom/markdown-preview)を見てみると`core:move-up`のようなイベントを受け取って、スクリプトからスクロールしているみたい。

有名どころが上の解決方法を使っていないので、何か問題があるかもしれない。Coffeescriptが読めないので時間がかかりそうだけどこのやり方でスクロールできるようにしたい
自宅で開発環境メモ

作成中

##0. 目次
 1.やりたいこと
 2.VMWARE Playerをダウンロード・インストール(vmwaweユーザ登録必要)
 3.CentOSのisoをダウンロード
 4.仮想マシン作成
 5.CentOSをインストール
 6.ネットワーク設定
 7.GUI環境の構築
 8.リモートデスクトップでアクセスできるようにする
##1. やりたいこと
・windows10環境にVMWARE Playerをインストール
・VMWARE Playerで仮想マシン作成(CentOs)
　- 開発環境用
　- gitサーバー用
## 2.VMWARE Playerをダウンロード・インストール(vmwaweユーザ登録必要)
・vmware公式にアクセス
https://www.vmware.com/jp.html
・ユーザ登録してログイン
・「製品のダウンロード」
・「VMware(R) Workstation 15 Player」をダウンロード
・ダウンロードしたexeを実行してインストール
## 3.CentOSのisoをダウンロード
・CentOS公式からisoをダウンロード
http://isoredirect.centos.org/centos/7/isos/x86_64/CentOS-7-x86_64-DVD-1810.iso
## 4.仮想マシン作成
・VMWARE Playerを起動して仮想マシンの作成
・インストーラ ディスク イメージファイルでCentOSのisoを指定
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/404257/87728224-555e-d040-0fed-ad9a3ebd4ea4.png)
・後は変える必要があるところのみ変えて作成(メモリ、HDDのサイズは用途に応じて変えたほうが良いかも)
## 5.CentOSをインストール
・仮想マシンの再生
・VMWAREロゴの時に「F2」ボタンを押下
・BootタブでCD-ROMを一番上にする(+/-で順序を変えられる)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/404257/325c11dc-1061-6437-0af1-4d1ae6e3568e.png)
・F10を押すとOSインストール画面に移行する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/404257/257d0b07-4814-8890-c484-95edac19cb68.png)
最後に再起動が必要だけど、次回起動する前にbios画面で起動順序を戻しておく
(そうしないと、またインストールが始まってしまう)
## 6.ネットワーク設定
以下2点を実現させる必要がある
⓵ホストOSからpingが通ること
⓶ホストOS経由でインターネットにつながること
[ホストOSでの作業]
・ホストOSで「コントロール パネル\ネットワークとインターネット\ネットワーク接続」でアダプタ一覧確認
・実際にインターネットに接続しているアダプタとVMware Network Adapter VMnet8を確認
・実際にインターネットに接続しているアダプタの「プロパティ」-「共有タブ」-インターネット接続の共有-ネットワークのほかのユーザに、～をチェック、ホームネットワーク接続でVMware Network Adapter VMnet8を選択
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/404257/9d240f1c-11cf-99d8-407a-5bf60a92ee60.png)

・VMware Network Adapter VMnet8のIPアドレス/DNSサーバを自動的に取得するに変更
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/404257/5a18b92d-3b8a-8f2a-fcd9-eba7ee654f3b.png)

・VMware WorkStationの仮想マシン設定でネットワークアダプタをNATに指定
[ゲストOS]
・設定で以下のように設定する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/404257/807955fa-9bdf-eb40-8aee-5eaa889e461d.png)
・ネットワークを再起動する

## 7.GUI環境の構築
ここからホストOSにTera Termを入れて設定されたIPにssh接続して実施

以下を参考にさせてもらいました
[CentOS7にGUI環境を追加する方法](https://qiita.com/Targityen/items/f2bfd3e7fe761ec0b83a)

yum update でエラーになる場合はネットワークの設定が上手くいっていない
大体仮想マシンからネットワークへの接続が上手くいってない(デフォルトデートウェイが間違っている？)
## 8.リモートデスクトップでアクセスできるようにする
以下を参考にさせてもらいました
[CentOS7.6にGUIリモートデスクトップ接続](https://qiita.com/okcoder/items/633822fa3ba53cd14790)
vimscriptからpythonするのを補助するpycallを作る

ええと、 `vim` で `python` を書く記事ではありません。

`vimscript` の `py3` もしくは `py3file` で定義した `python` 関数を、 `vimscript` から楽に呼び出せるようにする記事です。


作成中
https://github.com/ousttrue/vim-pycall


# vimscript の py3 コマンド


https://vim-jp.org/vimdoc-ja/if_pyth.html

> 例

```vim
        :python print(sys.version)
```

短い `python` 文を投げっぱなしにして、副作用は `python` 側でがんばれーという感じですね。引数を渡すことも、結果をもらうこともできなくなくないか。

`pydo` はわいの目的には合わないのでスルー。

> 引数を渡すためには明示的に sys.argv[] を使って設定してください。例:

```vim
        :python sys.argv = ["foo", "bar"]
        :pyfile myscript.py
```

・・・python側に最初から書いておけばいいのでは・・・
既存のコマンドラインのpythonスクリプトを無変更で呼び出すことを想定している？

# python 側で vim モジュールを使うのだ

```py
import vim
```

```py
# pythonにvim変数を渡す
foo = vim.eval("g:foo")
```

```py
# pythonからvim変数を変える
value = 1
vim.command(f"let g:ret = {value}")
```

変数名を固定すれば `vim` と `python` でやりとりできそうではある。

`vim.bindeval` は `nvim` には無かったのでスルー。

# python関数を呼び出すラッパー関数を作る

[Pythonでvim pluginを書く](https://qiita.com/zakuro9715/items/98449dd4c6b9e1d61ef5)

を見て関数を経由することで引数名を固定する方法を知る。

```py
# py3 か py3file で定義されたことにする
def hello(name):
  print('Hello {0}'.format(name))
```

```vim
function! pycall_hello(name)
  " python定義済みの関数呼び出し
  py3 hello(vim.eval('a:name'))
endfunction
```

`a:name` であって `g:name` でないのが素敵。なるほど。

## 返り値の名前を python 関数の引数に追加しよう

```py
# python側でprintするのをやめて let で vim側に値を渡す
def hello(name, ret_name):
  vim.command(f"let {ret_name} = '{name}'")
```

```vim
function! pycall_hello(name)
  " python定義済みの関数呼び出し
  py3 hello(vim.eval('a:name', 'l:ret'))
  if exists('l:ret')
    return l:ret
  endif
endfunction
```

返り値も同様に名前を固定。
`g:ret` でなく `l:ret` にできたので、`vimscript` のグローバル変数が `python` 関数毎に必要になるということは無くなった。

## 任意のpython関数を呼び出せる汎用の呼び出し関数にする

python関数に２つの拡張が必要

* 関数名を受ける引数の追加
* vim関数の可変長引数をpythonに渡す

pythonの関数名を受けて間接的に関数を呼び出す `py_dispatcher` を作った。

```py
def py_dispatch(name, ret_name, args):
    '''
    name: python関数名
    ret_name: 返り値を格納するvim変数名
    args: 引数
    '''
    # dispatch function
    value = globals()[name](*args)

    if value:
        # return to vim by let
        value = to_vim(value)
        command = f'let {ret_name} = {value}' # ここで ret_name に値をセットすることでvimに値を返す
        try:
            vim.command(command)
        except vim.error as e:
            print('error', command)
            print('error', e)
```

```vim
function! PyCall(name, ...)
    py3 py_dispatch(vim.eval('a:name'), 'l:ret', vim.eval('a:000'))
    if exists('l:ret')
        return l:ret
    endif
endfunction
```

globalスコープの任意のpython関数を呼び出せるようになった。

## 使い方

```py
# 他のところで定義
def hello2(hello1, hello2):
    return f'hello {hello1} and {hello2}!'
```

`hello` 関数を探して、引数を渡して呼び出し、返り値を `echo` する。
`:echo PycCall('hello', 'hoge', 'fuga')`

# 使ってみる

`ToDo`
【Gang of Four】Memento

#Memento
[目次]
当該パターンはある時点でのオブジェクトの状態を保存しておくのが目的？
プライベートメンバは基本的に外部からアクセスすることはできません。しかし、色々なソフトウェアでctrl(あるいはcommand)+zキーで1つ前の状態へ完璧に戻れるように、ある特定のオブジェクトの状態をまるっと保存しておきたいシチュエーションは多々あると思います。

そんな時に本パターンを用いると理解しています

##目的
カプセル化を破壊せずに、オブジェクトの内部状態を捉えて外面化しておき、オブジェクトを後にこの状態に戻すことができるようにする。 

##構成要素
・Memento あるオブジェクトの状態を保存しておくクラス
・Originator ある時点での状態を保存しておきたいオブジェクト。mementoオブジェクトを生成し、元に戻すためにmementoオブジェクトを使う。
・Caretaker Mementoオブジェクトの保管庫

##実装
ゲームのセーブデータを作るような感じのサンプルプログラムを実装します。

###Memento あるオブジェクトの状態を保存しておくクラス
セーブデータクラス
任意の時点でのレベル、所持金、経験値のキャプチャを保存します。

```SaveData.kt
package memento

class SaveData(val level: Int, val gold: Int, val point: Int) {
    fun show() {
        println("レベル：$level 所持金：$gold 経験値：$point")
    }
}
```

###Originator ある時点での状態を保存しておきたいオブジェクト。mementoオブジェクトを生成し、元に戻すためにmementoオブジェクトを使う。
現在プレイ中の情報

```Game.kt
package memento

class Game(private var level: Int, private var gold: Int, private var point: Int) {

    fun show() {
        println("レベル：$level 所持金：$gold 経験値：$point")
    }

    /**
     * 敵を倒した
     */
    fun enemyDown(enemyLevel: Int) {
        point += enemyLevel

        if (point >= 10) {
            level += point / 10
            point %= 10
        }

        gold += enemyLevel
    }

    /**
     * 現在の状態を取得
     */
    fun getData(): SaveData {
        return SaveData(level, gold, point)
    }
}
```

###Caretaker Mementoオブジェクトの保管庫

```MemoryCard.kt
package memento

class MemoryCard {
    private val memory = ArrayList<SaveData>()

    /**
     * セーブ（保存）
     */
    fun save(data: SaveData) {
        memory.add(data)
    }

    /**
     * ロード（復元）
     */
    fun load(index: Int): Game {
        val data = memory[index]
        return Game(data.level, data.gold, data.point)
    }
}
```

###使う人

```Client.kt
package memento

class Client {
    init {
        // メモリーカードを指す
        val memoryCard = MemoryCard()

        // ゲームスタート
        var game = Game(1, 0, 0)
        // 敵撃破
        game.enemyDown(1)
        game.enemyDown(5)
        game.enemyDown(6)

        // セーブ
        memoryCard.save(game.getData())

        // 現在の状態
        game.show()

        // 敵撃破
        game.enemyDown(4)
        game.enemyDown(2)
        game.enemyDown(8)

        // セーブ
        memoryCard.save(game.getData())

        // 現在の状態
        game.show()

        // 獲得し損ねたアイテムがあったため最初にセーブした状態へと戻す
        game = memoryCard.load(0)

        // 現在の状態
        game.show()
    }
}
```

###出力結果
```
[out-put]
レベル：2 所持金：12 経験値：2
レベル：3 所持金：26 経験値：6
レベル：2 所持金：12 経験値：2
```

以上
Raspbian Stretch with desktop インストール

#はじめに

ラズパイでブラウザを使いたくなったのでRasbianのOSをLiteからwith Desktopに交換することにしましたが、インストールで躓いたのでメモしておきます。

#準備

SDカードはSDカードフォーマッターを使ってフォーマットしておきます。Raspbian Stretch with desktopは以下からダウロードします。

https://downloads.raspberrypi.org/raspbian_latest
（今回は）ファイル名：**2019-04-08-raspbian-stretch.zip**

ダウンロードが完了したら展開します。
ファイル名：**2019-04-08-raspbian-stretch.img**

macにmicroSDカードを接続して、以下を実行します。

```
$ cd downloads
$ diskutil list
$ sudo diskutil unmountDisk /dev/disk2

Unmount of all volumes on disk2 was successful
```
ここまでは順調でした。

#sudoでSDカードに書き込む（結果失敗）

```
$ sudo dd bs=1m if=2019-04-08-raspbian-stretch.img of=/dev/disk2 conv=sync
```
SDカードにfor desktopのインストールし、ラズパイにSDカードを装着して起動しようとすると、何度やり直しても、**Unable to mount root fs on unknown-block** のメッセージで止まってしまうという状況に陥りました。Liteの時はこのやり方で成功しましたが、with Desktopでは何故かうまく行きません。そこで、他のやり方を試すことにしました。

#Etcherを使ってSDカードに書き込む（結果成功）

https://www.balena.io/etcher/ から、macOS用をダウンロードしインストールします。
立ち上げて、以下を順に実行します。
**1. Select image
2. Select drive（自動的にremovable driveを検出）
3. Flash!**

Flash終了後、ラズパイにSDカードを装着して起動したところ、成功しました。

**・背景画像が表示され、ブラウザChromiumも立ち上げ可能。
・gmail登録することでChromeのお気に入りが自動コピーされる。
・Wifiが自動検出され、PW入力して接続可能（外部アンテナは不要）。
・USBマウス、USBキーボード使用可能。**

#終わりに

ラズパイは、Raspbian Stretch with desktopをインストールして、ディスプレイ、キーボード、マウスを外付けすることで、PCとしても十分機能を果たすことを実感できました。

![IMG_3428.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/311614/60efc562-17d9-5af7-6c64-1ad418e3f8a8.jpeg)
java用PropertyBaseTestingツールEasyRamdomを試す

EasyRamdomはJavaのインスタンスをランダムに作ってくれるツール。Property Base Testingツールの一種です。

https://github.com/j-easy/easy-random

特徴はこんな感じ
- getter/setter/デフォルトコンストラクタがなくても生成可能(自分はgroovyのspockで試しました。spockでは不要でした。JUnitとかだと試していないです。念の為。)
- 型に合わせてデータを作ってくれる
- 複雑な型もOK
- とにかくシンプル
- 生成方法は柔軟に変更可能
- EnumはEnumの値からランダムで選択してくれる
- BeanValidationと併用するとValidationの制限値内でデータを作ってくれる

結構自分的には理想的なツールです。

dependenciesは一つだけ。
BeanValidationを使用する場合はeasy-random-bean-validationも。

```gradle
dependencies{
    testCompile "org.jeasy:easy-random-core:4.0.0.RC1"
    testCompile "org.jeasy:easy-random-bean-validation:4.0.0.RC1"
}
```

## 基本
```java
EasyRandom easyRandom = new EasyRandom()
Quantity quantity = easyRandom.nextObject(Quantity.class)
```
これだけでQuantityオブジェクトが生成されます。
Quantityの中身がどうあれ型に合わせて作ってくれます。

seedは固定のようなので基本毎回同じ値を返してします。なので、seedを指定することをおすすめします。

```java
EasyRandomParameters parameters = new EasyRandomParameters().seed(System.currentTimeMillis())
EasyRandom easyRandom = new EasyRandom(parameters)
Quantity quantity = easyRandom.nextObject(Quantity.class)
```

## 生成方法を変更する
Randomizerを作成すると自由に生成方法を変更できます。以下の例は(令和!?)１〜1000の範囲内で生成するようにしています。

EasyRamdomでbuildinのRandomizerもあって、名前や郵便番号などを生成してくれるものらしいです。内部で[faker](https://github.com/DiUS/java-faker)というツールを使用しているみたいです。
Localeも指定できるようなので、日本語の名前や住所なんかも生成できそう。まだ試してないけど。
使用にはeasy-random-randomizersをdependenciseに追加する必要があります。

```java:QuantityRandmizer.java
public class QuantityRandmizer implements Randomizer<Integer>
{
    @Override
    public Integer getRandomValue()
    {
        return ThreadLocalRandom.current().nextInt(1, 1000 + 1);
    }
}
```

```java
EasyRandomParameters parameters = new EasyRandomParameters().seed(System.currentTimeMillis())
                .randomize(FieldPredicates.named("value")
                .and(FieldPredicates.ofType(Integer.class))
                .and(FieldPredicates.inClass(Quantity.class)), new QuantityRandmizer())

EasyRandom easyRandom = new EasyRandom(parameters)
Quantity quantity = easyRandom.nextObject(Quantity.class)
```

## BeanValidationとともに使用

BeanValidationの範囲内で生成することもできます。
以下の例では、100から１000の範囲内で生成されます。

```java:Quantity.java
public class Quantity
{
    @Min(100)
    @Max(1000)
    Integer value;

    public Quantity(Integer value)
    {
        this.value = value;
    }
}
```

```java
EasyRandomParameters parameters = new EasyRandomParameters().seed(System.currentTimeMillis())
EasyRandom easyRandom = new EasyRandom(parameters)
Quantity quantity = easyRandom.nextObject(Quantity.class)
```

素晴らしい！
自己紹介


#初めましてQiita。
**GINJILISM**と申します。
今日は初めてこのQiitaを投稿して見ようと思います。

高専の情報科に通っていますが、普段は写真や映像などのアート系のことを専門としています？
またメディアアートに興味があり、ARアプリも作っています。

また、普段考えていることはnoteにあげようと思ったらあげようと思います。~~ちなフォロワー0~~
[note](https://note.mu/ginjiandginji123)
さらに将来アート系に進もうと思っているのでカメラは常に持ち歩いて感受性が鈍らないようにしています。
その写真はinstagramにほぼ毎日上げているのでチェケラ！
[instagram](https://www.instagram.com/silver_dancer_is/)

##このQittaの使い方##
##AR##
このQiitaではARについて何か作ったら上げていくようにしたいと思います。(アウトプットが大事!)
ARは主にSwiftのフレームワークであるARkitを使っています。また最近はARStudioでお手軽にフィルターを作って遊んでます。Apex Legendsより楽しい!?

直近だとアイアンマンになれるARフィルターを作りました。完成度はそこそこ高いと自負しています。
[FB appが入ったスマホでここを押す](www.facebook.com/fbcameraeffects/tryit/417962572327941/)とあなたもアベンジャー！
そのうちインスタでも随時シェアできるようになると思うので、インスタフォローお願いします。

##4次元/卒研##

今は高専5年で卒研まっしぐらです。卒研内容は**ARを用いた4次元空間の投影**です。4次元は2次元の紙面場では表現出来ないけれど、3次元的なARを用いれば投影できそう！という気がしたからです。また研究室も自由主義な理論物理学の教授に所属しているので、上手く行ったら4次元空間での重力の伝わりかたなども研究したいと思っていますが、今はまだそもそも4次元って?という段階です。なのでこのQiitaを通してわかったことはアウトプットしていきたい。(願望)

##そんな感じでよろしく！##
わいのリンクまとめ
[note](https://note.mu/ginjiandginji123)
[instagram](https://www.instagram.com/silver_dancer_is/)
[YouTube](https://www.youtube.com/channel/UCsvkxr041U49K69JPKkdOtA?view_as=subscriber)
[アイアンマンフィルター](www.facebook.com/fbcameraeffects/tryit/417962572327941/)
WWDC Pre Party 2019 [Timers Meetup #1]

# はじめに
[TIMERS inc.](https://timers-inc.com) さん主催で WWDC Pre Party 2019 が行われました！
[CONNPASS（イベントページ）](https://timers.connpass.com/event/125532/)

ここでは、イベントに参加して学んだことを WWDC 初心者としてまとめてみたいと思います。
実際に発表していただいた詳細な内容などは、プレゼン資料などで確認していただければと思います。

# WWDC 会場まで
- 空港から会場まで距離があるので、以下のことに注意するべし！
    - 交通手段
    - 宿泊場所
    - 出発・帰宅時間

- Uber
    - 距離があるなら迷わずコレ！
    - 複数人なら割り勘できる
    - スマホで決済が完結
    - 工夫すれば安く利用できる（キャンペーンコードを路上で配ってることも！？）
- VTA
    - $2 / 1 回乗車
    - VTAアプリでの決済がオススメ

# WWDC職人の朝は早い
- Day1 Keynote Session
    - 先着で座席が決まるので、何時間も前から並ぶ

- Day2 ~ Day5
    - Day1 ほどではない
    - UDLは人気なので抽選（これも朝に行われるので待機！）

# 持ち物
- iPhone
    - 発表されたっばかりの iOS をメイン端末にインストールするとアプリが正常に使えないことも！
        - インストールは優先で行うので変換端子・ケーブルもお忘れなく！
    - 検証端末を含めて2台以上持っていきましょう！
- サングラス必須とのこと！
    - 帽子もあるとGood
- 保温性の高い水筒（水分補給マジ大事！）
- アクティベート済のSIM
- 魔法のカード（クレカ）

# 食べ物
- WWDC 会場でもらえるご飯は美味しくない　で有名らしい
- スタバ・スーパーが近くにあるからオススメ！
- サンノゼ州立大学のフードコートがオススメとのこと！

# 事前準備
- ラボ参加希望の場合は iPad などで説明できる準備をしておくといいかも
    - メモ書きで回答してもらえることも！
    - 日本語対応して貰える場合もあるらしい
- SIMのアクティベート
- FacebookのWWDC参加日本人コミュニティに加わる

# 時間の使い方を工夫
- 初日は特に待ち時間が長い
- Company Store
    - 会場外で1時間、会場内で1時間の待ち時間
- 3人以上で行動すると良い！
    - 列に並んでいる途中で食事・トイレ等に行くことができる
    - 3人以上だと、一人トイレ等に行っても話し相手がいなくならない！

# 最後に
ここにまとめたことは、個人的な感想などを含みます。
正確な情報を必要とするときは、様々な情報源と照らし合わせて判断していただくようにお願いします。
最後まで読んでいただき、ありがとうございます。

WWDC結果報告でお会いしましょう！
Emacsにコード補完パッケージcompany-modeをインストールする（初心者向き）

## プロローグ
最近やむにやまれず、コマンドラインのlinux上でemacsというエディダを使う事になりました。
Pythonを開発するにあたって、コード補完機能が必要という事が分かり、emacs上でcompany-modeというコード補完のパッケージをインストールする際の備忘として残します。
参考：[Emacsの使い方~超初級編~](http://nigohiroki.hatenablog.com/entry/2012/09/16/005841)

emacsの完全なる初心者なので、このパッケージをインストールするだけで一苦労、ネット上には知っている前提でインストール法を紹介しているものが多く、心の中で「いや、この情報でインストールできる人はそもそもぐぐらねぇ！」と叫んでしまった。

という事で本題に進みます。
## Emacsのインストール
念のため、Emacs自体もインストールしていない場合は、インストールしておきます。
OSはUbuntu 16.04.6です。

```
sudo apt-get install emacs
```

## パッケージリストでcompany-modeの確認
コード補完をするパッケージとして、company-modeというものを使用しますが、パッケージ名はcompanyです。
まずは、それを確認する為にlinuxのコマンドライン上でemacsを立ち上げます。

```
emacs
```
次に、インストールできるパッケージを確認します。
ここで、まず壁にぶつかります。調べると「M-x package-list-package」で確認できるそうですが、普通にコマンドを打ってもうまくいきません。emacsでは「M-x」はショートカットキーを表していて、Esc + x　、つまり「Esc」キーと「x」の同時押しを意味します。。。なぜそう言ってくれないと初心者ながらに思います。その丁寧なひと言でどれだけ時間が節約できるか。
そして、「package-list-pacakge」のところも「-」はハイフンではなく、スペースキーを押すと勝手に「-」になります。
まとめるとパッケージリストを確認するためには、Esc+xの同時押しをした状態で、下記のようにコマンドを打つと「M-x package-list-package」になります。

```
package list package
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328424/924f5d5d-444c-2af1-1261-b14c958e7524.png)
companyの0.9.10のバージョンがあることが確認できました。

## Companyのインストール
Companyというパッケージがあることが確認できました。
次にいよいよインストールです。調べると、まぁ簡単「M-x pacakge-install company」でできるそうです。
「M-x」は意味が分かりました。「pacakge-install」もpackage、スペース、installでOK。
では、スペースとは？結論から言うとスペースではなく、[RET]と表記する事もあるようなのですが、要はEnterキーを打てってことです。
インストールするには、Esc+xの状態で、下記コマンドを打って、

```
package install
```
すると、

```
Install package: 
```
と表示されて、ここで「company」とパッケージ名を入力するとインストールできます。

## Emacsを終了する
これも意外にはっきり言われないとわかりにくいところですが、Emacsの終了方法は
「C-x C-c」で、C-xはCtrlキーとxの同時押しの意味で、つまりはCtrl+x の次にCtrl+cを押すと終了できるという事です。

以上Emacs初心者の自分が、こんな簡単なことを実現するために困ったことをまとめました。
AWS EC2でAmazon Linux2にuwsgiのインストールが失敗する件の対処方法

OS：Amazon Linux 2
インスタンスタイプ：t2.micro


uwsgiをインストールしようとして以下のコマンドを
実行するとエラーが発生してインストールが失敗する。

```
pip install uwsgi
```

「sudo yum groupinstall "Development Tools"」を実行して、
Development toolsのグループパッケージ一式をインストールしてから
再度「pip install uwsgi」を実行するとインストールが成功する。

```
sudo yum groupinstall "Development Tools"
pip install uwsgi
```
**参考URL**
[yum groupinstall "Development tools" で入るパッケージ一覧（CentOS）](https://qiita.com/hirapi/items/6f9da09b9af795c11b71)
Slack Incoming WebHooks を作成したユーザを解除した時の影響

[@koshi_life](https://twitter.com/koshi_life) です。

プロジェクト離任に伴い、自分のSlackアカウントで作成したincoming-webhooksがアカウント解除後も影響がないか心配だったので調べてみました。

# TL;DR

incoming-webhooks の設定を行ったアカウント解除しても影響はありません。

# ヘルプページを見てみる

冒頭の心配事について公式ページに記載がありました。

日本語ページ：
>[解除されたメンバーのアプリやインテグレーションを管理する](https://get.slack.help/hc/ja/articles/360000446446-%E8%A7%A3%E9%99%A4%E3%81%95%E3%82%8C%E3%81%9F%E3%83%A1%E3%83%B3%E3%83%90%E3%83%BC%E3%81%AE%E3%82%A2%E3%83%97%E3%83%AA%E3%82%84%E3%82%A4%E3%83%B3%E3%83%86%E3%82%B0%E3%83%AC%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3%E3%82%92%E7%AE%A1%E7%90%86%E3%81%99%E3%82%8B)
>メンバーのアカウントを解除すると、そのメンバーがインストールしたアプリや内部インテグレーションのいくつかが自動で無効になります。ボットユーザー、スラッシュコマンド、 Incoming Webhook など、機能の一部が引き続き利用できる場合もありますが、メンバー固有の権限が必要なアプリは完全に無効となります。

incoming-webhooks は引き続き利用できる一部機能に入っているらしい。

英語ページ：
>[Manage deactivated members' apps and integrations](https://get.slack.help/hc/en-us/articles/360000446446-Manage-deactivated-members-apps-and-integrations)
When member accounts are deactivated, some apps they've installed (whether third-party or custom) will automatically disable. Some features may remain active (bot users, slash commands, incoming webhooks, etc.), but apps that require member-specific permissions will disable entirely.

Some features(incoming webhooks) may remain active.
とのことなので、大丈夫っぽい。

# 心配なので一応実験してみた

<img width="800px" alt="test-incoming1.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/51734/f9106065-fff8-33b1-a81c-eeb86591aab6.png">

- ダミーアカウントでSlackに招待
- ダミーアカウントでチャンネル作る
- ダミーアカウントでそのチャンネルに incoming webhooks の設定をする
- 12:03 Webhooks 叩いてみる
- 12:08 アカウント解除する
- 12:38 Webhooks 叩いてみる

アカウント解除後もincoming-webhooksが継続的に利用できることがわかりました。
これで安心して離任できます。良かった良かった。

ちなみに該当のincoming webhooksを削除しない限り、[incoming webhooksの設定画面](https://slack.com/apps/A0F7XDUAZ-incoming-webhooks) に名は残ります。

<img width="800px" alt="slack_incoming_settings2.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/51734/a498ac3c-cc8c-c4b3-d80c-30d6348181ee.png">
redirect_toにflashメッセージを設定する

なかなか辿り着かなかったのでメモ。

```rb:controller
redirect_to users_url, flash: { danger: "不正なデータがあったため、登録出来ませんでした。" }
```

参考になりました！

http://to-developer.com/blog/?p=1866

```rb:view
<div class="container flash-area">
  <!-- フラッシュメッセージがある場合に表示-->
  <!-- bootstrapのメソッド 第一引数にsuccess, danger等のタイプ、第二引数にメッセージを格納-->
  <% flash.each do |message_type, message| %>

    <!-- タイプ毎に色を切り替える-->
    <div class="alert alert-<%= message_type %>">
    
      <!-- メッセージを表示する-->
      <%= message %>
    
    </div>
  <% end %>
</div>
```

```rb:controller
                                                                    # この部分がビューのmessage_typeに格納される
return redirect_to not_joined_service_user_settlements_url, flash: {warning: "この講座は料金が設定されていないため、現在加入出来ません。"} if @learning_course.payment_id == nil && @learning_course.payment_amount == nil
    
return redirect_to not_joined_service_user_settlements_url, flash: {warning: "既にこのコースは決済済です。"} if course_view_info.pay_times.present? && course_view_info.settlement_date.present? && course_view_info.settlement_status === "settled"
```
ファイルにパスを書いてfindコマンドにインプットする

## やりたいこと
テキストファイルにフルパスをいくつか書いてfindコマンドのインプットにする

**ファイル階層**

```bash
$ ls -lR /home/kusakari/test/
/home/kusakari/test/:
drwxrwxr-x 2 kusakari kusakari 18  4月 24 00:45 a
drwxrwxr-x 2 kusakari kusakari 18  4月 24 00:45 b
drwxrwxr-x 2 kusakari kusakari 18  4月 24 00:45 c

/home/kusakari/test/a:
-rw-rw-r-- 1 kusakari kusakari 0  4月 24 00:45 afile

/home/kusakari/test/b:
-rw-rw-r-- 1 kusakari kusakari 0  4月 24 00:45 bfile

/home/kusakari/test/c:
-rw-rw-r-- 1 kusakari kusakari 0  4月 24 00:45 cfile
```

**入力ファイル**

```text:input
$ cat input 
/home/kusakari/test/a
/home/kusakari/test/c
```

**コマンド**

```
$ pwd
/
$ find `cat /home/kusakari/input` -type f -print
/home/kusakari/test/a/afile
/home/kusakari/test/c/cfile
```

以上です
【ニコニコ動画】niconicoコンテンツ検索APIが2019/6/3よりリニューアルされる件

# はじめに

いちニコニコ動画ユーザーとして個人的にお世話になっている「niconicoコンテンツ検索API」が2019/6/3より大幅にリニューアルされるとの告知が2019/4/22に掲載されていた（というか既に新APIのページに切り替わっていた）ので、旧APIからの主な変更点をまとめてみた。

新API（現在のページ）：http://site.nicovideo.jp/search-api-docs/search.html
旧API（キャッシュ）：http://webcache.googleusercontent.com/search?q=cache:EDYSNbn5F4YJ:site.nicovideo.jp/search-api-docs/search.html

# 変更点

## 1. 検索対象が動画と生放送のみとなる

>本APIは2019年6月3日より以下の仕様に変更になり、動画と生放送以外は検索できなくなります。 今後も利用を続けられる場合は、検索対象のサービスおよびご利用中のフィールドが仕様に記載されているかご確認ください。 本ページに記載されていないものは今後ご利用になれません。

リニューアル前のAPIではニコニコ動画内の13種のサービスが検索対象として指定できたが、2019/6/3以降は検索対象が`video 動画`と`live 生放送`のみとなる。

### 2019/6/2以前

- video 動画
- live 生放送
- illust 静画(イラスト)
- manga 静画(マンガ)
- channel チャンネル
- channelarticle ブロマガ記事(著名人)
- news ニュース
- game ゲーム
- license_search 権利楽曲
- mylist_video 動画マイリスト
- summary まとめ
- community コミュニティ
- commons コモンズ

### 2019/6/3以降

- video 動画
- live 生放送

## 2. 検索に使用できるフィールドの追加

### 追加された video 動画 検索フィールド

| フィールド名 | 説明 |
|:---------|:--------|
|userId|投稿者のID|
|channelId|チャンネルのID|
|tagsExact|タグ完全一致(空白区切り)|
|lockTagsExact|ロックされたタグ完全一致(空白区切り)|
|genre|ジャンル|
|genreKey|ジャンルを識別する文字列|
|threadId|スレッドのID|


### 追加された live 生放送 検索フィールド

| フィールド名 | 説明 |
|:---------|:--------|
|userId|放送者のID|
|channelId|チャンネルID|
|communityId|コミュニティID|
|providerType|放送元種別|
|tagsExact|タグ完全一致(空白区切り)|
|openTime|生放送の開場時間|
|timeshiftEnabled|タイムシフト視聴可能か|
|scoreTimeshiftReserved|タイムシフト予約者数|
|communityText|コミュニティ名|
|memberOnly|チャンネル・コミュニティ限定か|

個人的には『生放送の検索において「放送者のID」「チャンネルID」「公式 or ユーザー（放送元種別）」のフィールドを利用したい』旨の要望を運営に対して上げていたので、実装されるのがとても嬉しい。

## 3. コンテンツ検索APIを商用利用できないことが明記された

>制限事項
>
>こちらのAPIの商用利用はできません。

ニコニコ動画のサードパーティアプリではコンテンツ情報の取得において基本的に既存の旧コンテンツ検索APIが使われていると思うのだが、リニューアル以降は課金の伴うアプリはすべて規約違反となるのだろうか。

以上
フィリピン・セブでオフショア開発した話【導入編】


どうも、サイトビジットの横沢です。（[Twitter](http://bit.ly/2PkyJHK)）

突然ですが弊社にはRubyエンジニアしかいません。

「でもアプリ出したい。」
「javascriptならちょっと書けます。」
「ReactNativeならイケんじゃね。」
「でもリソースなくね？」
「外注しようぜ。セブに。」

という流れでセブでオフショア開発してアプリをリリースしました。

- [iOS](https://itunes.apple.com/jp/app/%E4%BA%88%E5%82%99%E8%A9%A6%E9%A8%93%E7%9F%AD%E7%AD%94%E5%BC%8F%E5%95%8F%E9%A1%8C%E9%9B%86-%E5%8F%B8%E6%B3%95%E8%A9%A6%E9%A8%93%E4%BA%88%E5%82%99%E8%A9%A6%E9%A8%93%E3%81%AE%E5%8A%B9%E7%8E%87%E5%AD%A6%E7%BF%92/id1444050163?mt=8)
- [Android](https://play.google.com/store/apps/details?id=com.shikakunative&hl=ja)


2018年9月〜12月までの3ヶ月間、単身セブに乗り込みアプリ開発をしていました。
そんな中で色々と経験したので記事化してみます。（需要あるかなー）

ちょっと長くなりそうなので勝手にシリーズ化します。:relaxed: :clap: :clap: 

# 目次
- 導入編（本記事）
- オフショアのメリット
- オフショアのデメリット
- 次オフショアするならこうする

# 自己紹介

|項目|詳細|
|---|---|
|職業|PM（[参考](https://qiita.com/yokozawa0701/items/18eebed26c31443316b6)）|
|使える言語|Ruby, javascript（[超昔出したアプリ](https://apkpure.com/es/iroiroyayakoshize/jp.yokoko_1164.Iroiroyayakoshize)）|
|TOEIC|360点（え|
|趣味|カラオケ|

ということで超簡単なプロフィールがこちらです。
問題点は以下です。

- 英語ができない
- プログラミングも別にできない

そうです。僕は歌うことしかできません。:microphone: 

セブ到着の初日に、日本からはるばる輸出したTOEICの過去問を通しで受けてみた時に360点でした。（さすがに引きました :relaxed: ）
そしてセブに到着してから1ヶ月後の10月、人生初めてのTOEICをセブで受験し465点でした。


「TOEIC800点取ります！:muscle:」

そう言って意気揚々とセブに飛び立った社員の点数を見てドン引きしていた社長の顔を今でも鮮明に覚えています。



今年の2月に日本で受けた時は670点でした。（今年800点ガンバリマス）
![IMG_0078.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/75102/7076e969-3b0b-418d-ee84-24526e24a9af.jpeg)


脱線しましたが、正直コミュニケーションは絶望です。
東京タワーにいる外国人を駅まで案内することすらできない僕は、午前中セブの英語学校に通って午後から出社するというローテーションでオフショアしていました。

# アプリに関して

||項目|詳細|
|---|---|---|
|フロント側|言語|javascript|
||フレームワーク|React Native|
|サーバー側|言語|Ruby|
||フレームワーク|Ruby on Rails|

という構成です。

また今回作ったアプリは ***「司法試験予備試験の問題演習」*** という100%日本で出来ている僕ですら難解なアプリです。

# 背景

上記でサラッと説明しましたが、もう少し背景とかも付け加えておきます。

## なんでそもそもオフショア？日本の外注とかは？なんでセブ？

オフショアのメリットとしてはやっぱり安いことですよね。
弊社としても安い方がとーぜんいいです。

ただ、今回はただ安いからという理由だけではありません。

エンジニアの需給バランスって半端ないですよね。エンジニアが居すぎて困っちゃう会社なんてないんじゃないでしょうか？
さらに少子高齢化が進む日本でこれから優秀なエンジニアを獲得していくのってとっても大変です。

今後は海外のエンジニアを上手に使わないと開発競争とかでサクッと負けちゃうよね、という発想でした。

なので今回のオフショア開発の主な目的は以下でした。

- アプリ出したい ***（優先度MAX）***
- オフショア開発のROI検証
- 現地のエンジニア事情の調査

セブにした理由は以下です。

- まだオフショアが盛んじゃない
- 平均年齢24歳

あわよくば ***「現地で会社とか作っちゃいたいよね」*** くらいの気概はありました。（TOEIC360点だけど）

※ 日本の外注も検討しましたが、「短期的にはやりやすいけど将来性がねー」ということで見送ることに。

## なんでその開発環境？

前述の通り、弊社にはRubyを主に扱うWEBエンジニアしかいません。
アプリも積極的に出していく戦略ではなかったので、アプリ専用のエンジニアを雇っても持て余す勢いです。

現状弊社サービスのフロントエンドは `backbone.js` で動いています。（まじかよ）
これを読み解けるエンジニアもおらず、新しく学ぶ意味もあまりなさそうなので全ページのReact化を進めようか、という計画が水面下で動いていました。

なので、

- WEBエンジニアのリソースをスライドして改修とかできる
- WEBサイトもReact化するしちょうどいい
- 1ソースでiOS&Android出せるなんて素敵
- ReactNativeって今風だよね

という理由からReactNativeを選定しました。
バックエンドは今Railsで動いているのでそのまま使おうということになりました。


# まとめ
- 英語力がないエンジニアが頑張る
- セブでのオフショア開発
- 開発は ReactNative, Ruby on Rails

第2章「実体験から語る、オフショア開発のメリット」をお楽しみにどうぞ。

[Twitter](http://bit.ly/2PkyJHK) とかやってるのでご質問とかあったらそっちからしていただけると泣いて喜びます。
【VBA】セル移動でマクロ自動実行


```vb:worksheet
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
	Dim f1 As New UserForm1
	
	If ActiveCell.Value = "1" Then
		If flag Then
			f1.Show vbModeless
		Else
			UserForm1.Show vbModeless
		End If
	ElseIf ActiveCell.Value = "0" Then
		UserForm2.Show vbModeless
	Else
		If UserForm1.Visible Then
			Unload UserForm1
		End If
		If UserForm2.Visible Then
			Unload UserForm2
		End If
	End If
End Sub
```

----------------------------------------------------------------------

```vb:button
Public flag As Boolean

Sub ボタン1_Click()
	If flag Then
		flag = False
	Else
		flag = True
	End If
	Range("G6") = flag
End Sub
```


----------------------------------------------------------------------
■参考サイト
https://excel-excel.com/tips/vba_80.html
https://www.forguncy.com/blog/20181217_clickevent
VSCodeVimとVSCodeのバインドをうまい具合に共存させる

##はじめに

みなさん、こんにちは。
VSCodeを最近使い始めたのですが、一点だけ凄く困っている点がありました。
vscodevim(以下VSVim)でキーのバインドを行うと、
エディタがフォーカス状態になっていないと、キーが上手く動いてくれないのです。
例えば、pluginを表示している画面やmarkdownを表示している画面に
フォーカスが移動してしまうとエディタを移動したくても移動出来ず凄く困ります。

![スクリーンショット 2019-04-24 00.27.36.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/253308/87cf6684-6bec-1289-2010-6068572db787.png)
こいつが消せない・・  

```json:settings.json
"vim.leader":"<space>",//Map Leaderの設定
{"before": ["<Leader>", "x"],"commands": [":q!"]},		  　//tabを閉じる
{"before": ["<Leader>", "u"],"after"   : ["g","t"]},		//tab移動
{"before": ["<Leader>", "y"],"after"   : ["g","T"]},		//tab移動
```
このバインドが使えない

また、逆にVSCode上で設定するとprefixになるキーを押した状態で問答無用で
キーの入力待ちになりVSVimで動かしたいキーが上手く動いてくれませんでした。

苦肉の策として、VSVimとVSCodeで同じ動作をするキーを分けてみました。
VSCodeはCtrl+Space,VSVimはSpaceをprefixにして分けたのですが、大変使いづらい代物になってしまいました。

```json:settings.json

"vim.leader": "<space>",//Map Leaderの設定
{"before": ["<Leader>", "x"],"commands": [":q!"]},		   //tabを閉じる
{"before": ["<Leader>", "u"],"after"   : ["g","t"]},		//tab移動
{"before": ["<Leader>", "y"],"after"   : ["g","T"]},		//tab移動
```

```json:keybindings.json
//editorじゃない奴(markdownのprviewとか)はこれで消す
{
	"key": "space+ctrl ctrl+x",
	"command": "workbench.action.closeActiveEditor",
},
//editorじゃない奴(markdownのprviewとか)はこれでtab移動
{
	"key": "space+ctrl ctrl+u",
	"command": "workbench.action.nextEditor",
},
{
	"key": "space+ctrl ctrl+y",
	"command": "workbench.action.previousEditor",
},
```

##Whenを加えて、VSCodeVimとVSCodeを共存させる
そこで一捻り加えて見ました、全然使いこなせていなかった
VSCodeのwhenを入れてエディタ上ではVimコマンドを有効にし
エディタのテキストにフォーカスが行っていない時は
VSCodeのコマンドを有効にするようにしました。

```json:settings.json
    //editorじゃない奴(markdownのprviewとか)はこれで消す
    {
        "key": "space x",
        "command": "workbench.action.closeActiveEditor",
        "when":"!editorTextFocus && !editorHasSelection && !editorHasMultipleSelections"
    },
    //editorじゃない奴(markdownのprviewとか)はこれでtab移動
    {
        "key": "space u",
        "command": "workbench.action.nextEditor",
        "when":"!editorTextFocus && !editorHasSelection && !editorHasMultipleSelections"
    },
    {
        "key": "space y",
        "command": "workbench.action.previousEditor",
        "when":"!editorTextFocus && !editorHasSelection && !editorHasMultipleSelections"
    },
```

```
!editorTextFocus             //editor内のテキストにフォーカスがない 
!editorHasSelection          //editor内のテキストを選択していない   
!editorHasMultipleSelections //editorを複数選択していないとき
```
whenで設定した条件を満たした時に、VSCodeのコマンドが有効になります。

これにより、同じバインドで無事に操作する事が出来るようになりました。
これを応用して、コマンドパレットを呼びやすくしたり、
エクスプローラーでの操作も簡略化出来たので
かなり小指に優しいキーバインドを実現出来ました。
この記事が同じ問題で悩んでいる人の助けになれば幸いです。


参考
[Visual Studio Code (VS Code) Docsの日本語訳 キーバインディング #when節のコンテキスト](https://vscode-doc-jp.github.io/docs/getstarted/keybindings.html#when%E7%AF%80%E3%81%AE%E3%82%B3%E3%83%B3%E3%83%86%E3%82%AD%E3%82%B9%E3%83%88)
CentOS 7にCouchDB v. 2.3.1をインストール~Fauxtonでの初期設定（シングル構成）

# CouchDBのインストール
yumでインストールできます。

まず、以下のファイルを作り、以下の内容を書き込みます。
/etc/yum.repos.d/bintray-apache-couchdb-rpm.repo

```
[bintray--apache-couchdb-rpm]
name=bintray--apache-couchdb-rpm
baseurl=http://apache.bintray.com/couchdb-rpm/el$releasever/$basearch/
gpgcheck=0
repo_gpgcheck=0
enabled=1
```

その後、yum installでインストールできます。

```
$ sudo yum -y install epel-release && sudo yum install couchdb
```

# Fauxtonでの初期設定を行う
初期状態ではCouchDBは127.0.0.1にバインドされているため、例えばリモートのサーバ上にインストールした場合はGUIの画面を覗くことができません。
まずは設定ファイルを編集して、外部からでもアクセスできるようにします。

設定ファイルはデフォルトでは

```
/opt/couchdb/etc/local.ini
```
にあるはずです。
ここにあるIPアドレスとポートの設定を変更します。

変更前

```
[chttpd]
;port = 5984
;bind_address = 127.0.0.1
; Options for the MochiWeb HTTP server.
;server_options = [{backlog, 128}, {acceptor_pool_size, 16}]
; For more socket options, consult Erlang's module 'inet' man page.
;socket_options = [{sndbuf, 262144}, {nodelay, true}]
```

変更後

```
[chttpd]
port = 5984
bind_address = 0.0.0.0
; Options for the MochiWeb HTTP server.
;server_options = [{backlog, 128}, {acceptor_pool_size, 16}]
; For more socket options, consult Erlang's module 'inet' man page.
;socket_options = [{sndbuf, 262144}, {nodelay, true}]
```

次にCentOSでポートを開放します。
デフォルトでは5984を使用するので以下のコマンドで5984を開放します。

```
sudo firewall-cmd --zone=public --add-port=5984/tcp
```
設定を永続化したい場合は以下のコマンドを使用します。

```
firewall-cmd --zone=public --add-port=5984/tcp --permanent
```
以下のコマンドを使って設定が反映されているかを確認します。

```
$ firewall-cmd --list-all
public (active)
  target: default
  icmp-block-inversion: no
  interfaces: ens33
  sources: 
  services: ssh dhcpv6-client
  ports: 5984/tcp
  protocols: 
  masquerade: no
  forward-ports: 
  source-ports: 
  icmp-blocks: 
  rich rules: 
```

ここまでくればブラウザからFauxtonにアクセスできるはずです。

```
http://IPアドレス:5984/_utils
```
ホームページの更新をすぐに反映させる方法

　
「ホームページを更新したのに古い状態のままになっている」という状態を解消したい。

対策は、.htaccessファイルにて、ホームページのデータであるhtml、jpg、pdfなどのキャッシュを残さないような設定にする。

```
<Files ~ "\.(html|php|jpe?g|gif|png|css|js|pdf)$">
Header add Pragma "no-cache"
Header set Cache-Control no-cache
</Files>
```

これで実現できた。
元号表記の変更について

#元号表記の変更について
間もなく新元号になりますね。Microsoftの新元号パッチもまだ配信されておらず、最悪GW明けになる可能性もありますが・・・

さて、新元号パッチはともかく和暦表示をするシステムも沢山あるかと思います。通常であれば2019/5以降を和暦表示すると「令和●●年～」となると思いがちですが、昨年10月の月例パッチ頃より「和暦1年」が「和暦**元**年」と表示されるようになっております。

>[2018 年 10 月 19 日 — KB4462932 (OS ビルド 16299.755)](https://support.microsoft.com/ja-jp/help/4462932/windows-10-update-kb4462932)
 日本語の日付書式のうち、元号の最初の年に関する .NET Framework のサポートを更新します。 書式パターンが “y年” の場合、年の書式には元号が使用され、年番号 1 は使用されません。 さらに、.NET Framework は元号を含む日付をサポートします。

##「元年」で表示される条件
和暦表示で「和暦1年」ではなく「和暦元年」になるのは以下の条件を全て満たしている場合です。

- 和暦の書式(ggy等)又は「y」のみの年書式
- 年書式の後に「年」が来る
- 「和暦の1年」となる日付

この条件に満たない場合、「元」ではなく「1」で表示されます。

>[2019 年 4 月 3 日 — KB4489192 Windows 10 Version 1809 および Windows Server 2019 用の .NET Framework 3.5 および 4.7.2 の累積的な更新プログラム](https://support.microsoft.com/ja-jp/help/4489192/april-2-2019-kb4489192)
>[.NET Framework 用の日本の新元号対応更新プログラムの概要](https://support.microsoft.com/ja-jp/help/4477957/new-japanese-era-updates-for-net-framework)
>
>KB4489192のパッチが適用されていない場合、「年」をシングルコート「'」でくくる必要があります。その為、開発環境と実行環境で結果が異なる可能性がある点に注意してください。

##元号を使用するシステムで確認しなければならない点
まず確認しなければならない点は

- システムで「元年」を表示するか否か

です。表示する場合は元年に当たる日付により、結果がどうかの確認と修正が必要になります。

必要が無い場合の対応は簡単でApp.Configで「Switch.System.Globalization.FormatJapaneseFirstYearAsANumber」を「True」に設定します。

```App.config
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <startup> 
    <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.7.2" />
  </startup>
  <runtime>
    <AppContextSwitchOverrides value="Switch.System.Globalization.FormatJapaneseFirstYearAsANumber=True" />
  </runtime>
</configuration>
```

##「元年」を使用する場合の注意点
例えば和暦の年を取得し数値の大小等で比較していたり、和暦の年をInteger変数へ代入していたりすると動作が異なってきます。

##元年表示参考用PG
最後に元年表示のサンプルPGをあげておきます。
コンソールアプリプロジェクトを作成し、下記ソースを適用・実行してください。

```vb:Module1.vb
Imports System.Globalization

Module Module1
    Sub Main()
        Dim jpCulture = New CultureInfo("ja-JP")
        jpCulture.DateTimeFormat.Calendar = New JapaneseCalendar()

        Dim dt As New Date(1989, 1, 8)
        Console.WriteLine(dt.ToString("〇ggy年M月d日", jpCulture))
        Console.WriteLine(dt.ToString("〇gg y年M月d日", jpCulture))
        Console.WriteLine(dt.ToString("〇y年M月d日", jpCulture))
        Console.WriteLine(dt.ToString("×ggy 年M月d日 ⇒ 年書式と「年」の間に空白がある", jpCulture))
        Console.WriteLine(dt.ToString("×ggy.M.d ⇒ 年書式の後ろが「年」ではない", jpCulture))

        Console.WriteLine()
        Console.WriteLine("Push key...")
        Console.ReadLine()
    End Sub
End Module
```
ホームページをスマートフォンで見たら文字の大きさが自動で変わってしまう時の対処法

パソコン用ホームページを、そのままのレイアウトでスマホで見せたい時、なぜか文字のサイズが勝手に大きくなってしまう不具合が出た。


調べたところ、これで解消した。


body{
    -webkit-text-size-adjust:100% !important;
}
kdump設定

■kdump設定
①systemctl start kdump.serviceで起動した際にエラーになる
②cat /var/log/messages | grep kdump
Apr 23 07:05:51 localhost systemd: Unit kdump.service entered failed state.
Apr 23 07:05:51 localhost systemd: kdump.service failed.
Apr 23 07:09:11 localhost kdumpctl: No memory reserved for crash kernel.
Apr 23 07:09:11 localhost kdumpctl: Starting kdump: [FAILED]
Apr 23 07:09:11 localhost systemd: kdump.service: main process exited, code=exited, status=1/FAILURE

No memory reserved for crash kernel.
カーネルクラッシュ時のメモリがないよ。という意味らしい

③/etc/default/grubを編集
GRUB_CMDLINE_LINUX="crashkernel=auto rhgb quiet"
↓
GRUB_CMDLINE_LINUX="rd.lvm.lv=centos/swap vconsole.font=latarcyrheb-sun16 vconsole.keymap=jp106 rd.lvm.lv=centos/root crashkernel=128M  rhgb quiet"

④上記のように crashkernel=auto → crashkernel=128M へ変更
編集後、grub2-mkconfig で、最新のgrub設定ファイルを生成
grub2-mkconfig -o /boot/grub2/grub.cfg

⑤生成後、リブート
reboot

⑥再度、kdumpの状態を確認
[root@localhost ~]# systemctl status kdump.service
● kdump.service - Crash recovery kernel arming
   Loaded: loaded (/usr/lib/systemd/system/kdump.service; enabled; vendor preset: enabled)
   Active: active (exited) since Tue 2019-04-23 08:06:36 PDT; 1min 23s ago
  Process: 4398 ExecStart=/usr/bin/kdumpctl start (code=exited, status=0/SUCCESS)
 Main PID: 4398 (code=exited, status=0/SUCCESS)
    Tasks: 0
   CGroup: /system.slice/kdump.service

Apr 23 08:06:27 localhost.localdomain systemd[1]: Starting Crash recovery ker...
Apr 23 08:06:36 localhost.localdomain kdumpctl[4398]: kexec: loaded kdump kernel
Apr 23 08:06:36 localhost.localdomain kdumpctl[4398]: Starting kdump: [OK]
Apr 23 08:06:36 localhost.localdomain systemd[1]: Started Crash recovery kern...
Hint: Some lines were ellipsized, use -l to show in full.

⑦/var/log/messagesでも、問題ないことを確認する。
[root@localhost ~]# cat /var/log/messages | grep kdump
Apr 23 08:06:36 localhost kdumpctl: kexec: loaded kdump kernel
Apr 23 08:06:36 localhost kdumpctl: Starting kdump: [OK]
pythonでフォルダにある複数画像を一気に縮小して別名で保存する

```python
import os
import glob
from PIL import Image

#フォルダ名「dir」の中にある.jpgファイルを取得して配列に
files = glob.glob('./dir/*.jpg')

#縮小したい画像サイズを入力する
img_size = input('please enter img size width or height >')

#配列「files」をforで回す
for f in files:
    img = Image.open(f)
    img.thumbnail((int(img_size),int(img_size)), Image.ANTIALIAS)
    ftitle, fext = os.path.splitext(f)

    #ファイル名に「_small」を付けて、縮小した画像を保存する
    img.save(ftitle + '_small' + fext)
```
PandasのDateFrameでよく使うメソッド

Pandasでよく使うメソッドの備忘録
随時更新予定
公式doc:
>https://pandas.pydata.org/pandas-docs/stable/reference/frame.html

#CSVの取り扱い
###CSVの読み込み
```
df = pd.read_csv('hoge.csv')
```

###CSVの書き込み
```
df.to_csv('hoge.csv')
```
indexが必要ない場合：

```
df.to_csv('hoge.csv', index=None)
```

#データの確認
```
#先頭5行の確認
df.head()

#常に全ての列（カラム）を表示するように設定を変更
pd.options.display.max_columns = None

#常に10列のみ表示するように設定を変更
options.display.max_columns = 10
```

#データの抽出
```
#'hoge_column_name'の列の要素の文字列の内、hogeが含まれている物を全て抽出する
df[df['hoge_column_name'].str.contains('hoge')]

#'hoge_column_name'の列の要素の内、リストhode_listの要素である物を全て抽出する
df[df['hoge_column_name'].isin(hoge_list)]
```
#データの結合
###concat
```
#df_1,df_２,df_3を縦方向に連結
df = pd.concat([df_1, df_2, df_3])

#2つのSeriesを横方向に連結させて、DataFrameにする場合もconcatを使う
df = pd.concat([s_1, s_2, s_3], axis=1)
```
###marge
```
#df_1とdf_2をカラム名'key'の要素が一致するようにmerge
#その際how='left'と指定することで、df_1を基準に結合を行う(デフォルトはhow='inner'で内部結合を行う)
df = pd.merge(df_1, df_2, on='key', how='left')

#keyを複数にして、merge
df = pd.merge(df_1, df_2, on=['key_1', 'key_2'], how='left')
```

#データの分析
```
#'hoge_column_name'の列の要素ごとにグループ分けをし、それぞれについて売り上げ（価格x数量の和）を計算する
df.groupby(['hoge_column_name']).apply(lambda d: (d.amount * d.price).sum())
```
アプリ広告についての下調べ

# 前置き
- アプリ広告で副業したいなーとボヤっと考えてみたのですが、そもそもマネタイズのことを考えてこなかった人生だったので、整理がてら調査してみた。
- 2019年4月時点

# 広告の種類
上に行くほどアプリの広告で個人的に馴染みありそうなもの

## 動画視聴（動画リワード）
- 再生されれば報酬もらえる
- 月ごとの再生回数（インプレッション）によって報酬に差が出るらしい。
- AdMob(Google)、UnityAds、AdColony、DreeVee、Tapjoyなど

## 広告クリック（クリック時点）
- クリックされれば報酬もらえる（後述の広告クリックよりは単価低し）
- クリック保証型広告などが該当
- AdMob(Google)、Tapjoyなど

## 広告クリック（インストール時点）
- 広告媒体からクリック、インストールまでいくと報酬もらえる
- UnityAds（動画媒体のみ）、AppDriver、GMO SmaAD、Tapjoyなど

## 広告クリック（成約時点）
- 広告媒体からクリック、成約までいくと報酬もらえる
- 広告クリックの中では一番ハードル高いので一番単価は高そう
- GREE Ads Reward、GMO SmaAD、Tapjoyなど

# その他の要素
- 広告媒体のサイズ：全画面とか、バナーサイズとか色々種類ありそう
- Google 
    - AdSenceとかAdwordsとかもあるけど、違いアプリに関してはAdMobが対象（Mobile）。こちらの違いの説明が分かりやすかった：http://dev.kabu-oku.com/affiliate/adsense-adwords-admob
- 動画再生回数
    - 月単位で一定以上再生されないと、収益に繋がらない。その数は会社ごとに異なりそう。


# 先人の言葉
調べるよりまずは作った方がいい。アプリがなければ広告調べても意味ないし。
とりあえずAdMob使っておけばいい気がするし、まずは利用してもらうアプリを作ってから収益化は考えた方が良い。

と言われて確かにと思ったので、とりあえず下調べは終わりにしてなんか作ろうと思いました。


# 参考：
アプリ内広告の種類と仕組みについて。
https://pencre.com/application-koukoku/

「CPA」「CPC」「CPD」「CPE」「CPI」「CPM」「CPV」の意味
https://iso-labo.com/labo/CPA_CPC_CPD_CPE_CPI_CPM_CPV.html

UnityAdsを導入したんだけど、インプレッション数が少なすぎて収益０円だった件
http://application.hateblo.jp/entry/2017/04/23/201200

#### 調べてた上で面白かった記事
「一定回数の広告視聴で全広告削除」　個人制作アプリの広告手法が人気、作者に話を聞いた
https://nlab.itmedia.co.jp/nl/articles/1902/13/news141.html