OmniAICreator/Qiita-1.07M huggingface dataset:
EOSIO＋EOSJS＋Express＋Bootstrapで簡単なトークン送信システムを作ってみた

どーも、のぶこふです。

CLIでポチポチするのも良いのですが、やっぱり画面で出来たほうが良いよね。ということではじめました。
そういった記事も特に見当たらなかったですし。

作成した画面のイメージや、ソースコード、手順等はGitHubに配置してあります。
EOSIO実行手順は、公式や他の方の記事のほうがわかりやすいかと思います。
※拙い英語で書かれています
https://github.com/nobkovskii/eosjs-sample

* GUIで表示しているとは言え、UXはとても見れたものではないので、寛大なお気持ちで御覧ください。
（とりあえず、表示しとけばいいよね、くらいの気持ち）
* Bootstrapで、ソレっぽさだけは表現しています。
* Nodeのお作法（特にPromise関連）をあまり理解していないので、マサカリを投げられるとそのまま泉に沈みます。


## 出来ること
画面上からは、下記が行えます。

* ブロックの情報（getInfo,getBlock）を表示
* アカウントの作成(create account)
* アカウント一覧の表示(getAccount)
* アカウントのトークン数の表示
* アカウントのトークン授受履歴の表示
* トークンの授受(transfer)

反対に、下記は行なえません。（実装していません）

* トークンの作成（Create）、配布(Issue)
* トランザクションの表示
* 指定したブロック情報の表示
* エラーが発生した時の諸々
* 。。。など

## 困ったこととか、作ってみての感想的な

APIも一通り揃っていて、ドキュメントもあるので、大きく詰まったことはありませんでした。
＼EOSJSサイコー／

ただ、アカウント作成（create account）で、作成者（creator）をスーパーユーザ的な権限を持つ「eosio」ユーザに指定していたら、「権限がありません」といったエラーが出て、1日ほど悩みました。
結局、コントラクトの実行権限を持たせた「token」ユーザを指定することで解決しました。
CLIだと、eosioを指定するのだが。。。

トークン送信時のメッセージは、全角で85文字までみたいです。
1000文字くらいで送ると「Transaction took too long」と出るのですが、100文字くらいだと「eosio_assert_message assertion failure」で、1時間くらい悩みました。

## おわりに
個人的に、CLIだけで終わってしまうのはつまらないので、他のブロックチェーンプラットフォームも同じようにGUIで表現したいと考えています。

というか、メインでやろうとしていた「Hyperledger Fabric」の初期設定・導入が他のブロックチェーンプラットフォーム（eosio,mijin等）に比べて面倒すぎるし、APIもあんまり揃っていなさそうなので、上手いこと出来ないかちょいと踏ん張ってみようと思った今日このごろ。

---

今回はここまでです。
ありがとうございました。
ラズパイをmacからSSHできるようにする方法

# ラズパイをmacからSSHできるようにする方法

ラズパイを同一ネットワーク上のmaのターミナルからsshでアクセスできるようにする方法です。

## ラズパイの設定

まずは、ラズパイにマウスとキーボード、モニターをつないで作業

### SSHの有効化
左上のメニュー→設定→Raspberry Piの設定→インターフェイス→SSHを有効

### ホスト名、パスワードの変更
左上のメニュー→設定→Raspberry Piの設定→システム

ホスト名、パスワードの変更ができます。

## macから接続

macのターミナルから接続できるように

```
ssh pi@raspberrypi.local
```

※passwordは、raspberry

## おまけ：macからラズパイにファイルコピー

macのターミナルで以下を行います（ssh接続していない状態でやります）

```
scp test.txt pi@raspberrypi.local:
```
/home/pi にファイルがコピーされます。
:のあとにフォルダ名を書くと、/home/pi/フォルダ名　にコピーされます。
Heroku ConnectテーブルにJPAでinsertする際のアノテーション

Heroku ConnectでMappingした結果としてPostgresに作成されたテーブルは、そのPKが`id`(int4)というカラム

そのカラムのデフォルト値は例えばスキーマが`salesforce`でオブジェクト/テーブルが`Contact`であれば`nextval('salesforce.contact_id_seq'::regclass)`になる

JPAでinsertする際にinsert文にそのカラムを指定しないことでデフォルト値を発動させたいが、`@Id`を付けているためどうしてもinsert文に含まれてしまう (JPAの残念なところ)

なので、涙を飲んで以下のように書く

```Contact.java
    @Id
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "contact_id_generator")
    @SequenceGenerator(name = "contact_id_generator", sequenceName = "contact_id_seq", allocationSize = 1)
    @Column(name = "id")
    @Setter(AccessLevel.NONE)
    private int id;
```
_cgo_export.c:3:10: fatal error: 'stdlib.h' file not found の解決方法

# はじめに
開発中に遭遇した問題解決の備忘メモです。

# 問題事象
ローカル環境で `go test` を実行したところ、下記のエラーが表示され、実行できない状態になった。

```
_cgo_export.c:3:10: fatal error: 'stdlib.h' file not found
```

# 原因
原因はgolang関係なく、macOSをmojaveにアップグレードしたことの様子。

# 解決
多くのケースでは、 `xcode-select --install` で解決するみたいだが、自分の場合は、既に入っているよと怒られた。

```
$ xcode-select --install
xcode-select: error: command line tools are already installed, use "Software Update" to install updates
```

