OmniAICreator/Qiita-1.07M huggingface dataset:
Vue.jsを導入してみた

[ユアマイスターアドベントカレンダー2018](https://qiita.com/advent-calendar/2018/yourmystar)の3日目の記事です。


## 結論
めっちゃ便利。

## 導入の背景
元々フロントはjQueryで色々やっているんですが、ajaxで取得したデータをごにょごにょして画面に表示するのが面倒だったので、上手いことデータバインドで表示したいなーと思ったのが最初です。
初期表示時は非表示としたかったため、CSSで`display: none;`をつけて要素を隠しておく必要もあり、それをjQueryで表示する処理が必要だったりなど、色々気になることがあったことも理由です。
また、そろそろ一度くらいVue.jsに触れてみたいなぁと言う気持ちもあり、と言うかそれが最大の理由だったので、とりあえず導入してみた次第です。
まだあまり使えてはいないのですが、ざっと使ってみた内容を書いてみたいと思います。

ちなみにですが、サクッと使ってみたかったので[Vue.jsの公式](https://jp.vuejs.org/v2/guide/installation.html)からJSをダウンロードして使っています。

## よかったこと
### 表示・非表示の制御が簡単
`v-if`ディレクティブが思っていた以上に便利で、Vue側で定義した変数が変わるたびに表示・非表示を切り替えられるのがとても楽でした。
ajaxで取得したデータの整合性をチェックして、問題がなければある変数を切り替えるだけで要素の表示が可能だったので、

```sample.html
<div id="container">
	<div class="hoge">
		<p>hogehoge</p>
	</div>
</div>

<script>
	$(function () {
		if (hoge) {
			$('.fuga').show();
		} else {
			$('.fuga').hide();
		}
	});
</script>
```
こんな処理が

```sample.html
<div id="container">
	<div v-if="showHoge">
		<p>hogehoge</p>
	</div>
</div>

<script>
	new Vue({
		el: '#container',
		data: {
			showHoge: false
		}
	});
</script>
```
こんな感じで書けます。
`showHoge`が`true`になれば要素が表示され、`false`であれば非表示です。
また、非表示時はレンダリングされないので、`display: none;`のようにdevToolで表示できてしまう、と言うこともありません。

### 計算処理が楽
データバインディングが使えるので、画面の表示値を簡単に書き換えることができます。
表示中の要素から金額部分を抜き出して、それを数値型に変換した後に計算をし、再度画面にセットし直す、が下のように書けます。

```sample.html
<div id="container">
    <div>
        <p>{{price}}</p>
    </div>
    <button type="button" @click="addPrice">add</button>
</div>

<script>
    new Vue({
        el: '#container',
        data: {
            price: 0
        },
        methods: {
            addPrice: function () {
                this.price += 1000;
            }
        }
    });
</script>
```
もし、データは数値型で持ちたいけど表示はカンマで区切りたい、みたいな場合はHTMLの表示部分で
`<p>{{price.toLocaleString()}}</p>`
と書くとカンマ区切りで表示できます。
表示部分でもJSのメソッドを呼び出すことができるので、最終的に見せたい値はここで加工することも可能です。

## よくなかったこと
### 既存要素のデータを取得できない
jQueryでよくやる
`$('.hoge').text()`
みたいな書き方はできません。
(できるのかもしれませんがやったことないので分かりません)
データを取りたい時は生のJSで
`document.getElementById('hoge').innerText;`
みたいなことを書かなければいけないのでちょっと手間です。
レンダリング時に`v-bind`などを使ってバインドしておけばいいだけではありますが、jQueryに慣れているとちょっと戸惑いがちな部分だなと思いました。

### 単体でのアニメーションができない
jQueryだと`.fadeIn(200)`とかで簡単にアニメーションできましたが、Vue.jsではCSSと組み合わせないとアニメーションできません。
そんな難しいことではないのですが、jQueryでのアニメーションに慣れていると「あっ」となることがあったりするので、ちょっと不便かなーと。
慣れの問題もあるので個人的感想ですが。


## 結局
やっぱりデータバインドがすごく便利でした。
いちいち要素指定してデータ拾ってきて加工して、が不要になるので、それだけでもう大きなメリットかなと思います。
しばらくはjQueryと共存する予定ですが(ajaxもjQuery依存なので)、いずれはvue-cliを導入してコンパイルしたものを使う、と言う形にしていきたいと思っています。
【随時更新】reactがわからないのでとりあえずできることをまとめる

## 基本形

```src/app.js

//読み込んでる系
import React, { Component } from 'react';//react読み込んでる
import logo from './logo.svg';//ロゴ読み込んでる
import './App.css';//css読み込んでる
class App extends Component {//コンポーネント定義してる
  render() {
    return (
      <div>hello</div>
    );
  }
}

export default App;

```

##ちょっと応用
基本的にreturn内は並行してタグを並べることができず、なんらかの形で一つにくくらなければならない。しかし、下のように<React.Fragment>で囲うことによりそれも可能になるよ（唐突にふわっとした）
で、かつこれは省略型で書くことも可能なんだけど、一応最新記法なので対応していないことも多く、しばらくはちゃんと記述したほうがいい。

```js

    return (
      <React.Fragment>
      <div>hello</div>
      <div>hello~</div>
      </React.Fragment>
    );

    return (
      <>
      <div>hello</div>
      <div>hello~</div>
      </>
    );

```

## functionalCompornent

```js
const hello = () => {
 return <div>こんにちは</div>;
}

//props付ける場合
const hello = (props) => {
 return <div>こんにちは{props.sample}さん</div>;
}

//props吐き出し場所の書き方
　　<hello sample='ほげのげ' />

//吐き出される結果
<div>こんにちはほげほげさん</div>
```

## classCompornent
```js

class hello extends React.Compornent {
 render() {
  return <div>こんにちは{this.props.sample}さん</div>;
 }
}

//props吐き出し場所の書き方
　　<hello sample='ほげのげ' />

//吐き出される結果
<div>こんにちはほげほげさん</div>
```
2つの抽象化プログラミングパターンユースケース


##プログラミングの抽象化で混乱するケース
プログラミングでは抽象化が重要です。抽象化をすれば汎用的な処理を記述でき、一度の記述で多くの事ができます。

しかし、抽象化しようと思った時にどう抽象化すれば良いか混乱するケースが多いです。

その原因の一つが、抽象化が場合により部分集合と全体集合の全く逆の意味を持つという事があります。どういう事か書いていきます。


##部分集合と全体集合
部分集合とは、全体に共通する要素。全体集合とは、全ての要素の集まりです。

そして、抽象化という言葉は対象に着目する場合は全体集合の意味で使われ、性質に使われる場合は部分集合の意味で使われます。

例えば、「人間」という言葉で対象を表現をした場合、人類全体や、人間みんなをイメージさせます。これは人の全体集合です。

一方で、「人間」が性質に言及する文脈で使われた場合、「手足が2本つつあり、二足直立歩行をし、頭がある哺乳類」というように人間全員に共通する性質(要素)に着目します。これが部分集合です。

抽象化とはどちらの視点でも全体の概念を前提にしている点では共通していますが、
全体のなかの部分集合を意味するのか、全体からなる全体集合を意味するのかで意味が真逆になります。

プログラミングで記述を抽象化したいと思った時には、まず自分が部分集合と全体集合のどちらの抽象化をしたいのかを考えてみましょう。

##全体集合に対応するプログラミングパターン
全体集合について意識しているという時は、クラスを定義します。

例えば、太郎君、次郎君やマイケルを生成するために人間クラスを定義します。
人間という全体集合から個別の人を生成できるようにします。

この場合、全ての性質を網羅する必要があります。

```javascript
class Human {
   constructor(name, birthPlace) {
       this.name = name;
       this.birthPlace = birthPlace
   }
}

var taro = new Human('taro', 'Japan')
var jiro = new Human('taro', 'Japan')
var michael = new Human('taro', 'British')

```

全体を定義できるクラスから具体例を生成していきます。


##部分集合に対応するプログラミングパターン

部分集合について意識しているという時は、継承するためのクラスを定義します。

例えば、太郎君、次郎君、マイケルは共通してfirstName, lastNameを持つけれど、イギリス人のマイケルだけは加えてmiddleNameを持つという風に考えるとします。

すると以下のようになります。



```javascript
class Human {
   constructor(firstName, lastName) {
       this.firstName = firstName;
       this.firstName = lastName;
   }
}

lass Japanese extends Human {
   constructor(firstName, lastName) {
      super(firstName, lastName)
   }
}

class British extends Human {
   constructor(firstName, lastName, middleName) {
      super(firstName, lastName, middleName)
   }
}


```

抽象クラスを定義し、具体クラスには抽象クラス + α を定義してあげます。



##両者の比較

抽象クラスは定義せずに住むのが一番シンプルです。

抽象クラス定義する場合、具象クラスを大量に定義する事になるからです。

先ほど例でもBritishクラスなどを作るのは冗長すぎるでしょう。

しかしもっと複雑な、例えばhtmlのフォームコントロールをJavascriptから自動生成する抽象化した自作要素を作る場合などはどうなるでしょうか。

```html
##1つめ
<input type="radio" value=3 min=0, max=10 >
##2つめ
<select>
  <option value='option1'>Option1</option>
  <option value='option1'>Option2</option>
</select>

##3つめ
 <input type="radio" name="gender" value="male">
 <input type="radio" name="gender" value="female">
 <input type="radio" name="gender" value="other">
 
```

これらを全てを一般化して表現できるHTML要素を定義できるでしょうか。
また、定義できたとして、その要素は使い勝手が良いでしょうか。

おそらく非常に難しい事になるでしょう。

しかし、radio input要素をJavasSriptから自動生成するのと、select要素をJavasSriptから自動生成する処理を記述するのはそれほど難しくありません。

インターフェースも処理もそれほど複雑ではありません。

```javascript
createRadioInput(id, value, min, max)
createSelectControl(options)
```

しかし、フォームの種類を具体的に指定する必要があるため、違う種類のフォームコントロールを動的に生成する処理を記述するのが難しくなります。

では、動的に記述するためのはどうすれば良いでしょうか。

##switch case で具象クラスのラッピング

以下のようなメソッドを考えます。

```javascript

createFormControls(configs) {

  return configs.map(config => {
    switch(config.type) {
       case 'text':
          createTextInput(config);
       case 'select':
          createSelectControl(config);
       case 'radio';
          createRadioInput(config)
    }
  })
}

```

以上のように記述する事で、具体的なインターフェースしか考えてなかったのに、全てのケースに対応できるインターフェースを定義することができます。

動的な処理を記述するには抽象化が複雑すぎると感じた場合、具象クラスへ分割してから、具象クラスへ処理を分岐させるラッパーを作る事を考えましょう。


以上が考え方です。


##終わりに

抽象度の高いテーマで最適なうまく説明するのが難しかったです。
少しだけでも伝わる人がいたら幸いです。
これができたら中級者？探索アルゴリズム

# プログラミング中級者への道
プログラミングを勉強し、ある程度コーディングができるようになったけれどもなかなか自分の成長を感じることができないあなたに

# 幅優先探索と深さ優先探索

## 深さ優先探索とは
> 深さ優先探索（ふかさゆうせんたんさく、英: depth-first search, DFS、バックトラック法ともいう）は、木やグラフを探索するためのアルゴリズムである。アルゴリズムは根から(グラフの場合はどのノードを根にするか決定する)始まり、バックトラックするまで可能な限り探索を行う。「縦型探索」とも呼ばれる。 
from [wikipedia](https://ja.wikipedia.org/wiki/%E6%B7%B1%E3%81%95%E5%84%AA%E5%85%88%E6%8E%A2%E7%B4%A2) 

はい。わかりませんね。
細けぇこたぁいいんだよ！
**実践あるのみ！**

## 今回使うデータ(構造)はこれだ！
<img src="https://docs.google.com/drawings/d/e/2PACX-1vRO-W-Q2_ApoYXxT_4dxqihoHury0uryZcVfmx8dVFtROPlB6gbzxwMOC0KZTdj-LIaVPax3iNKrtl-/pub?w=960&amp;h=340">

"**幅優先探索**"の場合には1, 2, 3, 4, 5...というように番号順にノードを処理していきます。
"**深さ優先探索**"では、1, 2, 4, 7, 8...という順番になります。

# 前置きはここまで

実際にコードを紹介していきましょう。

## まずはデータを用意します。
```python
s10 = {"content": 10, "children": None}
s9 = {"content": 9, "children": None}
s8 = {"content": 8, "children": None}
s7 = {"content": 7, "children": None}
s6 = {"content": 6, "children": [s10]}
s5 = {"content": 5, "children": [s9]}
s4 = {"content": 4, "children": [s7, s8]}
s3 = {"content": 3, "children": [s6]}
s2 = {"content": 2, "children": [s4, s5]}
s1 = {"content": 1, "children": [s2, s3]}
root = {"content": None, "children": [s1]}

print(root)
# {'content': None, 'children': [{'content': 1, 'children': [{'content': 2, 'children': [{'content': 4, 'children': [{'content': 7, 'children': None}, {'content': 8, 'children': None}]}, {'content': 5, 'children': [{'content': 9, 'children': None}]}]}, {'content': 3, 'children': [{'content': 6, 'children': [{'content': 10, 'children': None}]}]}]}]}
```

## 深さ優先探索
深さ優先のアルゴリズムではループにおける一時変数にスタックを使います。
なお、今回スタック変数とキュー変数では同じdequeを使用します。
dequeとはDouble ended queueというデータ構造でスタックとキューの両方の性質を持つデータ構造です。
スタックとして使いたい場合popメソッド、キューとして使いたい場合popleftメソッドを使います。

``` python
from collections import deque
# 上記の変数rootをそのまま使います。
result = []
stack = deque()
stack.extend(root.get("children"))
while stack:
  tmp = stack.pop()# スタックとして扱うためpop()
  content = tmp.get("content")
  children = tmp.get("children")
  result.append(content)
  if children:
    stack.extend(children[::-1])

print(result)
# [1, 2, 4, 7, 8, 5, 9, 3, 6, 10]
```

## 幅優先探索
幅優先探索の場合のアルゴリズムはどうなるのでしょう？
簡単です。深さ優先探索の処理のループ一時変数をスタックからキューに変えるだけ！

``` python
from collections import deque
result = []
queue = deque()
queue.extend(root.get("children"))
while queue:
  tmp = queue.popleft()# キューのためpopleft()
  content = tmp.get("content")
  children = tmp.get("children")
  result.append(content)
  if children:
    queue.extend(children)

print(result)
# [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
```

# これで君も中級者？ちょっと待って！

中級者への道は再起表現をマスターすることで開かれます。
再起表現はプログラムのメモリ空間のスタック領域をそのまま使いループ処理を実行するもの。

わざわざスタック変数を定義せずに直感的に書くことができるのが利点
言語仕様でtail recursionという機能をサポートしていないと処理の規模によってスタックオーバーフローを引き起こしてしまうのが欠点

## 再起表現(深さ優先探索)

```python
def recursive(tmp, acc=[]):
  content = tmp.get("content")
  children = tmp.get("children")
  acc.append(content)
  if children is not None:
    for c in children:
      recursive(c, acc)
  return acc

result = recursive(root.get("children")[0])
print(result)
# [1, 2, 4, 7, 8, 5, 9, 3, 6, 10]
```

# 後日更新予定
IntelliJを利用したTerraform開発環境構築手順

#Terraform開発環境の構築手順概要
TerraformでAWS環境を構築することになり、開発環境を整えましたので、
情報整理も兼ねて手順を本記事で纏めておこうと思います。

#なぜTerraformか
AWSを自動構築する場合、Cloudformationを利用することが多いと思いますが、
DRY-RUN実行時にパラメータ差分まで分かる利点があることからTerraformを選択しました。
※2018/11 re:Inventにて「CloudFormationでスタック差分の検出機能をリリース」との発表あり。。詳細未確認。
CloudFormationと違いサポートが無いことがリスクとしてありますが、そこまで大きな問題はないと思います。
IntellijはHCL（Terraformを記述する言語）のプラグインをサポートしており、開発効率が高いです。

#Intellijインストール

①Intellij IDEAダウンロード

②IntellijをZipを適当な場所に解凍

③Intellijの起動
\${解凍したパス}\ideaIC-2018.2.5.win\binidea64.exeを実行
※64ビット版のOSを利用している場合

#Intellij日本語化
①Pleiades日本語化プラグインのダウンロード

②Pleiadesプラグインのインストール
解凍し、展開したフォルダを開きます。下図のファイルが含まれています。[setup.exe]ファイルをダブルクリックして実行します。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/311339/1366acc8-b08b-cb8f-a69c-d2ad6d03cef8.png)

[Pleiades 日本語化プラグインのセットアップ]ダイアログが表示されます。[日本語化するアプリケーション]の欄の右側の[選択]ボタンをクリックします。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/311339/b551d71b-5831-c550-3970-b94d9be46bbb.png)

ファイル選択ダイアログが表示されます。64ビット版のOSを利用している場合は"idea64.exe"ファイルを選択します。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/311339/63e04c40-6af5-f1d0-740b-2fd07fe26eaf.png)

