OmniAICreator/Qiita-1.07M huggingface dataset:
jsdoでdeviceorientation その4

#概要

jsdoでdeviceorientationやってみた。
driving car作って見た。

#写真

![](http://jsdo-static-contents.s3.amazonaws.com/images/capture/q/c/d/qcdi.jpg?t=1539080336)

#環境

nexus 7

#サンプルコード


```
var lastOrientation;
function onDeviceOrientationChange(event) {
    lastOrientation.gamma = event.gamma;
    lastOrientation.beta = event.beta;
}
function deviceOrientationTest(event) {
    window.removeEventListener('deviceorientation', deviceOrientationTest);
    if (event.beta != null && event.gamma != null) 
    {
        window.addEventListener('deviceorientation', onDeviceOrientationChange, false);
    }
}
lastOrientation = {}; 
window.addEventListener('deviceorientation', deviceOrientationTest, false);
var canvas = document.getElementById("canvas"); 
var ctx = canvas.getContext("2d");
var carWidth = [.25, .25];
var OFFSCREEN = document.createElement("canvas"); 
var OFFSCREEN_CTX = OFFSCREEN.getContext("2d");
var FOV = Math.PI / 3; 
var DEPTH = 2 * Math.tan(FOV * 0.5);
var EYE = canvas.width / DEPTH;
var tex0 = new Image();
tex0.src = "/assets/a/h/Y/V/ahYVV.png";
OFFSCREEN.height = canvas.height;
OFFSCREEN.width = Math.ceil(canvas.height * DEPTH);
var player = {
    x: 50, 
    y: 18, 
    z: 70, 
    a: Math.PI * 2, 
    vx: 0, 
    vy: 0, 
    vz: 0, 
    va: 0
};
function draw() {
    var horizon = Math.floor(canvas.height * 0.01);
    var scale = EYE * player.y;
    var yMin = Math.ceil(scale / OFFSCREEN.height);
    var yMax = canvas.height - horizon;
    var near = scale / yMax - 1;
    OFFSCREEN_CTX.clearRect(0, 0, OFFSCREEN.width, OFFSCREEN.height);
    OFFSCREEN_CTX.save();
    OFFSCREEN_CTX.translate(OFFSCREEN.width * 0.5, OFFSCREEN.height + near)
    OFFSCREEN_CTX.rotate(Math.PI * 1.5 - player.a);
    OFFSCREEN_CTX.drawImage(tex0, -player.x, -player.z);
    OFFSCREEN_CTX.restore();
    for (var y = yMin; y < yMax; y += height)
    {
        var top = scale / y,
            width = top * DEPTH;
        var height = Math.ceil(scale / Math.floor(top) - y);
        var bottom = scale / (y + height);
        ctx.drawImage(OFFSCREEN, (OFFSCREEN.width - width) * 0.5, OFFSCREEN.height + near - top, width, top - bottom, 0, horizon + y, canvas.width, height);
    }
}
function update() {
    var beta = lastOrientation.beta;
    var gamma = lastOrientation.gamma;
    if (beta > 20)
    {
        player.vx = 0;
        player.vz = 0;
        player.va = Math.sin(0.2);

    }
    else if (beta < -20) 
    {
        player.vx = 0;
        player.vz = 0;
        player.va = Math.sin(-0.2); 
    }
    else 
    {
        player.vx = 0;
        player.vz = 0;
        player.va = 0;   
    }
    if (gamma < -40)
    {
        player.vx = Math.cos(player.a) * 9;
        player.vz = Math.sin(player.a) * 9;
    }
    player.x += player.vx;
    player.z += player.vz;
    player.a += player.va;
}
setInterval(function() {
    update();
    draw();
}, 500);



```

#成果物
http://jsdo.it/ohisama1/qcdi


以上。
ARWorldTrackingConfigurationで画像認識を使うと固まる問題

# 問題

ARWorldTrackingConfiguration以下のように定義して、viewWillAppearで呼んでいたのですが、

```swift
private let configuration: ARWorldTrackingConfiguration = {
    let configuration = ARWorldTrackingConfiguration()
    guard let referenceImages = ARReferenceImage
        .referenceImages(inGroupNamed: "AR Resources", bundle: nil) else {
            fatalError("Missing expected asset catalog resources.")
    }
    configuration.detectionImages = referenceImages
    return configuration
}()

override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(animated)
    
    sceneView.session.run(configulation)
}
```

Xcode10でDeploymentTargetをiOS11.3やiOS11にして、iOS12でビルドすると、カメラがすぐに固まってしまいます。

# 再現方法
- Xcode 10.0
- DeploymentTarget iOS11.3
- iOS12でビルド(ちなみにiOS11.4の端末でやると再現しない)

# 解決策

**ちなみにDeploymentTargetをiOS12にすると治ります。** 

いやいやiOS12以下を切るのとかまだ現実的じゃない。。w

# 解決策２（追記）

**「Xcode 10.1」でビルドしたら治るかも**

https://developer.apple.com/documentation/xcode_release_notes/xcode_10_1_release_notes

# 解決策3（追記）

僕はこれで治りました。

ARImageResourcesに登録している画像がpngだったらjpgに変換してみてください。
https://forums.developer.apple.com/thread/104361

#　関連

https://stackoverflow.com/questions/50917583/arkit-image-detection-freezing-camera
TypeScriptで書いたCloud FunctionsをCloudBuildを使ってDeployする

## これを読んで出来るようになること

TypeScriptで書いたCloud Functionを、Code Buildを使ってdeployできるようになる。

## 前提と事前準備
### 前提
- CloudFunctionsのコードはwebpackを使ってまとめている
- Deployは serverless コマンドではなく、gcloudコマンドで行っている

### 事前準備 

- [過去資料 CloudBuildの設定をするところまで](https://selmertsx.hatenablog.com/entry/2018/10/05/GCP%E3%81%AECloud_Build%E3%81%A7CloudFunctions%E3%82%92%E3%83%87%E3%83%97%E3%83%AD%E3%82%A4%E3%81%99%E3%82%8B)

テスト用リポジトリ: https://github.com/selmertsx/cloud_source_repository_test

## 設定
### ディレクトリ構造

```
cloud_source_repository_test git:(master) tree -I node_modules
├── README.md
├── cloudbuild.yaml
├── package-lock.json
├── package.json
├── src
│   └── index.ts
├── tsconfig.json
└── webpack.config.js
```

### TypeScriptのサンプルコード

webpackを使って、コードが正しくimport出来ていることを確認するために `decimal.js`をimportした。

```typescript
import { Decimal } from "decimal.js";

function subscribe(req: any, res: any){
  const x = new Decimal('0xff.f')
  return res.send(`Hello World! ${x}`);
}

export { subscribe }
```

### cloudbuild.yamlの設定

```yaml
steps:
  - name: node:8
    entrypoint: npm
    args:
    - install

  - name: node:8
    entrypoint: npm
    args:
    - run
    - build

  - name: 'gcr.io/cloud-builders/gcloud'
    args:
    - functions
    - deploy
    - subscribe
    - --stage-bucket=xxx
    - --trigger-http
```

buildコマンドの中では `webpack --mode production`が実行されている。


### tsconfig.jsonの設定

```tsconfig.json
{
  "compilerOptions": {
    "target": "es2017",
    "module": "commonjs",
    "strict": true,
    "preserveConstEnums": true,
    "strictNullChecks": true,
    "sourceMap": true,
    "outDir": "./", # <= 重要
    "moduleResolution": "node",
    "esModuleInterop": true
  },
  "include": [
    "src/**/*.ts"
  ],
  "exclude": [
    "node_modules"
  ]
}
```

### Webpackの設定


```webpack.config.js
module.exports = {
  entry: "./src/index.ts",
  target: 'node',
  output: {
    path: __dirname,
    filename: 'index.js',
    libraryTarget: 'this'
  },
  module: {
    rules: [
      {
        test: /\.tsx?$/,
        use: 'ts-loader'
      }
    ]
  },
  resolve: {
    extensions: [ '.js', '.json' ]
  }
}
```

### IAM Roleの設定

![スクリーンショット 2018-10-09 13.56.09.png](https://qiita-image-store.s3.amazonaws.com/0/23606/ef5d589d-d94e-a681-27db-101e6a6c68c3.png)


## 動作確認

```
$ curl https://xxx.cloudfunctions.net/subscribe
Hello World! 255.9375%
```

## 備考
###  webpackを利用する理由

- node_modulesも、Cloud Functionにuploadすればwebpackを利用する必要は無い
- CodeBuild内でBuildとdeployをするため、Development環境用のpackageもinstallは必須
- Development環境用のpackageもgcloud コマンドでdeployするとファイルサイズが大きくなる

## 残タスク

- IAMのカスタムロールを、terraformで作りたい
- debug 用のsourceMapの設定がしたい
    - https://firebase.google.com/docs/functions/typescript?hl=ja
- webpackのexternalsの設定を勉強
    - https://webpack.js.org/configuration/externals/
【Swift 4】回転を伴う UIImageView で ContentMode が反映されない

# はじめに
UIImageView の `ContentMode` が反映されない問題は ScrollView の上に UIImageView を置いた場合などに遭遇しやすいです。しかし、今回は UIImageView を `Transform` で回転させた場合に同様の現象が発生したときの解決方法をご紹介します。

# ContentMode が反映されない一例

```swift
let cardView = UIImageView(image: #imageLiteral(resourceName: "sample_image"))
cardView.transform = CGAffineTransform(rotationAngle: 90 * CGFloat.pi / 180)
cardView.frame = CGRect(x: 0, y: 0, width: width, height: height)
cardView.center = self.view.center
cardView.contentMode = .scaleAspectFit
self.view.addSubview(cardView)
```

# 解決方法

Transform する前に ContentMode を指定しておくことで、回転後も ContentMode が反映された状態で表示されるようになります。

```diff
    let cardView = UIImageView(image: #imageLiteral(resourceName: "sample_image"))
+   cardView.contentMode = .scaleAspectFit
    cardView.transform = CGAffineTransform(rotationAngle: 90 * CGFloat.pi / 180)
    cardView.frame = CGRect(x: 0, y: 0, width: width, height: height)
    cardView.center = self.view.center
-   cardView.contentMode = .scaleAspectFit
    self.view.addSubview(cardView)
```

# おわりに
間違っている箇所などありましたら、ご指摘いただけると嬉しいです。
見ていただきありがとうございます :bow:
C言語でシェルソート

# シェルソートとは

[挿入ソート](https://qiita.com/omu58n/private/13d1cbbb7a50dae9d3fc)の改良版。挿入ソートを何度か繰り返すことで高速化を実現

##### 手順：
1. 適当な間隔$h$を決め、この間隔だけ離れた要素同士だけで挿入ソートを行う。
2. 間隔$h$を少し狭めて、同様にその間隔だけ離れた要素同士だけで挿入ソートを行う。
3. これを繰り返し、最後に$h=1$で挿入ソートを行う。

##### なんで速くなるのか：
- $h=1$の時点で、データ全体がかなり整列済み
- 挿入ソートは、整列済みの部分が多いほど高速になる

##### 間隔hについて：
- 一般的には$h_{n+1}=3h_n+1$を使う。
  - これがいいっていう証明は困難
  - ただし、例えば$h=4,2,1$とすると偶数同士、奇数同士の要素で組を作ってしまうからよくない（ので、$3h+1$を使う）
  - 具体的には$h=1,4,13,40,121,\cdots$ 
- 大体、要素数$/9$を超えないように$h$を選ぶ
  - 要素数が$100$の時に$h=40$にすればいいかというと、そうでもない
  - あまりにも遠く離れた要素同士のソートは効果が薄い 



# サンプルコード

ここでは、int型の配列を、シェルソートを用いて整列する。
下の例では要素数が10個しかないのでただの挿入ソートになってる

```c:shell_sort.c
#include<stdio.h>

/* 値を入れ替える関数 */
void swap (int *x, int *y) {
  int temp;    // 値を一時保存する変数

  temp = *x;
  *x = *y;
  *y = temp;
}

/* シェルソート */
void shell_sort (int array[], int array_size) {
  int i, j, h;

  for (h = 1; h <= array_size/9; h = 3*h + 1);   // 間隔hを決める
  for ( ; h > 0; h /= 3) {   // hを狭めていく
    /* 以下、挿入ソートとほぼ同じ */
    for (i = h; i < array_size; i++) {
      j = i;
      while ((j > h - 1) && (array[j-h] > array[j])) {
        swap(&array[j-h], &array[j]);
        j -= h;
      }
    }
  }
}

int main (void) {
  int array[10] = { 2, 1, 8, 5, 4, 7, 9, 0, 6, 3 };
  int i;

  printf("Before sort: ");
  for (i = 0; i < 10; i++) { printf("%d ", array[i]); }
  printf("\n");

  shell_sort(array, 10);

  printf("After sort: ");
  for (i = 0; i < 10; i++) { printf("%d ", array[i]); }
  printf("\n");

  return 0;
}
```

実行結果

```
Before sort: 2 1 8 5 4 7 9 0 6 3
After sort: 0 1 2 3 4 5 6 7 8 9
```
# 性能

- 挿入ソートでは、最悪$O(n^2)$
- シェルソートの場合、$h$個ずつ飛ばして探すので、比較回数が少なく、一度の移動量が大きい
- $n^{3/2}$以上に比較されることはない
Windows10 に scoop で nvm と yarn をインストールする

いろいろハマったのでメモ。
## これ書いたときのバージョン
- PowerShell: 5.1.17134.165
- scoop: 
- nvm: 1.1.7
- yarn: 1.10.1

## 実際の手順
### PowerShell を管理者権限で実行する
管理者権限じゃないと、後続手順のどこかで失敗しました (どこだか忘れた)

### PowerShell でのスクリプトの実行を一時的に許可する  
デフォルトではスクリプトの実行が許可されてないので、許可します。
この許可は、このシェルでだけ有効です。
(参考: [PowerShellのExecutionPolicyのスコープとかについて詳しく](https://qiita.com/kikuchi/items/59f219eae2a172880ba6) )

```powershell
PS> Set-ExecutionPolicy RemoteSigned -Scope Process
```
### scoop をインストールする

```powershell
PS> iex (new-object net.webclient).downloadstring('https://get.scoop.sh')
```

### scope で nvm と yarn をインストールする
```powershell
PS> scoop install nvm yarn
```
yarn インストール時、「'node' は、内部コマンドまたは外部コマンド、操作可能なプログラムまたはバッチ ファイルとして認識されていません。」というエラーが出ます。
でもどうしていいか分からないので無視しました… (まだ node 入れてないんだから無くて当然じゃない？ って思う。。)

### PowerShell を再起動する
nvm インストール時、「シェルを再起動してね」的なメッセージが出てたので再起動します。
(再起動しないとどう困るのかは試してないので知らない)

### nvm で node をインストールする
これ書いてるときに入れたいバージョンが 8.12.0 なので、それを入れます。

```
PS> nvm install 8.12.0
PS> nvm use 8.12.0
```

### nvm, yarn に Path を通す
インストールしただけだと Path が通らないみたいなので、PowerShell で Path を通します。  (参考: [PowerShellで環境変数を参照、設定する](http://zakiyamatakashi.hatenablog.com/entry/2018/07/09/171632) )

```powershell
PS> $env:Path += ";%USERPROFILE%\scoop\apps\nvm\current\nodejs\nodejs;%USERPROFILE%\scoop\apps\yarn\current\bin"
PS> [Environment]::SetEnvironmentVariable('PATH', $Env:Path, 'User')
```

### ちゃんとインストールできてるか確認します

```powershell
PS> nvm -v
PS> node -v
PS> yarn -v
```
"xcodeが予期しない理由で終了しました。"

#背景
困った。
xcodeのplaygroundで遊んでいたら、突然xcodeが落ちて、どのプロジェクトも開けなくなった。

#エラーメッセージ
xcodeが予期しない理由で終了しました。と言われ、長文のエラーメッセージが表示された。

以下のメッセージにヒントがありそうだが、調べてもよくわからない。

```
Crashed Thread:        0  Dispatch queue: com.apple.main-thread

Exception Type:        EXC_BAD_INSTRUCTION (SIGILL)
Exception Codes:       0x0000000000000001, 0x0000000000000000
Exception Note:        EXC_CORPSE_NOTIFY)
```

#行ったこと①
以下の記事を参考に、
- http://www.iwazer.com/~iwazawa/diary/2017/01/cannot-open-xcode8-xcworkspace.html
- https://dev.classmethod.jp/smartphone/iphone/remove-xcode-derived-data/

```
rm -rf ~/Library/Developer/Xcode/DerivedData/*
```
で、DerivedDataディレクトリの中身を全て削除した。

が、やはりxcodeは開けないまま。

#行ったこと②
playgroundで遊んでいる時に落ちたので、playgroundを削除して見ることに。

```
rm -rf ~/Library/Mobile Documents/com~apple~CloudDocs/Playground/MyPlayground.playground
```

結果は、、、

xcodeが無事開けた！！

#まとめ
理由は分かりませんでしたが、playgroundでコードを実行中にxcodeが落ちた場合は、一度playgroundを削除してみることで再びxcodeが使用できるようになる？
Grafanaにおけるパーミッションについて

Grafana 4.0からパーミッションの機能が追加された。

この機能により、ダッシュボードやフォルダー毎に権限を設定出来るようになった。

ここでは、公式ドキュメントから、Grafanaのパーミッションに関してまとめる。

# Grafanaにおけるパーミッション

Grafanaのユーザーの権限は、それらのもつ下記の条件から決まる。

- Organization Role
- Team memberships
- directly assigned permissions
- Grafana Admin user flag

# Organization Roles
ユーザーは一つ以上のorganizationに属している。ユーザーはorganizationのメンバーシップに応じて、出来ることが異なる。

## Admin Role
Admin Roleはorganization内では何でも出来る。例えば以下のようなこと。

- データソースの追加・編集
- organizationのユーザーやチームの追加・編集
- pluginの設定
- organizationの設定

## Editor Role
Editor Roleは以下のような事が可能である。

- ダッシュボードやアラートルールの作成や修正
  - フォルダーやダッシュボード毎にdisableにすることが出来る
- データソースの編集や新しいユーザーの招待は出来ない

## Viewer Role
Viewer Roleでは以下のような事が可能である。

- いずれのダッシュボードも閲覧できる
  - フォルダーやダッシュボード毎にdisableにすることが出来る
- ダッシュボードやデータソースの編集は出来ない

Grafana serverの設定で`viewers_can_edit`を`True`に設定すると、Viewerでもパネルやクエリの修正が可能となる。ただし、それらの変更は保存されない。

# Grafana Admin
admin flagをユーザーに与えると、`Super Admin`として操作できる。つまり、admin flagがあると`Server Admin`として全てのユーザーとorganizationの管理が可能となる。

# ダッシュボードとフォルダーの権限
ダッシュボードとフォルダーには以下の3つの権限レベルがある。

- Admin: ダッシュボードの作成と編集、権限の編集が行える
- Edit: ダッシュボードの作成と編集が行える
- View: ダッシュボードの閲覧が行える

`Permissions`ページではダッシュボードやフォルダーの権限を変更することが出来る。

デフォルトでは`Editors`と`Viewers`のroleに対してそれぞれ`Edit`と`View`の権限が与えられている。

`Permissions`ページではデフォルトで用意されている`Editors`と`Viewers`への権限の変更や、Users、Teams毎の権限の設定が可能である。
rails sでのエラーの対処法

<h1>rails s叩くとエラーがでる</h1>

```
$ rails s
=> Booting Puma
=> Rails 5.1.6 application starting in development
=> Run `rails server -h` for more startup options
Puma starting in single mode...
* Version 3.12.0 (ruby 2.5.0-p0), codename: Llamas in Pajamas
* Min threads: 5, max threads: 5
* Environment: development
* Listening on tcp://0.0.0.0:3000
Exiting
Traceback (most recent call last):
        34: from bin/rails:3:in `<main>'
        33: from bin/rails:3:in `load'
        32: from /Users/iharamoeka/workspace/blog/blog/bin/spring:15:in `<top (required)>'

.
.
.

/Users/iharamoeka/.rbenv/versions/2.5.0/lib/ruby/gems/2.5.0/gems/puma-3.12.0/lib/puma/binder.rb:272:in `initi
alize': Address already in use - bind(2) for "0.0.0.0" port 3000 (Errno::EADDRINUSE)
```

<h1>原因</h1>
ローカルサーバーを起動したままターミナルを消しちゃったことが原因らしい。

<h1>解決方法</h1>

```
lsof -i :3000
```
上記コマンドをうって出てくるものの中で、PID接続しているもののIDを見つける。

```
kill -QUIT ここにIDをコピペ
```

これで解決っ☆
CLI上で汚いSQLクエリを一撃整形して読みやすくする

# 準備

## 要node.js環境

環境構築方法は色々あるので、お好みの方法で導入してください。
以下はnodebrewを使う例

```shell:Linux
curl -L git.io/nodebrew | perl - setup
```

```shell:Mac
brew install nodebrew
```

```shell:共通
echo 'export PATH=$HOME/.nodebrew/current/bin:$PATH' >> ~/.bashrc
source ~/.bashrc
nodebrew install latest
nodebrew use latest
```

## SQLフォーマットツールを導入

[Poor Man's T-SQL Formatter - node command-line formatter](https://www.npmjs.com/package/poor-mans-t-sql-formatter-cli)

```shell:導入
npm install --global poor-mans-t-sql-formatter-cli
```

```shell:確認
$ which sqlformat
~/.nodebrew/current/bin/sqlformat
```

これで準備OK

# 整形してみる

整形したいSQL文字列を標準入力に流し込めばOK

```shell
sqlformat < ugly.sql
```

整形ルールはオプションで調整可。詳細は以下を参照してください。
[Poor Man's T-SQL Formatter - node command-line formatter](https://www.npmjs.com/package/poor-mans-t-sql-formatter-cli)
Parallels for Mac で仮想シリアルポートを Mac のコンソールとつなぐ

# はじめに
Parallels for Mac の仮想シリアルポートと、Macのコンソールでデータをやりとりしたかったのですが、検索してもズバリな記事がなかったので、備忘録としてやり方をメモしておきます。

## 仮想シリアルポートを作成
まず、Parallels for Mac の構成画面で シリアルポートを作成します。
「ソース...」から「新しいソケット...」を選んで、ソケット名を与えて「サーバー」を選択。

![スクリーンショット 2018-10-09 18.30.41.png](https://qiita-image-store.s3.amazonaws.com/0/43781/3c76bf7a-a1aa-0542-b2b7-0d64e8c95ee2.png)

ここでは win10vm というソケット名にしました。

## ソケットを特定
Parallels で OS を起動します。
Mac 側のコンソールで `lsof -U` を実行して UNIXドメインソケットの一覧をみて、ソケットを特定します。

```shell
$ lsof -U | grep win10vm | awk '{ print $8 }'
/var/folders/cz/(中略)/win10vm
```

## socat でソケットに繋ぐ
Mac 側のコンソールで、先程特定したソケットと標準入出力をつなぎます。`socat` がインストールされていなければ `brew install` してから、

```shell
$ socat - UNIX-CONNECT:/var/folders/cz/(中略)/T/win10vm 
```

あとは、Parallels のゲスト OS 側からシリアルポートにデータを送信すれば、その内容が標準出力に出てきます。逆に、文字をタイプする（標準入力にデータを流し込む）と、ゲスト OS 側のシリアルポートにその内容が出てきます。
gem installができない時にやってみること。

<h1>gem installでエラーが出てしまう時</h1>

bundlerをインストールしようとしたら以下のようなエラーが出た。

```
ERROR:  While executing gem ... (Errno::EACCES)
    Permission denied @ rb_sysopen - /Users/iharamoeka/.rbenv/versions/2.5.0/lib/ruby/gem
s/2.5.0/gems/bundler-1.16.6/CHANGELOG.md
```

調べてみると、
「/Users/ユーザ名/.rbenv/versions」配下にあるものは本来ユーザーアカウントの権限のものだが、何らかの時にsudoをつけてgem installを行うことでファイルへ書き込みする権限を失ってしまうことがある
というのが原因らしい。
参考サイト：　https://qiita.com/nachiguro1003/items/4b564b92eca3ba35744a

sudo chown -R ユーザ名:staff /Users/ユーザ名/.rbenv

を実行したらインストールできた
【初心者向け】初めての機械学習入門

# 初めての機械学習
初めて機械学習を行う方向け、初めての機械学習特集です。

今回は機械学習とはの概要と開発環境について紹介していきます。

## 機械学習とは
データから知識を引きだし活用すること。
大きく教師あり学習と教師なし学習の２種類ある。

## 教師あり学習
ユーザーが入力データと望ましい出力のペア群をアルコリズムに与える。このペアのデータを「教師」としてアルコリズムは出力を生成するからである。詳しくは次回紹介。


## 教師なし学習
ユーザーが入力データのみをアルコリズムに与える。よって出力結果はどういったものになるか、わからない。詳しくは第３回で。

# 開発環境
## Visual Studio Code
マイクロソフトが開発しているソースコードエディタ。
Windows、Mac OS、Linux上でも使え、マークダウン エディタとしても使える優れもの。
多言語対応、拡張機能もあり、Pythonのデバックを可能にできる。
ダウンロード：https://code.visualstudio.com 

## Python
Pythonは多くのデータサイエンスアプリケーションの共通語となっている。
今回Pythonを用いていく。
ダウンロード：https://www.python.org/downloads/

## Pythonの便利ツール
何もPythonパッケージをインストールしていない方はこちら。
今後紹介していくPythonで頻繁に使うライブラリ、Numpy、Scipy、matplotlib、IPython、Jupyter Notebook、scikit-learnが含まれている。


Anaconda:https://store.continuum.io/cshop/anaconda


### ・scikit-learn


科学技術計算向けPythonライブラリ





###  ・Jupyter Notebook

ブラウザ上でコードを実行するためのインタラクティブな環境

テキスト、画像の取り込みも簡単

コード例：https://github.om/amueller/introduction_to_ml_with_python


###  ・Numpy
Pythonで計算する際の基本的ツール。
scikit-learnではNumpyの配列で入力を受け取るため、データはNampy配列に変換する必要がある

###  ・Scipy
Pythonで使用する関数を集めたもの。特に疎行列を表現するscipy.sparseが重要。
Scipy Lecture Note:http://www.scipy-lectures.org/


###  ・matplotlib
Pythonのグラフ描画ライブラリ。データの可視化を実現する関数群を提供。

###  ・Pandas
データを変換、解析を行うライブラリ。エクセルのスプレッドシートに似ている。Numpyと異なり列ごとに異なる型であっても良い。また様々なファイルやデータベースからデータを取り込むことができる。

###  ・mglearn
読みやすく作成するために絵を生成したり、データをロードしたりできる。
コード：https://github.om/amueller/introdution_to_ml_with_python



これで基本の開発環境が整いました。
ananonda、またJupyter Notebookの使い方はこちらのサイトがわかりやすかったです。
「データ分析デ欠かせない！Jupyter Notebookの使い方【初心者向け】」
https://techacademy.jp/magazine/17430

次回は教師あり学習を深堀りしていきます。

### 参考文献
・Pythonではじめる機械学習ーscikit-learnで学ぶ特徴量エンジニアリングと機械学習の基礎
（著者　Andreas C.Muller、Sarah Guido  発行所　株式会社オライリー・ジャパン）
・Visual Studio Code（https://code.visualstudio.com 2018/10/05参照）
全ユーザでpathをそろえる

#環境
macOS Sierra 10.12.6
MacBook Pro (13-inch, 2017, Tour Thuderbolt 3 Ports)

#動機
ユーザーを切り替えても、管理者で使用しているpathを使用したい。
.bash_profileや.bashrcをそれぞれ作るのはめんどくさい。

#手順
- Apple公式サイトに従い、ルートユーザを有効にしてから、ルートユーザでログインする。
https://support.apple.com/ja-jp/HT204012

- /etc/pathsに必要なpathを加える。

以上です。
etc/pathsファイルは全ユーザにPATHを通せるようです。ただしルートユーザでログインしないとファイルを変更することができません。

#もろもろ
- PATHの確認
`echo $PATH`
【ローカル開発環境】VagrantでCyberduckに接続するまでの流れ

まずは、サーバーを管理するフォルダを複数管理するためのフォルダを作成し、移動する（フォルダ名はなんでもいい）

```
mkdir vagrant
cd vagrant
```
実際にサーバーを管理するフォルダを作成し、移動する（フォルダ名はなんでもいい）
ここら辺の概念を理解するには下記の動画サイトがおすすめ
https://dotinstall.com/lessons/basic_localdev_mac_v2/38505


```
mkdir centos
cd centos
```
vagrantを立ち上げる

```
vagrant up
```
ちゃんと立ち上がっているか確認する

```
vagrant status

```
localhostにログインする

```
vagrant ssh

```
ログアウトする場合


```
exit 

```
その後Cyberduckの新規接続でsftpを指定して、サーバ・ポート・ユーザー・パスワードを入力すれば接続完了。
ユーザー名とパスワードはデフォルトでvagrantになっている。

もし、接続できない場合は、SSH Private keyの入力が必要になるかもしれない。
その場合は vagrant ssh-config のコマンドで　IdentityFile のパスをコピペすれば良い。

ただしこのパスは隠しフォルダ内にあるので、OSの設定によっては隠しフォルダを表示するように設定する必要がある。
Macではファイル選択画面でcommand+shift+gを押すとファイルのパスを入力できるようになるので、そこにIdentityFileのパスをコピペして選択ボタンを押せばOK。

```
vagrant ssh-config

```
RMagickの環境構築

WSL（Debian GNU/Linux）でRMagickの環境構築をする方法を記載します。

環境：
Windows10
WSL（Debian GNU/Linux）
Ruby 2.5.1

参考：
https://qiita.com/yusuke_konishi/items/bb99faceada542ce2017
https://gist.github.com/ryderstorm/e3bc3ffc2903adc6f9bc0fe822af76f0

yum 使用する場合は↓参考に
https://qiita.com/gifu_w/items/173bb5c258198e941ecd


## WSLでDebianのインストール

まずは、Microsoft StoreでDebian GNU/Linuxのインストール。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/176619/c4ab157c-71ad-0fa8-a743-5891129e4449.png)

インストールが完了したら、Windowsボタンを押して、「最近追加されたもの」からDebian GNU/Linuxをダブルクリックしてください。下記のように任意のusernameとpasswordを入力してください（usernameとpasswordはどこかにわかるように保管しておいてください）。インストールが完了し、Bash が起動すると、プロンプトが $ になります。これだけでDebian使えるようになります。

```bash
Installing, this may take a few minutes...
Please create a default UNIX user account. The username does not need to match your Windows username.
For more information visit: https://aka.ms/wslusers
Enter new UNIX username: hoge
Enter new UNIX password:
Retype new UNIX password:
passwd: password updated successfully
Installation successful!
```

## 作業用フォルダの作成

Windows側のファイルシステム配下に作業用のディレクトリ (`C:\workspace`) を作成し、WSLから扱いやすいようにシンボリックリンクを作成します。

```bash
$ mkdir /mnt/c/workspace
$ ln -s /mnt/c/workspace ~/workspace
```

## Rubyのインストール

パッケージの更新をします。

```bash
$ sudo apt-get update
$ sudo apt-get upgrade
```

必要なパッケージをインストールします。
※Railsに必要なものも含まれています。

```bash
$ sudo apt-get install git nodejs build-essential zlib1g-dev libssl-dev libreadline-dev libyaml-dev libxslt-dev libcurl4-openssl-dev libffi-dev sqlite3 libsqlite3-dev
```

`rbenv`をインストールします。

```bash
$ git clone https://github.com/rbenv/rbenv.git ~/.rbenv
$ echo 'export PATH="$HOME/.rbenv/bin:$PATH"' >> ~/.bashrc
$ echo 'eval "$(rbenv init -)"' >> ~/.bashrc
$ source ~/.bashrc
```

`ruby-build`をインストールします。

```bash
$ git clone https://github.com/rbenv/ruby-build.git ~/.rbenv/plugins/ruby-build
$ echo 'export PATH="$HOME/.rbenv/plugins/ruby-build/bin:$PATH"' >> ~/.bashrc
$ source ~/.bashrc
```

Rubyをインストールします。2.5.1の場合です。

```bash
$ rbenv install 2.5.1
$ rbenv global 2.5.1
$ ruby -v
ruby 2.5.1p57 (2018-03-29 revision 63029) [x86_64-linux]
```

## RMagickのインストール

```bash
$ sudo apt-get purge graphicsmagick graphicsmagick-dbg imagemagick-common imagemagick imagemagick-6.q16 libmagickcore-6-headers libmagickwand-dev graphicsmagick-libmagick-dev-compat
$ sudo apt-get autoremove
$ sudo apt-get install imagemagick libmagickwand-dev
$ sudo ln -s /usr/lib/x86_64-linux-gnu/ImageMagick-6.8.9/bin-Q16/Magick-config /usr/bin/Magick-config
$ export PKG_CONFIG_PATH=/usr/lib/x86_64-linux-gnu/pkgconfig
$ gem install rmagick
```
git clone でルートフォルダ名の変更

# はじめに
プロジェクトをクローンしてくるときに、そのままクローンするとクローン元のフォルダ名のままになるので、自分で任意のフォルダ名にしたいときのTipsです。

# やり方
### そのままクローンした場合

```terminal:terminal
~$ git clone [クローン元のURL]
// これだとクローン元のフォルダ名のままになってしまいます
```

### 任意のフォルダ名に変更したい場合

```terminal:terminal
~$ git clone [クローン元のURL] sample
// これで sample という名前にリネームしてくれます
```
LINE Messaging API を使って MML を送れるようにしてみた。

[ この記事は [LINE Messaging API を使って LaTex を送れるようにしてみた。](https://qiita.com/plageoj/items/3df087999d550338e2b8) の続編です。 ]

# LINE で音楽を送る

LINE で人と Z-MUSIC の話をするとき、どうしても音符を送りたいときがありますよね。
でも、鼻歌はマルチチャンネルにできませんし、紙がなければ五線譜も書けません。

相手が生の MML を読める人ならいいのですが、そうもいかないことも多々あります。
MML を送ると音楽を返してくれる bot がないかと思って探してみましたが、なかったので作ってみました。

# 動作イメージ

友だち追加はこちらからどうぞ。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/116845/1a17e00b-7286-95a5-6780-e7aea1debac7.png)

![image.png](https://qiita-image-store.s3.amazonaws.com/0/116845/bdac6867-ec82-da11-0db8-40d395105269.png)

MMLの変換には[「サクラ」](https://sakuramml.com)を使っているので、ストトン記法も使えます。

# システムについて

サーバーはなんの変哲もない Debian Linux です。
サーバー側で mml → midi → wav → m4a という変換を行って、LINE で再生できる形式にします。

## MML → MIDI

MML → MIDI の変換には CLI版サクラの `csakura` を使います。
配布されているバイナリは MacOS と RPi 向けですので、Debian では使えません。
自前でビルドします。

```bash
sudo apt install fpc nkf
git clone https://github.com/kujirahand/sakuramml.git
cd sakuramml
./make.sh
```

## MIDI → WAV

この変換には `fluidsynth` を使います。

```bash
sudo apt install fluidsynth
```

ついでにお好みのサウンドフォントも探しておきましょう。
今回は、Z-MUSIC 風になればいいなということで、FM 音源風のサウンドフォントを見つけてきました。

ただし、あまりサウンドフォントが大きいとメモリ上に展開できずに `fluidsynth` が死にます。
小さいサウンドフォントにするか、サーバーに課金してください。

ホントはちゃんと波形を生成するほうがリアルなんですけどね……
できたところで自分は使いこなせる気がしないので、とりあえず MIDI で妥協します。

## WAV → M4A

LINE のドキュメントには m4a で投げろと書いてあったので、WAV のままではだめなんだと思います。
WAV のまま送れそうな気もしますが、実験はしていません。

WAV → M4A の変換のため、`ffmpeg` をインストールします。
環境によっては、他のコンポーネントも必要になるかもしれません。適宜入れます。

```bash
sudo apt install ffmpeg
```

## サーバー

今回は nginx を使います。
が、この記事にはサーバー設定回りは書きませんので、静的ファイルが配れて php が動けばなんでもいいです。

今回は php 用のサーバーに生成した m4a も置くのですが、絶対 s3 等のストレージにアップするべきだとは思っています。今後の課題です。

# ソース

前回は受け取ったテキストを Google Charts API に投げるだけでよかったのですが、今回はそうはいきません。

今回のミソは、`csakura` 関係の部分です。こいつは SJIS で動くので、入出力をそのまま
UTF-8 系の PHP に食わせると文字化けします。つまり

+ MML ソースの UTF-8 → SJIS 変換
+ `csakura` の出力の SJIS → UTF-8 変換

をしてやる必要があります。
ソースでは前者は `mbstring` で、後者は `iconv` で実現しています。

サウンドフォントの都合で音が小さかったので、`ffmpeg` で音量の調整をかけています。
音質も下がり、非力な音源チップ感が出て非常にいいです。

# サンプル

冒頭のイメージで使った MML コードを貼っておきます。

きらきら星

```mml
ccggaag2 ffeeddc2 [ggffeed2] ccggaag2 ffeeddc2
```

ザナック１面のようなもの

```mml
トラック1
l16
れーふぁーらーそらーー↑どー↓しーそーら1
[
[れーみーふぁーれみーふぁーみれーみー]
[ふぁーそーらーふぁそーらーそふぁーそー]
[し-ー↑どーれー↓し-↑どーれーど↓し-ー↑どー↓]
らーし-ー↑どー↓らし-ー↑どー↓し-らーし-ー
らーし-ー↑[6どー]

れ2ど2↓し-らーそら2.
↑ど2↓し-2ら2そ4ら4
し-2ら2そ2ふぁ2
[8みふぁ]
み1
]

トラック2
l16
れーーれれーど↓しーししーらーそー[3らー↑どれ↓]↑ど↓しらー↓
[[
[4[4れ]ら[3れ]]
[4[4ふぁ]↑ど↓[3ふぁ]]
[4[4し-]↑ふぁ↓[3し-]]
[4[4ら]↑み↓[3ら]]
]]
```
マイクロサービス化・Microservices事例集

昨今、何かと話題に挙がっている（気がする）マイクロサービス化・Microservicesの企業事例で、割と最近のものを集めてみました。

追記：2019/11 時を経てもいいねもらうので、少しだけ更新

---
- mercari
    - [メルカリは開発組織を拡大するためにマイクロサービスアーキテクチャを採用した（前編）](https://www.publickey1.jp/blog/18/mercari_tech_conf_2018.html)（後編もリンクがあります）
    - [なぜMicroservicesか?](https://deeeet.com/writing/2019/05/20/why-microservices/)
    - [マイクロサービスチーム編成のベストプラクティスとメルカリでの構想](https://tech.mercari.com/entry/2018/12/01/200159)
- 食べログ（カカクコム)
    - [食べログのマイクロサービス化PJについて](https://www.slideshare.net/KoutaTerashima/pj-2018926-ebisurb-18)
- クックパッド
    - [クックパッドにおける最近のMicroservices事例](https://techlife.cookpad.com/entry/2016/03/16/100043)
- Wantedly
    - [Microservices on "Rails" - Wantedlyのマイクロサービス事例](https://speakerdeck.com/altech/microservices-on-rails-wantedly-falsemaikurosabisushi-li)
- LINE
    - [実践マイクロサービス ─ コンポーネント分割やトラブル回避の考え方をLINEの導入事例に学ぶ](https://employment.en-japan.com/engineerhub/entry/2018/10/09/110000)
   - （ちょっと古いけど…）[LINEのマイクロサービス環境における分散ストレージング](https://engineering.linecorp.com/ja/blog/detail/48)
- RAKUS
    - [マイクロサービスアーキテクチャにおけるサービス分割の難しさ](http://tech-blog.rakus.co.jp/entry/20180926/microservice)
    

### 番外編
- Google
    - [ホワイトペーパー : モノリスからマイクロサービスへの移行](https://cloudplatform-jp.googleblog.com/2018/02/whitepaper-embark-on-journey-from-monoliths-to-microservices.html)
英数字を入力で受け取り，数値表示に変えて出力する（PHPで実装してみた）

#はじめに
Qiitaに初めて投稿するので，
見にくい記事になるかもしれませんが，
ご勘弁ください．

筆者はPHPを約３年ほど触れている院生です．
なので多少自身があったのですが，
ある企業さんのコーディングテストで打ちのめされてしまい，
とても悔しいので，記事として投稿させていただきます．
もちろん問題内容は少し変えています．
（もし規則的にダメなことをしてしまっていたらすぐに非公開にします）

他に書く理由として，
「ここはこう書くんだよ」だったり，
「これはこの関数でできちゃうよ」というコメントが欲しいからです．
なので，遠慮なさらずに，アドバイスください．

#実装したい機能概要
例えば,　<b>"one"</b>　と打てば　<b>"1"</b>　が出力されるというもの．
それが,　<b>","</b>　を切れ目として羅列しているデータが入力となり，
出力はその英数字群を数字に直したもの．

入力：one,two,three
出力：123

#実際に馬鹿正直に実装してみる
一応実装できたソースコードは以下の通りです．
コメントで疑問を残しております．．．
（アドバイス・解説コメントお待ちしておりますw）

```php:test.php
<?php
  $num = $_POST['num']; #入力データを変数に格納
  $nums = explode(",",$num); #カンマで分けて，分けた文字列を配列に格納して行く
  $i = 0;
  $array = array(); #空の配列を用意して，そこに入れて最後にまとめて表示しようとしている

  while($i < count($nums)){
    if(strcmp($nums[$i], "zero") == 0){
      $array[$i] = "0"; #$array配列に格納する際に"　"を書かないとなぜか格納してくれなかった
      echo $array[$i]; #正直 "echo 0"　と書いた方が早いかもしれないが，配列に入れて最後に表示できる方が格好いいと思ったためこう書いている
      $i++;
    }else if (strcmp($nums[$i], "one") == 0){
      $array[$i] = "1";
      echo $array[$i];
      $i++;
    }else if (strcmp($nums[$i], "two") == 0){
      $array[$i] = "2";
      echo $array[$i];
      $i++;
    }else if (strcmp($nums[$i], "three") == 0){
      $array[$i] = "3";
      echo $array[$i];
      $i++;
    }else if (strcmp($nums[$i], "four") == 0){
      $array[$i] = "4";
      echo $array[$i];
      $i++;
    }else if (strcmp($nums[$i], "five") == 0){
      $array[$i] = "5";
      echo $array[$i];
      $i++;
    }else if (strcmp($nums[$i], "six") == 0){
      $array[$i] = "6";
      echo $array[$i];
      $i++;
    }else if (strcmp($nums[$i], "seven") == 0){
      $array[$i] = "7";
      echo $array[$i];
      $i++;
    }else if (strcmp($nums[$i], "eight") == 0){
      $array[$i] = "8";
      echo $array[$i];
      $i++;
    }else if (strcmp($nums[$i], "nine") == 0){
      $array[$i] = "9";
      echo $array[$i];
      $i++;
    }
#各if文内の"echo $array[$i];$i++"を消して，ここに"echo $array[$i];i++;"でまとめようとしたができなかった．　これはif文を出るとwhileが次のターンにいっているからなの？
  }

?>
```


#アドバイスを踏まえて実装してみた
2018.10.12追記
アドバイスコメントで，

```
str_replace( $検索文字列 , $置換後文字列 , $検索対象文字列 )
```

を用いたソースコードを教えて頂いたので，
そのコードも載せておきます．

```php:test.php
<?php
  $num = $_POST['num'];
  function str2int($str){
    return str_replace(explode('/', 'zero/one/two/three/four/five/six/seven/eight/nine/,'), range(0,9), $str);
  }
  #explode（）で'/'を排除して,"英字" と "," を各配列に入れます
  #zero→0　one→1 ","→" " に置き換える関数

  $num_int = str2int($num);
  echo $num_int;  
?>
```


#最後に
筆者の書き方はあまり良くないことは自覚しています．．．
例えば，英数字を数字に変えるライブラリや関数があれば，if分岐をする必要がないわけで．．．
あとは出力の仕方で賢い方法等あればコメント欲しいです！

初投稿でしたが，
こんな感じでいいのかな？
Genexus備忘録(操作編)

##Genexusとは
仕事で使うことになったので備忘録。
https://www.genexus.com/ja-JP/japan
Javaだけかなと思ってたらC#とかRubyとかCOBOLとかRPGも対応してるみたい。
RPGは使ったことないけど、ニッチなとこサポートしてるんだなぁ。

[Genexus Wiki](http://wiki.genexus.jp/hwiki.aspx?%e3%82%ab%e3%83%86%e3%82%b4%e3%83%aa%3aGeneXus+X+Evolution+3+%e3%83%98%e3%83%ab%e3%83%97,)

※量が増えてスクロールが面倒になったので記事を分割した。
→[実装編](https://qiita.com/aoi_erimiya/items/8b44b5b9f7aaacfcb3ed)

###ナレッジベース
Projectの事。

###オブジェクト
4オブジェクトを使えばとりあえずアプリ作れそう。

* WebPanel
* SDT
* Transaction
* Procedure

###WebPanel
.NetのForm的なもの。
ツールボックスから要素を配置できる。
イベント周りのロジックはここで記載する

###SDT
Cの構造体。データ構造のみ表現できて、メソッドとかは持たない。
=Struct,≠Class
ロジックはProcedureに持たせる

###Transaction
DBModelみたいなもの

###Procedure
業務ロジックとかソースコード、ライブラリ系はこれを使う

##オブジェクト検索
クイックアクセス横の三角ボタンに検索窓が隠蔽されている。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/270579/6b3a5f8d-d289-d982-4cae-b43f5b4ad6a9.png)

## 帳票
Procedureで定義する。
作ったレイアウトを、呼び出し元からCallするイメージ。

１：Procedureを作成
２：Procedure本体のプロパティ変更
→Call ProtocolをHTTPに設定する
※Procedureを編集しているタブ名を右クリックするとプロパティ表示できる。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/270579/d2c9306b-2407-0907-f58f-efed065e9faf.png)
３：「Layout」タブで帳票定義を設定する
![image.png](https://qiita-image-store.s3.amazonaws.com/0/270579/340b5717-7991-c1e3-701b-8c8dce208342.png)

ツールボックスから項目を置いていく。
残念ながら複数項目を一気に配置したりできないので、地道にレイアウトする。
線はプロパティから縦横変更可能。
また、格子状に箱を作りたい場合は、長方形＋線で頑張るしかない。
横に項目を並べたい場合は、標準機能では何ともならないので、工夫が必要。

４：「Source」タブで作ったPrintBlock名を指定して出力する
For Eachで回しているデータと対応していれば、うまいことbindしてくれる。

```
For Each orders
  print printBlock1

  For Each orders.detail
     print printBlock2
  EndFor

  print printBlock3
End For
```

改ページはこの命令。

```
Eject
```

SDTも指定できるが、Collection型にしたものを画面項目として設定してもうまくいかない。
帳票Layoutには単体のSDTの項目を定義する。

## Transaction
1:「ファイル」「新規」「オブジェクト」「共通」Transactionを選択
2:「Structure」タブで項目定義する
・主キーに設定しとくと、同一項目を他Transactionに定義したときに
　自動で外部キーとして処理してくれる。
※逆に、whoカラムみたいな項目の名前が一緒だと、外部キー扱いされる
　悲しみを背負っているので、テーブルごとに別の名前にする必要がある。
・名称項目属性に設定しとくと、Genexusが自動生成してくれるマスメン画面で
　ポップアップlistから選択できる項目になる。(業務では使わんかも？)
・Numericの桁数指定は以下の通り。

```
Numeric(6.2)->100.00
Numeric(全体桁数.小数部)
※全体桁数には.を含むので注意。
```

3:実行してみる(F5)
「Web Form」タブを見ると、自動でいい感じのマスメン画面を作ってくれてる。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/270579/9ed32fad-7223-d09c-ab81-e6cb47c70895.png)

虫眼鏡を押すとこんな感じの選択ウィンドウが出てくる。
Transaction定義で設定した「名称項目属性」に下線が出て、選択できるようになる。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/270579/bbec210b-e5bb-0bb9-2314-d56e41196bdb.png)

### 複雑なTransaction

![image.png](https://qiita-image-store.s3.amazonaws.com/0/270579/f75cb7e7-4018-6fbc-b10c-b43061035cec.png)

「レベルを挿入」でデータ構造をネストしたりできる。
式を入力して、自動計算させる事も可能。

なお、ネストした項目でソートする際は以下構文で実施。

```

// NG(エラーにはならないがソートされない)
&t_order.Sort('amount')

// OK
&t_order.Sort('list.amount')
```

## ほか
続きは随時追記していく方式で。

そのうち書く
・freestyleGrid
・WorkWithPlus
ネットワークグラフ描画ライブラリ7個まとめ

## ネットワークグラフとは

こんな感じのもの。

関連図とか、関係図、ソーシャルグラフとか言いますが、今回はネットワークグラフを呼称とします。

[Spysee2](http://spysee2.jp/)
![ネットワークグラフ.jpg](https://qiita-image-store.s3.amazonaws.com/0/256853/3cbc9477-628d-91f0-ff14-3b6ae572f613.jpeg)


事前にこのスライドに目を通しておくといいです。

> [(2017.6.9) Neo4jの可視化ライブラリまとめ](https://www.slideshare.net/mkiuchi4/201769-neo4j)

## ネットワークグラフ描画ライブラリ

ざっと調べたところ、これを実現できそうなJavaScriptライブラリは以下の6つ

|名前|情報量|実装のしやすさ|拡張性|動作が軽いか|Neo4jとの使用例|備考
|---|---|---|---|---|---|---|
|[D3.js](https://d3js.org/)|◎(バージョン注意)|〇(jqueryライク)|◎|〇？|△(中国圏)|リファレンスは多めだが元々グラフDB向けではない
|[sigma.js](http://sigmajs.org/)|〇(日本語少)|△|?|◎(WebGL)|△(英語圏)|SVG,Canvas,WebGL対応、Neo4j使用例有
|[vis.js](http://visjs.org/index.html)|〇|◎|△|〇|〇(英語圏)|グニャグニャ動く|
|[VivaGraphJS](https://github.com/anvaka/VivaGraphJS)|△(Githubのみ)|?|△|◎|×|双方向矢印有(?)|
|[Cytoscape.js](http://js.cytoscape.org/)|〇(日本語少)|△|〇|〇|〇(拡張機能で対応)|開発者に日本人がいる|
|[cola.js](https://ialab.it.monash.edu/webcola/)|△|〇|◎|〇(ノード数100以下推奨)|〇|D3.js、Cytoscape.jsと組み合わせる|
|[KeyLines](https://cambridge-intelligence.com/keylines/)|◎|〇|△|◎|◎|HTTPS対応。有償|

## 参考ページ

### D3.js

> [D3.js v4/v5 force simulation 最小構成 – サンプル](https://wizardace.com/d3-forcesimulation-simple/)
 
> [d3.jsでスゴイっぽい図(force layout)を作ってみたら思ったより簡単だった件](https://qiita.com/shoki_kitajima/items/34ad6e2209fde5b4dedc)

### sigma.js

> [How to use Sigmajs to display your graph ?](https://www.bsimard.com/2018/04/25/graph-viz-with-sigmajs.html)

### vis.js

> [Network Examples](http://visjs.org/network_examples.html)

> [vis.jsを使ってネットワークを書く](https://qiita.com/junjis0203/items/ecc3f4eb9b3a1c4802e4)

> [vis.jsでグラフ描写](https://qiita.com/NomuraS/items/bb14a888f8e8fb0a88e2)

### VivaGraphJS

> [VivaGraphJS](https://github.com/anvaka/VivaGraphJS)
> [Amazon Visualization](http://www.yasiv.com/amazon#/Search?q=surface%20laptop&category=All&lang=US)

### Cola.js

> [Cola.js](https://ialab.it.monash.edu/webcola/)

> [cola.jsによるデータビジュアライゼーション](https://midoriit.com/2016/10/cola-js%E3%81%AB%E3%82%88%E3%82%8B%E3%83%87%E3%83%BC%E3%82%BF%E3%83%93%E3%82%B8%E3%83%A5%E3%82%A2%E3%83%A9%E3%82%A4%E3%82%BC%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3.html)

### Cytoscape.js

> [Cytoscape.jsを試してみた](http://steavevaivai.hatenablog.com/entry/2017/03/25/065734)

> [Cytoscape.js でインタラクティブなグラフ構造描画 - WordNet の可視化例](http://shinaisan.hatenablog.com/entry/2017/04/30/230908)

>[自律分散監視システムとそれを利用したネットワークグラフ可視化への挑戦](http://developer.hatenastaff.com/entry/2017/09/12/132935)

[CYTOSCAPEを使った データの可視化 - MotDB](http://motdb.dbcls.jp/?plugin=attach&pcmd=open&file=AJACS62_Cytoscape.pdf&refer=AJACS62)

## 総合的に考えるとCytoscape.jsとcola.jsの併用がよさそう

- データ視覚化ライブラリとして有名なD3.jsですが、今回の目的であるNeo4jから持ってきたデータを表示するには手間がかかりそうである。
- Cytoscape.jsは拡張機能を使えばNeo4Jにも対応できるとのこと。また、日本人の開発者がいるため日本語で本人に質問等可能
- ユーザーはGUIベースで見た目のカスタマイズ可能

## 予算に余裕があるならKeyLines

有料にはなってしまいますが、品質、サポートが保証されているKeyLinesも良いです。

Neo4jのわかりやすい導入事例もあるので工数は減らせそうです。

## デスクトップアプリケーションならCytoscapeも有効

Cytoscape.jsは元々学術向けのCytoscapeをJavaScriptライブラリ化したものです。

Webアプリケーションにこだわらなければ、全て英語ですが、こちらのほうが使いやすいかもしれません。
laravel DBを作成しよう


# サーバーのパーミッションに注意

ssh で root ログインしていると生成されるファイルをFTPで触れなくなる。
よって root でログインしてファイルを生成する作業する時は必ず

```
su username

```

で FTPユーザーになってから作業しましょう。

# マイグレーションって何？

コマンドからテーブルを作成できる。
テストレコードとかも挿入できるので良いみたい。




# .env ファイルに注意

2つのファイルを設定。
なぜかphpstormに表示されない。
よって centos から 直接 vim で編集

/config/database.php 44行目あたり

```
        'mysql' => [
            'driver' => 'mysql',
            'host' => env('DB_HOST', '193.99.19.73'),// 変更
            'port' => env('DB_PORT', '3306'),
            'database' => env('DB_DATABASE', 'yourdb'),// 変更
            'username' => env('DB_USERNAME', 'youri'),// 変更
            'password' => env('DB_PASSWORD', 'yourpass'),// 変更
            'unix_socket' => env('DB_SOCKET', ''),
            'charset' => 'utf8mb4',
            'collation' => 'utf8mb4_unicode_ci',
            'prefix' => '',
            'strict' => true,
            'engine' => null,
        ],

```


centos にログインし、 vim .env 10行目あたり

```

DB_CONNECTION=mysql
DB_HOST=193.99.19.73
DB_PORT=3306
DB_DATABASE=yourdb
DB_USERNAME=your
DB_PASSWORD=yourpass


```


これで DB情報を作成OK


# 次はマイグレーション

```

php artisan make:migration create_articles_table

```

するとファイルができあがる。
database\migrations\xxxx_xx_xx_xxxxxx_create_articles_table.php


centosから

```

php artisan migrate

```

これでarticles テーブルが完成。
初心者がする「初めてのlaravel」＊homesteadで環境構築するの巻（そのニ）

台風一過で清々しい良い３連休でした。（どこにも行ってないけど・・・）
さて、[初心者がする「初めてのlaravel」＊homesteadで環境構築するの巻（その一）](https://qiita.com/joejack/items/3b071ca732ca63f32a80)の続きです。

####【手順３】homesteadの設定

C:\Users\ユーザ名\Homesteadのフォルダ内にある「Homestead.yaml 」の内容を変更します。秀丸等のエディタを用意（メモ帳は文字コードの関係上上手くいかないようです）。私はATOMを使いました。エディタを立ち上げHomestead.yamlをエディタにドラッグ＆ドロップしてください。

ip: "xxx, xxx, xx, xx"
memory: xxxx
cpus: 1
以下続く

こんな文字列が見れます。下の方のsite:を
sites:
to: /home/vagrant/code/public
     ↓
to: /home/vagrant/code/sampleapp/public

へ変更ください。

#### 【手順４】共有ディレクトリを作成

コマンドプロンプトでホームディレクトリに戻り（`cd %USERPROFILE%`）code名のディレクトリを作成します。
```mkdir code```

#### 【手順５】hostsファイルの編集（管理者権限必要）

エクスプローラーから「C:\Windows\System32\drivers\etc」まで辿り、hostsファイルを開いてください（手順３のようにエディタのドラッグ＆ドロップ）最後尾に

192.168.10.10    homestead.test

を追加してください。

#### 【手順６】sshキーの設定

コマンドプロンプトで「C:\Users\ユーザ名\Homestead」に入り
`ssh-keygen`
と打ち込んでください。
RSA暗号キーの保管場所を聞かれますので下記の/.ssh/id rsaでよければenterしてください。
![homesteadpass .PNG](https://qiita-image-store.s3.amazonaws.com/0/137730/7f8b3efe-8288-a7c0-00a0-38fcc613106a.png)
その後にsshキーのパスフレーズを聞かれます。任意のフレーズを入力して忘れないようにしてください。

#### 【手順７】vagrantの起動

vagrantフォルダのあるHashiCorpフォルダの直上「C:」に移動して
`vagrant up`
と入力。
`vagrant up`でセットアップを開始します。
starts and provisions the vagrant environment（vagrant -hから）
エラーが出る場合はPowerShellから試してください。
![homestead.PNG](https://qiita-image-store.s3.amazonaws.com/0/137730/d8eda1e4-dde4-bb49-aaed-cdfa86374433.png)
こんな感じになれば正常に終わっています。
終わったら
http://homestead.test/
で
No input file specified
と表示されるか確認します。
次にコマンドプロンプトから
`vagrant ssh`
と打ってください。
![仮想ubuntu.PNG](https://qiita-image-store.s3.amazonaws.com/0/137730/9bd62741-73c9-152f-dbeb-11ee3803bf51.png)
こうなるはずです。
`ls`（仮想マシン通じてubuntu環境になっているのでLinuxコマンド）
でcodeフォルダが表示されれば無事vagrantの仮想環境が作成されました。

#### 【手順７】Laravelのインストール
そのままの状態で
`laravel new sampleapp`
と打ってください。
少し時間がかかりますが、
Package manifest generated successfully.
Application ready! Build something amazing
となればインストール完了です。
http://homestead.test/
で
![laravel.PNG](https://qiita-image-store.s3.amazonaws.com/0/137730/9aae516d-accf-63c1-837d-5fe05eb0b111.png)
となって環境構築完了です！！

お疲れ様でした。
javascript練習:お腹が空いてますか？

##お腹が空いてるか聞くjavascriptを作成してみた
confirmの「はい」または「いいえ」でその後の処理を変えています。


```javascript:qiita.js
var isHungry = confirm('おなかがすいていますか？');
if(isHungry){
  var isRich = confirm('財布に1500円以上入っている')
  if(isRich){
    var isLike = confirm('ピザが好き？')
    if(isLike){
      alert('ピザを食べよう！')
    }
    else{
      alert('oh...')
    }
  }
  else{
    alert('探してみよう！')
  }
}
else{
  alert('寝ないでね！')
}
```
Django2.0でブログの作成（その９：記事の検索）

その９

記事を検索したい時ってありますよね？
トップページに検索ボックスと検索ボタンをつけて、記事タイトル検索をしましょう！

# forms.py
検索ボックスもformですよね？
次のclassを追加しましょう。

```blog/forms.py
class SearchForm(forms.Form):
    q = forms.CharField(label="検索")
```
qは一般的にqueryです。なんでもいいですが、qがわかりやすそうです。

# views.py
今回は`def post_list内`の処理でよさそうです。

```views.py
def post_list(request):
    posts = Post.objects.all()
    form = forms.SearchForm()
    print(request.GET)

    if request.GET.get('q'):
        posts = posts.filter(title__contains = request.GET.get('q')) #titleにqを含む、部分一致検索が可能

    return render(request, 'blog/post_list.html', {
        'posts': posts,
        'form': form
    })
```
return renderの中に`form`も追加してくださいね。

# urls.py
ページ内処理なので変更ありません。

# post_list.html
```post_list.html
<form method="get" action="">
  {{ form }}
  <input type="submit" value="検索">
</form>
```

# 確認
<img width="517" alt="スクリーンショット 2018-10-09 17.31.17.png" src="https://qiita-image-store.s3.amazonaws.com/0/192887/93359582-532f-7cc6-17c7-3055b7440249.png">
よく使う Python ロギングスニペット

完全に自分向け。
`DEBUG` 以上のログを Hourly でローテートしつつファイルに書き出し。

```python
import logging
from logging import getLogger, Formatter
from logging.handlers import TimedRotatingFileHandler

logger = getLogger('ConvertLog')
logger.setLevel(logging.DEBUG)
rotate_handler = TimedRotatingFileHandler(filename='convert.log', when='H')
rotate_handler.setFormatter(Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s'))
logger.addHandler(rotate_handler)
```
SIerからWeb業界に転職した話

##経歴
 - 2013年新卒で独立系弱小SIerに就職
 - 5年弱働いて９プロジェクトに参画(ほぼWebシステム)
 - 基本情報技術者
 - 思い出せる範囲での保有スキル：Java(SE ７、SE 8、Struts、Spring)、JavaScript(jQuery、BackBone.js、NodeJS)、PHP、VB.NET、HTML、CSS、PostgreSQL、MySQL、ORACLE
 - Eclipse、Visual Studio、Git、SVN、Redmine
 - 2018年Web業界に転職

#なんでSIerに就職したの
 - なんかすごい景気悪くて(~~人のせいにするな~~)就職先が見つからなくて迷走
 - まぁIT業界で食いっぱぐれる事はないだろうという安易な考え

##働いてみて
####思ったこと
- 短期間で現場変わって全部リセット（場所、人間関係、言語、etc）

####続・思ったこと
- 人売りITって自分の力じゃどうにもならないところで色々なことが決まってゆきますよね

####続・思ったこと２
- ~~こんなんただのコードく書く機械じゃん~~
- ~~幾らでも代替え効くし...~~

##ちくしょう、転職だ
![job_computer_technocrat.png](https://qiita-image-store.s3.amazonaws.com/0/262530/76846110-eaf6-85d2-4d97-eacd44319951.png)

でも、はじめての転職ってわからないことだらけ:worried:

##とりあえずエージェントに相談してみよう
というわけで、エンジニアの転職に強いらしいレバテックキャリアさんに登録して面談しに行きました。

**BtoC、CtoCのサービスを自社事業でやってる会社がいいです！（漠然)**
と伝えたら、その日のうちに３０社ほど紹介していただいて
履歴書のフォーマット等も貰えました。
前職では現場にアサインするたびにスキルの棚卸しをしていたので、
スキル面の書類作成は時間をかけずに行うことができました。
逆に転職理由や志望動機などはめちゃくちゃ時間がかかりました。

面接の日取りはエージェントとやりとりすることでサクサク決まっていきました。
LINEでのやりとりだったので
在職中の日程調整はなかなか大変なので助かりました。

##面接
新卒のときよりフランクでした。
ある程度技術を身に着けた上での面接なので、
新卒のときにありがちなエンジニアとして働くにあたって
本質的じゃない不毛なやりとりはなかったですし、
同じフィールドで話ができて楽しいと思えることもありました。

##筆記試験ってあるの？
1社だけありました。
「16進数から2進数に変換してください」などの計算問題や、
情報処理技術者試験に出るような用語の知ってる知らないを問うもの、
紙とペンを渡されて、「あなたが知っている言語で○○を実装してください」
といったIDEに頼らないコーディング力を問う問題もありました。
周りの話を聞いていると、実施する会社に遭遇したと聞くのである程度身構えていた方が良さそうです。

##気をつけていたこと
転職理由マイナスの理由を言いたくなる（自分でわかってても）んですよね。
フランクな空気感だと愚痴が出やすくなってしまうので気をつけました。

##結果
１ヶ月ちょっとで現職に内定しました。

####結果
エントリー：6社
書類選考通過：5社
内定:1社
不合格:1社
持ち駒３社くらいを維持しながら最初に内定した会社の志望度が高かったので他を辞退しました。

##退職は、計画的に
次の現場が決まるまでにケリをつけようと活動していましたが、
次の現場をアサインされて退職に手間取りました。

##在職中or退職してから
エージェントに登録すると、企業とのやり取りはほとんどやってくれるので、
在職しながらでも比較的負荷が少なく転職活動ができたなと思いました。
人売りSESでこっそり転職活動をしていると、
タイミング悪くアサインされてしまい会社との関係が最悪になるかもしれません。
（鋼のメンタルをお持ちの方は問題なし）
当面の生活費が工面できるor技術面で優れていてすぐに転職先が決まりそうとかであれば
辞めてから転職活動をするのも全然アリなきがします。

##現在
新規事業系部署のエンジニアになって一年半がたちました。
現在携わっているプロジェクトは２つ目です。

##働いてみて
####思ったこと
- プロジェクトが変わっても勤務地・作業環境が変わらないのが良い
- ゼロイチでの経験を積めたことで視野が広がった
- わりとフルスタックで動くことを求められる
- 企画サイドと直接交渉したり、場合によってはエンジニア目線で提案できるのでプロダクトを作ってる実感が湧く

次は何をやろうかな・・・？
GitBookの検索機能を簡単に日本語対応化

GitBookの標準の検索機能は日本語だと使い物になりません。
`algolia` というサービスを使うのが定番ですが、APIキーを取得したり、プランやクローラーのことなど、考えることが増えてしまいます。

そこで単純に部分一致で記事を検索するだけでよいという場合にぴったりな `search-pro-kui` というプラグインがあるので紹介します。

（`algolia` は名寄せなどもでき、かなりパワフルなので、記事数がかなり多い場合は素直に `algolia` を選んだ方がいいと思います。)

## インストール方法

[search-pro-kui](https://plugins.gitbook.com/plugin/search-pro-kui)

`book.js` の `plugins` に `-lunr` `-search` `search-pro-kui`を追加して `$ gitbook install` を実行するだけです。

`-lunr` と `-search` はデフォルトの検索エンジンを無効化するものです。

```js:book.js
{
    "plugins": [
      "-lunr", "-search", "search-pro-kui"
    ]
}
```

## デモページ

デモページが用意されているので、導入前にこちらで自分の求めているものかどうか確認してみると良いと思います。
デモページの言語は中国語ですが、日本語も同じように対応可能なので言語は気にせずに触って見てください。
イメージ通りに動くと思います。

http://gitbook-plugins.github.io/gitbook-plugin-search-pro/book/

![image.png](https://qiita-image-store.s3.amazonaws.com/0/186574/b3bbd63d-5fc1-2083-46ff-a6453fffbf69.png)

試しに「`装这两个加`」 というキーワードで検索かけた例ですが、しっかりと部分一致で検索できているのがわかります。
これくらいのページ数でもサクサク動くので、ある程度の規模までは耐えられそうです。
Django2.0でブログの作成（その８：記事の削除）

その８

記事の削除です。
一つ前の記事の編集と全く同じです、むしろそれより簡単。
いきますよー

# views.py
```blog/views.py
def delete_article(request, pk):
    article = Post.objects.get(id=pk)

    if request.user.id == article.author.id: #記事の投稿者だけ削除実行できる。
        article.delete()
    return redirect('blog:post_list')
```


# urls.py
```blog/urls.py
path('article/<int:pk>/delete', views.delete_article, name='delete_article'),
```
追加

# edit_article.html
ここでは、編集画面に消去ボタンをつけます。
そもそも編集画面は記事の投稿者しか入れないページなので(その７でやりました！)
html上でif文を書く必要はありませんね。

```edit_article.html
<a href="{% url 'blog:delete_article' form.instance.id %}" class="btn btn-danger">消去</a>
```
この一文を`<form></form>`内に追加します。

# 確認
<img width="364" alt="スクリーンショット 2018-10-09 17.12.48.png" src="https://qiita-image-store.s3.amazonaws.com/0/192887/a507b9bb-b11d-e17c-91de-f938f5a3f0a5.png">
.gitlab-ci.yml ジョブ事例集

npm を使ったGitLab CIプロジェクトで使っている秘伝のタレをご紹介します。

# 参考

* [Configuration of your jobs with .gitlab-ci.yml](https://docs.gitlab.com/ee/ci/yaml/)

# package.json が編集された時だけ npm install する

ビルドの度に npm install しているとビルドに余計な時間がかかるので、package.json が編集された時だけ、 node_modules/ をクリアして npm install します。

```yaml
variables:
  DEST_DIR: dest/

build:prod:
  stage: build
  dependencies: []
  script:
    - mkdir -p .cache
    - npm config set cache $CI_PROJECT_DIR/.cache/npm --global
    - yarn config set cache-folder $CI_PROJECT_DIR/.cache/yarn
    - >
      (test -d node_modules/ && diff .cache/package.json package.json > /dev/null 2>&1) ||
      (rm -fr node_modules/ &&
        (test -f yarn.lock && yarn install) ||
        (test -f package-lock.json && npm ci) ||
        npm install
      )
    - npm run build
    - cp -p package.json .cache/
  cache:
    paths:
      - .cache/
      - node_modules/
  artifacts:
    paths:
      - $DEST_DIR
```

# 画像ファイルのフォーマットを確認する

「拡張子が.jpgなのに中身がPNGだった」等の事故が起きないよう、画像ファイルの拡張子と中身が一致しているかを確認します。
また、JPEGファイルの色がCMYKだったという事故が起きないよう、RGBかGrayscaleかどうかも確認します。
RubyとImageMagickが必要です。

```yaml
variables:
  DEST_DIR: dest/

test:image_format:
  stage: test
  script:
    - find "$DEST_DIR" -type f -name '*.jpg' | xargs identify -format '%i %m\n' | ruby -ne 'BEGIN{$e=0}; unless /JPEG\s*$/ then print; $e=1 end; END{exit $e}'
    - find "$DEST_DIR" -type f -name '*.png' | xargs identify -format '%i %m\n' | ruby -ne 'BEGIN{$e=0}; unless /PNG\s*$/ then print; $e=1 end; END{exit $e}'
    - find "$DEST_DIR" -type f -name '*.svg' | xargs identify -format '%i %m\n' | ruby -ne 'BEGIN{$e=0}; unless /SVG\s*$/ then print; $e=1 end; END{exit $e}'
    - find "$DEST_DIR" -type f -name '*.ico' | xargs identify -format '%i %m\n' | ruby -ne 'BEGIN{$e=0}; unless /ICO\s*$/ then print; $e=1 end; END{exit $e}'
    - find "$DEST_DIR" -type f -name '*.jpg' | xargs identify -format '%i %r\n' | ruby -ne 'BEGIN{$e=0}; unless /(sRGB|Gray)\s*$/ then print; $e=1 end; END{exit $e}'
```

# SSH + rsyncでファイルをコピーする

ビルドをDockerで動かしている場合など、ジョブのscriptにrsyncを仕込むだけだと、そんなコピー先ホストなんてシラネと言われてしまうので、お膳立てをしてからrsyncします。

```yaml
variables:
  DEST_DIR: dist/
  STAGE_HOST: rsyncコピー先ホスト名
  STAGE_USER: SSHリモートユーザー名
  STAGE_PATH: /path/to/rsync/コピー先/ディレクトリ

deploy:stage:
  stage: deploy
  script:
    - mkdir -p ~/.ssh
    - chmod 700 ~/.ssh
    - eval $(ssh-agent -s)
    - echo "$SSH_PRIVATE_KEY" | tr -d '\r' | ssh-add - > /dev/null
    - touch ~/.ssh/known_hosts
    - chmod 644 ~/.ssh/known_hosts
    - ssh-keyscan $STAGE_HOST >> ~/.ssh/known_hosts
    - ssh $STAGE_USER@$STAGE_HOST mkdir -p "$STAGE_PATH"
    - rsync -av -e ssh --delete --checksum "$DEST_DIR" $STAGE_USER@$STAGE_HOST:"$STAGE_PATH"
  only:
    variables:
      - $SSH_PRIVATE_KEY
```

## 参考

* [Using SSH keys with GitLab CI/CD](https://docs.gitlab.com/ee/ci/ssh_keys/)
C言語におけるBoehmGCの利用(備忘録)

勉強がてら，C言語上でGarbage Collectionを利用することができる[Bohem GC](http://www.hboehm.info/gc/)の導入方法を記載します．
C言語上でBohem GCを導入することで，手動メモリ管理(malloc)を使う代わりに，自動的にメモリ管理を行うことができます．
もちろん，そのトレードオフとしてGCによる停止時間があることは留意してください．また，本記事では"保守的なGC (conservative GC)"や"正確なGC (precise GC)"については解説しません．

# 想定読者
 - C言語, GCをある程度知っている人
 - C言語で気軽にGC利用したい人 => free()を書きたくない/メモリ管理したくない人

# 実行環境
OS :Ubuntu 22.04.2 LTS
compiler : gcc version 11.3.0 (Ubuntu 11.3.0-1ubuntu1~22.04) 

```
$ lsb_release -a 
No LSB modules are available.
Distributor ID:	Ubuntu
Description:	Ubuntu 22.04.2 LTS
Release:	22.04
Codename:	jammy
$ gcc --version
gcc (Ubuntu 11.3.0-1ubuntu1~22.04) 11.3.0
...
```

# 導入
- ソースコードの入手とビルド
[BohemGC](http://www.hboehm.info/gc/)に従い，以下のコマンドを実行する．このとき git, automake, autoconf, libtoolなどはインストールしておく必要がある．

```
$ sudo apt-get install autoconf automake libtool
$ mkdir testBohemGC && cd $_
$ git clone git://github.com/ivmai/libatomic_ops.git
$ git clone git://github.com/ivmai/bdwgc.git
$ ln -s  [AbsolutePath]/libatomic_ops [AbsolutePath]/bdwgc/libatomic_ops
$ cd bdwgc
$ autoreconf -vif
$ automake --add-missing
$ ./configure
$ make
$ sudo make install
```

これで準備は終わり．

# 実行
メモリ管理が必要なC言語プログラムを用意する. 
[プログラミング言語: 保守的GCを使ってみる](https://www.eidos.ic.i.u-tokyo.ac.jp/~tau/lecture/programming_languages/gen/html/gc.html)のarray.cサンプルとします
参照先にも書いてありますが，callocの部分はGC_mallocに書き換えが必要(伴いgc/gc.hも追加)．

```
$ gcc array.c -lgc
$ ./a.out
object size = 1000 bytes
array length = 12345
iterations = 123456
minimum = 8 * 12345 + 1000 * 12345 = 12443760
total alloc = 8 * 12345 + 1000 x 123456 = 123554760
0.291509 sec for 123456 allocs (2361.237308 nsec per alloc)
```

# 教えてほしい部分
+ 正確なGCを実行するための変換器 [Magpie](https://www.cs.utah.edu/~rafkind/gc/magpie/)をコンパイルできた方いましたら教えてください．