OmniAICreator/Qiita-1.07M huggingface dataset:
virt-managerをMacBookにインストール

##1.はじめに
Linuxではvirt-manakgerをパッケージマネージャからインストール出来ますが、MacではHomebrewにてインストールする場合には公式以外のリポジトリを利用する必要があります。
KVMホストにsshでログインしvirshコマンドにて仮想マシンを制御していましたが、virt-managerでも操作したいためMacBookにvirt-managerをインストールします。

##2.virt-managerのインストール
virt-managerはHomebrew公式のリポジトリにないので、公式以外のリポジトリからインストールします。[jeffreywildman/homebrew-virt-manager](https://github.com/jeffreywildman/homebrew-virt-manager)がGitHubにて公開されているのでそちらを利用します。

```
brew tap
brew tap jeffreywildman/homebrew-virt-manager
brew search virt-manager

brew install virt-manager virt-viewer
# ビルドするので時間がかかります。完了するまで待ちます。
```

brew tapは公式以外のリポジトリを追加するHomebrewのコマンド。
username/repositoryの形式でbrew tapを実行するとGitHubリポジトリを参照できるようになります。


##3.virt-managerの起動とKVMホストへの接続

KVMにはqemu+sshで接続します。公開鍵をホストに登録してしておきます。
(鍵ペアを作成していない場合、ssh-keygen -t rsa で作成.)

```
ssh-copy-id username@libvirthost
```

ターミナルから以下のコマンドを実行し、virt-managerを起動し、KVMホストに接続します。

```
# 初回接続時は以下のコマンドの方がトラブルなく接続できます
virt-manager -c 'qemu+ssh://user@libvirthost/system?socket=/var/run/libvirt/libvirt-sock'

# 2回目以降は以下のコマンドを起動すると過去の接続情報が残っているので選択して再接続します
virt-manager --no-fork
```
接続すると↓のような感じ。(すでにVM作成済み)
<img width="559" alt="virt-manager-test.png" src="https://qiita-image-store.s3.amazonaws.com/0/280717/b4908bd9-0b7a-becc-1830-e1026662600b.png">

##4.参考
リモートからKVMに接続するには以下の設定が必要ですが、qemu+ssh方式での接続の場合には不要とおもわれます。(一応メモ)

```/etc/libvirt/libvirtd.conf
listen_tls=0
listen_tcp=1
tcp_port=16509
listen_addr="*"
mdns_adv=0
auth_tcp="none" 
```


```/etc/init/libvirt-bin.conf(Ubuntu)
# -lを追加
exec /usr/sbin/libvirtd -l $libvirtd_opts
```

```/etc/sysconfig/libvirtd(CentOS)
#コメントアウトを外す
LIBVIRTD_ARGS="--listen"
```

```
sudo service libvirtd restart
```

##5.参考情報
[jeffreywildman/homebrew-virt-manager](https://github.com/jeffreywildman/homebrew-virt-manager)
youtube似サイト作成ツールclipbucketをセットアップした。

ubuntu16.04でclipbucketをセットアップした。
https://clipbucket.com/
以下はその顛末

まずセットアップの前に環境をととのえる必要がある。
localhostではできないと言われたのでサーバーを借りた。
でubutnu 16.04を入れた。centosと悩んだがubuntuのほうが私にとって使いやすい。
LAMPは入れずopensshだけ入れた。あとでカスタマイズしたかったので。

でダウンロードだけど
https://clipbucket.com/download/
からやると面倒なのでなにかないかさがしたら
https://github.com/MacWarrior/clipbucket-5.0/blob/master/utils/install_ubuntu16.04.sh
が見つかった。なにやら楽そうなのでこれをつかう。
ただヴァージョンが5.0で先の公式の4.1よりちょっと新しいがgithubだからと考えた。

早速これをサーバーにviで書き込んだ。install.sh とした。ただ最後に

        ServerName clipbucket.local
        DocumentRoot /home/http/clipbucket/upload/
        ErrorLog ${APACHE_LOG_DIR}/error.log
        CustomLog ${APACHE_LOG_DIR}/access.log combined

の記述があるがこれどう考えても
ServerName clipbucket.local　を現実のサーバーに書き換える必要がある。
        ServerName XXXXX.jpにした。
下にecho - Website URL : http://clipbucket.local
とあるのでこれも書き換えたければ書き換える。（コメントなので重要でない）
で
sudo chmod a+x install.sh
sudo -s
./install.sh
でインストール
途中でDBの名前、ログイン名、パスワードがでるので記録。
終わったら
a2dissite　/etc/apache2/sites-available/000-default.conf
で古い設定を削除して
service apache2 reload
でサーバー再起動

ブラウザからサーバーにアクセスしてセットアップ画面が出るのを確認。
https://clip-bucket.com/index.php?mode=view_guide&action=13
このページの画面がでる。
とりあえずセットアップする。
言われるがままにボタンを押すだけ。
途中でadminの名前とパスが出る。これを記録
またさっきのDBのアカウントの入力を促されるので入力

最後まで辿りつけるとadminでログインするよう誘導される。
するとまずPHPのパラメータを直せといわれるので直す。（後述）
その正しい値はこれ
https://clipbucket.com/cb-install-requirements/
上から一行ずつ見ていってなおす。
ただ結果から言うがffmpegはここに書いている2.xでは変換エラーになったので
ppa:jonathonf/ffmpeg-3
をつかった。DBもmariaDBになっているはず。mysql5.6など入れられないので。
あとphp.iniはここを編集した。/etc/php/7.0/apache2/php.ini 
このパスはphpinfo()とかで表示して確認して下さい。
またモジュールも追加する必要があるのがcb-install-requirementsとinfoを見比べると分かる。
あとcb_installも削除しろと言われるのでそれもした。
https://clipbucket.com/cb-install-requirements/
は全体として記述が古い気がするが問題ないといえば問題ない。微妙な記述。
        
この操作をまとめてここに書く。
とりあえずこれらが足りない
sudo apt install mplayer
sudo apt install mailutils
sudo apt install php7.0-gd
sudo apt install imagemagick
入れたらsendmailできるのを確認。（しないとサインアップのメールができない）
a2enmod rewrite

php.ini の書き直し

max_execution_time = 12000
post_max_size = 1000M
upload_max_filesize = 1000M
memory_limit = 128M
sendmail_path = /usr/sbin/sendmail -t -i
date.timezone = "Asia/Tokyo"

以上。
で
service apache2 reload
でブラウザーからadminでログイン
まず。
General->Website Configurationでパスを直す。
General->Email Settingsでメールの設定を直す。
ここでSMTPを選ばないこと。選んだら認証メールが飛ばない
確認は
General->Email Tester
ToolBox->Server Modules Info
ToolBox->Server Configuration Info
でできる。すべてエラーがないのを確認。
ToolBox->Development Mode があるがこれはONにしない。
ONにすると一般人用のログイン画面が出ないという謎不具合がある。
むらむらと押したくなるが押すと２，３日潰れる

最後にNETで検索をかけると
cronを入れろとあるので一応入れる。

```
* * * * * php -q /home/http/clipbucket/upload/actions/video_convert.php
* * * * * php -q /home/http/clipbucket/upload/action/verify_converted_videos.php
0 0,12,13 * * *  php -q /home/http/clipbucket/upload/actions/update_cb_stats.php
```
あと
RAM :  8-10 gb (DDR3)
Processor :  i5 2.5 + ghz base speed
とあるがあまり気にする必要なし。
8G core 2 duo で動いた。
safe_mode = off
open_basedir = off
も無視でOK　謎記述だ。
MacでUSBやSDのフォーマットができない時

USBやSDカードが開けない時、「ディスクユーティリティ」を使用して内容を削除（初期化）してください。的な感じになりますがそれはうまくいきません。

ターミナルからコマンドで直接フォーマットした方が早くて正確でしたので
方法を載せておきます。

## ディレクトリを確認
USBやSDカードを抜いた状態と挿した状態で以下のコマンドを実行
`$ diskutil list`
すると
`/dev/disk2`または`/dev/disk3`が増えたり減ったりします。
それがUSBやSDカードのマウントされているディレクトリです。

## フォーマット
方法はシンプルで対応しているディレクトリに対して以下のコマンド
(`/dev/disk2`の場合)
`$ diskutil eraseDisk HFS+ Untitled /dev/disk2`
ローカルディレクトリにある画像ファイルをS３にぶち込むコード

#rmagickで生成した画像をS3にあげたい
carrierwaveを利用すればええやんと思ったのですが、今回は利用していません。
サービスの機能として、アップロードする際にモーダルからファイルを選んで投稿。。。。とかではなく、インスタンスをsaveするタイミングで、画像も同時に生成されるようにしたかったからです。つまりよくあるファイルを選んでください。
みたいなものはないわけです。
せっかくなんでcarrierwaveを使わずにやってみたいというのもありましたので、
・carrierwaveを使わない
・インスタンスがsaveされた段階で、そのインスタンスのもつtitleカラムやauthorカラムが画像処理され、awsのバケットに入る
みたいなことをやってみました。


#実際の作業とコード

今回はバケットがすでに生成されていること前提です。

まずは２つのgemをインストール
dotenvはセキュリティのため、aws-sdkはrubyからawsを操作できるようにするgemです。

```
bundle install
gem 'dotenv'
gem 'aws-sdk'
```

次にモデルの方に記述。

```sample.rb
require 'aws-sdk'

def upload_aws
    Aws.config.update({
    credentials: Aws::Credentials.new(ENV['ACCESS_KEY_ID'], ENV['SECRET_ACCESS_KEY'])})
    s3 = Aws::S3::Resource.new(region: 'ap-northeast-1')
    bucket = s3.bucket('bucket')
    object = bucket.object('object.png')
    object.upload_file("object_img.png")
end

```

requireは必須ぽい。ドキュメントに書いてあります。
ENVを使って実際のkeyは.envファイルに逃す。あとは普通にインスタンスを生成してメソッド追加していくだけです。（格納するオブジェクトを生成する。）
リージョンは東京。
最後のobject_img.pngがrmagickで生成されている画像です。
最終的にその画像がバケット内に格納されます。

#感想
自分今までaws苦手意識がありましたが、今回で少し理解できたような気がしました。（上のコード実装できたとき気持ちよかった）
あとドキュメントをちゃんと読む、一次情報に当たることが大切だと気づけました。色々な参考webページもあったんですが、awsの仕様がどんどん更新されており、古くなっている気がしています。。。
＝＞　特にここのドキュメントを参考にしました。アマゾン公式です。
https://docs.aws.amazon.com/ja_jp/sdk-for-ruby/v3/developer-guide/hello.html
ただまだあげられるようになっただけなので、これから改修するべきところはいくつもあるのでそちらをやっていきます。
（上のコードだと、あげられた画像が全て同じファイル名になってしまう。。。）
Goのarrayとsliceって値なの？ポインタなの？

Goのarrayとsliceについて説明しようとしたときに、自分でも混乱して説明できないことがあったので、もう一度調査してまとめてみました
あとは自分が過去にsliceでハマったところも記載してます

# まずはarrayを理解しよう

[Go Slices: usage and internals](https://blog.golang.org/go-slices-usage-and-internals)にも書いてありますが、sliceを理解するにはまず配列について理解する必要があります

## Goの配列は値である

Goの配列は値であり、C言語のように配列の先頭要素へのポインタではありません
その為、例えば関数の引数で配列を渡したり別の変数にいれたりすると、その配列のコピーが作成されます
関数内で配列の中身を変更したい場合は、配列のポインタを渡しましょう

```go
var a = [4]int{1, 2, 3, 4}
fmt.Printf("%#v\n", a) // [4]int{1, 2, 3, 4}
fmt.Printf("%p\n", &a) // 0xc42009c000

b := a
b[0] = 0
fmt.Printf("%#v\n", b) // [4]int{0, 2, 3, 4}
fmt.Printf("%p\n", &b) // 0xc4200161a0

fmt.Printf("%#v\n", a) // [4]int{1, 2, 3, 4}
```

# sliceは値？ポインタ？

## sliceの実体はarrayへのポインタ、しかしそれだけではない

sliceはarrayへのポインタを保持しています
しかしarrayのポインタそのものではなく、arrayのポインタ、length、capacityを保持している構造体です

```go:runtime/slice.go
type slice struct {
	array unsafe.Pointer
	len   int
	cap   int
}
```

arrayのポインタを保持しているため、他の変数に渡して要素の値を変更したら元の要素の値も変わります

```go
a := make([]int, 1)
fmt.Printf("%#v\n", a) // []int{0}

b := a
b[0] = 1
fmt.Printf("%#v\n", b) // []int{1}

fmt.Printf("%#v\n", a) // []int{1}
```

## sliceの宣言

`var s []T`でsliceを宣言すると、sliceの構造体の中でarrayへのポインタを保持していないのでsliceは`nil`になります
この場合、`slice == nil`が`true`になるほか、jsonへエンコードしても`null`となります
`make([]T, 0)`でsliceを宣言した場合は、`nil`にはなりません
jsonへエンコードすると空の配列になります
ちなみに`len()`はどちらの場合も`0`になります

```go
package main

import (
	"encoding/json"
	"fmt"
	"log"
)

func main() {
	var a []int
	fmt.Printf("%#v: len = %d, isNil = %v, json = %s\n", a, len(a), isNil(a), marshal(a))
	// []int(nil): len = 0, isNil = true, json = null

	b := make([]int, 0)
	fmt.Printf("%#v: len = %d, isNil = %v, json = %s\n", b, len(b), isNil(b), marshal(b))
	// []int{}: len = 0, isNil = false, json = []
}

func isNil(s []int) bool {
	return s == nil
}

func marshal(s []int) string {
	bytes, err := json.Marshal(s)
	if err != nil {
		log.Fatal(err)
	}
	return string(bytes)
}
```

## capacityは指定したほうが良い？

`make([]T, 0)`でcapacityを宣言しないと、capacityはlengthと同じになります
`append()`でcapacityを超えても要素を追加できるから、常にcapacity省略してもいいのでは？と思いますが（私は昔そう思ってました。。。）それは間違いです
capacityを超えてappendする場合は、メモリアロケーションが発生しパフォーマンスが悪くなります

```go
package main

import "testing"

func BenchmarkAppendNoCapacitySpecified(b *testing.B) {
	s := make([]int, 0)
	b.ResetTimer()
	for i := 0; i < b.N; i++ {
		s = append(s, i)
	}
}

func BenchmarkAppendCapacitySpecified(b *testing.B) {
	s := make([]int, 0, b.N)
	b.ResetTimer()
	for i := 0; i < b.N; i++ {
		s = append(s, i)
	}
}
```

```
BenchmarkAppendNoCapacitySpecified-4    100000000               42.6 ns/op            49 B/op          0 allocs/op
BenchmarkAppendCapacitySpecified-4      2000000000              12.1 ns/op             0 B/op          0 allocs/op
```

ベンチマークを見てもcapacityを指定したほうがパフォーマンスが良いのは明らかです
要素数の最大値がわかっているときはcapacityを指定しましょう

# まとめ
- Goのarrayは値
- Goのsliceはarrayへのポインタ、length、capacityを保持した構造体
- sliceはnilになるケースがある
- capacityはなるべく指定する

# 参考

- [Go Slices: usage and internals](https://blog.golang.org/go-slices-usage-and-internals)
- [Goのarrayとsliceを理解するときがきた](https://qiita.com/seihmd/items/d9bc98a4f4f606ecaef7#slicing%E3%81%A7array%E3%82%92%E3%82%B9%E3%83%A9%E3%82%A4%E3%82%B9%E3%81%99%E3%82%8B)
SwiftコンパイラのManglingの勉強方法

SwiftコンパイラのManglingについて勉強するときは、
下記のアプローチがあります。

1. ドキュメントを読む
2. デマングルしてみる
3. Manglerのコードを読む
4. Demanglerのコードを読む

以降, 個別に詳細を説明します。

## ドキュメントを読む

幸いなことに、Manglingについてはドキュメントがあるので、
これを読むと良いでしょう。

https://github.com/apple/swift/blob/master/docs/ABI/Mangling.rst

## デマングルしてみる

`swift demangle` というコマンドで、デマングルすることができます。

```
$ swift demangle '$S1a3CatC4nameSSvg'
$S1a3CatC4nameSSvg ---> a.Cat.name.getter : Swift.String
```

`-expand` オプションを使うと、構造もわかります。

```
$ swift demangle -expand '$S1a3CatC4nameSSvg'
Demangling for $S1a3CatC4nameSSvg
kind=Global
  kind=Getter
    kind=Variable
      kind=Class
        kind=Module, text="a"
        kind=Identifier, text="Cat"
      kind=Identifier, text="name"
      kind=Type
        kind=Structure
          kind=Module, text="Swift"
          kind=Identifier, text="String"
$S1a3CatC4nameSSvg ---> a.Cat.name.getter : Swift.String
```

## Manglerのコードを読む

Manglerのコードを読んだり、
実際にマングルする処理をデバッガで追いかけてみるとわかりやすいです。

Manglerは下記の2つがあります。

ASTMangler
https://github.com/apple/swift/blob/master/include/swift/AST/ASTMangler.h

IRGenMangler
https://github.com/apple/swift/blob/master/lib/IRGen/IRGenMangler.h

IRGenManglerはASTManglerを継承して、機能を追加しています。

SILGenステージではASTManglerが使用されていて、
IRGenステージではIRgenManglerが使用されています。

例えば、メソッド名などはSILでMangling済みなので、
ASTManglerにメソッドがあります。

```cpp
std::string ASTMangler::mangleEntity(const ValueDecl *decl, bool isCurried,
                                     SymbolKind SKind)
```

型名そのものや、メタタイプなどについては、
IRGenステージで必要になるので、IRGenManglerにメソッドがあります。

```cpp
std::string IRGenMangler::mangleTypeForLLVMTypeName(CanType Ty)

std::string IRGenMangler::mangleTypeMetadataFull(Type type)
```

## Demanglerのコードを読む

Demanglerのコードを読んだり、
実際にデマングルする処理をデバッガで追いかけてみるとわかりやすいです。

`swift demangle` コマンドのソースは、`swift-demangle.cpp` です。
https://github.com/apple/swift/blob/master/tools/swift-demangle/swift-demangle.cpp

デマングルを利用するインターフェースは、`swift::Demangle::Context`です。
https://github.com/apple/swift/blob/master/include/swift/Demangling/Demangle.h

`swift demangle` コマンドでは、ユーザから与えられたシンボルを、
下記メソッドに渡すようになっています。

```cpp
NodePointer Context::demangleSymbolAsNode(llvm::StringRef MangledName)
```

## 余談

Demanglerは下位互換性が必要なので、過去の仕様が垣間見えます。
下記のコードから、prefixが変更されてきた様子がわかります。

```cpp
int swift::Demangle::getManglingPrefixLength(llvm::StringRef mangledName) {
  if (mangledName.empty()) return 0;

  llvm::StringRef prefixes[] = {
    /*Swift 4*/   "_T0",
    /*Swift 4.x*/ "$S", "_$S",
    /*Swift 5+*/  "$s", "_$s"};

  // Look for any of the known prefixes
  for (auto prefix : prefixes) {
    if (mangledName.startswith(prefix))
      return prefix.size();
  }

  return 0;
}

bool swift::Demangle::isOldFunctionTypeMangling(llvm::StringRef mangledName) {
  return mangledName.startswith("_T");
}
```

SwiftはABIが安定していないので、
マングリングルールが変わるときは、
prefixごと変えてしまうことで、
バージョン番号のように機能させていたのだと思います。

そして最近、swiftコンパイラでは、Mangler側のprefixが `$s` になりました。
https://github.com/apple/swift/pull/19388

Swift5ではABIが安定化することが予定されているので、
それがうまくいけば、以降は `$s` から変更されることはないでしょう。
AnacondaにCOMBOを導入する (AnacondaでCythonが"error: Unable to find vcvarsall.bat"を出す問題の解決)

東京大学津田研究室で開発されたベイズ最適化計算用のライブラリ<b>COMmon Bayesian Optimization Library ( COMBO )</b>の導入で躓いた箇所があったのでメモを残しておきます．

<h1>はじめに</h1>
COMBOはベイズ最適化用の高速計算ライブラリでMITライセンスにより公開されているオープンソースソフトウェアになります．
ベイズ最適化を用いれば中身の分からないブラックボックスである関数の最大値（もしくは最小値）を効率的に求めることが可能になります．
ベイズ最適化そのものについての詳しい紹介は他の記事等に譲りたいと思います．概念的な部分の理解だけならば以下のスライドが参考になるかと思います．
[機械学習のためのベイズ最適化入門](https://www.slideshare.net/hoxo_m/ss-77421091)

また，COMBOは以下のURLからダウンロードすることが出来ます．
https://github.com/tsudalab/combo


<h1>インストール方法(Anaconda以外)</h1>
GitのInstallの箇所を見れば簡単に導入できます．
Required Packagesに示されたソフトをpip等でインストールした後，
ダウンロードしたcomboファイルのディレクトリに移動して
`python setup.py install`
を実行することでインストールが完了します．
尚，実行環境としてpython2.7が指定されていることにご注意ください．


<h1>インストール方法(Anaconda)</h1>
躓いた部分がここになります．
COMBOにはexampleとしてtutorial.ipynbというファイルが用意されており，これを実行するためにjupyter notebookでCOMBOを実行する必要があります．
しかし，Anaconda PromptからCOMBOをインストールしようとすると，
`~>python setup.py install
running install
running build
running build_py
running build_ext
skipping 'combo/misc/_src\traceAB.c' Cython extension (up-to-date)
building 'combo.misc._src.traceAB' extension
error: Unable to find vcvarsall.bat`
というエラーが出てAnacondaにインストールすることが出来ないという問題が発生しました．


<h2>解決の為に行ったこと</h2>
まず，vcvarsall.batがインストールされていない可能性が有るので確認します．
以下のパッケージをインストールすることで，python2.7に対応したvsvarsallが導入されます．
[Microsoft Visual C++ Compiler for Python 2.7](https://www.microsoft.com/en-us/download/details.aspx?id=44266)

Windowsが標準で使用するpythonとAnacondaが使用しているpythonは別にインストールされています．
その為，上記パッケージをインストールしただけではパスが通っていない為エラーが消えません．
以下の手順でAnacondaが使用しているpythonにvcvarsall.batのパスを通してやります．

1. "C:\Users\（ユーザー名）\AppData\Local\conda\conda\pkgs\python-2.7.15-he216670_0\Lib\distutils\msvc9compiler.py"をテキストエディタ等で開く（お使いの環境によって場所や名前が異なる可能性が有ります）
2. 254行目辺りに
`if not productdir:
        log.debug("No productdir found")
        return None`
のような記述があるのでその直前に
    `productdir = "C:\\Users\\（ユーザー名）\\AppData\\Local\\Programs\\Common\\Microsoft\\Visual C++ for Python\\9.0"`（先ほどインストールしたMicrosoft Visual C++ Compiler for Python 2.7へのパス）というコードを追加します．

以上でインストールが実行できるようになると思います．
まだ問題が発生する場合は，上で示したパスがお使いの環境に合わせて設定されているかどうかや足りないパッケージがないか等を確認してください．


<h1>あとがき</h1>
標準の環境への導入は簡単に出来たのにAnacondaでは動かず，モヤモヤしたまま解決までに2日程かかってしまい非常に疲れました．
個人的には，今回のように仮想環境ゆえに融通が利かない部分があったり，ブラウザでコーディングしなければならない（私にとってブラウザはあくまで情報収集・娯楽目的のツールで，起動も遅くコーディング環境として常用したくない）という点が苦手で，Anacondaやjupyternotebookがあまり好きになれてはいないのですが，世間の潮流的には非常に活気づいている２ツールなので早く慣れておきたいところです．
MacOSのFinderで隠しファイルを表示する/隠しフォルダに移動する

よく忘れるやつ

macOS High Sierra Version 10.13.6
Finder version 10.13.5

# 方法1: 隠しファイルを表示する
Finderを開いた状態で

`Shift` + `⌘` + `.`

# 方法2: Go to Folder(Go > Go to Folder...) で隠しフォルダに移動する
`Shift` + `⌘` + `G`


![Volumes.png](https://qiita-image-store.s3.amazonaws.com/0/26393/6834d01e-26a8-2356-5388-45ae892cc5cb.png)

# 参考URL
https://support.apple.com/kb/PH25294?locale=ja_JP&viewlocale=ja_JP
MySQLの環境構築

# MySQLのインストール
参考にしたサイトのコマンドそのまま打っただけですがメモ。

```
wget https://dev.mysql.com/get/mysql-apt-config_0.8.10-1_all.deb
sudo dpkg -i mysql-apt-config_0.8.10-1_all.deb
```

SQLのバージョンをmysql5.7を選んでOK

```
sudo apt update
sudo apt install mysql-server -y
```

root用のパスワードを指定する。

起動、停止は

```
sudo service mysql start
sudo service mysql stop

mysql -u root -p
```

参考
[UbuntuにMySQL5.7をAPTでインストール](https://qiita.com/blue-ossan/items/e7e7229a37feaf792e35)

そして
[MySQL初心者入門講座](http://mysqlweb.net/)
で勉強し始めたんですが、テーブルにデータ挿入するとこでエラー。
どうやら文字コードの問題で日本語が入力できないらしい。

```:etc/mysql/my.cnf
[client]
default-character-set=sjis

[mysql]
default-character-set=sjis

[mysqldump]
default-character-set=sjis

[mysqld]
character-set-server=sjis
```
これを追加してみて文字コード直したんですが、依然エラーのまま...
なぜだ
<img width="345" alt="sql_moji.png" src="https://qiita-image-store.s3.amazonaws.com/0/292031/3c7130dc-c3c7-d40c-8028-0501aaf18541.png">

ちゃんと直ってると思うんだけどなぁ
原因分かる人だれか教えて...
httpd.confでのCGIの実行設定

## CGIプログラムの置き場所を/cgi-bin/に絞る場合
下記ディレクティブをhttpd.confに追記すればOK

```Apache:httpd.conf
<IfModule alias_module>
    ScriptAlias /cgi-bin/ "/var/www/cgi-bin/"
</IfModule>
<Directory "/var/www/cgi-bin">
    AllowOverride None
    Options None
    Require all granted
</Directory>
```

## CGIプログラムの置き場所を絞らない場合
上記設定に加えて、AddHandlerとExecCGIを設定する

### AddHandler
apacheに特定拡張子で作成されたファイルをcgi-scriptとして認識させる
これで、対象拡張子を持つファイルをCGIプログラム扱いできる
`AddHandler cgi-script .cgi .pl`
### ExecCGI
CGIの使用を許可するディレクティブ内で、下記設定を追加する
`Options ExecCGI`
これで、対象ディレクティブでは（/chi-bin/でなくても）CGIスクリプトの実行が可能になる。  
以下は/bbs/にCGIプログラムを配置する場合の設定

```Apache:httpd.conf
<Directory "/var/www/bbs">
    AllowOverride None
    Options ExecCGI
    Require all granted
</Directory>
```
「scikit-learnとTensorFlowによる実践機械学習」でハマった時の解決策

2.3.2 データをダウンロードする
2.3.3 データの構造をざっと見てみる　の話です

#「p.44」コードそのままそっくり書いたはずなのに・・・エラーでる問題

## 問題１：ダウンロードのURLが違う
<code>DOWNLOAD_ROOT = "https://raw.githubusercontent.com/ageron/handson-ml/master/"</code>
この部分、たたいて見ると404が出ます。


下記のようにすると繋がるようになりました。
<code>DOWNLOAD_ROOT = "https://cdn.rawgit.com/killakalle/ageron_handson-ml/3201b89b/"</code>


他の部分は、?raw=trueとつけてあげると、良いようです。
<code>
HOUSING_URL = DOWNLOAD_ROOT + "datasets/housing/housing.tgz"

HOUSING_URL = DOWNLOAD_ROOT + "datasets/housing/housing.tgz?raw=true"</code>

<code>
csv_path=os.path.join(housing_path, "housing.csv")

csv_path=os.path.join(housing_path, "housing.csv?raw=true")</code>


# 問題２：SSLCertVerificationError

問題１をパスしても、SSL認証エラーが出てしまいます。
パスはあっているから繋がってもおかしくないのに・・

これは、ローカルにあるpythonの設定が、SSL認証に対応していないのが原因のようです。
下記パスにあるファイルをダブルクリックして実行して見ると、。
/Applications/Python 3.7/Install Certificates.command


![スクリーンショット 2018-09-22 19.27.54.png](https://qiita-image-store.s3.amazonaws.com/0/247390/17cb317a-b1e4-20de-a13b-2d5d526203c4.png)

ちゃんと実行できるようになりました。

![スクリーンショット 2018-09-22 19.33.01.png](https://qiita-image-store.s3.amazonaws.com/0/247390/d01722c8-d8f0-4899-08c2-6399cb7395e6.png)
Google SpreadsheetとCloud Functionsでランダムに出力するオミクジ的なサイトを作る

Google Spreadsheetの値を他のアプリから扱えると何かと便利だが、URLが`https://script.google.com/macros/s/{11文字+２８文字+15文字}/exec`と、ちょっと使いにくいのでCloud Functionsと組み合わせて使いやすくしてみる。

# SpreadSheetの値を取得する

まずスプレッドシートを作る。作ったスプレッドシートのURLに注目。IDの部分をコピペしておく。

```
https://docs.google.com/spreadsheets/d/{この部分がスプレッドシートのID}/edit#gid=0
```

ツールから「スクリプトエディタ」を開く。

<img width="654" alt="スクリーンショット 2018-09-22 17.56.14.png" src="https://qiita-image-store.s3.amazonaws.com/0/33389/8eedf5bf-d1dc-8eaf-ed30-e9eae7d5f6b5.png">

元の関数を消して下記のdoGet()をコピペ。ざっくり解説すると、getLastRow()で行数を取得し、ランダムに行を取得したものを出力している。別にランダムでなくてよければ、getRange(1,1)のように普通にセル指定して取得すればよい。

なお、元の「シート１」というシート名でエラーが起きてるようだったので「sheet1」とリネームしている。（これが原因だったか自信がないが・・・）

```js
function doGet(){
  var spreadsheet = SpreadsheetApp.openById('{スプレッドシートのID}');
  var sheet = spreadsheet.getSheetByName('sheet1');
  var lastRow = sheet.getLastRow();
  var rand = Math.floor( Math.random() * lastRow ) + 1;

  var rowData = {};
  rowData.num = rand;
  rowData.value = sheet.getRange(rand,2).getValue();
  var result = JSON.stringify(rowData);
  return ContentService.createTextOutput(result);
}
```

コピペできたらスクリプトエディタから「ウェブアプリケーションとして導入」を選ぶ。

<img width="607" alt="スクリーンショット 2018-09-22 17.57.22.png" src="https://qiita-image-store.s3.amazonaws.com/0/33389/84475358-e9b2-a6b8-a856-20acb4bb8dcc.png">

「アプリケーションにアクセスできるユーザ」を全員にして「導入」ボタンを押す。

<img width="720" alt="スクリーンショット 2018-09-22 17.57.47.png" src="https://qiita-image-store.s3.amazonaws.com/0/33389/4d3c857b-29ed-7fd8-acdd-206e6ac5d595.png">

この画面で「詳細」を押すと、アプリを許可する画面に進む。ここ、最初のうちは気づかなかった。

<img width="869" alt="スクリーンショット 2018-09-22 18.04.52.png" src="https://qiita-image-store.s3.amazonaws.com/0/33389/1ef2e5f4-e3f1-d920-9728-e77242aed3f1.png">

こんな感じでURLが生成されたら成功。別のブラウザ（curlやChromeのプライベートブラウズなど）でアクセスして動作確認する。

<img width="719" alt="スクリーンショット 2018-09-22 18.05.11.png" src="https://qiita-image-store.s3.amazonaws.com/0/33389/d26d2425-3807-a860-00c1-c9c32e2998eb.png">


# Cloud Functionsで値を取得・表示する

まずチュートリアルを参考に、helloGETできるところまで動作確認する。（プロジェクト作成から課金まで、意外にやることが多い）

https://cloud.google.com/functions/docs/tutorials/http

helloGETが動いたら、Google Spreadsheetの値を取得するようindex.jsを書き換えてみる。

```js:index.js
/**
 * HTTP Cloud Function.
 *
 * @param {Object} req Cloud Function request context.
 * @param {Object} res Cloud Function response context.
 */

const request = require('request');

exports.content = (req, res) => {

  let url = 'https://script.googleusercontent.com/macros/echo?user_content_key=xx'
  request.get(url, function (error, response, body) {
    body = JSON.parse(body);
    let out = new String();
    out += body.value;
    res.status(200).send(out);
  });

};
```
requireはpackage.jsonに書かないと読み込んでくれないので、package.jsonもコピペ。

```js:package.json
{
  "name": "test",
  "version": "0.0.1",
  "dependencies":{
    "request": "~2.88"
  }
}
```

チュートリアルで作ったhelloGETを削除して、新しく作ったcontentをデプロイする。

```bash
gcloud beta functions delete helloGET --trigger-http
gcloud beta functions deploy content --trigger-http
```

これでSpreadsheetの値をCloud Functionsで取得できる。めでたしめでたし。

ちなみに[quote for TOEIC](https://sites.google.com/view/qft5/)という技術系の英文をランダムで表示するサイトも、こんな感じでサーバレスで動いてる。
【Python】word2vecの類義語を品詞でフィルタリングする

#前提
* modelは学習済みのgensimのmodel
* 品詞判定にはJanomeのTokenizerを利用
* '鬼'に類似した単語1,00個を取得してからフィルタリング

# TokenFilterを使う方法
```py
from janome.analyzer import Analyzer
from janome.tokenfilter import POSKeepFilter, POSStopFilter
    
target_word = '鬼'
topn = 1000

for word, score in model.similar(target_word, topn=topn):
    tokens = a.analyze(word)
    for token in tokens:
        print(token, score)

```
###TokenFilterの利用イメージ
```py
from janome.analyzer import Analyzer
from janome.tokenfilter import POSKeepFilter, POSStopFilter
    
target_word = '「鬼の」'

# 「名詞」を取得して、「記号」と「助詞」は除く
token_filters = [POSKeepFilter('名詞'), POSStopFilter(['記号', '助詞'])]
a = Analyzer(token_filters=token_filters)
tokens = a.analyze(target_word)
for token in tokens:
    print(token)
#=> 鬼	名詞,一般,*,*,*,*,鬼,オニ,オニ
```

# TokenFilterを使わない方法
```py
from janome.tokenizer import Tokenizer

t = Tokenizer()
target_word = '鬼'
topn = 1000

for word, score in model.similar(target_word, topn=topn):
    tokens = t.tokenize(word)
    for token in tokens:
        pos0 = token.part_of_speech.split(',')[0]
        pos1 = token.part_of_speech.split(',')[1]
        # 形容詞と形容動詞に限定して取得
        if pos0 == '形容詞' or pos1 == '形容動詞':
            print(token.surface, score, pos0, pos1)
```

# 品詞について
- [形態素解析ツールの品詞体系](http://www.unixuser.org/~euske/doc/postag/)
NginxがどのようにしてC10K問題に対応しているのか？

![image.png](https://qiita-image-store.s3.amazonaws.com/0/202653/11687549-40c6-5d1a-d321-186f0bedf055.png)

nginx(エンジンエックスと読みます)

## Nginxの由来

### C10K問題

nginxはApacheでC10K問題が起こったことにより開発され始めました。
C10K問題とは、簡単にいうとクライアントが多すぎてサーバーがパンクすることです。
サーバーにクライアントが接続すると、`worker/thread`が発生します。`worker/thread`とはクライアントが仕事が来たら働くが、来ない場合は待機するというものです。
`worker`はメモリをある量だけ確保します。これによって一定数以上のクライアントが接続するとサーバーが食い尽くされます。
この現象が起きるのがだいたいClientが10Kilo個の時におこるという意味でC10K問題と言います。

実際は他にも原因があるようですが、細かいところまではわかりませんでした。
わかる方は
http://www.aosabook.org/en/nginx.html
を読んでいただくとわかると思います。

### C10K問題の解消

上記の問題を解消するためにNginxが作られました。
どうやって解決したのでしょう？

nginxではイベント駆動モデルというのを採用しています。
イベント駆動型モデルでは、クライアントの接続を1プロセスとして扱い、それをきっかけに処理が行われます。
また1プロセス1スレッドとなるため、クライアントの数が増えてもプロセス数は増えないためC10K問題が起こるのを防ぎます。

#### I/Oの多重化

1プロセスで多数のクライアントの接続を処理するためには

- マルチプロセス（Apache）
- マルチスレッド（Apahce）
- 非同期I/O
- I/Oの多重化（Apache、Nginx）

があります。

nginxではI/Oの多重化という方式を使っています。

I/Oの多重化の実現にはシステムコール「select, poll, epoll」を使っています、

詳しくは
https://blog.shibayu36.org/entry/20120101/1325418188
を読んでください。
結局細かいことまですっきりとはわかりませんでしたが、これらを使ってI/O多重化を実現し1プロセスで多数のクライアント接続に対処しているそうです。

















## 参考文献

https://qiita.com/ayana_shi/items/d529ee7d4fcac0f8b046
https://blog.framinal.life/entry/2015/09/13/195121

これが一番わかりやすくてまとまっている
http://www2.matsue-ct.ac.jp/home/kanayama/text/nginx/all.html
doubleとバインドしているTextBoxに小数点が入力できない！

## 背景

- C# + XAML
- `TextBox`が数値型（`int`や`double`）とバインドしている
- リアルタイムに入力値でバインドしているプロパティを更新する

```xml
<TextBox Text="{Binding Path=Number, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
```

`TextBox.Text`プロパティを、数値型の`Number`とバインドしています。

`Mode=TwoWay`としていますので、`TextBox`に入力するとその値をバインドしている`Number`へ書き込みます。（これは`TextBox`のデフォルトの動作ですから、記述しなくても構いませんね）

また、`UpdateSourceTrigger=PropertyChanged`としていますので、`TextBox`のデフォルトの動作であるフォーカスが外れたときではなく、値を入力した瞬間に`Number`へ書き込みます。

## int（long）だとバッチリ！

バインドしている`Number`が、`int`や`long`など整数型だと、何の問題もなく動作します！

ちなみに、数字以外の文字列を入れた場合は、枠が赤くなり、入力に誤りがあることも自動的に表示してくれます！
入力に誤りがあれば、バインドしている`Number`も更新されません。

![キャプチャ.PNG](https://qiita-image-store.s3.amazonaws.com/0/293884/a904ebcf-ec47-accd-5712-a6934de05daa.png)

なんと便利！

## double（float）だと…

ところが、バインドしている`Number`が、`double`や`float`など小数点以下を含む数値型になると、問題が生じます！

**小数点が入力できないんです！**

「123.45」と左の1から順に入力していくと、小数点が入力されず「12345」になってしまいます！

小数点が全く入力できないかというと、そうでもなくて、「12345」と入力した後、「3」と「4」の間にカーソルを置き、「.」を入力すると、正しく「123.45」になります。

つまり、**数字列の最後（末尾）へ小数点が入力できない**んです！

## どうなってるの？（推測）

```
System.Windows.Data Error: 7 : ConvertBack cannot convert value '123a' (type 'String'). BindingExpression:Path=Model.Number1; DataItem='SimpleCalcViewModel' (HashCode=20876819); target element is 'TextBox' (Name=''); target property is 'Text' (type 'String') FormatException:'System.FormatException: 入力文字列の形式が正しくありません。
   場所 System.Number.StringToNumber(String str, NumberStyles options, NumberBuffer& number, NumberFormatInfo info, Boolean parseDecimal)
   場所 System.Number.ParseInt64(String value, NumberStyles options, NumberFormatInfo numfmt)
   場所 System.String.System.IConvertible.ToInt64(IFormatProvider provider)
   場所 System.Convert.ChangeType(Object value, Type conversionType, IFormatProvider provider)
   場所 MS.Internal.Data.SystemConvertConverter.ConvertBack(Object o, Type type, Object parameter, CultureInfo culture)
   場所 System.Windows.Data.BindingExpression.ConvertBackHelper(IValueConverter converter, Object value, Type sourceType, Object parameter, CultureInfo culture)'
```

数値以外を入力したときに、Visual Studioの出力ウィンドウに出る例外のバックトレースから、次のような機序になっているようです。

1. `TextBox`に数字（文字）を入力する
2. 入力された文字列全体を、`Number.ParseInt64`メソッドや`Number.ParseDouble`メソッドを使って、数値に変換する
3. 変換に成功したら、その数値を`TextBox`に表示する
4. バインドしているプロパティに書き込む

ここで問題になるのが、「変換に成功したら、その数値を`TextBox`に表示する」ところです。

末尾に小数点を入力すると、たとえば「123.」という文字列になります。
これを`Number.ParseDouble`メソッドが変換すると、123という数値になります。
123という数値は、表示すると「123」になり、小数点はなくなってしまいます！

## どうすればいいの？（HELP!）

では、どうすればいいのかですが、すみません！まだ、わかっていません！
どなたか、ご教授いただければ幸いです！

`UpdateSourceTrigger=PropertyChanged`を取ればいいんですが、リアルタイムに更新されなくなっちゃいますからねぇ。リアルタイムに更新し、かつ、末尾に小数点を入力したいんですけど…。

[解決編⁉](https://qiita.com/h084/items/066d0289833cad858f9b)、[完結編‼](https://qiita.com/h084/items/1c266839bad95f6f90fe)へつづく。
APIのドキュメント書いてモックサーバーまで起動する話(api blueprint + aglio + drakov)

## まえがき

みなさんサーバーのAPI仕様書、どのように管理してますか？
ConfluenceとかDropboxとかで保管したりしている人やプロジェクトも多々あると思いますが、こんな問題抱えていませんか？

- メンテナンスされない
- 仕様書があいまいで結局よくわからない
- 仕様書を書いた後にモックサーバー作るのが面倒

仕様書くだけで綺麗なドキュメントになって、モックサーバーまで起動できたら上のような問題が解消されるのではないでしょうか。

## 開発フロー

![api-flow.png](https://qiita-image-store.s3.amazonaws.com/0/252348/5f035f1d-88f9-0377-3eca-c3ce54c9e589.png)

上のような図でいうと、特に決まったルールもないAPI仕様書を書いて、それにそってモックサーバーを作ってクライアント側のエンジニアも作業できるような環境を整えてから実サーバーの作成といった流れで開発が進む場合を考えます。

冒頭にも書いたのですが、なにかしらルールを設けてAPI仕様書を書いたところで、作った仕様自体が曖昧だったり、モックサーバー作ってるうちに足りない、仕様書と違う、なんて状況になると、時間をかけて仕様書も直してモックもその通り作れるようなプロジェクトならいいですが、実際のところAPI仕様書がメンテされなくなるか、仕様書を書き直したところでAPIの曖昧さは残ったりします。

そんな中、決まったルールでAPI仕様書を書いたらコマンド1発でモックサーバーが作成でき、見やすいドキュメントまで生成することができる仕様・ライブラリがあるわけです。

![api-flow (1).png](https://qiita-image-store.s3.amazonaws.com/0/252348/1f2f490c-06c7-87b3-a71c-7e26f4fc036f.png)

## [API Blueprint](https://apiblueprint.org/)

APIの仕様を書くための仕様で、[API Blueprint](https://apiblueprint.org/)(以下apibと略します)というものがあります。
[この仕様の通り](https://apiblueprint.org/documentation/)にapibを書いていけば、関連するライブラリを使って、ドキュメントを生成したり、モックサーバーを起動することができます。

ライブラリは様々ありますが、今回は[aglio](https://github.com/danielgtaylor/aglio)と[drakov]()について書いていきます。他のツールについては、[主にこちら](https://apiblueprint.org/tools.html)に書かれているので、ユースケースに応じて調べてみてください。ちなみに、ドキュメントを生成するツールは`renderers`、モックサーバーを起動するツールは`mock servers`と書かれています。

## [aglio](https://github.com/danielgtaylor/aglio)

aglioは`renderers`に分類される、ドキュメントを生成するツールです。ちなみにイタリア語で「にんにく」らしいですが、なぜこんなにおいしいが臭い食材を命名したのかはよくわかりません。

コマンドは `$ aglio -i xxx.apib -o xxx.html` のようにしてドキュメントを生成したり、 `$ aglio -i xxx.apib -s -p 8080` のようにしてドキュメントのサーバーを起動したりできます。

`--compile`オプションをつけると、分割した複数のapibファイルを1つのapibファイルにまとめることができます、これに関してはdrakovの説明の後に使いどころを書きます。

## [drakov](https://github.com/Aconex/drakov)

drakovは`mock servers`に分類される、モックサーバーを起動するツールです。ちなみにスロバキア語で「ドラゴン」らしいです。

コマンドは`$ drakov`コマンドでモックサーバーを起動するのですが、起動条件の指定は`.drakovrc`ファイルか、コマンドライン引数で指定します。`.drakovrc`ファイルを作ると全てのコマンドライン引数が無視されます。

## ファイルの分割

実際にapibを書いているとすぐに思うのは、仕様書って莫大な量になるので1つのファイルに書いていると管理が大変です。なので、aglioでは`<!-- include(xxx.apib) -->`のようにしてファイルを分割することができます。

しかしこれ、drakovは認識してくれないんです。なので1つのapibファイルしかモックサーバーを起動できない感じになってきました。

そこでaglioの`--compile`オプションなんですが、これを使うと複数に分けて管理していたapibから1つのapibファイルを出力することができるので、どんなにファイルを分割してもaglioがまとめてくれる範囲内でモックを起動することができます。

## さいごに

正直なところ、apibの仕様がかなり膨大なので全部覚えるのは大変なんですが、基本的なところだけ覚えればかなり運用まで考慮した効率的な開発ができると思います。

ぜひ試して見てください。
Blender から GLTF を出し、 Three.js で使うまでの覚書　（アニメーション編１、ずん子さん編）

Blenderは、GLTF(2.0)を出せます。

Three.jsは、GTLF(2.0)を、読めます。

以上。めでたしめでたし。

ということで、[モデルメッシュ編](https://qiita.com/adrs2002/items/dc6416d6fd2389c75ab5)の続きとして、アニメーション編・・の、その１です。
というかコレを書いてよいのかどうか迷いましたが、多分残す意味がある気がしたので、公開して後悔することにします。

＊この文では、「Blenderでのモデルの作り方」とか「Three.jsの使い方」とかは全くやりません。いじょ。


## やりたかったこと
：配布されているBlenderモデル（[東北ずん子さん](https://zunko.jp/))を、GLTFで出力して、Three.jsで読ませる


ずん子さんカワイイ
[![zzm_a1zunko53.png](https://qiita-image-store.s3.amazonaws.com/0/133895/844afc61-e449-88c4-e92e-b468fe0ee5a5.png)](https://zunko.jp/con_illust.html)



## やったこと

- ずん子さんのデータを、[こちらから](https://zunko.jp/con_illust.html)DLする（使用規約は読みましょうね）
- Blenderで開く
- Blenderに、[GLTFエクスポーター](https://github.com/KhronosGroup/glTF-Blender-Exporter)を導入する（導入済みならよし）
- ずん子さんをBlenderで開く

- GLBでエクスポートを、下記の設定の通りで行う（重要）
![putZunko_1.png](https://qiita-image-store.s3.amazonaws.com/0/133895/b8c9dfb5-62ce-57ad-f1c6-cd39fd506cfb.png)

- 出力に**失敗**する:skull:（重要！必要なステップ）

- アニメーションビューにして、ドープシートを「アクション」にすると、Actionが増えている！（これが上記出力失敗時に増えたもの）
![putzunko_2.png](https://qiita-image-store.s3.amazonaws.com/0/133895/48722f2b-93be-9f07-9938-aad64aff4aa9.png)


- GLBでエクスポートを、下記の設定の通りで行う（ Bake Skinning constrains を外す）
![putZunko_3.png](https://qiita-image-store.s3.amazonaws.com/0/133895/5994e28b-5916-185d-cd96-81cb034f8889.png)

- Three.js で、出力されたデータを読み込む


- っしゃおら 

![putZunko_4.png](https://qiita-image-store.s3.amazonaws.com/0/133895/d02240a6-90bf-fd5e-3b5c-d5a087e0460a.png)


- 色をもうちょっと頑張って出したいなら、Blender側でPBRマテリアルを適用したりしてから出力したりする


[動くサンプルはこちら](http://adrs2002.com/sandbox/gltf_viewer/gltfTes_zunko.html)


## なんでこれでうまくったんだろう？（予想を含む考察）

- 試しに初回から「Bake Skinning constrains」を外して出力してみてください。足などの一部がアニメーションされません。
- おそらく、上記の設定のOnによる失敗により、「初期位置のデータ」が、どっかに入った（雑・・・）
- それで、正式出力の時に、うまくいった。

## モーフは？

- ずん子さんには、15種類表情モーフ（シェイプ）が設定されている模様？
- ただ、その15種類のモーフを使いたい場合は、「 モディファイヤを適用 」のチェックを外す！
![putZunko_5.png](https://qiita-image-store.s3.amazonaws.com/0/133895/8d5662c3-218a-7764-ce96-af20d436f2a5.png)


- 「Head」のグループの中のメッシュに、モーフ付きメッシュが入ってるので、うまいことやってください。モーフの適用などは前回などで書いたので参照を。








東北地方は、これからしばらく（10月中旬まで）は　[コスモスが見ごろ](http://www.michinoku-park.info/wp/service/ohanabatake/)　のようですよ！
たまの脳みそのリフレッシュに、東北地方に行ってみよう！
Vueのオプション構成・ライフサイクルダイアグラム

# Vueのオプション構成

## マウントで使用する要素
`el`はアプリケーションを紐づける要素のセレクタ

```js
new Vue({
    el: '#app'
})
```

## アプリケーションで使用するデータ
`data`はアプリケーションで使用するデータ。
オブジェクトや配列を登録することができる

```js
new Vue({
    el: '#app',
    data: {
	message: 'Vue.js'
    }
})
```

## 算出プロパティ
`computed`は関数によって算出されたデータ。
`data`と同じような感覚で使うことができる。

```js
new Vue({
    el: '#app',
    computed: {
    computedMessage: function() {
      //何か処理をした結果をデータとして返す
      return this.message + '!'
    }
  }
})
```

## ライフサイクルハック
`ライフサイクル`は、一定のサイクルを表す。
`フック`は、あらかじめ登録した処理を、Vueインスタンスの特定のタイミングで自動的に呼び出しを行う。
### 使用可能なライフサイクル
`created`はライフサイクルハックの一つ
`created`は、このメソッドを登録したVueのインスタンスが作成され、データの監視などリアクティブまわりの**初期化**が終わったあとに呼び出しが行われる

```js
new Vue({
    el: '#app',
    created: function() {
    //このインスタンスの作成&初期化が終わってらすぐ
        console.log('created')
    }
})
```
### 使用できるライフサイクルハックメソッド
| メソッド | タイミング |
|---|---|
|beforeCreate| インスタンスが作成され、リアクティブの初期化がされる前 |
| created | インスタンスが作成され、リアクティブの初期化がされた後 |
| beforeMount | インスタンスがマウントされる前 |
| mounted | インスタンスがマウントされた後 |
| beforeUpdate | データが変更され、DOMに適応される前 |
| updated | データが変更され、DOMに適応された後 |
| beforeDestroy | Vueインスタンスが破壊される前 |
| destroyed | Vueインスタンスが破壊された後 |
| errorCaptured | 任意の子孫コンポーネントからエラーが補足されたとき |

## アプリケーションで使用するメソッド
`methods`はアプリケーション内で使用するメソッド。
コードを管理しやすくするために処理を分けたり、イベントパンドラなど細かな実装を担当する。

```js
new Vue({
  el: '#app',
  methods: {
    myMethod: function() {
       //処理
    }
  }
})
```

# vueのライフサイクルダイアグラム

![lifecycle.png](https://qiita-image-store.s3.amazonaws.com/0/214546/d881c574-e919-39d0-120c-14c282b514b5.png)
Rust 勉強メモ: futures (LocalPoolとThreadPool)

Future を実装するには　Item, Error と poll 関数があればよい

```rust
impl Future for Something {
    type Item = ();
    type Error = Never;

    fn poll(&mut self, _cx: &mut Context) -> Poll<Self::Item, Self::Error> {
        //
    }
}
```

LocalPool は 同じスレッド内で非同期処理するためのもの (task とも呼ばれる)

```rust
let mut pool = LocalPool::new();
```

LocalExecutor は Pool 単位でタスク実行時に内部で呼ばれるもの

```rust
let mut exec = pool.executor();
```

lazy で遅延処理用の関数（FnOnce)をFutureとしてラップし、

```rust
let f = lazy(move |_| -> FutureResult<Something, Never> {
    //
});
```

それを pool の run_until 関数に に executer と一緒に呼び出すと非同期処理をはじめさせることができる

```rust
let res = pool.run_until(f, &mut exec)
```

run_until は複数定義できたりもしますので、DB処理などをバックグラウンドで処理させることなどにも利用できます。

exec.spawn_local は spawn のスレッド内版 (Sendを実装されていない）

```rust

exec.spawn_local(lazy(move |_| {
    Ok(())
})).unwrap();
```

Poolから複数のexecutorを生成して、spawn_local内にspawn_localすることもできる。(nested)
spawn まわりは、所有権は渡さないといけないので move する必要がある。

```rust
let mut exec = pool.executor();
let mut exec_2 = pool.executor();

let _ = exec.spawn_local(lazy(move |_| {
    exec_2.spawn_local(lazy(move |_| {
　　　　　　　　　　　　　　　　　　　　// 
          Ok(())
    })).unwrap();
    Ok(())
}));
```

あと,中で共通のデータを触りたい場合は、Rc (Reference Count)でラップするとよい、同じスレッドなので、Arc (Atomic Rc)は必要ない。

```rust
let cnt = Rc::new(Cell::new(something));
let cnt_2 = cnt.clone();
```

LocalPool を使わずに　ThreadPool を使って Channel でやり取りする方法もある。

仮に　pool 2つ使うとして、ThreadPoolをこんな感じで作れます。

```rust
let mut cpu_pool = ThreadPoolBuilder::new()
        .pool_size(2) 
        .create().unwrap();
```

送信者２つ用のChannelを作り

```rust
let (tx, rx) = mpsc::sync_channel(2);
let tx_2 = tx.clone();
```

spawn で送ったり、

```rust
let _ = cpu_pool.spawn(Box::new(lazy(move |_| {
    tx.send(1).unwrap();
    Ok(())
})));
```

遅延関数内で送ったりすることができます

```rust
let f = lazy(move |_| {
    tx_2.send(1).unwrap();
    //
});

cpu_pool.run(f);
```

受信側の rx で普通に読めるようになります。

```rust
rx.into_iter().count()
```

以上、
at coder beginner 029

B
英小文字からなる 12 個の文字列 S1, S2, ..., S12 が入力されます。
これらの文字列のうち、文字 r が含まれるものの個数を数えてください。

```
#include<iostream>
#include<string>
using namespace std;
int main() {
	string S;
	int count = 0;
	for (int i = 0; i < 12; ++i) {
		cin >> S;
		for (int j = 0; j < S.size(); ++j) {
			if (S[j] == 'r')｛
				count++;
			break;
　　　　　　　　　　　｝
		}
	}
	
	cout << count << endl;
	return 0;
}
```
今回も楽目だったな。ちゃんとカッコは意識して書いたほうがよい。


C

```
#include <iostream>
#include<vector>
#include<algorithm>
#include<string>
using namespace std;
using ll = long long;
const int INF = 1e9;
void f(int rest, string s) {
	if (rest == 0) {
		cout << s << endl;
	}
	else {
		for (char c = 'a'; c <= 'c'; c++) {
			f(rest - 1, s + c);
		}
	}
}
int main() {
	int N;
	cin >> N;
	f(N, "");
	return 0;
}
```
再帰。
シェルスクリプトでevalに助けられた話

一応、個人でプロダクトを出してみようとちょろちょろやっているのですが
シェルスクリプトでちょっとしたtoolを作っていた時にevalに助けられた話です。

※そもそもevalってなんだろという点に関しては多くの方が書いていたり、ググればすぐ出てくるので割愛

# 1.連想配列的な使い方
bashでも4系であれば連想配列が使えるようなのですが、残念ながら事情があり3系の状態で
連想配列を使いたくなる状況が出てきました。
結論的には連想配列とは違うのですが、こんな感じで出来たので、まぁ良しとします。

```associative_array.sh
#!/bin/bash
ruby_path="/Users/overq/ruby"
python_path="/Users/overq/python"

lang=$1
eval echo \$${lang}_path
```

```
./associative_array.sh ruby
/Users/overq/ruby
```


# 2.パイプが入ったコマンドの実行
普通にこんな感じでは実行できると思いますが

```pipe1.sh
num=`ls -l | wc -l`
```

こんな感じだと

```pipe2.sh
command="ls -l | wc -l"
num=`$command`
```

```
ls: -l: No such file or directory
ls: wc: No such file or directory
ls: |: No such file or directory
```

となってしまい、lsのオプション扱いになってしまいます。
evalを使うと・・・いけました！
(結果を変数に入れて後の処理に使いたかったのでfunctionに切り出した形を取っています)

```pipe3.sh
function file_num() {
  command="ls -l | wc -l"
  eval $command
}

num=`file_num`
echo $num
```

結構適当な例になってしまったのと、このあたり全く詳しくないのでツッコミどころはあると思います。
もっといい方法とかご意見いただけるとありがたいです！
h2oのログをalpで解析する [ISUCON8]

先日ISUCON8に出場して、ログ解析ツールの [alp](https://tkuchiki.hatenablog.com/entry/2015/09/25/130900) を使う想定で準備をしていたのですが、h2oのログをそのままalpに食わせられないのでログフォーマットをカスタマイズしたときのメモです。

<blockquote class="twitter-tweet" data-partner="tweetdeck"><p lang="ja" dir="ltr">講評ブログにも書くつもりだけど、h2oだから慣れてなくて手間取ったまでは分かるけど、h2oは十分に高速だしDNS RRでLBできるしアクセスログだってカスタムできてalpとかに食わせられるので、慣れてるものに変えるという目的以外ではh2oを使い続けて何も損はなかったはずですよ <a href="https://twitter.com/hashtag/isucon?src=hash&amp;ref_src=twsrc%5Etfw">#isucon</a></p>&mdash; かるぱねるら@9/30千葉LOOM (@karupanerura) <a href="https://twitter.com/karupanerura/status/1041901428921356288?ref_src=twsrc%5Etfw">September 18, 2018</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

nginxでは [alpのインストールからNginxのアクセスログ解析までの手順【ISUCON】
](https://nishinatoshiharu.com/install-alp-to-nginx/) の通りltsv形式かつカスタムされた形式でログを吐けばよかったので、alpでもこの形式で吐いてくれるように `/etc/h2o/h2o.conf` を書き換えます。こんな感じで↓

```
access-log:
  path: /var/log/h2o/access.log
  format: "time:%t\thost:%h\tua:\"%{User-agent}i\"\tstatus:%s\treq:%r\turi:%U\treqtime:%{duration}x\tsize:%b\tmethod:%m\t"
```

これで吐かれたログを 
`cat /var/log/h2o/access.log | alp --aggregates="/api/users/.*","/api/events/.*","/admin/api/reports/events/.*"`
 てな感じで解析できます。
以下はISUCON8当日初期状態の解析結果です。
![____________________________2018-09-15_12_25_32.png](https://qiita-image-store.s3.amazonaws.com/0/47101/0b3c9244-d6bc-dbb3-5951-d3ecae6f8762.png)
【Game a Week】７週間目

# Game A Week
1. 一週間（月曜日から日曜日）に一本ゲームをリリースする。
2. 日曜日（まで）に制作したゲームを何らかの手段で公開する。
3. 制作したゲームはGame A Weekが終わるまで改変しては行けない。

# 前置き
先週の作品：[【Game a Week】６週間目](https://qiita.com/hota1024/items/a349c45f26fd7503d7d1)

# 今回作ったゲーム
今回は[Scratch2.0](https://scratch.mit.edu/)を使って「だるまさんがころんだ」を作ってみました。

# 使った技術
| 名前 | 説明 |
|:-:|:-:|
| [Scratch2.0](https://scratch.mit.edu/)  |  子供向けのプログラミング環境。  |

# ゲームの詳細
名前は「だるまさんがころんだ」。
[こちら](https://scratch.mit.edu/projects/247591326/)から遊べるので是非遊んでみてください。

名の通り「だるまさんがころんだ」をScratchで作ってみました。
<img width="476" alt="スクリーンショット 2018-09-22 18.14.54.png" src="https://qiita-image-store.s3.amazonaws.com/0/154299/2b5e78ef-a853-4979-0551-509a1ad64467.png">
左にいる黄色いキャラクター（名前は「ゴボ」といいます。）をスペースキー連打で進ませます。

右にいるねこが「ころんだ！」と言ったら止まりましょう。

猫に触れると勝ちです。

# 6週間目の感想
最近[CoderDojo静岡](https://coderdojo-shizuoka.org/)のYouth Mentor(若いメンター)をしていて、子どもたちにうけそうなゲームを作りたくてこのゲームをつくりました。

もう一つゲームを作ろうかなーなんて思ってたのですが、Nuxt.jsが楽しすぎるせいでできませんでした。

# 最後に
ここまで読んでいただきありがとうございます。
良ければアドバイスや質問よろしくおねがいします。
obnizに駅すぱあとの駅コードを表示する

Node.js内でWeb APIに接続する勉強も兼ねて。
obnizの画面上に「駅すぱあと」で定義した駅コードを表示させます。

（22671はJR高円寺駅の駅コードです）
![IMG_0849.JPG](https://qiita-image-store.s3.amazonaws.com/0/79577/8840ed94-63b4-29c0-9d5a-725af8733cb2.jpeg)

obnizのセットアップ方法は[こちら](https://obniz.io/doc/quickstart)。
Node.jsの起動方法は[こちら](https://obniz.io/doc/lessons_nodejs)。
駅すぱあとWebサービスのアクセスキーの取得は[こちら](https://ekiworld.net/free_provision/index.php)。ですがすぐに発行されないので、こちらの[入門書](http://amzn.asia/d/6G6uj89)（0円書籍）にサンプル用のキーを用意しているので、そちらを使うのが速いです（笑）


```js
var Obniz = require("obniz");
var rp = require('request-promise');

var obnizeId = "YOUR-OBNIZ-ID";
var ekispertKey = 'YOUR-EKISPERT-ACCESS-KEY';

var stationCode = '';
var obniz = new Obniz(obnizeId);

obniz.onconnect = async function () {

  var options = {
    uri: 'https://api.ekispert.jp/v1/json/station',
    qs: {
      key: ekispertKey,
      name: '高円寺'
    },
    json: true
  };

  var ekispertReq = await rp(options)
  .then(function (body) {
    var points = body.ResultSet.Point;
    if(points) {
      if(points[0]) {
        stationCode = points[0].Station.code;
      } else {
        stationCode = points.Station.code;
      }
    } else {
      console.log('station is null');
    }
  })
  .catch(function (err) {
    console.log("error");
  });

  obniz.display.clear();
  obniz.display.print("Hello " + stationCode);
}
```

obnizとは？：
Node.jsで簡単にセンサ情報を扱えるツール。
https://obniz.io/

駅すぱあとWebサービスとは？：
みなさんご存知「駅すぱあと」の機能をWeb APIで提供したもの。
https://ekiworld.net/service/sier/webservice/index.html
Twilio FunctionsからobnizのRestAPIを呼び出す

:::note alert
2023年5月1日を持ちまして、株式会社KDDIウェブコミュニケーションズのTwilioリセール事業が終了したため、本記事に記載されている内容は正確ではないことを予めご了承ください。
:::

# はじめに

Twilio Functionsから、obnizのRest APIを呼び出す方法を試したので、記録のために記事にしておきます。

## obnizのセットアップ

obnizのセットアップ方法については、[こちらの記事](https://obniz.io/doc/quickstart)をご参照ください。

## Twilio側の準備

- 管理コンソールにログインします。
- スライドメニューの**RUNTIME**から、**Functions**を選択します。
- さらに、**Configure**を選択します。
- **Dependencies**の赤い＋アイコンを押して、以下のモジュールを追加します。

NAME|VERSION
:--|:--
obniz|1.10.0

**（重要）**
obnizのnpm最新バージョンは1.11.2ですが、1.11.xを選択すると、Twilio側のデプロイが失敗してしまいますので、必ず1.10.0を選択してください。

<img width="844" alt="スクリーンショット 2018-09-22 18.00.00.png" src="https://qiita-image-store.s3.amazonaws.com/0/86046/2b8ff930-44bf-762a-3a6e-99e7f4c2b372.png">


- **SAVE**ボタンを押して、設定を保存します。
- 左側のメニューから、**Functions**の**Manage**を選択します。
- Runtimeメニューの中から、**Manage**を選択します。
- 赤いプラスアイコンをクリックするか、「Create a new function」を選択して、新しいFunctionを作成します。
- **New Function**ダイアログでは、**Blank**を選択し、**Create**ボタンを押します。
- **FUNCTION NAME**欄に「restapi」、**PATH**欄に「/restapi」と入力します。
- **CODE**欄に予め書かれているコードをすべて削除し、以下のコードを貼り付けます。

```lang:Function
const Obniz = require('obniz');

exports.handler = function(context, event, callback) {
    const obnizId = 'XXXX-XXXX';
    const obniz = new Obniz(obnizId);
    obniz.onconnect = async () => {
        obniz.display.clear();
        obniz.display.print('Hello World.');
        await obniz.wait(500);
        callback(null, 'OK');
    };
    // callback(null, 'OK');
};
```

- 4行目は、ご自分のobnizのIDに置き換えます。
- **SAVE**ボタンを押して、コードを保存します。
- しばらくして、デプロイ完了の緑色のバナーが表示されたら、作業はすべて終了です。

**（重要）**
エラーマークが表示されてしまいますが、コードは実行できるので気にせずSAVEしちゃいましょうｗ

### テストしてみる

- 今保存したFunctionの**PATH**欄の右側にあるコピーアイコンを押して、URLをコピーします。
- ブラウザで別のタブを開き、コピーしたURLを開きます。
obniz上に「Hello World.」と表示されれば成功です。

![IMG_7585.JPG](https://qiita-image-store.s3.amazonaws.com/0/86046/91ce7d32-ce79-99f1-f91c-c268b90e6dfe.jpeg)
at coder beginner 028

B
文字列 S が与えられます。
この文字列は A, B, C, D, E, F の 6 種類の文字から構成されている事が分かっています。
6 種類の文字それぞれについて、S のなかに何回出てくるかを数えてください。

```
#include<iostream>
#include<string>
using namespace std;
int main() {
	string S;
	cin >> S;
	int a = 0, b = 0, c = 0, d = 0, e = 0, f = 0;
	for (int i = 0; i < S.size(); ++i) {
		if (S[i] == 'A')
			a++;
		else if (S[i] == 'B')
			b++;
		else if (S[i] == 'C')
			c++;
		else if (S[i] == 'D')
			d++;
		else if (S[i] == 'E')
			e++;
		else if (S[i] == 'F')
			f++;
	}
	cout << a << " " << b << " " << c << " " << d << " " << e << " " << f << endl;
	return 0;
}
```
なんか久しぶりにちょろかったな（所詮beginnerのb問題だけど

C

```
#include <iostream>
#include<vector>
#include<algorithm>
using namespace std;
using ll = long long;
const int INF = 1e9;
int main() {
	vector<int>A(5);
	vector<int>sum;
	for (int i = 0; i < 5; ++i) {
		cin >> A.at(i);
	}
	for (int i = 0; i < 3; ++i) {
		for (int j = i + 1; j < 4; ++j) {
			for (int k = j + 1; k < 5; ++k) {
				int s = A.at(i) + A.at(j) + A.at(k);
				sum.push_back(s);
			}
		}
	}
	sort(sum.begin(), sum.end());
	reverse(sum.begin(), sum.end());
	cout << sum.at(2) << endl;
	return 0;
}
```
Unityでオブジェクトプール実装＋拡張

Unityのオブジェクトプールの実装と拡張についてメモを残しときます。
現在開発中のゲーム「ProjectActress（仮）」にて実装済みです。

# オブジェクトプールってなんぞ

参考資料：
http://marudice.hatenablog.jp/entry/2016/11/25/013344

ゲーム開発とかで組んだりするタスクシステムをもうちょっと限定的にしたイメージかな？
（タスクシステムも方言がありすぎるわけだけど）

この機能によって、使用オブジェクトについて動作速度を気にすることなく、動的に追加、および動的に削除（に見える）できるようになります。

# オブジェクトプールの拡張

ただ上記の実装だと問題がありまして、
「1種類のキャラしかオブジェクトプール実装できない」
ということになります。
よって、オブジェクトプールを並列管理できるクラスを作成します。
（一部しか書かないけどご了承ください）
static宣言が多いけどご了承ください。
あと16って数値についてはあまり意味ありません。
急ぎ実装したので数値を直に入力してます。

# オブジェクトプール（並列版）

```C#:EnemyPool.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public abstract class EnemyPool<T> : MonoBehaviour {
    private static GameObject[] mOriginal = new GameObject[16];
    private static Stack<T>[] mObjPool = new Stack<T>[16];
	private static Stack<T> objPool_seed;
	private static bool[] isInstanced = new bool[16];

    public static void SetOriginal(GameObject origin, int number ) {
		//オブジェクトプールの数は制限しておく。
		if( number >= 16){
			return ;
		}

		//オブジェクトプールのスタックを動的生成
			objPool_seed = new Stack<T>();
			mObjPool[number] = objPool_seed;

		//オブジェクトをセット。
        mOriginal[number] = origin;
    }
    public static T Create(int number)
    {
        T obj;

        if (mObjPool[number].Count > 0)
        {
            obj = Pop(number);
        }
        else
        {
            var go = Instantiate<GameObject>(mOriginal[number]);
            obj = go.GetComponent<T>();
        }
        (obj as EnemyPool<T>).Init();
        return obj;
    }

    /*
        Stackからポップする（取り出す）
        LIFOの形になる。
     */
    private static T Pop(int number)
    {
        var ret = mObjPool[number].Pop();
        return ret;
    }

    /*
        データをプールする。

        Staticでデータを残して再度呼び出しの形で利用する。
        （HP等の初期化はゲームごとに行う事）
     */
    public static void Pool(T obj, int number)
    {
        (obj as EnemyPool<T>).Sleep();
        mObjPool[number].Push(obj);
    }
    
    /*
        キューをクリアする。

        Staticなデータなので、次のシーン呼び出しor再度のシーン呼び出しにて
        残っているデータを参照しようとしてエラーを吐くらしいので、
        シーン初期化の際は必ず呼び出すこと。
     */
    public static void Clear(int number)
    {
        mObjPool[number].Clear();
    }

    public abstract void Init();
    public abstract void Sleep();
}
```
プーリングするGameObjectはInspector上で指定可能なので、ステージごとに使用するGameObjectを指定して使ってます。

# オブジェクトプール使うときの注意点

ロックオンシステムみたいに「対象オブジェクトを継続して目標に捉える」ケースがある場合、オブジェクトを再利用すると、新しく出てきたオブジェクトが目標として捉えられるケースが存在します。
これはオブジェクト使い回しの弊害ってヤツですね。
なのでその場合はロックオン解除を別途実装する形にしてください。
お手軽GCP Jupyter NoteBook を Docker で試す。

# はじめに
ここ数年でPythonを中心とした。Deeplearning, Statisticsを試すために職場の開発環境が汚れに汚れまくって嫌気がさし環境を再構築する前にお試し環境をGCP&Dockerで確認したお話です。

## 前提条件
1. GCPを利用したことがある。
2. sshポートフォワードを理解している。
3. 最低限のDockerコマンドが使える。

## 1. GCPでComput Engine インスタンスの作成
- [x]  コンテナ　→ 「この VM インスタンスにコンテナ イメージをデプロイします。」
- コンテナイメージ　→ jupyterhub/singleuser  を記入

*※ 詳しくは「jupyterhub/singleuser」をdockerhubで検索する。*
## 2. SSHポートフォワード
```none:command
$ ssh -L 8889:localhost:8888 <SERVER NAME or IPADDRESS>
```
*GCP DockerのJupyterはTCP:8888で起動しているのでそのPortへフォワーディングします。*
## 3. DockerとJupyter-notebookの状態確認
```none:command
$ docker ps -a
```
### 表示されたIDでlogを確認する。
```none:command
$ docker logs 6312XXXXXX
```
### logの中にJupyterのTokenつきURLをコピー
```none:result
http://(jupyternotebook or 127.0.0.1):8888/?token=eef40685abe8048368d7d0dee25da7c19XXXXXXXXX
```
### SSHのアクセス元PCのブラウザでJupyterにアクセス。
```none:Browser
http://localhost:8889/?token=eef40685abe8048368d7d0dee25da7c19XXXXXXXXX
```
*接続元Port:8889にアクセスすることでGCPのLocal Port:8888に接続されるのがミソです。*
![スクリーンショット 2018-09-22 16.36.02.png](https://qiita-image-store.s3.amazonaws.com/0/57467/362c7d7c-7972-c66d-36a3-63f25318fb27.png)

### 結論
- だいぶ省略していますが4分間ぐらいでJupyterの環境が手に入ります。開発環境を汚すことを考えればかなり相当な効率化(時短)ができます。
- 本来であればPVCからファイヤーフォールの設定やら何やらゴニョゴニョありますがSSHポートフォワードで気にする必要ありません。SSHの制限は最低限やりましょうね。