ファイルが選択されると下図の画面表示になります。ダイアログ右下の[日本語化する]ボタンをクリックします。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/311339/8aacbf63-1759-4d4f-ce09-4c649028ae00.png)

日本語化処理が実行されます。処理が完了すると下図のメッセージボックスが表示されます。[OK]ボタンをクリックしてメッセージボックスを閉じます。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/311339/5c47edba-6231-81fc-58b5-4a777b84a42b.png)

ダイアログ右下の[終了]ボタンをクリックしてインストーラーを終了します。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/311339/f46be563-685a-6265-36d6-d66c5294e550.png)

#HCLプラグインの設定
①　intellijを起動します。

②メニューバーから「ファイル」→「設定」を選択します。

③「プラグイン」を選択します。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/311339/a660cec6-c590-f2d4-4818-f59977712337.png)

④リポジトリの参照を選択します。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/311339/c6dfe0f6-b93d-87f5-420f-e98d538c3216.png)

⑤HCLプラグインを検索しインストールします。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/311339/08c35803-afd7-7449-5295-31526e91af9e.png)

⑥intellijを再起動します。

#その他
IntelliJの他にTerraformやAWS CLIをインストールすればコーディングが開始できます。
複数人で作業する場合はGitなどのバージョン管理ツールを使うと便利です。
MavenをJava 8で動かしつつコンパイルはJava 6、テストはJava 11で行う

フレームワークを作ったりしていると後方互換の関係でJava 6でコンパイルしたいことがあります。
また、新規案件では古いJDKとか使わないのでコンパイルはJava 6でしたとしてもテストはJava 6・7・8・11で実施したかったりします。