[stackoverflow](https://stackoverflow.com/questions/52509602/cant-compile-c-program-on-a-mac-after-upgrade-to-mojave)によると、下記コマンドで解決するとのこと。
あらかじめ、AppleのID/PASSが必要です。

```
$ open /Library/Developer/CommandLineTools/Packages/macOS_SDK_headers_for_macOS_10.14.pkg
```

これで、実行できるようになった。
めでたし、めでたし。
Optunaで特定の初期値から最適化を開始する

Optunaでは値の範囲を変えて追加で学習させることができる。
同様に、初期値を指定して学習を開始することも可能。
事前の手動の実験で良さそうなパラメータがわかっていてその周囲から探索してほしいとき、を想定している。

# TL, DR
trial.trial_idで条件分岐させて初期値を指定する。
最適化する分布と同じ分布型(suggest_uniformとか）で指定する必要がある

ただし、カテゴリカル変数(suggest_categorical)は範囲の変更に対応していないので、カテゴリカル変数を含めて初期条件を指定したいときはリセマラしないといけないかも。

# 範囲を変化させる
Optunaのtutorialに載っている例から。

```python
import optuna

def objective(trial):
    x = trial.suggest_uniform('x', -10, 10)
    return (x - 2) ** 2

study = optuna.create_study()
study.optimize(objective, n_trials=100)

study.trials_dataframe()[('params', 'x')].plot()
```
![image.png](https://qiita-image-store.s3.amazonaws.com/0/177689/833091a8-583e-070c-6bd0-e98d15293906.png)

これは普通の最適化。


まずはtutorial通り、追加で学習する。

```python
study.optimize(objective, n_trials=100)

study.trials_dataframe()[('params', 'x')].plot()
```
![image.png](https://qiita-image-store.s3.amazonaws.com/0/177689/6a644072-cd62-40df-76bc-8af336b827f4.png)

値の範囲を変えてみる。objectiveを再定義する。

```python

def objective2(trial):
    x = trial.suggest_uniform('x', -40, 40)
    return (x - 2) ** 2

study.optimize(objective2, n_trials=500)
study.trials_dataframe()[('params', 'x')].plot()
```
![image.png](https://qiita-image-store.s3.amazonaws.com/0/177689/fd15a7a0-e7e6-88ca-f285-07f9952498d1.png)

# 初期値の設定

```python
import optuna

def objective(trial):
    if trial.trial_id ==0:
        x = trial.suggest_uniform('x', 2, 2)
    else:
        x = trial.suggest_uniform('x', -10, 10)

    return (x - 2) ** 2

study = optuna.create_study()
study.optimize(objective, n_trials=100)

study.trials_dataframe()[('params', 'x')].plot()
```

![image.png](https://qiita-image-store.s3.amazonaws.com/0/177689/f00de191-c60b-f754-633f-5803eae9d6bc.png)

```python
study.trials_dataframe().head(5)
```
![image.png](https://qiita-image-store.s3.amazonaws.com/0/177689/dfdf1b3f-710e-9435-d7d4-242a662a83f3.png)

x=2から始めることができました。ざっとソースを眺めた限りでは、サンプリング(trial.suggest)する段階でそれ以前に試行した値とその結果を元にサンプリングしてきているようなので大きな副作用はないんじゃないかと思います。

※ ただし、suggest_categoricalで１つの値のみ指定しようとするとカテゴリ変数はdynamic range changeに対応していないといったエラーが返ってくる。
PHP7.3でxdebug2.6が入らない場合の対処法（Homestead）

# peclでxdebugインストールしようとしてエラー
```make: *** [xdebug_compat.lo] Error 1
ERROR: `make' failed```

# xdebug2.6はphp7.3に対応していません
最近Laravel入門してHomesteadにXdebug入れてリモートデバッグしようとしたらハマりました。

現時点ではPHP7.3を使用する場合、xdebug2.7.0beta1を入れましょう。
下記コマンドで入ります。
`pecl install xdebug-beta`

バージョン大事。
vuex の store 内で i18n を使う

store で何らかの文字列を持ちたいとき、store にベタ書きしたくないなあと思い調べました

## プロジェクトのセットアップと vuex, vue-i18n のインストール

~~~sh
$ npm install -g vue-cli
$ vue init webpack lion_project
$ cd lion_project/
$ npm i -s vuex vue-i18n
~~~

## vue-i18n のファイル作成

フォルダ名や json のファイル名は何でも良いです
今回は src/lang 下に作成します

~~~sh
$ mkdir src/lang
~~~

~~~src/lang/index.js
import Vue from 'vue'
import VueI18n from 'vue-i18n'

const messages = require('@/lang/messages.json')

Vue.use(VueI18n)

export default new VueI18n({
  locale: 'ja',
  messages
})
~~~

~~~src/lang/messages.json
{
  "ja": {
    "message": {
      "lion": "A big suprise of a beer!"
    }
  }
}
~~~

## vuex のファイル作成

src/store 下に作成します

~~~sh
$ mkdir -p src/store/modules
~~~

~~~src/store/index.js
import Vue from 'vue'
import Vuex from 'vuex'

import message from '@/store/modules/message'

Vue.use(Vuex)

export default new Vuex.Store({
  modules: {
    message
  }
})
~~~

~~~src/store/modules/message.js
import i18n from '@/lang'

export default {
  namespaced: true,
  state: {
    info: ''
  },
  mutations: {
    create (state, info) {
      state.info = info
    }
  },
  actions: {
    create ({ commit }) {
      // src/lang/messages.json から文言を取得
      commit('create', i18n.tc('message.lion'))
    }
  }
}
~~~

## main.js に store と lang を追加

~~~src/main.js
// The Vue build version to load with the `import` command
// (runtime-only or standalone) has been set in webpack.base.conf with an alias.
import Vue from 'vue'
import App from './App'
import router from './router'
import store from './store' // 追加
import lang from './lang' // 追加

Vue.config.productionTip = false

/* eslint-disable no-new */
new Vue({
  el: '#app',
  router,
  store, // 追加
  i18n: lang, // 追加
  components: { App },
  template: '<App/>'
})
~~~

## HelloWorld.vue を変更

間借りして表示確認します
script の部分だけ変更します
抜粋です

~~~src/components/HelloWorld.vue
<script>
export default {
  name: 'HelloWorld',
  computed: {
    msg () {
      // store/modules/message.js の info の値を取得
      return this.$store.state.message.info
    }
  },
  mounted: function () {
    // store/modules/message.js の create をコールして message.lion をセット
    this.$store.dispatch('message/create')
  }
}
</script>
~~~

## 動作確認

~~~sh
$ npm run dev
~~~

Hello World の代わりに A big suprise of a beer! が表示されていることを確認します

<img width="1440" alt="Screen_Shot_2019-01-30_at_10_23_42.png" src="https://qiita-image-store.s3.amazonaws.com/0/106789/d07fc186-f1d2-0e08-6ee9-cf5eba7f13a9.png">

## 参考記事

- [Use Vue-i18n in Vuex store](https://www.guipss.com/posts/vuex_and_vue_i18n/)
Windows環境でlaradockのMariadb/MongoDB/Mysqlが起動失敗する場合

# 環境
| OS   | Windows |
|:------------|---|
| Tool | Docker Toolbox |


# 結論から言うと
> volume設定のマウンド先変えて見ると起動できるかも！


# 現象と対策 [Mongodb]
```shell:logs
$ docker-compose.exe up -d mongo
Starting laradock_mongo_1 ... done

$ docker-compose.exe ps
      Name                   Command              State    Ports
----------------------------------------------------------------
laradock_mongo_1   docker-entrypoint.sh mongod   Exit 14

$ docker-compose logs mongo
#[initandlisten] Failed to start up WiredTiger under any compatibility version.
#[initandlisten] Reason: 26: Text file busy
#[initandlisten] Fatal Assertion 28595 at src/mongo/db/storage/wiredtiger/wiredtiger_kv_engine.cpp 645
```

```yml:docker-compose.yml
### MongoDB ##############################################
    mongo:
      build: ./mongo
      ports:
        - "${MONGODB_PORT}:27017"
      volumes:
        #- ${DATA_PATH_HOST}/mongo:/data/db
        - ${DATA_PATH_HOST}/mongo:/data/mongodb
      networks:
        - backend
```



# 現象と対策 [mariadb]
```sh
$ docker-compose.exe logs mariadb

mariadb_1              | 2019-01-30  1:01:50 0 [Warning] InnoDB: Failed to set O_DIRECT on file./ibdata1; OPEN: Invalid argument, continuing anyway. O_DIRECT is known to result in 'Invalid argument' on Linux on tmpfs, see MySQL Bug#26662.
mariadb_1              | 2019-01-30  1:01:50 0 [ERROR] InnoDB: Header page consists of zero bytes in datafile: ./ibdata1, Space ID:0, Flags: 0. Please refer to http://dev.mysql.com/doc/refman/5.7/en/innodb-troubleshooting-datadict.html for how to resolve the issue.
mariadb_1              | 2019-01-30  1:01:50 0 [ERROR] InnoDB: Corrupted page [page id: space=0, page number=0] of datafile './ibdata1' could not be found in the doublewrite buffer.
mariadb_1              | 2019-01-30  1:01:50 0 [ERROR] InnoDB: Plugin initialization aborted with error Data structure corruption
mariadb_1              | 2019-01-30  1:01:50 0 [Note] InnoDB: Starting shutdown...
mariadb_1              | 2019-01-30  1:01:51 0 [ERROR] Plugin 'InnoDB' init function returned error.
mariadb_1              | 2019-01-30  1:01:51 0 [ERROR] Plugin 'InnoDB' registration as a STORAGE ENGINE failed.
mariadb_1              | 2019-01-30  1:01:51 0 [Note] Plugin 'FEEDBACK' is disabled.
mariadb_1              | 2019-01-30  1:01:51 0 [ERROR] Could not open mysql.plugin table. Some plugins may be not loaded
mariadb_1              | 2019-01-30  1:01:51 0 [ERROR] Unknown/unsupported storage engine: InnoDB
mariadb_1              | 2019-01-30  1:01:51 0 [ERROR] Aborting
```

```yml:docker-compose.yml
### MariaDB ##############################################
    mariadb:
      build: ./mariadb
      volumes:
        #- ${DATA_PATH_HOST}/mariadb:/var/lib/mysql
        - ${DATA_PATH_HOST}/mariadb:/var/lib/mariadb
        - ${MARIADB_ENTRYPOINT_INITDB}:/docker-entrypoint-initdb.d
      ports:
        - "${MARIADB_PORT}:3306"
      environment:
        - MYSQL_DATABASE=${MARIADB_DATABASE}
        - MYSQL_USER=${MARIADB_USER}
        - MYSQL_PASSWORD=${MARIADB_PASSWORD}
        - MYSQL_ROOT_PASSWORD=${MARIADB_ROOT_PASSWORD}
      networks:
        - backend
```
RS-232C > USBシリアル変換アダプタ > USBの物理ポートによりCOMXがCOM8やCOM10に変わる + UI: 設計ミス > COM10を選択できないUI

```txt:動作環境
Windows 7 Pro (32bit)
USBシリアル変換アダプター
```


### 関連

- [USB-RS232 > USBシリアル変換アダプター > 表記のない製品 (青色半透明のハウジング) > 将来の情報参照が不可能になる](https://qiita.com/7of9/items/9feae1f906b8007a0b4c)


### 状況

- 組込みの装置
- 昨日の試験と同じことをしようとしたら動かない
- USBシリアル変換アダプタを使用
- ノートPCのUSBポートの挿す場所が変わっていた
    - COM8がCOM10に

### 物理ポートとCOMXのX (COM8やCOM10)

ノートPCなどの「どのUSBポート」に挿すかによってCOM8やCOM10に変わる。
そのような情報を記憶しているのだろう。

### UI: 設計ミス > COM10を選択できないUI

- 提供されるソフトウェアがコンボボックスでCOMXを選択するUI
- COM9までしか選択できない
   
COM10だとそもそも動かない。

USBシリアル変換アダプタを使うとCOM12になったりCOM14になったりもする。
(これまで使ってきた変換アダプタの種類にもよるのかもしれない）

COMX(X>=10)が使える設計をするがよい。
Rubyでtelnetする

ネットワークエンジニアの筆者は、NW機器にtelnetすることが多かった経験があります。
入力ミスがあると嫌なので、自動でconfig(設定)を取得したり、設定を変えたりするスクリプトを作りました。
その時のノウハウをざっくりと。

#1.gemのインストール
Rubyは標準のライブラリと追加しなければならないライブラリがあります。
今回はnet/telnetをインストールする必要があります。

```
gem install net-telnet
```

#2.telnetで機器の設定を取得

```ruby:telnet.rb
require "net/telnet"

telnet_server = "IP address" #telnet接続したい機器のIPアドレス
user = "user"　#telnet接続したい機器のログインユーザ名
password = "password"　#telnet接続したい機器のログインパスワード
telnet_port = 23#telnet接続したい機器のtelnetポート番号(デフォルトは23)
timeout = 60

telnet = Net::Telnet.new("Host" => telnet_server, "Timeout" => timeout, "Port" => telnet_port)
	telnet.login(user, password)
	telnet.cmd("enable command") #特権モード切替コマンド
	telnet.cmd("show config command") #機器の設定を表示
	telnet.cmd("exit")
	telnet.close

```

#3.機器の設定をファイルに保存したい場合

```ruby:telnet-store.rb

require "net/telnet"

telnet_server = "IP address" #telnet接続したい機器のIPアドレス
user = "user"　#telnet接続したい機器のログインユーザ名
password = "password"　#telnet接続したい機器のログインパスワード
telnet_port = 23#telnet接続したい機器のtelnetポート番号(デフォルトは23)
timeout = 60
file = "cmdfile" #設定を保存したいファイルパス

$stdout = File.open(file, 'a')
telnet = Net::Telnet.new("Host" => telnet_server, "Timeout" => timeout, "Port" => telnet_port)
	telnet.login(user, password)
	telnet.cmd("enable command") #特権モード切替コマンド
	telnet.cmd("show config command") #機器の設定を表示
	telnet.cmd("exit")
	telnet.close
$stdout = STDOUT

```

#4.まとめ
　昨今、GUIの用意されていない機器は少数派ですがスクリプトによる自動化の基本となるコマンドです。
Pythonの辞書(Dictionary)のkeyにリストを設定する

# Dictionaryのキーにリストを設定する

Dictionaryのkey値にリストを設定したかったのですが，値の変更が可能なListは設定できませんでした。
※辞書のキーは一意でなければならない

調べた結果，イミュータブル（不変）なリストであるタプル（tuple）を利用することでリスト型のキーを指定できました。

```python:sample.py
test_dict = { 
    ('key1', 'key2'):'value1', 
    ('key3', 'key4'):'value2' 
}

print(test_dict)
# {('key1', 'key2'): 'value1', ('key3', 'key4'): 'value2'}
```

**★追記**
本記事のコメント欄で以下のように辞書にキーを追加していく書き方を教えていただきました。
実際のプログラムでは，何か元の情報から辞書を作成することが多いと思うので，こちらの方が頻繁に使いそうです。
ありがとうございます！

~~~python:sample2.py
test_dict = {}
test_dict['key1', 'key2'] = 'value1'
test_dict['key3', 'key4'] = 'value2'

print(test_dict)
# {('key1', 'key2'): 'value1', ('key3', 'key4'): 'value2'}
~~~
【C#】List中の重複する要素を抽出する方法

# はじめに

「Listから重複した要素を削除する時」はDistinctメソッド、「引数で指定した要素がList中に存在するかをチェックする時」はContainsメソッドが使われます。
ですが、これらのメソッドでは「List中の重複する要素を抽出する時」には対応できないため、LINQの機能を活用して処理を考えてみました。

例えば「読み込んだデータ中に重複があるかどうかをチェックしつつ、どのデータが重複しているのかを知りたい」といった時には、以下のコードが役に立つかもしれません。

# コード

```c#:ListUtils.cs
public class ListUtils
{
    /// <summary>
    /// 引数のリスト（何らかの名称のリスト）から、重複する要素を抽出する。
    /// </summary>
    /// <param name="list">何らかの名称のリスト。</param>
    /// <returns>重複している要素のリスト。</returns>
    public static List<string> FindDuplication(List<string> list)
    {
        // 要素名でGroupByした後、グループ内の件数が2以上（※重複あり）に絞り込み、
        // 最後にIGrouping.Keyからグループ化に使ったキーを抽出している。
        var duplicates = list.GroupBy(name => name).Where(name => name.Count() > 1)
            .Select(group => group.Key).ToList();

        return duplicates;
    }
}
```

# コードの実行

## テストコード

* テストには、"Tokyo"と"Yokohama"が重複しているリストを使っています。

```c#:UnitTestListUtils.cs
[TestClass]
public class UnitTestListUtils
{
    [TestMethod]
    public void TestMethod1()
    {
        // "Tokyo"と"Yokohama"が重複しているリスト
        List<string> cityNames = new List<string>() {
            "Tokyo", "Osaka", "Yokohama", "Nagoya", "Kobe", 
            "Tokyo", "Yokohama", "Sapporo", "Fukuoka", "Tokyo"};

        var duplicates = ListUtils.FindDuplication(cityNames);
        System.Console.WriteLine(string.Join(",", duplicates));
    }
}
```

## テストコードの実行結果

* 重複している"Tokyo"と"Yokohama"が出力されました。

```text:実行結果
Tokyo,Yokohama
```
[FirstVR] oculus Goで、コントローラと組み合わせて遊んでみる

## 概要

今回は、普通のoculus Goのコンテンツに、[FirstVR](https://first-vr.com/)を組み込んで遊んでみた記事です。

## oculus Goセットアップ

oculus Goの開発をするにはまず、oculus GoはAndroidベースで動作するのでswitch platformでAndroidに変更しておきます。
続いて、Player Settingsの「**XR Settings**」にある、Virtual Supportedのフラグをオンにし、さらに「＋」ボタンを押して「**Oculus**」をリストに追加します。

設定が終わったら、UnityのAsset Storeで配布されている「[Oculus Integration](https://assetstore.unity.com/packages/tools/integration/oculus-integration-82022)」をimportします。

![Oculus Integration importing](https://qiita-image-store.s3.amazonaws.com/0/5616/2c352a52-7a18-8b4c-6583-0be654997981.png)

インポートが終わったら`/Assets/Oculus/VR/Prefabs/`フォルダにある「**OVRCameraRig**」をシーンに配置します。

![Setting of OVRCameraRig](https://qiita-image-store.s3.amazonaws.com/0/5616/9d3d71a7-6fa2-9a4d-e0cd-0b1672942207.png)
これが、oculus Goの操作をサポートしてくれるPrefabとなります。

そして同様に `/Assets/Oculus/VR/Prefabs/` フォルダにある「**TrackedRemote**」を、たった今配置した「**OVRCameraRig**」の中、 `OVRCameraRig/TrackingSpace/RightHandAnchor/RightControllerAnchor/` の下に配置します。

![20190129-083713.png](https://qiita-image-store.s3.amazonaws.com/0/5616/fa382ac2-dcca-f454-5e59-c2b6d91dd940.png)

これを、以下のように配置します。

![Put on CameraRig](https://qiita-image-store.s3.amazonaws.com/0/5616/6081064e-21c4-3b34-c684-4d05129882d2.png)


基本的にはこれを置いてビルドすれば、VRでの操作に関する内容はすべて対応できたことになります。
あとはコンテンツを作っていくのみです。

### uGUIを扱う準備

oculus Goのセットアップは以上で完了ですが、uGUIを扱うにはもう少し準備が必要です。
今回は以下の記事を参考にさせていただきました。

- [Oculus Go 開発メモ - uGUI編](https://qiita.com/JunSuzukiJapan/items/bead777e8dfeaa49ea30)

ちなみに、バージョン違いの問題で説明されている方法だけだと正常に動作していませんでした。
記事で紹介されている「**OVRInputModule**」のインスペクタから行う設定で、「**Cursor**」の項目が新しく追加されており、これを適切に設定することで（記事で説明されている**OVRGazePointer**を設定すればOK）正常に動作しました。


## FirstVRのセットアップ

さて、今回はoculus GoのコントローラとFirstVRを組み合わせるのが目的なので、同様にFirstVRのセットアップも行います。
詳細については以前の記事「[FirstVRでカスタムジェスチャーの登録をするサンプル](https://qiita.com/edo_m18/items/4f03b2bbf182afd3e7a0)」をご覧ください。基本的なセットアップはこちらに記載されているものを同様のことを行います。


## コンテンツを作る

さて。以上ですべてのセットアップが完了しました。
あとはこれらを組み合わせてコンテンツを作っていくことになります。

今回作ったのは非常に単純なシューティングゲームですが、アクセントとしてFirstVRを利用し、力を溜めることでシューティングの弾が強化される、というものです。

oculus Goにはコントローラがひとつしかなく、どうしても片方の手が手持ち無沙汰になりがちなので、それを利用しました。

↓実際に動かしてみた図
<blockquote class="twitter-tweet" data-lang="en"><p lang="ja" dir="ltr">FirstVRとoculus Goコントローラを組み合わせてみる。 <a href="https://twitter.com/hashtag/FirstVR?src=hash&amp;ref_src=twsrc%5Etfw">#FirstVR</a> <a href="https://t.co/n72FjyEphC">pic.twitter.com/n72FjyEphC</a></p>&mdash; edom18@VR (@edo_m18) <a href="https://twitter.com/edo_m18/status/1090283806664212480?ref_src=twsrc%5Etfw">January 29, 2019</a></blockquote>

ちょっと分かりづらいかもしれませんが、普通にトリガーを引いているだけだと小さな弾が射出されます。
しかし、FirstVRで登録したジェスチャを、もう片方の手で作ることによって弾の大きさを変えています。
（ジェスチャをしているところが見えないのでジェスチャしている感ゼロですが；）

手の形はいくつか設定することができるので、これを応用するともっと面白いゲームが作れそうですね。
例えば、グーだとパワーを溜める。パーだと眼の前にシールドが出てきて防御する、などなど。

コントローラの操作というのは、得てして複雑になりがちですが、手でこの形を作ってください、というのができない人はほぼいないでしょう。
そういう意味では、トリガーだけに集中させて、手の形で操作を変えていくやり方は結構ありかもしれません。

残念ながら今はPCで利用できないようですが、PCでも利用ができるとそれこそViveなどと連携して、コントローラ以外での入力として使うと色々幅が広がりそうですね。
Inno Setup 変数をデバッグ画面に出力

検証条件
Inno Setup Ver5.6.1


変数をデバッグ画面に表示する
=========================
``` pascal
var
  str: string;

begin
  Log(str);
end;
```


BooleanをStringにする
---------------------

``` pascal
//ブーリアンを出力する関数を定義
function BoolToStr(Value: Boolean): String; 
begin
  if Value then
    Result := 'True';
  else
    Result := 'False';
end;

function isFileExist():Boolean;
begin
  Result := FileExists( ExpandConstant('{app}\file.txt') );
  Log(BoolToStr(Result));
end;

```

IntをStringにする
---------------------
``` pascal
//function IntToStr(i: Int64): String;
var
  Value: Integer;

begin
Log(IntToStr(Value));

```

FloatをStringにする
---------------------
``` pascal
function FloatToStr(e: extended): String;
```





公式ヘルプ
http://www.jrsoftware.org/ishelp/index.php?topic=scriptcreating
PHP で文字列を走査する

## はじめに

文字列を先頭から順に一文字ずつ走査し、何らかの処理を行いたいケースがしばしばあります。いや、ないかな...。

## マルチバイト文字を含む可能性がある場合

```php
<?php
    $s = "あいうえお";
    for ($i = 0; $i < mb_strlen($s); $i++) {
        $char = mb_substr($s, $i, 1, 'UTF-8');
        echo "$i: $char \n";
    }
```

<!--
```php:PHP_7.4.0_以降
<?php
    $s = "あaいbうcえdお";
    foreach (mb_str_split($s, 1) as $chr) {
        echo "$chr\n";
    }
```
-->

他の方法。

```php:PHP_4.2.0_以降
<?php
    $s = "あaいbうcえdお";
    foreach (preg_split('//u', $s, null, PREG_SPLIT_NO_EMPTY) as $i => $chr) {
        echo "$i : $chr\n";
    }
```

## マルチバイト文字を絶対に含まない場合

```php
<?php
    $s = "ABCDE";
    foreach (str_split($s, 1) as $i => $char) {
        echo "$i: $char\n";
    }
```
【rails5】Ruby Sass is deprecated and will be unmaintained as of 26 March 2019. というメッセージ

##Ruby Sass is deprecated and will be unmaintained as of 26 March 2019. というメッセージが出た。

AWScloud9で新しくワークスペースを作り、railsアプリ作成後、bundle installすると以下のメッセージ。

```
Ruby Sass is deprecated and will be unmaintained as of 26 March 2019.

* If you use Sass as a command-line tool, we recommend using Dart Sass, the new
primary implementation: https://sass-lang.com/install

* If you use Sass as a plug-in for a Ruby web framework, we recommend using the
sassc gem: https://github.com/sass/sassc-ruby#readme

* For more details, please refer to the Sass blog:
http://sass.logdown.com/posts/7081811
```

rubyのsassがサポート終了するのでsasscにして下さい、とのことで変更したのでメモ。

以下の記事を参考にしました。
https://qiita.com/cymbiformis/items/a965d9bfef536edf41a2

https://qiita.com/tkosuga@github/items/46094b630f57594e86f0

http://sass-lang.com/libsass

sasscはsassをcやc++言語で実装したライブラリ、sassよりも高速でコンパイルが出来るとのこと。

①gem 'sassc-rails'に変える。

②GemfileとGemfile.lock内の、ファイル名がsassとなってるもの全て削除する。

```
Gemfile

#gem 'sass-rails',   '5.0.6'

gem 'sassc-rails'
```

```
Gemfile.lock

ファイル名がsassとなっているものを全て削除
```

その後、
gem uninstall sass-rails

bundle install

sasscがインストール出来ているかどうか確認する。

１つsassが残っていたので、rails sでエラーが出ました。

削除して、再度bundle installでインストール出来、正常に動作しました。
スキーマ一覧を取得するSQL(Oracle/MySQL/PostgreSQL/SQLServer/Cassandra)

#はじめに

[MiluDBViewer(JavaFXを使ったGUI DBクライアント)](https://github.com/milukiriu2010/MiluDBViewer)を
作ったときの内容を忘れてきたのでメモします。

今回は、スキーマ一覧を取得するSQLについてです。

# Oracle - 12c Release2

```
select distinct owner from all_objects order by owner
```

# MySQL - 8.0.11

```
select schema_name from information_schema.schemata order by schema_name
```

# PostgreSQL - 10.4

```
select schema_name from information_schema.schemata order by schema_name
```

# SQLServer - 2017

```
select name from sys.schemas order by name
```

# Cassandra - 3.9.0

```
select keyspace_name, durable_writes from system_schema.keyspaces
```

# 上記以外のDB

後から知ったのですが、JDBCが実装していれば、
java.sql.DatabaseMeataDataのgetSchemas()メソッドで、
java.sql.ResultSetが返ってくるので、
resultset.getString("TABLE_SCHEM")でとれます。

参考URL
http://www.java2s.com/Tutorial/Java/0340__Database/GettableinformationfromDatabaseMetaData.htm
UMLのツール

# astah* community
使いやすくて、ずっと使っていたけど、提供終了になってしまった。。。
http://astah.change-vision.com/ja/product/astah-community.html

# Visual Studio CodeとPlantUML
UMLのダイアグラムを作成するテキストベースの言語で、テキストからUML図が描ける。
文法を知らないと描けないので、慣れるのに時間がかかりそうだが、少し書いてみて使いやすそうなのと、テキストで保存できるのは嬉しいので、これをメインに使ってみよう。
angular(7)のルーティングについて

#angularのルーティングについてまとめました。
- 内容はangular6でも変わりません。

モジュールでAngularのルーティング設定を行います。
おそらく`app.module.ts`の中ではなく、`route.module.ts`を作成してルーティングの設定。

```route.module.ts
import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';

// ここにパスの定義をかく
const routes: Routes = [
  // cliとかで入れるとデフォルトでトップにリダイレクトされる処理がここある
  // { path: '', redirectTo: '/top', pathMatch: 'full' },
  // リダイレクトしなくても良いなら、Componentを指定
  { path: '', component: TopComponent, pathMatch: 'full' },

  // 最後に上記のパスに当てはまらない場合のコンポーネントを指定。「Pagenotfound」を表示
  { path: '**', component: PageNotFoundComponent }
]

@NgModule({
  imports: [RouterModule.forRoot(routes, {
    // ルーターの設定で、スクロール位置の復元をオンに
    scrollPositionRestoration: 'enabled', 
    anchorScrolling: 'enabled',
  })],
  exports: [RouterModule]
})

```

## 子モジュールでルーティンを階層にする
- `children`を使用する

```route.module.ts
import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';

// ここにパスの定義をかく
const routes: Routes = [
  { path: '', component: TopComponent, pathMatch: 'full' },
  //階層にしたいパス
  { path: 'articles',
    // 「articles/」という URL になる
    children: [
      //「articles/edit」
      { path: 'edit', component: EditComponent },
    ]
  },
  // 最後に上記のパスに当てはまらない場合のコンポーネントを指定。「Pagenotfound」を表示
  { path: '**', component: PageNotFoundComponent }
]

@NgModule({
  imports: [RouterModule.forRoot(routes, {
    // ルーターの設定で、スクロール位置の復元をオンに
    scrollPositionRestoration: 'enabled', 
    anchorScrolling: 'enabled',
  })],
  exports: [RouterModule]
})

```


## ここで遅延読み込みについて
angularではModuleの遅延読込みが可能です。
これにより最初に読込むコンテンツの量を減るので、初期ページの読み込みの高速化します。
イメージ的には、もう一つ`app.module`と`router`のセットを作ってしまう感じです。
もちろん出力されるjsファイル(デフォルトだと`dist`以下のフォルダにできる)も増えます。

```route.module.ts
import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';

// ここにパスの定義をかく
const routes: Routes = [
  { path: '', component: TopComponent, pathMatch: 'full' },
  //遅延読込みしたいところ!!!!!!
  { path: 'sub',
    // 「sub/」という URL になる
    //  loadChildren:を使い、右辺に対象のmoduleまでのpathを記載
    loadChildren:'./sub/sub.module#SubModule' }
  },
  // 最後に上記のパスに当てはまらない場合のコンポーネントを指定。「Pagenotfound」を表示
  { path: '**', component: PageNotFoundComponent }
]

@NgModule({
  imports: [RouterModule.forRoot(routes, {
    // ルーターの設定で、スクロール位置の復元をオンに
    scrollPositionRestoration: 'enabled', 
    anchorScrolling: 'enabled',
  })],
  exports: [RouterModule]
})

```

あとはsub-moduleを作りましょう。

```sub-module.ts
import { NgModule } from '@angular/core';
import { SubRouteModule } from './sub-route.module';
import { SubPageComponent } from 'ページまでのパス';
 
@NgModule({
  imports: [
    // このmodule用のルーティングをインポート
    SubRouteModule 
  ],
  declarations: [SubPageComponent]
})
export class SubModule { }
```

こちらはsub-moduleのルーティング

```sub-route.module.ts
import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
import { SubPageComponent } from 'ページまでのパス';
 
//普通のルーティングと同様に切ってよい
const routes: Routes = [
  {
    path: '',
    component: SubPageComponent 
  }
];
 
@NgModule({
  imports: [RouterModule.forChild(routes)],
  exports: [RouterModule]
})

export class SubRouteModule {}
```
CMAFとTransfer-Encoding: chunked

# これは何

CMAFを利用すると低遅延のストリーミング配信を実現できるといいますが、その理由をHTTP/1.1の転送の仕組みと合わせて記述してみます。

# HLSやMPEG-DASHの配信

HLSやMPEG-DASHでは、まず最初に動画の断片ファイル(セグメント)の一覧が書かれたマニフェストファイルをダウンロードします。マニフェストファイルには、「ストリーミングしたい動画のx秒目からy秒目までのn秒間のファイルの名前はこれです。」という情報が書かれています。リアルタイムに配信される場合は、マニフェストファイルがリアルタイムに更新されていきます。プレイヤーは、再生したい時刻に合致した断片ファイルをダウンロードして再生します。

この時の再生遅延は、おおむねセグメントに含まれる動画断片の再生時間が少なくともかかります。また途切れなく再生させる為には、通常複数のセグメントを先読みしておきます。なので、カメラから出力された映像が視聴者の元で再生されるまでには一般的に数十秒の遅延が発生することになります。

この遅延を短くするためには動画セグメントに含まれる動画の再生時間を短くすることが考えられますが、動画セグメントのダウンロードをするたびにリクエスト/レスポンスのオーバーヘッドがかかるので、分割数が多くなるにつれてオーバーヘッドが増えていきます。

# CMAF

CMAFは別に低遅延伝送だけが取り柄ではないのですが、今回はそこだけにスポットを当てます。

CMAFでは、動画セグメントをさらにチャンクと呼ばれる単位に分割します。動画セグメントはその再生時間に縛られていましたが、チャンクは任意の長さにできます。そしてそれぞれのチャンクをHTTPで転送する時に、chunked形式で伝送を行うというのがキモになります。これにより、セグメント全てを受信しきらないと動画プレイヤーに渡せなかったのを、チャンクを受信したら動画プレイヤーは即座にそれを再生させるように努めます。

# `Transfer-Encoding: chunked`

さて、上記の記述の中に、chunked形式という言葉が出てきました。これはHTTP/1.1の通信方式の話なので、一旦HTTP/1.1の通信方式に話を移します。

HTTP/1.1ではKeep-Aliveといって、1つのファイルの転送が終わってから同じTCPセッションを使って別のファイルのリクエストを行う機能があります。これにより、ファイルを転送するたびにTCPセッションの確立を行う必要がなくなります。TCPセッションの確立はそこそこ時間や転送量がかかるので、そこが節約できるというわけです。

1つのファイルを1つのTCPセッションで転送するときは、ファイルの転送が終わったら一方的にTCPセッションを切断するという方法で転送の終了を示すことができました。しかし複数のファイルを転送する場合にはそういうわけにはいきません。なので、`Content-Length`リクエストヘッダーによって転送するファイルのサイズを予め明示することが必要になります。

とはいえライブストリーミングしている動画のように、予めファイルサイズが分からないような物を転送したいというケースもあります。そういう場合に使うのが、`Transfer-Encoding: chunked`です。これは転送したいファイルを一度に送るという通常のHTTPでのファイルの伝送方法とは異なり、細切れにして少しずつ送っていくという伝送方法です。これによりHTTPサーバーは「とりあえず1kBだけ送信する」ということが可能になります。

# `Transfer-Encoding: chunked`とCMAF

chunked方式でのデータ転送を映像配信に応用できると、デコーダが対応していれば一旦途中まで受信したところまででデコーダにチャンクを渡してデコード処理を開始できるようになります。何秒間か分の動画セグメントの受信を完了するまで待つ必要がなく、届いたデータを即座にデコーダに渡すことが出来ます。HTTPのプロトコルの枠組みから離れる必要もありません。

これにより、動画セグメントが起因で発生する再生遅延を短くすることができるようになるのです。もちろん映像データを受信するクライアント側で、非同期で受信した映像データを、映像を再生している傍からプレイヤーに渡せるようにするといった対応は必須です。

# HTTP/1.1 only

実は、`Transfer-Encoding: chunked`はHTTP/1.1にしかありません。HTTP/2はそもそもデータの転送方式がフレーム単位になっていますし、DATAフレームを立て続けに送ることで同様のことを実現できます。しかしながらCMAFがHTTP/2にマッピングされる話は寡聞にして知りません。HTTP/2のHTTP/1.1と比べた時の利点は、

* Webサイトの表示のように小さなファイルを数多くダウンロードしようとする時に、multiplexingによってhead-of-line blockingを起こさない。
* TCPセッションのestablishmentのオーバーヘッドが減る。

なので、動画のストリーミングのように長時間・大容量のデータを転送する場合には、あまりHTTP/2を使うこと自体がメリットがありません。もちろんHTTP/2で転送できないわけではないのでしょうが、特にメリットがあるわけでも無いので今後も特に積極的にHTTP/2でどうこうしようということは起きないのかもしれません。
Navigation Editor 導入の仕方　android studio３.３

Navigation Editorの導入がイマイチ難しい人へ
自分が色んな記事を見ながらなかなか出来なかったので超初心者向けに記述しておきます。


<img width="1060" alt="スクリーンショット 2019-01-30 5.26.16.png" src="https://qiita-image-store.s3.amazonaws.com/0/297466/da14a2c1-13a5-228a-17fe-d23e64959b6a.png">
こんな開発画面でやりたい！Xcode風にやりたい！って時にどうするか。。

まず普通に新規Project作成
android studioはバージョン３.２以上であること。自分は３.３です。
<img width="871" alt="スクリーンショット 2019-01-30 5.48.19.png" src="https://qiita-image-store.s3.amazonaws.com/0/297466/cc200dd7-1168-2d46-9cbc-d5f13057e697.png">

<img width="931" alt="スクリーンショット 2019-01-30 5.50.27.png" src="https://qiita-image-store.s3.amazonaws.com/0/297466/9742dd91-b883-c81a-ed6d-b29ab76ded40.png">
Empty Activityを選択します。選択してNextを押す。


名前は自分で分かりやすいものを。写真はNaviTestとしました。
名前入れたらFinishを押す。
<img width="925" alt="スクリーンショット 2019-01-30 5.52.09.png" src="https://qiita-image-store.s3.amazonaws.com/0/297466/29d1b2cc-4a60-7a0c-0a8f-7ef447b35e57.png">

build.gradleにコードを追加する。まず青色部分をダブルクリックして開く
<img width="556" alt="スクリーンショット 2019-01-30 5.53.52.png" src="https://qiita-image-store.s3.amazonaws.com/0/297466/85e04aaa-fba9-823d-893f-9008963bd4ab.png">



そうすると次の画面が出てきます。右ペインを見てね。
<img width="1467" alt="スクリーンショット 2019-01-30 5.54.15.png" src="https://qiita-image-store.s3.amazonaws.com/0/297466/82e03e11-6a10-83c9-ff11-06d47207e2ab.png">


下図写真の四角で囲った部分が以下の追加したコード。

dependencies {
    def nav_version = "1.0.0-alpha11"
    implementation "android.arch.navigation:navigation-fragment-ktx:$nav_version"
    implementation "android.arch.navigation:navigation-ui-ktx:$nav_version"
}

上記はkotlin向けです。javaなら「-ktx」と記述されている二箇所を削除してください。

<img width="1063" alt="スクリーンショット 2019-01-30 5.55.13.png" src="https://qiita-image-store.s3.amazonaws.com/0/297466/dd0dd08f-c20a-befd-3e33-5a30a10d2af2.png">

追加したら上図写真の右上に青色文字でSync…と書かれている文字をクリック


次にres

<img width="555" alt="スクリーンショット 2019-01-30 5.55.37.png" src="https://qiita-image-store.s3.amazonaws.com/0/297466/891e9208-b3e7-11ca-9825-fb3a20e46555.png">


下図写真の様にFile⇨New⇨Android Resource Fileを選択



<img width="848" alt="スクリーンショット 2019-01-30 5.56.25.png" src="https://qiita-image-store.s3.amazonaws.com/0/297466/ef8568e6-63ed-8988-dd62-5da724262432.png">

File nameを写真の様に　nav_graph
Resource type は写真の様にNavigationを選択してOKを押す。

<img width="1054" alt="スクリーンショット 2019-01-30 5.57.27.png" src="https://qiita-image-store.s3.amazonaws.com/0/297466/407e3f8b-034c-57e8-5e03-bb24631acb47.png">

<img width="392" alt="スクリーンショット 2019-01-30 6.49.21.png" src="https://qiita-image-store.s3.amazonaws.com/0/297466/874ef870-3086-b0b9-ae8b-7ee66504cae9.png">
この画像の様になればオッケーだと思います。
Discordにファイルをアップロードするactionsを作成してみた

## はじめに
技術書典で本を書いています
Re:VIEWでビルドするworkflowをgithub actionsで作成していますが、ビルドしたPDFをDiscordへアップロードする部分をactionとして公開してみました(おもしろそうだったので)

## 作ったもの
[sinshutu/upload-to-discord: A GitHub Action that uploads a file to Discord channel.](https://github.com/sinshutu/upload-to-discord/tree/master)


## 作り方
簡単には以下の3つの手順です
1. entrypoint.shを作成
2. Dockerfileを作成
3. workflowに組み込む

### entrypoint.shを作成
Discordへファイルをアップロードする方法を調べる

webhookのurlをcurlで叩くのがシンプルそうなのでそれを調べる
[cURL · Discord Webhooks Guide](https://birdie0.github.io/discord-webhooks-guide/tools/curl.html) を参考にcurlコマンドで送信

curlでファイルを送信する場合は -F オプションが使える
ファイルを指定する場合は `curl -F "file=@/path/to/file"` のように @を付ける必要がある
[curl option 覚え書き - Qiita](https://qiita.com/takayukioda/items/edf371b3566bea64d046#-f-key-value-data-%E3%83%87%E3%83%BC%E3%82%BF%E3%81%AE%E6%8C%87%E5%AE%9A%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB%E3%81%AE%E3%82%A2%E3%83%83%E3%83%97%E3%83%AD%E3%83%BC%E3%83%89%E7%AD%89)

結果として以下のような感じで送信するように

```shell
curl -H 'Content-Type: multipart/form-data' \
-X POST \
-F "file=@$1" $DISCORD_WEBHOOK
```

`$1` はコマンドの第一引数
`$DISCORD_WEBHOOK` はGithubのSecretsに登録した環境変数が読み込まれる

### Dockerfileを作成する
curlが実行できるDockerイメージを作成するだけなのでベースには `alpine` を使う
actionに使われるLABELの設定と先ほど作成したentrypoint.shをCOPYする

```dockerfile
FROM alpine:latest
LABEL author="@sinshutu"

LABEL "com.github.actions.name"="Upload to Discord"
LABEL "com.github.actions.description"="Uploads a file to Discord channel."
LABEL "com.github.actions.icon"="package"
LABEL "com.github.actions.color"="blue"

RUN	apk add --no-cache curl

COPY entrypoint.sh /usr/bin/entrypoint.sh

ENTRYPOINT ["entrypoint.sh"]
```

### workflowに組み込む
[README](https://github.com/sinshutu/upload-to-discord/blob/master/README.md) を参照ください

## おわりに
以外と簡単に作れました
この程度ならactionにする必要ないのでは?って思ってたりする

Slackへファイルアップロードするのも欲しいかも


### 参考
- [今後絶対大事になってくるGitHub Actions - Qiita](https://qiita.com/s_kozo/items/f2a2182f353672e63a47)
- [GitHub Actions (beta) が使えるようになったので調査した - はやくプログラムになりたい](https://rhysd.hatenablog.com/entry/2018/12/10/201302)
- [GitHub Actions で Go言語の lint と test を実行する ｜ DevelopersIO](https://dev.classmethod.jp/etc/github-actions-golang/)
- [GitHub Actions | GitHub Developer Guide](https://developer.github.com/actions/)
- [JasonEtco/upload-to-release: A GitHub Action that uploads a file to a new release.](https://github.com/JasonEtco/upload-to-release) <= これをベースに作った
世界的にサイバーセキュリティのプロ不足　メモ書き

世界では今300万人のサイバーセキュリティのプロ不足。

大企業は防御体制が弱い上に、大きなパートナー企業への”通路”として利用できる為中小企業よりも攻撃されやすい。



【企業や政府が求めているサイバープロの才能】

・プログラミンング
・コンピューターサイエンス、コンピューターエンジニアリングの学士号
・統計、数学のコースを専修した人材
・サイバーセキュリティの資格
・侵入検知、安全なソフトウェア開発
・ネットワーク監査
・専門家としての経験


【プロになる為には】

・特定のツールやテクノロジーに通じる為のトレーニング→大学、専門学校、ブートキャンプ（アメリカSecurest Academy、Open Cloud Academy、Evolve Security Academy）
・探究心、現在の危機をめぐる知識、学習や研究に対する情熱



【サイバープロとして有望な人】

下記の経歴がある人

・プログラマー 
・システムアドミニストレーター（システム管理者）
・ネットワークエンジニア



【IBMが作った”ニューカラー”と呼ばれる職】

ホワイトカラー：スーツやネクタイ、ワイシャツを着て働く事務職の人
ブルーカラー：作業着を着て工場などで働く人
ニューカラー：スキルや知識を重視。労働者は職場内教育、業界検定を通してスキルを選ぶ
create-elm-app で Webpack の Loader がうまく動かなかった問題

[create-elm-app](https://github.com/halfzebra/create-elm-app) (v3.0.3) で、YAML ファイルを JSON ファイルのように `import` するために [js-yaml-loader](https://www.npmjs.com/package/js-yaml-loader) あるいは [yaml-loader](https://www.npmjs.com/package/yaml-loader) を使おうとしたときに起きた問題。

まずこれらのローダーを使用するため、 https://github.com/halfzebra/create-elm-app/blob/master/template/README.md#overriding-webpack-config にあるように Webpack Config 書き換え用のファイルを作った。

```js:elmapp.config.js
const merge = require('webpack-merge');

module.exports = {
  configureWebpack: (config, env) => {
    return merge(config, {
      module: {
        rules: [
          {
            test: /\.ya?ml$/,
            use: ["js-yaml-loader"],
          },
        ],
      },
    });
  },
};
```

が、うまくいかない。試しに `import` した YAML ファイルがどうなっているのか見てみると

```yaml:data.yml
- 42
```

```js:index.js
import data from './data.yml';
console.log(data);
```

```text:出力
data:text/yaml;base64,bW9kdWxlLmV4cG9ydHMgPSBbNDJdOw==
```

```text:中身
module.exports = [42];
```

勝手に Base64 エンコードされてしまっていた。create-elm-app を使っていないときには起こらなかった問題だったので、create-elm-app が何かしらしているのだろうと思って調べると、おそらく Webpack Config に問題があった。

```js:elmapp.config.js
console.log(config.module.rules);
```

```js
[ { parser: { requireEnsure: false } },
  { test: /\.js$/,
    exclude:
     [ /[\/\\\\]elm-stuff[\/\\\\]/, /[\/\\\\]node_modules[\/\\\\]/ ],
    include: 'プロジェクトのパス\\src',
    loader:
     'プロジェクトのパス\\node_modules\\babel-loader\\lib\\index.js',
    query: { presets: [Array], plugins: [Array] } },
  { test: /\.js$/, use: [ [Object] ] },
  { test: /\.elm$/,
    include: 'プロジェクトのパス\\src',
    exclude:
     [ /[\/\\\\]elm-stuff[\/\\\\]/, /[\/\\\\]node_modules[\/\\\\]/ ],
    use: [ [Object], [Object], [Object] ] },
  { test: /\.css/,
    use:
     [ 'プロジェクトのパス\\node_modules\\style-loader\\index.js',
       [Object],
       [Object] ] },
  { exclude:
     [ /\.html$/, /\.js$/, /\.elm$/, /\.css$/, /\.json$/, /\.svg$/ ],
    loader:
     'プロジェクトのパス\\node_modules\\url-loader\\dist\\cjs.js',
    options: { limit: 10000, name: 'static/media/[name].[hash:8].[ext]' } },
  { test: /\.svg$/,
    loader:
     'プロジェクトのパス\\node_modules\\file-loader\\dist\\cjs.js',
    options: { name: 'static/media/[name].[hash:8].[ext]' } } ]
```

下から２番めのルールにおいて、`exclude` しか指定されていない。YAML ファイルがこれに引っかかって、他の例えば画像ファイルのように Base64 エンコードの対象になったのだろうと思い、`configureWebpack` に以下を追記してみた。

```diff:elmapp.config.js
  configureWebpack: (config, env) => {
+   for (const rule of config.module.rules) {
+     if (!rule.test && !rule.include && rule.exclude) {
+       rule.exclude.push(/\.ya?ml$/);
+     }
+   }
    return merge(config, {
```

すると正常に YAML が認識された。

```js:
[42]
```

対策がアドホックすぎる……。何かいい方法はあるんでしょうか。
jQueryのプラグインでスライドショーを実装する

#目的：jQueryでスライドショーを実装する
bxsliderというプラグインを使用してサイトにスライドショーを実装する．
とっても便利！
[https://bxslider.com/]

#手順１：bxsliderを使用するためのファイルをサーバ上から\<head>内に読み込む
```
<head>
  <link rel="stylesheet" href="https://cdn.jsdelivr.net/bxslider/4.2.12/jquery.bxslider.css">
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
  <script src="https://cdn.jsdelivr.net/bxslider/4.2.12/jquery.bxslider.min.js"></script>
</head>
```
#手順２：スライドショーしたい画像をhtmlに\<ul>タグとして記述
<br>クラス名は任意につけて良いが今回はbxsliderとする．

```
<ul class="bxslider">
  <li><img src="../images/sample-01.png" alt="" width="640" height="300"></li>
  <li><img src="../images/sample-02.png" alt="" width="640" height="300"></li>
  <li><img src="../images/sample-03.png" alt="" width="640" height="300"></li>
  <li><img src="../images/sample-04.png" alt="" width="640" height="300"></li>
</ul>
```

#手順３：\<script>内またはjsファイルにjQueryのコードを記述する
\<ul>タグのクラス名をセレクタに書き込む．
スライドショーのオプションは必要に応じて書き込む．

```
$('.bxslider').bxSlider({
　　auto: true,　　　　＃自動再生ON
　　slideWidth: 640,　　＃スライドの大きさを640pxにする
　　minSlides: 3,　　　＃表示されるスライドの最小枚数は１枚
　　maxSlides: 3　　　＃表示されるスライドの最大枚数は１枚
});
```

完成('◇')ゞ

#スライドショーのオプションは以下を参考にすると良い．
```
autoplay #自動再生
autoplaySpeed #自動再生の間隔
arrows #左右のナヴィゲーションの矢印を表示
dots #サムネイルのドットを表示
draggable #ドラッグによるコントロール
fade #スライダーの要素をフェードイン・フェードアウトで切り替え
easing #easingの種類を指定可能
infinite #ループさせるか否か
pauseOnHover #マウスオーバーで自動再生を一時停止
pauseOnDotsHover #ドットにマウスオーバーで一時停止
responsive 3レスポンシヴの設定
```
Rubyで「忘れ物はしません」を1万回繰り返す方法

https://togetter.com/li/1313773
話題になってた。学校は奴隷養成所だから、こういう理不尽なことが起きるのは当然
嫌なら、学校に行かずにネットと本で独学して、いい大学いい会社に入ればいい
そうすれば、理不尽なことを最小に済ますことができる

今回は、そういう理不尽なことを最小にしたい人向けの記事

Rubyを使って、「忘れ物はしません」を1万回繰り返す方法を書いていく

僕自身がプログラミングを学び始めたばかりなので、間違いがあれば、指摘してもらいたい

まず一番短いと思われる書き方

```rb
10000.times{
    puts"忘れ物はしません"
}
```
{}はdo、endでもできる

```rb
10000.times do
    puts"忘れ物はしません"
end
```

回数.timesというのは、非常にわかりやすいが、Ruby特有の書き方らしい。他の言語でも応用するためにも、forとwhileの書き方も覚えておくといいのだろう

```rb
for i in 1..10000 do 
  puts"忘れ物はしません" 
end
```

```rb
i=0
while i < 10000 do
  puts"忘れ物はしません"
  i=i+1 
end
```

ちなみにiというのは変数であり、別にiでなくてもいい。数学に出てくる、aとｂ,xとyだ。ではなぜ、iなのか。おそらくinteger（整数）のことを表していると思う。僕は独学で学んでいるので、知り合いにプログラマーがいないので、確定とは言えないが、おそらくそういうことだろう

ちなみに、永遠に続けたい場合は

```rb
loop do
    puts "忘れ物はしません"
end
```
loopを使うといい

paiza.io（https://paiza.io/ja）
に行けば、環境構築しなくても、上記のコードをコピペするだけで、自動化を実感することができる

以上
rubyで条件付きメソッドチェーン（tap, try, inject）

頭が回転しだして眠れなくなった。

メソッドチェーンしたいけど条件によってはしてほしくないときあるよね。
そういうときになぜだかあまり気が進まないやりかた：

```ruby
condition = true
n = 0

n = n.next if condition
n = n.next if !condition
n
```

理由はわからないが気が進まないものは気が進まないので、他の方法を調べてみた。

## `.tap { break }` を使う
https://qiita.com/takeru@github/items/29f9cad9e2318b7e5b82
↑参考

```ruby
condition = true
n = 0

n.tap { |x| break x.next if condition }.tap { |x| break x.next if condition }
# => 2

n.tap { |x| break x.next if condition }.tap { |x| break x.next if !condition }
# => 1

n.tap { |x| break x.next if !condition }.tap { |x| break x.next if condition }
# => 1

n.tap { |x| break x.next if !condition }.tap { |x| break x.next if condition }
# => 0
```

ハックっぽさが仕事では使いにくそう。
break しなければレシーバが引き継がれるのが良いところ。

## try を使ってみる (rails)

https://stackoverflow.com/questions/33744368/conditionally-call-chained-method
↑の一番下の例。
[try にブロックを渡せるのは知らなかった](https://github.com/rails/rails/blob/b4fa6516c1fc81f7da2a92adee9634d2771b7df0/activesupport/lib/active_support/core_ext/object/try.rb#L41)。

```ruby
condition = true
n = 0

n.try { |x| condition ? x.next : x }.try { |x| condition ? x.next : x }
# => 2

n.try { |x| condition ? x.next : x }.try { |x| !condition ? x.next : x }
# => 1

n.try { |x| !condition ? x.next : x }.try { |x| condition ? x.next : x }
# => 1

n.try { |x| !condition ? x.next : x }.try { |x| !condition ? x.next : x }
# => 0
```

この try が何をしてるかというと引数がブロックのみだったら yield してるだけ。
レシーバは引き継がれないので返してやる必要がある。

## 配列に入れて inject (reduce)
https://stackoverflow.com/questions/1797189/conditional-chaining-in-ruby
↑の最初の例。

```ruby
condition = ture
n = 0

l = []
l << :next if condition
l << :next if !condition
l << :next if condition

# l => [:next, :next]

l.inject(n) { |obj, method| obj.send(method) }
# => 2
```
引数を渡したければ配列で包んで渡してブロックの中でも使ってやれば良い。

```ruby
l = []
l << [:method, arg1, arg2] if condition
```

ところで私は確信しておりますが、rubyist が好むのはこれじゃないでしょうか。
ファミコンソフトをCircleCIでビルドする

# きっかけ
[MAPPER 4 CARTRIDGE](https://www.kadenken.com/shopdetail/000000000849/)や[kazzo](https://www.kadenken.com/shopdetail/000000000567/ct158/page1/order/)のおかげで、ROM焼きができそうなので、NESファイルのビルド環境を作りたくなった。せっかくなので、CircleCIの手習いも兼ねてみる。仲間内で環境を共有したいし。
# 前提
GitHubアカウントがあればよい。リポジトリは作っておく。CircleCIはGitHubアカウントでログイン可能なので、リポジトリを連携する。
# ビルド設定
test.cをコンパイル・アセンブル・リンクするだけの設定。Makefileなど使いたいところだが、それはおいおい。

```yaml:.circleci/config.yml
version: 2
jobs:
  build:
    docker:
      - image: debian:stretch
    steps:
      - checkout
      - run: echo 'deb http://download.opensuse.org/repositories/home:/strik/Debian_9.0/ /' > /etc/apt/sources.list.d/home:strik.list
      - run: apt-get update
      - run: apt-get install -y ca-certificates
      - run: apt-get install -y --allow-unauthenticated cc65
      - run: cc65 -t nes test.c
      - run: ca65 -t nes test.s
      - run: ld65 -t nes test.o nes.lib atmos.lib -o test.nes
      - store_artifacts:
          path: ./test.nes
          destination: test.nes
```
## ハマりポイント
- `apt-get install -y ca-certificates`がないと`store_artifacts`でエラーになった
- `apt-get install -y --allow-unauthenticated cc65`の`--allow-unauthenticated`で証明書エラーを回避。証明書を導入する方法もあるが、手っ取り早く…

# 参考文献
- [cc65 @ wiki](https://www34.atwiki.jp/cc65/)
- [cc65 on GNU/Linux](https://github.com/cc65/wiki/wiki/GNU-Linux)
取引所サーバーから最新の日経225 オプション清算値データを取得、抽出するモジュールを作成しPyPIに登録

取引所サーバーから最新の日経225 オプション清算値データを取得するモジュールを作成し、PyPIに登録してみました。

#nk225op 
`nk225op`  はJPX(日本証券取引所)のサーバーから、最新の日経２２５オプション清算値を取得するモジュールです。　
> ブラウザでお気軽に試す場合　⇒　 [Jupyter Notebook example on Google Colab](https://colab.research.google.com/github/zaq9/nk225op/blob/master/doc/eg_nk225op.ipynb)



## Demo:　 (２月限と３月限　権利価格　20500～20750 の清算値とIVデータ表示)

```python
from nk225op import nk225op as nk
nk([201902,201903] , [20500,20750])
```

### Output:

| lb         | PRICE | IV          |
| ---------- | ----- | ----------- |
| 02/C20500  | 340   | 18.3289     |
| 02/C20625  | 260   | 17.5826     |
| 02/C20750  | 195   | 17.2045     |
| .......... | ...   | (以下省略） |




## Install:　(Google Colaboratory 上での利用方法 )

```
!pip install nk225op
```

> ブラウザでお気軽に試す場合　⇒　 [Jupyter Notebook example on Google Colab](https://colab.research.google.com/github/zaq9/nk225op/blob/master/doc/eg_nk225op.ipynb)

------

### ※ローカル環境にInstallする場合   ``` pip install nk225op ```
#### Requirement

- Pandas
- bs4

---------



## 利用できる関数:

```python

def nk225op(maturities=None, strike_range=None):
	"""Download latest Options DATA(NK255) from JPX
	:param maturities: List
		#eg1(monthly type): [201902]
		#eg2(weekly type): [20190125]
		#eg3: [201902 , 201903 , 20190125]
	:param strike_range: List
		#eg: [19000,20000]
	:return: DataFrame
		OptionsPriceList :
	Examples
	--------
	>>>  nk225op([201902],[20500, 21000])
	"""

```


​	

```python

def latest_csv_path():
    """JPXサーバ内にある最新の清算値CSVファイルへのPATHを返す"""

def csv_to_df(csv_path, max_maturity_day=90):
	"""
	清算値CSVファイルをDataFrameに変換
	Parameters
	----------
	csv_path : str
	max_maturity_day :  int , default 90
		最大、SQ期日が何日後までのデータを取得するか（規定値９０日後）
	Returns
	-------
	DataFrame
	"""

```

##PyPIへの登録:
[PyPI: nk225op](https://pypi.org/project/nk225op/)
Ruby のメソッド、Proc のソースを取り出す

Ruby 2.6 から `RubyVM::AbstractSyntaxTree.of` が使えるようになりました。これは `Method` か `Proc` オブジェクトを受け取りその AST を返すものです。

```ruby
RubyVM::AbstractSyntaxTree.of(-> {1 + 1}) #=> RubyVM::AbstractSyntaxTree::Node
```

例えばこんな感じでメソッドや Proc のソースを取り出すことが出来るようになります。

```ruby
module NodeToSource
  def to_source
    node = RubyVM::AbstractSyntaxTree.of(self)
    return nil if node.nil?

    path, _lineno = source_location
    lines_for_file = File.readlines(path)
    extract_source(node: node, lines_for_file: lines_for_file)
  end

  private

  def extract_source(node:, lines_for_file:)
    first_lineno = node.first_lineno - 1
    first_column = node.first_column
    last_lineno = node.last_lineno - 1
    last_column = node.last_column - 1

    if first_lineno == last_lineno
      lines_for_file[first_lineno][first_column..last_column]
    else
      src = ' ' * first_column + lines_for_file[first_lineno][first_column..]
      ((first_lineno + 1)...last_lineno).each do |lineno|
        src << lines_for_file[lineno]
      end
      src << lines_for_file[last_lineno][0..last_column]
    end
  end
end

class Method
  include NodeToSource
end

class Proc
  include NodeToSource
end

def foo
  puts 'hello world'
end

n = Proc.new { |i| i * 3 }

puts method(:foo).to_source
puts n.to_source
```

実行結果

```
def foo
  puts 'hello world'
end
{ |i| i * 3 }
```

ただ、C で定義されているメソッドは `RubyVM::AbstractSyntaxTree.of(self)` の返り値が `nil` になるためソースは取得出来ません。
Google Cloud 認定資格 Associate Cloud Engineer を取得しました

2019年1月27日に受験し、無事合格しました！
**合格までの勉強方法とおさえるべきポイント**をまとめたので、これから受験する方の参考になれば幸いです

# 試験について
- 試験時間: 2時間
- 試験料: 125米ドル (約13,687円)
- 設問数: 全50問

## 筆者のスペック
- 基本情報技術者試験 合格（6年前）
- AWS歴: 2年 (構築経験なし。運用経験あり)
- GCP歴: 6ヶ月（ゼロから構築中。運用経験なし）
- サーバーエンジニア5年目

# **Associate Cloud Engineer**と**Professional Cloud Architect**の違い（主観）

#### [Professional Cloud Architect](https://cloud.google.com/certification/cloud-architect?hl=ja)

```
・　クラウド ソリューション アーキテクチャの設計と計画
・　クラウド ソリューション インフラストラクチャの管理とプロビジョニング
・　セキュリティとコンプライアンスに対応した設計
・　技術プロセスやビジネス プロセスの分析と最適化
・　クラウド アーキテクチャの実装の管理
・　ソリューションとオペレーションの信頼性の確保
```

クラウドソリューションの設計に長けている **Googleクラウド環境でのベストプラクティスの提案・構築が実現できるエンジニア向け**という印象
・　セキュリティとコンプライアンスに対応した設計
・　技術プロセスやビジネス プロセスの分析と最適化
など、特に**インフラエンジニア・プロジェクトマネージャー**に求められるスキルが問われるようです。

---

#### [Associate Cloud Engineer](https://cloud.google.com/certification/cloud-engineer?hl=ja)

```
・　クラウド ソリューション環境の設定
・　クラウド ソリューションの計画と構成
・　クラウド ソリューションのデプロイと実装
・　クラウド ソリューションの正常なオペレーションの確保
・　アクセスとセキュリティの構成
```

2018年6月頃？から始まった新しい認定資格で
**クラウドソリューションの設計に長年の経験がないものの、Googleクラウド環境に精通している(したい)エンジニア向け**という印象です

Professional Cloud Architectと比べると
・セキュリティとコンプライアンス
・ビジネスプロセスの分析と最適化
・オンプレからのクラウド移行
などの問題が省略されているためか、**より実践的な問題**が多く出題されました。

- これからGCPについて学びたい
- GCPで構築されたプロジェクトに参画する
- 特定のプロダクト(BigQueryなど)は使用しているが、他のプロダクトの知見を深めたい
という方にはぴったりな試験だと思います。

# 勉強方法 ・ 必ず押さえておくポイント

### 1. GCPのプロダクトとサービスの概念と略語を理解する
GCEとは？ GAEとは？
[プロダクトとサービス](https://cloud.google.com/products/?hl=JA)のページに記載されているものは全て覚える

### 2. [IAM]((https://cloud.google.com/iam/docs/overview?hl=JA))概念と用語を完璧に理解する
役割や権限付与などGCPプロダクトの全般に関わるため、IAMの知識は必ず押さえておく必要があります。
実際にコンソール上で、ポチポチやってみるのが最善です


### 3. チュートリアルを行う
各プロダクトのドキュメントにある [チュートリアル](https://cloud.google.com/compute/docs/tutorials?hl=JA)の中から、上から1~2個は動かしてみる

### 4. <font color="#FF0000">**おすすめの方法**</font>と<font color="#FF0000">**Googleが推奨する方法**</font> をおさえる
各プロダクトのドキュメントにある「概念」カテゴリから全てのコンセプトを読む
概念カテゴリ内に **[おすすめの方法](https://cloud.google.com/iam/docs/concepts?hl=JA#header_2)** や**ベストプラクティス**があれば特に目を通しておく


### 5. 次のプロダクト全てで 3.4を行う

- IAM
- Compute Engine
- Deployment Manager
- App Engine (Standard環境)
- Kubenetes
- Cloud Storage
- BigQuery

### 6. 模擬試験を受験する
インターネット上で受験することができます。
雰囲気がつかめるので、両方やっておくことをおすすめします

- [Associate Cloud Engineer 模擬試験](https://cloud.google.com/certification/practice-exam/cloud-architect?hl=ja)
- [Professional Cloud Architect 模擬試験](https://cloud.google.com/certification/practice-exam/cloud-engineer?hl=ja)

### 7. その他押さえておくべきポイント
- gcloudコマンドでできること、できないことを把握しておく(bqコマンドやkubectlコマンドが必要となる操作があるため)
- CIDERやサブネットなどIPアドレスについての基本的な理解
- Cloud Storageのライフサイクル
- CloudSQL・Bigtable・Spanner・DatastoreこれらのDBの特徴とそれぞれがどのようなデータを保存するのに長けているかを理解する

# 合否発表と合格者特典
3日後に合格メールが届きました

特典として以下のいずれかから選んだ物が貰えます！
・Google13インチラップトップケースとGoogleマグカップ
・Google15インチラップトップケースとGoogleマグカップ
・Google靴下とGoogleブランケットのセット 

![スクリーンショット 2019-01-30 1.07.58.png](https://qiita-image-store.s3.amazonaws.com/0/40799/043f11dd-f83b-b8c7-9df5-2f9cf47c15c4.png)

## さいごに
GCPは最高です :blush:

## 関連
[【2020年度版】Google Cloud 認定資格 Professional Cloud Developer を取得しました](https://qiita.com/wMETAw/items/ef3534961784e3596d57)