最近のMavenはJava 6では動かないんですけど、工夫をすればMaven自体はJava 8で動かしつつコンパイルはJava 6、テストはJava 11で行うといったことが可能です。

`maven-compiler-plugin`の`executable`で`javac`コマンドを指定することで任意のJDKでコンパイルができます。
それから`maven-surefire-plugin`の`jvm`で`java`コマンドを指定することで任意のJDKでテストができます。
いずれもシステムプロパティで設定できます。

コマンド例はこんな感じ。

```
export JAVA_HOME=/path/to/jdk8
mvn -Dmaven.compiler.executable=/path/to/jdk6/bin/javac \
    -Dmaven.compiler.fork=true \
    -Djvm=/path/to/jdk11/bin/java \
    test
```

## 参考

- https://maven.apache.org/plugins/maven-compiler-plugin/compile-mojo.html#executable
- https://maven.apache.org/plugins/maven-compiler-plugin/compile-mojo.html#fork
- https://maven.apache.org/surefire/maven-surefire-plugin/test-mojo.html#jvm
react、typescriptでStateless Functional Component の書き方をググった

react、typescript初心者です。

react、typescriptのチュートリアルを見ると、基本的にclass Componentでのやり方が多く、Stateless Functional Component(以下SFC)ではどう書くのか気になったのでググってみました。

react/typescriptの環境は @toshi-toma さんの [ReactのプロジェクトにTypeScriptを導入する〜npm installからコンパイルまで〜](https://qiita.com/toshi-toma/items/080b89000ed7f0242bee) を参考にさせていただきました！

【[コードはこちら](https://github.com/okumurakengo/00001)】

### 動作環境作成

```bash
$ yarn init --yes
$ yarn add -D webpack webpack-cli typescript ts-loader react react-dom @types/{react,react-dom}
```

```json:tsconfig.json
{
    "compilerOptions": {
        "noImplicitAny": true,
        "module": "ES2015",
        "target": "es5",
        "jsx": "react"
    }
}
```

```js:webpack.config.js
module.exports = {
    mode: "development",
    entry: "./src/index",
    output: {
        path: __dirname + "/dist",
        filename: "bundle.js",
    },
    module: {
        rules: [
            {
                test: /\.tsx?$/,
                loader: ["ts-loader"],
            },
        ],
    },
    resolve: {
        extensions: [".ts", ".tsx", ".js"]
    },
};
```

# サンプル1 interfaceを使った場合

```tsx
import * as React from "react";

interface IProps {
    foo: string;
}

export default (props: IProps) => (
    <h1>{props.foo}</h1>
);
```

# サンプル2 type aliasを使った場合

```tsx
import * as React from "react";

type Props = {
    foo: string;
}

export default (props: Props) => (
    <h1>{props.foo}</h1>
);
```

# サンプル3 React.SFC

```tsx
import * as React from "react";

interface IProps {
    foo: string;
}

const App: React.SFC<IProps> = props => (
    <h1>{props.foo}</h1>
);

export default App;
```

試してみましたが、`as`を使えば `React.SFC`の場合でも`export default` の部分でかけるようです。(間違ってたらごめんなさい)

```tsx
import * as React from "react";

interface IProps {
    foo: string;
}

export default (
    props => (
        <h1>{props.foo}</h1>
    )
) as React.SFC<IProps>;
```
### 追記

SFC より FC を使ったほうが良さそうです。コメント参考

@suzu2469 さんコメントありがとうございます！

最後まで見ていただいてありがとうございました。

---

参考

- [React Stateless Functional Component with TypeScript](https://medium.com/@ethan_ikt/react-stateless-functional-component-with-typescript-ce5043466011)
- [React TypeScript Tutorial ( Setup, Installation, Static Type Checking )
](https://www.youtube.com/watch?v=tS6czSZW2oo)

---
Instant Search with Laravel Scout & Algolia

Algoliaは、高速で高機能な検索を提供してくれるサービスです。
この記事では、Laravel Scoutを使ってAlgoliaにデータをindexして、Vue.jsで検索フォームを実装する方法を説明します。基本的なことしか説明していないので、詳しくは公式ドキュメントを参照してください。

# Algoliaについて
- https://www.algolia.com
- データベースからAlgoliaにデータを登録しておけば、AlgoliaのAPIを使ってフロントエンドやサーバーサイドから検索リクエストを送れる
- 類義語の関連付けができる
- 検索対象のプロパティに対して重み付けができる
- 世界中にデータセンターがあるので、日本でも高速
![image.png](https://qiita-image-store.s3.amazonaws.com/0/47414/34037155-4bd6-9e42-1367-c6a13f29d01c.png)

# Laravel Scout
- LaravelのEloquentモデルをAlgoliaと連動させられる
- Composerパッケージとして提供されている

## Docs
- https://laravel.com/docs/5.7/scout
- https://www.algolia.com/doc/api-client/laravel
- https://github.com/algolia/algoliasearch-laravel-example

## Install

```shell
composer require laravel/scout
composer require algolia/algoliasearch-client-php
```

## Config

```shell:configファイルがコピーされる
php artisan vendor:publish --provider="Laravel\Scout\ScoutServiceProvider"
```


```:.env
ALGOLIA_APP_ID=YourApplicationID
ALGOLIA_SECRET=YourAPIKey
```

環境変数に設定する値は、AlgoliaのAPI Keysから取得できます。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/47414/1a68ade3-2d0f-c191-fce7-bc0a3b512025.png)

## Eloquent
AlgoliaにindexしたいEloquentモデルで、 `Searchable` traitをuse

```php:Product.php
<?php

namespace App;

use Laravel\Scout\Searchable;
use Illuminate\Database\Eloquent\Model;

class Product extends Model
{
    use Searchable;

    //
}
```

これだけで、このテーブルにレコードを作成したり更新したときに、Algoliaにindexされるようになります。

## Queue
LaravelのQueueを使って、Algoliaにindexするのをバックグラウンドで実行させることができます。
環境変数を以下のように設定し、Queue Workerを起動するだけです。

```:.env
SCOUT_QUEUE=true
```

```bash
$ php artisan queue:work
[2018-10-31 16:11:54][XDt6YC6SH63xdKJOoMn8kLixY3i97i6t] Processing: Laravel\Scout\Jobs\MakeSearchable
[2018-10-31 16:11:54][XDt6YC6SH63xdKJOoMn8kLixY3i97i6t] Processed:  Laravel\Scout\Jobs\MakeSearchable
```

# Vue InstantSearch
Vue.jsでAlgoliaの検索を簡単に実装するためのComponentたちが、[Vue InstantSearch](https://community.algolia.com/vue-instantsearch/)として提供されています。
これを使えば、驚くほど簡単にVue.jsでAlgoliaの検索APIを利用できます。

vue-instantsearchをインストール

```bash
yarn add vue-instantsearch
```

以下のようにInstantSearchを初期化。

```js
import Vue from 'vue';
import App from './App.vue'
import InstantSearch from 'vue-instantsearch';

Vue.use(InstantSearch);

new Vue({
  el: '#app',
  render: h => h(App)
});
```

あとは、こんな感じでInstantSearchのコンポーネントを使ってやれば、検索フォームと検索結果を表示することができます。
`ais` はAlgoliaInstantSearchの略。

```vue
<ais-index
  app-id="your-app-id"
  api-key="your-api-key"
  index-name="products"
>
  <ais-input placeholder="何をお探しですか？"></ais-input>
  <ais-results>
    <template slot-scope="{ result }">
      <p>{{ result.product_name }}</p>
    </template>
  </ais-results>
</ais-index>
```

# Multiple data source
複数のデータソースを１つの検索結果として表示することはできません。
例えば、LaravelとWordPressそれぞれのDBに入っているデータをAlgoliaで1つの検索結果として表示するためには、Algoliaで1つのindexの中に両方のデータを保存する必要があります。
https://github.com/algolia/algoliasearch-helper-js/issues/468
5分でelectronの開発環境整える(Windows)

## 概要

Electronのアプリ作りたい！って思ったときに速攻できちゃう開発環境の整え方。
作りたいアプリは未定（いやなんか作りたいって思ってたんだけど忘れちゃったのよ:frowning2:）

何番煎じか分からないけどとりあえず書いちゃえ！みたいなテンションで書いちゃいます。
アウトプット大事。

## 前提条件

・npmが入っていること
・gitが入っていること

## 手順

### その1

ひとまずelectronをダウンロード

```
> npm install -g electron
```

### その2

Electronのクイックスタートリポジトリをフォークしてクローン

クイックスタートの公開先はこちらです。
https://github.com/electron/electron-quick-start

とりあえず実行してみたいって人は以下のコマンド。

```
> git clone https://github.com/electron/electron-quick-start.git
```

### その3

実行

```
> electron .
```

## ね？簡単でしょう？

今後これでなに作ろうかなーって考えてます。
なんかいいアイデアないかなぁ…
GStreamer1.14のwebrtcプラグイン

Gstreamerで音声・画像ストリームを解析処理に流し込みながら、WebRTCにも流したい。

Pythonでアプリを書いているので、WebRTCのPython Native実装のaiortcも考えた。が、ストリームを柔軟に塩梅できるGstreamerで、 [「Gstreamerのwebrtcサポート紹介」](http://blog.nirbheek.in/2018/02/gstreamer-webrtc.html) にある GstreamerV1.14 の webrtcプラグイン webrtcbin を試したい。

Ubuntu LTS (現在18.04)には、GstreamerV1.14.1の本体とbase pluginが入っているが、webrtcbinが入っているのは、plugins-bad。どうすれば使えるか？　

いろいろ試したが、結論：　非LTSの最新Ubuntu18.10に、前提Packageをapt installするだけ。

UbuntuのLTSではない現在最新の18.10には、DebianのUnstable Package相当が含まれており、その中にはGstreamer1.14.4も含まれている。

- Ubuntu18.04LTS用に、[「Gstreamerのwebrtcサンプル」](https://github.com/centricular/gstwebrtc-demos) に指示があって、以下だけでよい。これだけで、Ubuntu18.04LTSで、Cからならwebrtcbinを使えるようになる。

```
sudo apt-get install -y gstreamer1.0-tools gstreamer1.0-nice gstreamer1.0-plugins-bad gstreamer1.0-plugins-ugly gstreamer1.0-plugins-good libgstreamer1.0-dev git libglib2.0-dev libgstreamer-plugins-bad1.0-dev libsoup2.4-dev libjson-glib-dev
```

また、[「本家のサイト」](https://gstreamer.freedesktop.org/documentation/installing/on-linux.html)に、Ubuntu, Debianの場合、以下の指示がある。

```
apt-get install libgstreamer1.0-0 gstreamer1.0-plugins-base gstreamer1.0-plugins-good gstreamer1.0-plugins-bad gstreamer1.0-plugins-ugly gstreamer1.0-libav gstreamer1.0-doc gstreamer1.0-tools gstreamer1.0-x gstreamer1.0-alsa gstreamer1.0-gl gstreamer1.0-gtk3 gstreamer1.0-qt5 gstreamer1.0-pulseaudio
```
Ubuntu18.10に、上記両方やって、うまくいきました。

一方、Ubuntu LTS 18.04にこだわるなら、上記前提Packageを入れれば、Cからなら、GStreamer1.14.1 のプラグインが使える。しかし、Pythonからは最低1.14.2のBindingが必要とのことで、使えない。

以下、だめだったアプローチ：UbuntuのLTSにこだわらなければ、試す必要もなかった。

* Gstreamerの仮想環境を作る、[「gst-uninstalled」] (https://arunraghavan.net/2014/07/quick-start-guide-to-gst-uninstalled-1-x/)  というツールを使ってみた。が、webrtcbinは入るが、srtp,　niceというpluginも必要なことがわかって、それらは一緒に入れてくれない。最新のPython-Bindingも入れてくれない。

* それならと、srtp, nice, python-bindingも全部面倒見ている[「このスクリプト」（もともとRpi用）](https://gist.github.com/ykazakov/472a46e3838bf9259921b273ca8a0173) を真似して改造し、最新のGstreamer1.14.4ソースからやってみたが、コンパイル、linkはうまくいくが、インストール時、起動（ロード）時に、エラーが出る。Ubuntu　LTSの抱えているGstreamer1.14.1をうまく上書きできない様子。
expoのコマンドラインからpublishする。


WebIDE(XDE)経由じゃなくてcommand lineからpublishする方法。standaloneアプリではない。
詳しくは[こちら](https://docs.expo.io/versions/latest/workflow/publishing)を見ればいい。

### ログイン

まずはログインする（その前に必要なら[Expo](https://expo.io/)の登録をする）。

```bash
expo login
? You are already logged in as hogehoge. Log in as new user? Yes
? Username/Email Address: hogehoge@hoge.com
? Password: [hidden]

Success. You are now logged in as hogehoge.
```

### publish

パブリッシュする

結論から言えば、app.jsonを正しく設定していないと怒られる。先に、下記のapp.jsの項目を見て対応しておいてもよい。
怒られたい人はそのままどうぞ。

```bash
expo publish


[15:22:34] Publishing to channel 'default'...
[15:22:35] Must specify a bundle identifier in order to build this experience for iOS.Please specify one in app.json at "expo.ios.bundleIdentifier"

expo publish
[15:24:56] Publishing to channel 'default'...
[15:24:56] Must specify a java package in order to build this experience for Android.Please specify one in app.json at "expo.android.package"

expo publish
[15:25:55] Publishing to channel 'default'...
[15:25:56] We noticed you did not build a standalone app with this SDK version and release channel before. Remeber that OTA updates will not work with the app built with different SDK version and/or release channel. Read more: https://docs.expo.io/versions/latest/guides/publishing.html#limitations
[15:25:58] Building iOS bundle
[15:26:27] Building Android bundle
[15:26:54] Analyzing assets
[15:26:58] Uploading assets
[15:26:59] No assets changed, skipped.
[15:26:59] Processing asset bundle patterns:
[15:26:59] - /Users/hogehoge/myapp/**/*
[15:26:59] Uploading JavaScript bundles
[15:27:03] Published
[15:27:03] Your URL is

https://exp.host/@hogehoge/myapp

```

### app.json

先にいじったほうがいい。iosのbundleIdentifierとandroidのpackageは必須で追加しないと上記の用になる。
あとは公開したくない場合は、privacyを"unlisted"とかにすればいい（これはWeb画面からもできるみたい）。

```diff:app.js
{
  "expo": {
    "name": "rnclient01",
    "description": "This project is really great.",
    "slug": "rnclient01",
+   "privacy": "public",
    "sdkVersion": "31.0.0",
    "platforms": ["ios", "android"],
    "version": "1.0.0",
    "orientation": "portrait",
    "icon": "./assets/icon.png",
    "splash": {
      "image": "./assets/splash.png",
      "resizeMode": "contain",
      "backgroundColor": "#ffffff"
    },
    "updates": {
      "fallbackToCacheTimeout": 0
    },
    "assetBundlePatterns": [
      "**/*"
    ],
    "ios": {
      "supportsTablet": true,
+     "bundleIdentifier": "jp.youardomain.myapp"
    },
    "android": {
+     "package": "jp.yourdomain.myapp"
    }
  }
}
```

後はWebでQRコード表示してExpoアプリで読み込めばよい。
企画やプロト段階での確認用配布などには十分かなと。

簡単ですが以上です。
リンク

#リンクを挿入するには？
下記のように記載する

```ruby:html
<a href="〜〜.com">サイト名表記</a>
```
##クラス指定
・クラス指定可能
・hrefのすぐ後ろにclass="クラス名"を記入してあげる

```ruby:html
<a href="〜〜.com" class="クラス名">サイト名表記</a>
```

##target指定
・targetを設定してあげないとリンク先のページを開くことができない
・主に使われるのは下記２種類である

|コード|内容|
|:--|:--|
|_brank　　|新しいウィンドウを増やしてページを閲覧する|
|new|ウィンドウを増やし続けることなく一つ増やしたウィンドウで新しいページを開く|

##ページの途中へのリンク
・IDにしか飛べない
・リンク先のHTMLに記入が必要

```ruby:html
<h1 id="ID名">リンク先</h1>
```
・リンク元のHTMLには以下のように記載
・＃allが以下に相当する

```ruby:html
<a href="#ID名">リンク先</a>
```
###ヌルリンク
何も指定していないリンクのこと

```ruby:html
<a href="#">サイト名</a>
```

###デフォルトでつく下の線を消したい場合

```ruby:css
a {text-decoration: none;}
```
※none...無しにする

###ホールドの色変え

```ruby:css
a:hover{color:指定したい色;}
```

※color...色
Next.jsをはじめる

Next.jsアドベントカレンダー2018の1日目です。

Reactを使ってSPAで開発したい事情がある、でもSEOとユーザビリティのためにSSRが最適解。
そういった場合、Reactを用いたシンプルなIsomorphic JavascriptフレームワークであるNext.jsがあります。
使ってみると案外簡単でフレキシブルで、非常に良いです。
世間ではNuxt.jsが大流行ですが、Next.jsを少しでも使ってもらえるように、はじめるにあたってのガイドを共有したいと思います。

## 特徴を知る
[Next.js公式サイト](https://nextjs.org/)の中にある、[チュートリアル](https://nextjs.org/learn)の冒頭に下記特徴が書かれています。

- Server-rendered by default
    - デフォルトでサーバーサイドレンダリングされる
- Automatic code splitting for faster page loads
    - 高速ページローディングのため自動でコードスプリッティング
- Simple client-side routing (page based)
    - ページごとにルーティングが作られる、シンプルなクライアントサイドでのルーティング
- Webpack-based dev environment which supports (HMR)
    - HMRをサポートしたWebpackベースの開発環境
- Able to implement with Express or any other Node.js HTTP server
    - Expressや、どのNode.jsのHTTPサーバでも実行可能
- Customizable with your own Babel and Webpack configurations
    - BabelやWebpackでの独自カスタマイズが容易

Next.jsを半年使ってみて思うのは、シンプルでフレキシブルなフレームワークということ。
エッセンシャルな機能はあらかたデフォルトで用意してくれています。
さらに、どの状態管理ライブラリを使うか、どのHTTPサーバを使うか、どのCSSフレームワークを入れるか、TypeScriptを使うかなど、開発者が技術を自由に選択し簡単に導入できることが利点だと思います。

また、Next.jsを生んだ会社ZEITのエンジニア@nkzawaさんが、Next.jsがOSS化された際のブログを日本語訳しています。
こちらも是非ご一読を。
https://qiita.com/nkzawa/items/1e0e93efd13fb982c8c0


## 手を動かしてみる
公式サイトではNext.jsの基本を学べるチュートリアルが用意されています。
https://nextjs.org/learn
Next.jsはシンプルなフレームワークなので、最初の学習コストが低いと思っています。
Reactもおぼつかないレベルだった私でも、Next.jsのエッセンシャルな挙動は半日で理解できました。

抑えるべきポイントは、

- ページがルーティングとして使われること
- `getInitialProps()` というサーバーサイド・クライアントサイド両者で実行される、データ取得のための重要な関数があるということ
- HTTPサーバーからReactコンポーネントへのデータの流れを知ること
- 初回アクセスでSSRされたソースをブラウザでレンダリングした後の、SPAの挙動をするためのNext.jsが用意するAPI群を知ること

でしょうか。
明日のアドアドベントカレンダー記事はチュートリアルの翻訳とまとめをしてみようかと思います。
↑[「Next.jsチュートリアル翻訳」](https://qiita.com/tetsutaroendo/items/31300a5e475688a2f4ec)を書きました。

## 困った時は
チュートリアルだけでは開発で困ることもあります。そんなときは下記の資料が役に立ちます。
### README
困ったらリファレンス的にGitHubのREADMEを見ています。Next.jsの機能全体が網羅されていて、ここを読めばたいていのことは解決します。
https://github.com/zeit/next.js

実は同僚が中心となって日本語化ページを鋭意作成中です。ある程度翻訳できたらここに共有したいです。

### Examples
Next.jsは公式リポジトリに、各種ライブラリの導入方法やベストプラクティスのソースコード例が大量に置いてあります。
自分が導入したい技術の名称をこのページで検索すればたいてい引っかかります。
https://github.com/zeit/next.js/tree/master/examples


### Issues
READMEでもExamplesでも拾えない困ったことがあると、GitHubのIssueに答えがあります。ベストプラクティスなども議論されていたりして、かなり助かっています。
`[困っている事象] next.js`で検索するとたいていClosed issueが出てきてくれて、読めば解決します。


### Showcase
Next.jsをプロダクションで使っているWebサイトがここで紹介されています。
https://nextjs.org/showcase

Reactを使っている人は一度は目にしたことがあるかもしれない、styled-componentsの公式サイトもNext.jsで作られていたりします。
https://www.styled-components.com/
そしてソースコードが公開されているので、Next.jsをプロダクション運用で始める際には是非参考にしてみて下さい。
https://github.com/styled-components/styled-components-website

### Spectrum
SpectrumというコミュニティチャットにNext.jsチャネルがあります。
https://spectrum.chat/next-js
ここでリアルタイムで開発者とやりとりできます。

## おわりに
この記事はNext.jsアドベントカレンダーの1日目なのですが、昨日時点で4つしか枠が埋まっていませんでした。
Next.jsのことを紹介、解説する記事をなるべく多く作っていきたいと思います。
Rails tutorial １章でheroku loginできない時[Cloud9]

#Herokuインストールできてるのにloginできない！
cloud9にてherokuインストールしてるのに、heroku loginコマンドが使えなく何日もググっては試すを繰り返していた。

そしてどうやらCLIが古いバージョンになっているのが原因みたい、、、
```
See more details with DEBUG=*
 ›   Warning: heroku-cli update available from 7.0.9 to 
 ›   7.18.9
CLI to interact with Heroku

VERSION
  heroku-cli/7.0.9 linux-x64 node-v8.3.0
```

⇒heroku updateでもCLIがupdateされなかった。

#解決

```
:~/environment/hello_app (master) $ heroku plugins
no plugins installed
```

⇒CLIのpluginが何もないのが原因だった。



```
:~/environment/hello_app (master) $ heroku plugins:install heroku-repo
```
⇒これでCLIがアップデートされて、loginできるようになった！
Ubuntu18.04 へ OpneMPI3.1.3のインストール

# Ubuntu18.04 へ OpneMPI3.1.3のインストール
シングルGPU向けだったDeep LearningのコードをマルチGPU用に書き換えたいことがあると思います。
その際の解決策として、[horovod](https://github.com/uber/horovod)があります。
horovodはUberが開発したオープンソースソフトウェアで、シングルGPU向けの処理をマルチGPU向けに簡単に書き換えることができるライブラリとなっています。

horovodの使い方はこちらの記事が参考になると思います。
[horovodのご紹介 ~Tensorflowの分散処理(Distributed Tensorflow)を簡単に実現！！~](https://qiita.com/kurosawa1/items/5aeb9efb2eceeb9c8206)

horovodを使うためにはOpenMPI3.1.3のインストールが必要となるため、この記事ではOpenMPI3.1.3のインストール方法を紹介します。


## ダウンロード
```
sudo wget https://download.open-mpi.org/release/open-mpi/v3.1/openmpi-3.1.3.tar.gz --no-check-certificate
```

## 展開してビルド

```
gunzip -c openmpi-3.1.3.tar.gz | tar xf -
cd openmpi-3.1.3
./configure --prefix=/usr/local
<エラー含めたくさんのアウトプット>
make all install
```

configure中にたくさんのエラーが出るが、これはライブラリが存在するかなどをチェックしており、存在しない場合に、そのライブラリには対応しない形でインストールしているということに過ぎないため問題ありません。
TypeScriptのORマッパーならTypeORM

# はじめに

express.jsとリレーショナルDBを組み合わせる際のORMは長らくsequelize一強だったみたいですが、
ここに来てより洗練されたTypeORMというORMが台頭してきたので、PJへの組み込み方をば。

あ、TypeORMという名前ですが、JavaScript (ES7, ES6, ES5)もサポートしています。
typescript使わないよーという人もsequelizeと比較してみて良さげなら導入すると良いと思います。

# 紹介

TypeORMを使って開発すると、

 - PythonのSQLAlchemyのようなRepositoryパターン、
 - RailsのようなActiveRecordパターン
 
のどちらの方式でも書くことができます。

また、モデルの定義をしっかり書けば型の恩恵を最大限受けられたり、
複雑なリレーションを組めたり、migration世代管理できたり
各種機能が高水準でまとまっています。

## Repository パターン例

モデルはこんな感じ。デコレーターでDBカラムの情報を定義します。
デコレーターにオプションオブジェクトを渡すことで様々な設定ができます。

```ts

import {Entity, PrimaryGeneratedColumn, Column} from "typeorm";

@Entity()
export class User {

    @PrimaryGeneratedColumn()
    id: number;

    @Column({ type: 'varchar', length: 255 })
    firstName: string;

    @Column({ type: 'varchar', length: 255, nullable: true })
    lastName: string;

    @Column({ type: 'int' })
    age: number;

}
```

ドメインロジックはこんな感じ。

```ts

const user = new User();
user.firstName = "Timber";
user.lastName = "Saw";
user.age = 25;
await repository.save(user);

const allUsers = await repository.find();
const firstUser = await repository.findOne(1); // find by id
const timber = await repository.findOne({ firstName: "Timber", lastName: "Saw" });

await repository.remove(timber);
```


## ActiveRecord パターン例

モデルはこんな感じ。継承元クラスが違うだけで、Repositoryパターンとほとんど同じです。

```ts

import {Entity, PrimaryGeneratedColumn, Column, BaseEntity} from "typeorm";

@Entity()
export class User extends BaseEntity {

    @PrimaryGeneratedColumn()
    id: number;

    @Column({ type: 'varchar', length: 255 })
    firstName: string;

    @Column({ type: 'varchar', length: 255, nullable: true })
    lastName: string;

    @Column({ type: 'int' })
    age: number;
}
```

ドメインロジックはこんな感じ。
モデル自身に生えたsaveやdeleteメソッドを使います。
Rails使いならこっちのほうがしっくりきますね。

```ts

const user = new User();
user.firstName = "Timber";
user.lastName = "Saw";
user.age = 25;
await user.save();

const allUsers = await User.find();
const firstUser = await User.findOne(1);
const timber = await User.findOne({ firstName: "Timber", lastName: "Saw" });

await timber.remove();
```


# 使い方

長くなったので別記事にしました。
[Typescript + TypeORMセットアップ & migration世代管理 & expressへの組み込み](https://qiita.com/yuukive/items/0655f4d88187b65a8520)
【プログラミングいろは】文字を書く(メッセージ表示)

好きな文字を書いてみましょう。

プログラミングの第一歩は、画面に好きな文字を出してみること。といっても前回の投稿で、すでに"abc"という文字を書いてみています。

前回の投稿⇒[【プログラミングいろは】はじめるのはカンタンです](https://qiita.com/drrn/items/96a86e8fa83dc48741cf)

なので、次は"abc"ではなくて好きな文字に変えてみる…

"abc"のところをタップすると好きな文字を入れられます。例えば"こんにちは"に書き換えて実行。

<img width="70%" src="https://qiita-image-store.s3.amazonaws.com/0/297642/c1dfaed2-3f9c-3a14-17c7-e695801fdff4.png">

出ます。

<img width="70%" src="https://qiita-image-store.s3.amazonaws.com/0/297642/08fab8a3-921e-d452-7b9d-0b09cecbdba3.png">

K3Tunnelでプログラミングしています。⇒https://k3tunnel.com/
ユースケース駆動開発実践ガイドメモ

#はじめに
この記事は*ユースケース駆動開発実践ガイド*の個人的なまとめになります。
最初はザックリ書き、少しずつ内容を詰めていく予定です。

# ICONIX
最小限のUMLのコアサブセットとユースケースからオブジェクト思考ソフトウェア設計を導出するための思考プロセスのこと

以下にプロセスと簡単な説明を記載します。

## 1. 要求
###a. 機能要求
システムができることの定義する
###b. [ドメインモデリング](https://qiita.com/terumichi1209/items/ed5c37657a75f8d9aa28)
分かりやすい用語で問題領域を理解する

###c. [振る舞い要求（ユースケース作成）](https://qiita.com/terumichi1209/items/3ab1cf62b999dd959443)
ユーザとシステムの対話を定義する
###d. 要求レビュー
ユースケース記述が顧客の要望に応えているかを確認する

## ２. 分析/予備レビュー　
###ロバストネス分析
・ロバストネス図を書きユースケース図とドメインモデルを更新する
・クラスの発見、曖昧な記述の修正、ドメインオブジェクトに対する属性を追加する
・ユースケースを動かすために必要な全ての論理的なソフトウェア機能（コントローラ）に名前を付ける

## ３. 予備設計レビュー（PDR）
・これまでに書いた図が全て辻褄が合っているかを確認する
・詳細設計に踏み込んでないことを確認する

## ４. 詳細設計
###シーケンス図の作成
・クラスに責務を割り当てる
・ドメインモデルを更新し、ドメインオブジェクトに操作を追加(operation)する

## ５. 詳細設計レビュー（CDR）
・ユースケース図とシーケンス図を合致させる
・メッセージの一貫性を確認する

## ６. 実装
・コーディングと単体テスト
・結合テストとシナリオテスト
今でもほとんど古びていない、かなり昔に出版されたコンピュータ関連の技術系書籍紹介

# はじめに
　本棚を整理していたところ、懐かしい技術書がゴロゴロ出てきたので、ご紹介します。

# UNIX関連
　UNIXの考え方（設計思想と哲学）を知っておくと、あらゆることに応用が効く、ように思う。

-  [UNIXという考え方―その設計思想と哲学][1]
[1]:https://www.amazon.co.jp/gp/product/4274064069

-  [Life with UNIX―UNIXを愛するすべての人に][12]
[12]:https://www.amazon.co.jp/gp/product/4756107834

# TCP/IP関連
　TCP/IPは誕生から約50年（半世紀！）たった今でも、広く使われているプロトコルで、IT分野でこれほど長生きしている技術も少ない、と思う。

-  [詳解TCP/IP〈Vol.1〉プロトコル][2]
[2]:https://www.amazon.co.jp/gp/product/4894713209

-  [詳解TCP/IP〈Vol.2〉実装][3]
[3]:https://www.amazon.co.jp/gp/product/4894714957


-  [UNIXネットワークプログラミング〈Vol.1〉ネットワークAPI:ソケットとXTI][4]
[4]:https://www.amazon.co.jp/gp/product/4894712059

-  [UNIXネットワークプログラミング〈Vol.2〉IPC:プロセス間通信][5]
[5]:https://www.amazon.co.jp/gp/product/4894712571

#  コンパイラ関連
　最初の仕事がコンパイラ自体を開発することだったが、ドラゴンブックにはお世話になりました。私が読んだのは下記の1990年出版された二冊です。

-  [コンパイラ―原理・技法・ツール〈1〉 (Information & Computing)][6]
[6]:https://www.amazon.co.jp/gp/product/4781905854

-  [コンパイラ―原理・技法・ツール〈2〉 (Information & Computing) ][7]
[7]:https://www.amazon.co.jp/gp/product/4781905862

#  ソフトウェア開発関連
デザインパターンといえばGoF、テストといえばボリス・バイザー、C言語はK&R、C++はARM

-  [オブジェクト指向における再利用のためのデザインパターン][8]
[8]:https://www.amazon.co.jp/gp/product/4797311126

-  [ソフトウェアテスト技法][9]
[9]:https://www.amazon.co.jp/gp/product/4822710017

-  [プログラミング言語C 第2版 ANSI規格準拠][10]
　K&Rで知られる。第1版は、ANSI準拠以前の仕様なので、さすがに今となってはオススメしにくい。
[10]:https://www.amazon.co.jp/gp/product/4320026926

-  [注解 C++リファレンスマニュアル (アジソン ウェスレイ・トッパン情報科学シリーズ) ][11]
　C++初期の頃、理解にもっとも役に立った書籍
[11]:https://www.amazon.co.jp/gp/product/4810180271

# おわりに
　昔に出版されたTCP/IPや理論に関する技術書の紹介でした。いわゆる「原典」的な書籍が多くなりましたが、内容は全然古くなっておらず、一部入手が難しい本もありますが、今でもオススメできる本ばかりです。
TypeScript+Reactで、propsにデフォルト値を持たせたかった

# こう書きました
```tsx
<SayHello {...createSayHelloProps({lastName: 'Iijima'})}/>

const SayHello: React.SFC<SayHelloProps> = props => {
  return (<div>Hello, {props.firstName} {props.lastName}</div>)
}

function createSayHelloProps({
  firstName = 'Kaga',
  lastName = 'Tetsuo'
}): SayHelloProps {
  return {
    firstName,
    lastName
  }
}

interface SayHelloProps {
  firstName: string
  lastName: string
}
```

- 引数を hash にすることで、**名前付き引数っぽく**使っています
- また、デフォルト値を持たせた関数を経由しているので、hash の key を**省略可能**です。

ちなみに、下記部分は hash のkey と value が同名の時の省略記法(tslint推奨)です。 

```tsx
return {
  firstName,
  lastName
}

// これと意味は同じ
return {
  firstName: firstName,
  lastName: lastName
}
```

# おわりに
より良い書き方ありましたらコメントお願いします🙇‍♂️
FreeBSD で SJIS の zip ファイルを開く

Windows 環境で作られたアーカイブファイルはたいがい zip で容赦なくファイル名が日本語 SJIS なわけです。そんな zip ファイルをFreeBSD の標準の/usr/bin/unzip で展開すると容赦なく文字化けして削除もままならないわけです。

## ports から iconv 変換対応した unzip をインストールする
SJISなzipを展開するには、pkgではなくportsから iconv パッチが当たった unzip をインストールします。
portsのarchivers/unzip 標準のオプションではパッチが当たりません。pkgのバイナリはportsの標準オプションでビルドしてできているのでパッチは当たっていません。なので、pkgからではなくportsでオプションを変えてからインストールする必要があります。

## make configでオプション指定
/usr/ports/archivers/unzip で make configを実行すると出てくる以下の画面で **iconv** のチェックをしてからmake install でインストールします。

![Screenshot from 2018-12-01 13-42-38.png](https://qiita-image-store.s3.amazonaws.com/0/103137/5599590f-5343-8f74-7eaa-c7988727c15a.png)

インストール後、/usr/local/bin/unzip をオプション無しで実行すると、ヘルプが表示されます。
その中に以下の行が入っていれば、iconv パッチが当たっています。

<pre>
$ /usr/local/bin/unzip
〜〜（略)〜〜
  -O CHARSET  specify a character encoding for DOS, Windows and OS/2 archives
  -I CHARSET  specify a character encoding for UNIX and other archives
</pre>

## -O オプションで文字コード指定
展開する場合は -Oオプションで cp932またはsjis-winを指定して
<pre>
$ unzip -Ocp932 sjis.zip
</pre>
とすれば、UTF-8なファイル名として展開されます。

## alias などに登録
普通に unzip コマンドを打つと、/usr/bin/unzip が使われるので、/usr/local/bin/unzip -Ocp932 をシェルのalias に登録しておくといいでしょう。

```shell:.cshrc
alias unzip '/usr/local/bin/unzip -Ocp932'
```

```shell:.bashrc
alias unzip='/usr/local/bin/unzip -Ocp932'
```

#pkgのアップグレードに注意
configをいじったports全般で起きる問題ですが、pkgがアップグレードを検知すると、pkgが勝手にアップグレードを実行し、パッチの当たってない pkg バイナリ版に置き換わってしまいます。

```
# pkg lock unzip
```

でロックすることで、勝手に置き換わらないように出来ますが、バージョンアップは自分で検知して、手動で行う必要があります。
xUnit Test Patterns ユニットテストの不吉な臭い

# はじめに

[xUnit Test Patterns: Refactoring Test Code](https://www.amazon.co.jp/dp/0131495054)にあるユニットテストの不吉な臭いから抜粋。

# テストコードの不吉な臭い(Code Smells)

1. 条件付きのテストコード(Conditional Test Logic)
2. テストを書くのが困難なコード(Hard-to-Test Code)
3. テストコードの重複(Test Code Duplication)
4. 製品コードにテストコードがある(Test Logic in Production)

# 振る舞いの不吉な臭い(Behavior Smells)

1. アサート文がランダムに実行される(Assertion Roulette)
2. テストが不規則に実行される(Assertion Roulette)
3. 壊れやすいテスト(Fragile Test)
4. 何らかの機会にデバッグが必要。(Frequent Debugging)
5. テストの実行に手動の介入が必要(Manual Intervention)
6. 遅いテスト(Slow Tests)

# プロジェクトの不吉な臭い(Project Smells)

1. バグだらけのテスト(Buggy Tests)
2. 開発者がテストコードを書かない(Developers Not Writing Tests)
3. テストコードの保守コストが高い(High Test Maintenance Cost)
4. 製品のバグ(Production Bugs)
インラインブロック要素

#インラインブロック要素とは
・置換インライン要素とも言う
・通常のインライン要素は横幅と高さを持たないが置換インライン要素は横幅（ **width** ）高さ（ **height** ）を持つ
・余白がデフォルトでついてしまうので消したければ**margin**や**padding**で消してあげる

|コード|内容|
|:--|:--|
|img|画像|
|textarea   |下の方によくある感想書く白枠|
|input|感想枠のしたにいる送信ボタンを作る時に使う|
|select　 |個人情報入力画面のところの１月２月３月とかの選択肢が出る四角い枠のこと|
prettierを使って過去のコミットをすべてフォーマットする

## 困ったことに
古い古い自社ライブラリのお話です。はじめのコードはインデントが4で作成されていました。後から入ってきた私はJavaScriptのファイルのインデントは2と聞かされておりましたので、IDEの設定で2にしておいたのです。

古いライブラリなので改修の頻度は少ないですが、新規の機能を作成しました。新しく作成されたファイルはインデントが2で書かれました。気づかないレビュー者。見かねてEslintを入れてくれました。EditorConfigも入れてくれました。EslintとEditorConfigでインデントが食い違っています。2なのか4なのか、混乱するIDE。私は悲しみました。

## `eslint --fix`で直るよ!
直ります！しかし、こんな話が上がりました。

Aさん > `git annotate`で見れるのが、全てフォーマット修正のコミットになるのがつらいかも...
私 > 確かに!!

古いライブラリで実装を理解している人間も少ないため、修正についてはコミットを追う必要がありました。私もデグレードが起きないように行単位でコミットを追っていました。

## 歴史を変えるしかない...
### 事前準備
グローバルに`prettier`をインストールしておいてください。

```shell
$ yarn global add prettier
```

### 本題
`git annotate`を変更しないためには、過去に存在する全てのコミットに対して、フォーマットを行った状態で再度コミットするという必要があります。
そこで、`git filter-branch`を使用します。このコマンドで調べると、「コミットしてしまった秘密鍵を削除する」「コミットのEmail, Authorを変更する」という内容が多く出てきます。歴史を変えるための最強のコマンドです。


```shell
# 現状のブランチの全てのコミット
$ git filter-branch -f --tree-filter 'prettier --no-config --print-width=120 --write "src/**/**.js" || echo "Error"' --
# 全てのブランチの全てのコミット
$ git filter-branch -f --tree-filter 'prettier --no-config --print-width=120 --write "src/**/**.js" || echo "Error"' -- --all
# 特定のブランチの特定のコミットからコミットまで
# コミット間の指定が面倒なので、ブランチを作成して指定している
$ git filter-branch -f --tree-filter 'prettier --no-config --print-width=120 --write "src/**/**.js" || echo "Error" from_branch..to_branch
```

これらのコマンドによって全てのコミットのインデントが2に修正されているはずです。

### 一つ問題点
インデント以外もフォーマットされるので、正直何が起こるか予測が難しいかも。
特定のルールのみ修正するのであれば、Eslintで行うのがいいかもしれないです。

```shell
$ git filter-branch -f --tree-filter 'eslint --fix --no-eslintrc --rule "indent: [\"error\", 2]" --parser-options "ecxaVersion: 2017" --env "es6" "src/**/**.js" || echo "Error"' --
```

コミットの数分だけ実行するので、実行速度がprettierよりも遅いのが懸念点ではあります。

## 最後に
規模のでかいリポジトリであれば、Eslintの実行に時間がかかるでしょう。filter-branchを使用した後はブランチの取り直し、面倒であれば`git clone`を行う必要があります。
元も子もないですが、コミットのログを気にしないのであれば、普通にフォーマットしてコミットしてあげればいいと思います。
【MySQL】Windowsのlower_case_table_names設定でWindowsでは0にできないときがある

MySQLにはlower_case_table_namesという設定値があり、テーブル名をどのように設定するか変わってきます。

この設定値がOS別に異なるので、複数OSで開発・運用する際に問題が発生することがありますが、
この設定値を変更する際に表題の問題が発生したのでメモ。

Windows上ではlower_case_table_names の設定値を0には変えられないときがあるようです。
自分はこの場合にWindowsのサービスから設定値を変更して再起動したところ、
MySQLが起動できない1067のエラーコードが出てしまいました。

したがって、0にできないことがあるみたいです。
回避策をとるのは面倒だったので2に変更できたので、それで回避しました。


1じゃどうしようもありませんし、色々困るので
0にできないときは2にして回避しましょう。
コンストラクタの継承【C#】

サブクラス（継承先）のコンストラクタでスーパークラス（基底クラス）の処理も呼び出したいときの実装方法。


```csharp
//継承先に引数がないパターン
public SuperClass(int num, string text)
{
  // 処理
}

public SubClass() : base(5, "text")
{
  // 処理
}

//継承先の引数が多いパターン
public SuperClass(int num, string text)
{
  // 処理
}

public SubClass(int num, string text, bool flag) : base(num, text)
{
  // 処理
}
```
サービス運営におけるドキュメントの書き方まとめ

今年の半分ぐらいが過ぎた頃からDOOR賃貸を開発・運用をしております @iwtn です。
これまで社内では3つのWebのサービスに関わってきました。
それぞれがWeb業界では歴史のあるサービスで、すべて8年以上サービス開始から経過しております。

途中から開発に参加してきた開発者は、システムの全体像を掴むのに苦労するものです。
大抵の場合、まず最初に読むのはプロダクトの概要をまとめたドキュメントやREADMEです。
そしてサービスを運用していく中で、日々ドキュメントを作成し、更新しています。
そんな経験の中から、ドキュメントをどう日々書いていくべきか、というところをまとめました。

## 3行で
* ドキュメントはマニュアルとログに区別される
* マニュアルは常に更新を怠らず、可能な限り自動化して少なくする
* ログはその時の情報をしっかり残すことで後で活用できるので、潤沢に取っておく

## マニュアルとログの区別
マニュアルは、繰り返し参照され正しいものが常にひとつになるように更新が必要なものです。
ログは、議事録や障害時のポストモーテムなど一時的に発生し、その後更新しない情報の記録です。

### 更新する必要の有無で判別
マニュアルを更新しないと、実行する際に誤りが発生します。リカバリできるものなら良いのですが、致命的なミスにも繋がります。
ログを更新すると過去の情報を改竄してしまうことになり、正確な記録になりません。記録は正確でないと、その先に誤った判断をしてしまう元になります。
なにかドキュメントを作成するとき、更新し続けて行く必要があるかどうかで、マニュアルかログかを判別できます。

### そのドキュメントは作成すべきなのか
マニュアルは常に更新に必要があり、管理コストが高くなるため、最低限に抑えましょう。
開発環境の設定などはDockerなどのコンテナやAinsbleなどの構成管理ツールを使って自動化するのがベストです。

逆に、ログは情報を残しておくために、必要な分だけ潤沢に残しましょう。デジタルデータはあっさり消えてしまうときは本当に消えてしまうので、そのときにしかわからないことはまるっとアーカイブしておくと後で調査できます。
また、**あなたの頭の中だけにあることも記録には残りません。**文章として残しておくと、引き継ぐ人が助かるかもしれません。
ストレージのコストはすごく下がっておりますので、容量的な問題はあまりないと思います。あとで調査するときのためにまとめておくことも大事ですが、時間がないときはどんどん記録しておく方針で良いと思います。

## マニュアル
環境の立ち上げ方だったり、テストの実行方法だったり、主にリポジトリごとのREADMEとして作られます。
その他、自動化するには頻度が少なすぎる運用手順などは、社内wikiなどにマニュアルを作成しておきましょう。メモ程度でもドキュメント化されていることで、微妙な手順の変更なども修正していくことで致命的なミスを防げます。
繰り返しになりますが**マニュアルはソースコードと一緒で常に更新が必要**です。マニュアルに影響する箇所のコードを修正した場合は、同じ修正にマニュアルの更新も含めておくと良いでしょう。レビューも一緒にしてもらうと実装との乖離が防げます。

### README
GitHubでライブラリを公開している方はよくご存知だとは思いますが、社内のプロダクトであってもREADMEは書くべきです。
そのリポジトリの目的、使用方法、単体で動作するサービスであれば起動やバージョンアップの方法などを載せておきます。
最も良いのは、そのREADMEを読みさえすれば、少なくともそのリポジトリの開発まで持っていける状態であることです。
ですので、ミドルウェアなどのセットアップなどを別リポジトリで管理している場合は、そちらへのリンクを貼っておくとより親切です。

### 手動運用のための手順書
手順書は、誰でもできるように厳密に記述しておきましょう。また、その目的も簡単に併記しておきましょう。実はその手順の実行が不要になっている場合などに気づけます。

内容は、事前チェック→実行→結果の確認の流れで作成しておきましょう。
手順書通りに実行できなかった、もしくは結果が意図するものと違った場合は、そのログを残し、実行できるようマニュアルの更新もしておくと良いです。
また、実行時のログを毎回残しておくと、いつそれを行ったかの記録にもなります。

## ログ
ログは、開発者以外のステークホルダーとの会議の議事録や、なんからの技術選定をしたときの意思決定の様子、トラブル発生時のポストモーテムとして作成します。

### 会議の議事録
議事録は、決定したいことや決定事項を完結に毎回まとめ、関係者が誰でも見れる場所に置いておくことで、参加者も最低限に減らせます。

### 技術選定の経過と結果
技術選定の記録は、どうしてこのような決定をしたのかを残しておくと、途中から参加した開発者がその意図や目的を知れます。システムのリプレースなどでその意図がわからないと、本当にそれを変更してよいか調査が必要になります。できる限り**なぜそれを選んだのかを残してください。**

開発言語、フレームワーク、データベース、検索エンジンなどのミドルウェアの選定も作りたいシステムの全体像が明らかになっている上で比較検討されていると、説得力のある資料になります。また、次に技術選定する際の参考にもなります。

個人的に使いたかったから、という理由であればそれでも大丈夫です。そういった場合は然るべき技術が他にあれば、そちらに変更するという決定がしやすいので、それはそれで助かります。

### ポストモーテム
意図せぬトラブルや障害から、そのプロダクトについて学ぶことは多いので、ポストモーテムとして記録しておきましょう。過去にあった障害を記録しておくことで、新しい障害が起こったときの調査に役立つ場合もあります。

以下は、[オライリーから出版されているTeamGeek](https://www.oreilly.co.jp/books/9784873116303/)の1章24ページからの引用で、このような内容が記録されていれば、後々役に立つと思います。

> 優れたポストモーテムには以下のことが含まれる。
● 概要
● イベントのタイムライン(調査開始から解決に至るまで)
● イベントの根本原因
● 影響と損害の評価
● すぐに問題を解決するための行動一式
● 再発を防止するための行動一式
● 学習した教訓

## 感想
長く続くサービスのプロダクトであればあるほど、開発者は入れ替わります。開発者は入れ替わってもドキュメントはその場に残せます。良いドキュメントがあると、運用の負荷も減り、楽しい開発を続けられます。ぜひ、良いドキュメントを残して、良いサービスを継続的に提供できる開発を行っていきましょう！
Rubyでも思いのほか簡単にスクレイピングができたのでメモ

スクレイピングといえば、勝手にPythonのイメージがありました。
でもRubyでも意外と簡単にスクレイピングできました。

## Greenの求人からタイトルとURL、概要を取り出す
例えば、下記のコードを実行すると求人サイトから必要なデータを取ることができます。

```ruby:green.rb
require 'mechanize'

agent = Mechanize.new
page = agent.get('https://www.green-japan.com/search_key/01?keyword=rails%E3%80%80%E3%83%9D%E3%83%86%E3%83%B3%E3%82%B7%E3%83%A3%E3%83%AB')

title = page.search('.card-info__heading-area__title')
url = page.search('.js-search-result-box.card-info')
company = page.search('.card-info__detail-area__box__title')
summary = page.search('.card-info__detail-area__text')

title.zip(url,company,summary).each do |ti,a,com,su|
 puts ti.inner_text
 puts su.inner_text
 puts "https://www.green-japan.com/" + a.get_attribute(:href)
 puts com.inner_text
end
```
実行結果はこんな感じ

```
【Swiftエンジニア】トレたまで紹介された「フェイクビデオ」作成する最先端アプリを開発しています！大幅リニューアルを担当をお願いします。
【概要】
Swiftを用いてXpressionアプリを開発するエンジニアを募集します。
Xpressionアプリの大幅リニューアルを担当していただきます。 もっと見る
https://www.green-japan.com//job/73345
株式会社 EmbodyMe

（中略）
```

##Mechanizeというgemを使用
スクレイピングを行うにあたり、MechanizeというGemを使用しました。
他にもnokogiriなど複数スクレイピングできるライブラリはあるのですが今回はこちらを。
（Javascriptで動くものはスクレイピングできません。）

###gemを追加
```
gem install 'mechanize'
```

###インスタンス生成
```
agent = Mechanize.new
```
これはこういうものだと思ってください。

###getメゾットでスクレイピングするURLを指定
```
page = agent.get('https://www.green-japan.com/search_key/01?keyword=rails%E3%80%80%E3%83%9D%E3%83%86%E3%83%B3%E3%82%B7%E3%83%A3%E3%83%AB')
```
pageはMechanizeのpageオブジェクトです。
参考url
https://seesaawiki.jp/ruby_mechanize/d/Mechanize%3A%3APage

###指定したページで取りたい部分を指定
ページで取りたい部分のクラスを指定しています。
search() メソッドを使っています。
この場合はタイトル、求人の詳細url、会社名、概要をこのコードで取り出しています。

```
title = page.search('.card-info__heading-area__title')
url = page.search('.js-search-result-box.card-info')
company = page.search('.card-info__detail-area__box__title')
summary = page.search('.card-info__detail-area__text')
```

###最後は普通に出力
inner_textメゾットでテキストのみを出力しています。
複数一気に取り出したい場合はzipメゾットがおすすめです、
参考url
https://qiita.com/bSRATulen2N90kL/items/4d6d93e97d8a25a2c90a

```
title.zip(url,company,summary).each do |ti,a,com,su|
 puts ti.inner_text
 puts su.inner_text
 puts "https://www.green-japan.com/" + a.get_attribute(:href)
 puts com.inner_text
end
```
以上です。
参考になればうれしいです。

##参考URL
https://qiita.com/shizuma/items/d04facaa732f606f00ff
VisualStudioCode の クリーンアンインストール

いろんなサイトを見て、残るものは以下の様子。

```
rm -Rf "~/Library/Application Support/Code"
rm -Rf ~/Library/Preferences/com.microsoft.VScode.plist
rm -Rf ~/.vscode
rm /usr/local/bin/code
rm -Rf "/Applications/Visual Studio Code.app"
```
【40代SIerの文系SEでも[独学]で合格】JDLA Deep Learning for GENERAL 2018 #2


11月24日のG検定に合格できました。

##●スケジュール
2018/6/16
JDLA Deep Learning for GENERAL 2018 #1 受験⇒不合格

2018/11/24
JDLA Deep Learning for GENERAL 2018 #2 受験⇒合格（2018/11/30合格発表）
試験までの間、通勤時間中に必死こいて勉強してました。


##●投稿の趣旨
既にあちこちで合格の記事が記載されていますので、
40代のSIer文系SEでも合格できる！という点をポイントに記載いたします。

##●G検定を受験した理由
もともとSIerでデジタルトランスフォーメーション（DX)を主とした部署に所属している点と、JDLAのロゴを名刺に是非！入れたい！という不純な動機から来ています。
これかっこいいんですよね（笑）
https://www.jdla.org/

##●試験について
試験概要は以下のようになってます。
試験概要：120分、多肢選択式の知識問題226問、オンライン実施（自宅受験）
正直、オンラインだから試験中に検索すればいいやという考えでは合格は難しいと思います。

##●試験への戦略

・人工知能の歴史や取り巻く環境（法律や規制、組織など）
⇒ここは知識問題となりますので何となく〜でいいので記憶していることがbetterですが、最後の見直し時間で、ネットでググって調べれば+10問ぐらいは確実に正解することができます。

・機械学習、ディープラーニングの知識を理解することが必要
⇒深く理解していないと解けませんので、しっかりと理解しておく必要があります。

・計算問題や数式的な部分はあまりいらない
・試験時間がほんとにないので、わからない問題はさっさと飛ばす

・JDLAの参考図書だけでは不十分と感じていますので、余裕があれば下記サイトに記載されている本もご覧いただくことをお勧めします。
http://jinsight.hatenablog.com/entry/2018/11/30/223043

##●勉強材料
以下に絞りました。

★参考書
①G検定公式テキスト

★問題集
①Study-AIの模擬試験（G検定（ディープラーニングと機械学習の検定）模擬テストと
公式例題解説を無料公開中）
http://study-ai.com/generalist/

②資格スクエアのオリジナル問題集
→ご自身で買ってください（笑

★基礎講座（参考書読んでもようわからんという方へ）
①資格スクエアのG検定対策講座（ビデオ教材）

##●私がかけた費用
★資格スクエア（JDLAの浅川講師が担当していますので安心です）
・G検定対策講座（リリースキャンペーン）　9,800円（現在 64,800円）
・G検定：オリジナル問題集（200問）　　　10,800円

★Study-Ai
・G検定（ディープラーニングと機械学習の検定）模擬テストと公式例題解説を無料公開中　無料
　http://study-ai.com/generalist/

★やさしい機械学習入門　無料
　http://gagbot.net/

★深層学習教科書 ディープラーニング G検定（ジェネラリスト） 公式テキスト　3,024円
・JDLA Deep Learning for GENERAL 2018 #1 受験料　12,960円
・JDLA Deep Learning for GENERAL 2018 #2 受験料　12,960円

合計費用　49,544円

結構かかりました・・・

##●最後に

前回と比較して、合格率が50％→60％Overになっています。
G検定公式テキストが出版されたことが影響しているのではと分析しています。

私の場合、IoT検定も既に合格していたこともあって、データ分析である程度把握していたので今回はAIの理解することに注力しましたが、人によってはyoutubeや資格スクエアさんなどの動画から基本を記憶することも必要かもしれません。

受験される皆様、頑張ってください！

年内の試験受験はこれで終わりにして
Courseraの機械学習コース Machine Learning by Stanford University

https://www.coursera.org/learn/machine-learning/lecture/Ujm7v/what-is-machine-learning

を合間を見て進めようと考えています。

下記にそれ以外の参考図書も記載しておりますので、宜しければこちらもご覧ください

http://jinsight.hatenablog.com/entry/2018/11/30/223043

ご覧いただきありがとうございました。

※誤り問題等ございましたら、コメントなどでご指摘いただけますと助かります。
cohfinさんのKuin関連ツイート

cohfinさんはKuinで.knobjファイルを作成することに成功した人らしいです。cohfinさんに許可をいただいてリンクを記事にさせていただきました。

https://twitter.com/search?f=tweets&vertical=default&q=%40cohfin%20Kuin&src=typd