OmniAICreator/Qiita-1.07M huggingface dataset:
RustからWebAssemblyを出力するまで（2019年3月現在）


TL;DR; Rust、Node.js、wasm-pack、webpack、そしてwebpack-dev-serveが必要です

2019年3月の時点で、何が必要がわからなかったのでまとめました。

# Rustを使ってWebAssemblyを出力するまでの流れ

RustはそのままでもWebAssembly（以下、WASM）に出力することはできます。しかしJavaScriptとの連携を考えると、[wasm-pack](https://github.com/rustwasm/wasm-pack)を使うのが、一番簡単です。

プロジェクトの作成から、作ったWASMをWebブラウザーで動かすまでの流れは、こんな感じです：

1. Cargoでプロジェクトを作成
2. Rustでプログラムを書く
3. wasm-packを使って、RustをWASMを出力。
4. WASMを利用するJSを書く
5. JSとWASMをバンドルする
6. サーバーで作ったものを配信する
7. ブラウザーでアクセスする

Rustをビルドした後に、JSをビルドするというところがコツです。

# プロジェクトを始める前に必要なもの

プロジェクトを始める前に、次の2つは必要です。

* [rustupとRustコンパイラー](https://rustup.rs/)
* [Node.js](https://nodejs.org/)とnpm(http://npmjs.com/)
* [wasm-pack](https://github.com/rustwasm/wasm-pack)

[rustupの使い方はこちらの記事](https://qiita.com/chikoski/items/b6461367e8c3875bb235)を参照してください。

wasm-packのインストールは、Rustをインストールした後です。次のようにCargoを使えばインストールできます。

```sh
% cargo install wasm-pack
```

# プロジェクトの準備

Cargoを使ってプロジェクトを作成します。ライブラリとして作ります。

```sh
% cargo new --lib hello-world 
```

つくったら、`cargo.toml`に依存するライブラリを追加していきます。最低でも、次のように[wasm-bindgen](https://crates.io/crates/wasm-bindgen)は追加します。

```toml
[package]
name = "greet"
version = "0.1.0"
authors = ["chikoski <some.email.address@example.com>"]
edition = "2018"

[lib]
crate-type = ["cdylib"]

[dependencies]
wasm-bindgen = "0.2.37"
```

詳しくは[wasm-bindgenのドキュメント](https://rustwasm.github.io/wasm-bindgen/examples/hello-world.html)を参照してください。

# JavaScript開発の準備

wasm-packコマンドでビルドすると.wasmファイルに加えて、WASMからエクスポートされた関数をラップした関数や、文字列やオブジェクトをWASM-JS間でやり取りするためのユーティリティなどが定義されているJSファイルも作成されます。これらは`pkg`フォルダ以下に配置されています。

```
/ 
├── Cargo.lock
├── Cargo.toml
├── bin
├── pkg
├── src
├── target
├── wasm-pack.log
```

ビルド直後のプロジェクトフォルダ直下は上記のようになっています。

## JSプロジェクトへの組み込みかた

作成したWASMファイルをJSへ組み込むには、2つの選択肢があります。

1. JSのプロジェクトを別に作り、そちらからnpmパッケージとしてインポートする
2. Rustのソースコード中に、JSのコードも配置する

どちらの場合でもWebpackを使ってビルドします。フォルダの配置が異なるので、`webpack.config.js`の内容や、`package.json`の記述が少し変わります。

## Webpackを使ってビルド

wasm-packで出力されるJSは、次のようにWASMファイルをインポートしています。WASMのモジュールと、JSのモジュールの相互運用は提案されていますが、利用できる実行環境はありません。したがって、Webpackを使いビルドして、現在の環境でも利用できるコードを生成します。

プラグインなしでもWebpackはWASMを処理できます。もし、JSのビルドに合わせてRustのビルドも行いたい場合は、[@wasm-tool/wasm-pack-plugin](https://www.npmjs.com/package/@wasm-tool/wasm-pack-plugin)というプラグインを使います。

# Webサーバーに配置する際の注意

Webpackで出力されたコードは、[WASMファイルをストリームコンパイル](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/WebAssembly/compileStreaming)します。

WASMファイルは`application/wasm`というコンテントタイプで配信されなければなりません。[webpack-dev-server](https://github.com/webpack/webpack-dev-server)は特に設定する必要ありませんが、他の場合は設定の追加が必要な場合があります。

# まとめ

wasm-packとWebpackが、よしなにしてくれます。特にWebpackは特別なプラグインなしで使えるのは楽でした。

どういうコードを書けば良いかは、[wasm-bindgenのチュートリアル](https://rustwasm.github.io/wasm-bindgen/)をやると、見えてくると思います。
AWSのIAMロールとポリシーの違い

# ■概要

### ◆AWSのIAMとは？(Identity and Access Management)
　AWSのリソースに紐付けることができる権限設定を行うサービスの事。
　(AWSのリソースは、EC2,RDS,Lambda...etcといった全てのサービスで生成するものに必要な物となります)

### ◆IAMの4つの要素
　IAMには「グループ」、「ユーザ」、「ロール」、「ポリシー」の４つの要素がある。
　(グループとユーザについては別途機会があれば＾＾；)

# ■結論

~~~
IAMロール(Role)　＝　「AWSのリソースに付与するもの」で、実態はIAMポリシーをグルーピングしたもの
~~~
~~~
IAMポリシー(policy)　＝　「AWSリソースにアクセスするための権限設定」で、AWSが最初から用意してくれている
~~~
つまりポリシーはロールに内包されている物であり、ロールはAWSリソースに付与されるものである。

例えば、あるEC2には一つだけIAMロールが付与出来るが、そのロールに様々なポリシーを付与する事で、そのEC2は様々なAWSリソースにアクセスする事が出来るようになる。
(AWSCliコマンドから、S3バケットにアクセスしたり、Lambdaを実行したり出来る。)

![IAM.PNG](https://qiita-image-store.s3.amazonaws.com/0/369592/8f0affe0-8501-18fa-3706-d72f93f7b97c.png)

# ■詳細

### ◆IAMロールの細かい話
  - IAMロールは作成する際に、どのサービスで使うかを選択する必要がある。
　(よく使われるサービスがEC2とLambdaなので、下記のキャプチャのように、上のほうにピックアップされている)
![IAM2.PNG](https://qiita-image-store.s3.amazonaws.com/0/369592/8dac9438-c8bd-d0e1-d868-4e9fd9807e0e.png)

### ◆IAMポリシーの細かい話
  - IAMポリシーは、AWSが用意してくれているもの以外に、自作することも出来る(インラインポリシー)
　(その際は、ビジュアルエディタでポチポチサービスを選んで作ることも、JSONを書いて作ることも出来る)
    - これは、AWSが用意しているポリシーでは、細かい設定が仕切れない事や、対象リソースを絞ったポリシーを作る必要がある人の為。
    - さらにロールに設定できるAWSのマネージメントポリシーは最大10個までしか付与できないため(インラインポリシーなら無限？に付与できる)

# ■最後に
　今回はAWSの最初によく躓く最初にIAM周りにふれてみました。
　IAMグループは、さらにポリシー設定をグルーピング化した物で、IAMユーザはAWSにログインした時orプログラムに権限を渡すときに作るものです。
　↑説明が雑なので、要望があれば別途書きます。
　以上、フィードバックやご指摘等いただけると大変ありがたいです!!よろしくお願いいたします!!
LINE Notify

# 概要
LINE Notify を使ってみる。

# 手順
## Line Notify にログイン
https://notify-bot.line.me/en/
![image](https://qiita-image-store.s3.amazonaws.com/0/366472/d8f8b309-b603-ff42-daf5-38ae8271456d.png)

## アクセストークンを取得
![image](https://qiita-image-store.s3.amazonaws.com/0/366472/5663f813-cfbe-d15c-89c6-6c4c46c40d4a.png)

![image](https://qiita-image-store.s3.amazonaws.com/0/366472/6566ee56-4db5-08be-4f97-e428fb700e1f.png)

- 適当な文字列（20文字以下）
- Notify 通知先の部屋

を入力（選択）

## 通知を送る
アクセストークンを使って、Post リクエストを発行する。
例えば、[次のページ](
https://cipepser.hatenablog.com/entry/go-line-notify) のようにgo を利用して送ってみる。

```
% cat line.go
package main

import (
    "log"
    "net/http"
    "net/url"
    "strings"
)

func main() {
    accessToken := <access-token>
    msg := "テストメッセージ"

    URL := "https://notify-api.line.me/api/notify"

    u, err := url.ParseRequestURI(URL)
    if err != nil {
        log.Fatal(err)
    }

    c := &http.Client{}

    form := url.Values{}
    form.Add("message", msg)

    body := strings.NewReader(form.Encode())

    req, err := http.NewRequest("POST", u.String(), body)
    if err != nil {
        log.Fatal(err)
    }

    req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
    req.Header.Set("Authorization", "Bearer "+accessToken)

    _, err = c.Do(req)
    if err != nil {
        log.Fatal(err)
    }
}
```

## 実行すれば、メッセージが届く
```
% go run line.go
```
UnityでAndroidのアプリ作成実践

# はじめに
UnityでAndroidのアプリ作成を試してみたくて、まずはチュートリアルを試してみました。
<https://unity3d.com/jp/learn/tutorials/projects/hajiuni-jp>

#開発環境
Unity 2018.3.0f2
Visual Studio 2017
Android Studio 3.3.1
Unity Remote5
GitHub for Unity 1.2.1

#チュートリアルから修正
チュートリアルの説明に従い1～7まで作成したところで、一応PC上ではゲームとして遊べる状態になったので、Android用のビルド、実機上のデバッグまで実行してみました。
手順は以下ページが参考になりました。
<https://qiita.com/taroyan/items/2ff7f6aadd640221bde5>

チュートリアルはPC向けのため操作はキーボードなのですが、このままではAndroid上で操作できません。
操作に対応するコードPlayerControllerをタッチ操作できるように書き換えます。
以下ページが参考になりました。
<https://docs.unity3d.com/jp/460/ScriptReference/Input.GetTouch.html>

#Unity Remote
実機上でデバッグするためにはAndroid用にビルドする必要があるのですが、非常に時間がかかります。
PC上だけでは、タッチ操作などAndroidに依存する機能はデバッグできないため、簡易的にデバッグするツールとしてUnity Remoteが使えます。

#ソースコード管理
ここまでできたところで、GitHub上でソースコード管理してみようと考えてGitHub for Unityを導入しました。
手順は以下ページが参考になりました。
<http://kan-kikuchi.hatenablog.com/entry/GitHub_for_Unity>
Unity上から簡単にGitHubへのpushまで行えました。
gitignoreファイルが自動で作成されるので非常に助かります。
今回作成したリポジトリは以下になります。
<https://github.com/SatoshiTakahama/Roll-a-Ball.git>
「Debugger for Chrome」で launch.json の file の書き方

#「Debugger for Chrome」で launch.json の file の書き方

### 誰のため？
[Visual Studio Code] で HTML 内に Javascript のコードを書いて、その場でデバッグ実行してみようと [Debugger for Chrome] プラグインを入れて F5 キーを押してみたけど、うまくいかず「いや、だから、index.html じゃなくて、いま開いている編集中のこのHTMLのコードをデバッグ実行したいんだってば！！」って思ったひと向け。

ちなみに、[Debugger for Chrome] は超絶便利なので、[Visual Studio Code]を入れたら絶対入れるべきおすすめプラグイン

[Visual Studio Code]:https://ja.wikipedia.org/wiki/Visual_Studio_Code

[Debugger for Chrome]:https://marketplace.visualstudio.com/items?itemName=msjsdiag.debugger-for-chrome

### 答えは ${file}

キモはこれ -> `"file": "${file}"`

launch.json にこれを書くだけで VSCode が開いているHTMLファイルをChromeが開くようになる。もちろんデバッグもできるようになる。

最初から、そう書いておいてくれれば百倍助かるのにね。

```JSON:launch.json
{
    // IntelliSense を使用して利用可能な属性を学べます。
    // 既存の属性の説明をホバーして表示します。
    // 詳細情報は次を確認してください: https://go.microsoft.com/fwlink/?linkid=830387
    "version": "0.2.0",
    "configurations": [
        {
            "type": "chrome",
            "request": "launch",
            "name": "Launch Chrome",
            "file": "${file}"
        }
    ]
}
```
たったそれだけのことなのに、ググってもなかなか出てこないんだよね。

これで、Javascript を高速デバッグできますね。どぉ？できた？？

### 参考：
${file} 以外に定義されている変数はこちら
https://code.visualstudio.com/docs/editor/variables-reference

> The following predefined variables are supported:
> 
> ${workspaceFolder} - the path of the folder opened in VS Code
> ${workspaceFolderBasename} - the name of the folder opened in VS Code without any slashes (/)
> ${file} - the current opened file
> ${relativeFile} - the current opened file relative to workspaceFolder
> ${fileBasename} - the current opened file's basename
> ${fileBasenameNoExtension} - the current opened file's basename with no file extension
> ${fileDirname} - the current opened file's dirname
> ${fileExtname} - the current opened file's extension
> ${cwd} - the task runner's current working directory on startup
> ${lineNumber} - the current selected line number in the active file
> ${selectedText} - the current selected text in the active file
> ${execPath} - the path to the running VS Code executable
heavens_doorを使ってみた

#はじめに

Rails/Rubyのコミッターである[a_matsuda](https://github.com/amatsuda)さんが制作されている[heavens_door](https://github.com/amatsuda/heavens_door)のチュートリアル記事です

#実際のデモ

実際にはこんな感じで動作します

![heavens_door.gif](https://qiita-image-store.s3.amazonaws.com/0/191521/e6a7456e-cdad-249d-0cd7-501cc8ae057d.gif)

なお、実際に作ったものは[こちら](https://github.com/S-H-GAMELINKS/heavens_door_sample)

#チュートリアル
## rails new

まずは、`rails new`で`heavens_door`を試すサンプルアプリを作ります

```shell
rails new heavens_door
```

## capybaraの導入

次に、[`capybara`](https://github.com/teamcapybara/capybara)を導入します

```ruby:Gemfile
gem 'capybara', '>= 2.15', group: :development
```

そのあと、`bundle install`を実行します

```shell
bundle install
```

## テスト用CRUD作成

テストするためのCRUDを作成します

```shell
rails g scaffold post title content
```

その後、`rails db:migrate`を実行します

```shell
rails db:migrate RAILS_ENV=test
```

## heavens_doorの導入

`heavens_door`を導入したいと思います！

`Gemfile`に`heavens_door`を追加します

```ruby:Gemfile
gem 'heavens_door', group: :development
```

`bundle install`で`gem`をインストールします

```shell
bundle install
```

## heavens_doorを使う

最後に、`heavens_door`を使ってみましょう！

まず、`test/intgration/posts_test.rb`を作成し、以下のようにします

```ruby:test/intgration/posts_test.rb
require 'capybara/rails'
require 'capybara/minitest'

class ActionDispatch::IntegrationTest
  include Capybara::DSL
  include Capybara::Minitest::Assertions

  def heavens_door
  end
end
```

その後、`rails s`でローカルサーバを起動し、`localhost:3000/posts`にアクセスします

```shell
rails s
```

あとは画面右上に表示されているボタンをクリックするとUI操作の記録がはじまります

適当に操作したあと、バインダーマークをクリックするとUIテストのコードがクリップされます

あとは、`test/intgration/posts_test.rb`にクリップしたコードを貼り付けます

```ruby:test/intgration/posts_test.rb
require 'capybara/rails'
require 'capybara/minitest'

class ActionDispatch::IntegrationTest
  # Make the Capybara DSL available in all integration tests
  include Capybara::DSL
  # Make `assert_*` methods behave like Minitest assertions
  include Capybara::Minitest::Assertions

  # Reset sessions and driver between tests
  # Use super wherever this method is redefined in your individual test classes
  def heavens_door
    scenario 'GENERATED' do
        visit '/posts'
    
        click_link 'New Post'
    
        fill_in 'Title', with: 'test'
        fill_in 'Content', with: 'aaaaaaaaaaaaaaaaaaaaaaaaa'
        click_button 'Create Post'
    
        click_link 'Back'
    end    
  end
end
```

最後に、`rails test`を実行してください

```shell
rails test
```

テストが実行されていればOKです！

# 参考

[amatsuda/heavens_door](https://github.com/amatsuda/heavens_door)

[teamcapybara/capybara#using-capybara-with-minitest](https://github.com/teamcapybara/capybara#using-capybara-with-minitest)
LaravelのEloquentでリレーション関係の子データを取得して、そのデータをVue.jsで使用するときに困った





はじめての記事なのでうまく伝わるかわかりませんが、
joinを使わないやり方で調べてもなかなか出てこなかったので備忘録。

#DBの構成

Employee(社員)テーブル

```
+---------+--------+---------------+
| id      | name   | department_id |
+---------+--------+---------------+
|       1 | 田中    | 1             |
|       2 | 鈴木    | 2             |
|       3 | 佐藤    | 3             |
|       4 | 吉田    | 1             |
+---------+--------+---------------+
```

Department(部署)テーブル

```
Department(部署)テーブル
+---------+-----------+
| id      | name      |
+---------+-----------+
|       1 | 営業部     |
|       2 | 経理部     |
|       3 | 技術部     |
+---------+-----------+
```


このとき、EmployeeテーブルとDepartmentテーブルのリレーションは多対１になります。


#リレーションの簡単な説明(前置き)

このテーブルを使って、社員の一覧を表示する。
その際に、社員それぞれの部署名も一緒に表示させたい。

こういう風な一覧を作りたい

```
+---------+--------+------------+
| id      | name   | department |
+---------+--------+------------+
|       1 | 田中    | 営業部　　　 |
|       2 | 鈴木    | 経理部      |
|       3 | 佐藤    | 技術部      |
|       4 | 吉田    | 営業部      |
+---------+--------+------------+
```

Laravelでは、リレーションを張ることで、簡単に表示させることができるようです。

リレーションに関するドキュメント
https://readouble.com/laravel/5.7/ja/eloquent-relationships.html

それぞれのModelクラスを作り、Employee.phpを以下のように記述

```Employee.php
<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Employee extends Model
{
    /**
     * この社員が持っているdepartment_idと一致するレコードを部署テーブルから取得
     */
    public function department()
    {
        return $this->belongsTo('App\Department');
    }
}

```

belongsTo関数を第１引数しか使わない場合は、関数名はテーブル名にしないといけないようです。
関数名_id と belongsTo() の第１引数で指定したモデルが持つidを結びつけるとのこと。

idとして使うカラムの名前が違う場合は、第２、第３引数で変更できるみたいです。

そして、あとは社員テーブルの一覧を普通に取得するだけ

```Employee.php

public function get()
{
    $results = Employee::all();
    return $results;
}
```

これだけで勝手にDepartmentテーブルのデータと結合してくれます。
phpで使うなら

```
$result->department->name
```
で部署名が取れます。

真ん中のdepartmentはテーブルじゃなく関数名っぽいです。


1対1だったり、この例題と逆の参照でやる場合とかはドキュメントに乗ってたり
他の人が書いてくれているのでそちらを参考に

ここからが本題

#本題

これをAPIを使ってVue.jsで受け取ったあと

```Vue.js
{{ result.department.name }}
```

こんな感じで表示させようとしたときにエラーがでました。

```
Error in render: "TypeError: Cannot read property 'name' of undefined"
```

console.logとかで見てもあるやん！としかならなくて困りました。

多分、レスポンスを返すときにresponse()->json()でjsonにしていたつもりが
departmentの中までは正しく変換されていなかった感じだと思います。
(よくわかんないので詳しい方解説してくれれば嬉しいです...)

そういう雰囲気で検索かけたら、stackoverflowに質問していた方がいて、
さらに回答してくれている方がいました！

#解決策
https://stackoverflow.com/questions/37289274/convert-eloquent-relationship-into-vue-js-code

社員一覧を取得するときに、こう書けよということみたいです

```Employee.php

public function get()
{
    // $results = Employee::all();
    $results = Employee::with('department')->all(); 
    return $results;
}

```

withの中はbelongsToを使っている関数名っぽいです

Modelクラスのつもりなんでそのままリターンしてますが、
クライアントに返すときはちゃんとJsonにして返すといいと思います。




指摘があれば教えて下さい。
同じ境遇の人の助けになると嬉しいですm(_ _)m
google-fluentdのログが容量食いまくってた


## 概要
GCEで稼働しているサーバ(CentOS7)のディスクが妙に減っているので、見てみたところgoogle-fluentdが悪さしていた。

## ディスクの容量確認

rootボリュームとして50GBのPersistent Diskをアタッチしている。
Apache+Tomcatが稼働していて、Tomcatとかのログローテも入れてるのに妙に容量食っている。

```sh
$ df -h
ファイルシス   サイズ  使用  残り 使用% マウント位置
/dev/sda1         50G   20G   31G   40% /
devtmpfs         3.6G     0  3.6G    0% /dev
tmpfs            3.6G     0  3.6G    0% /dev/shm
tmpfs            3.6G  337M  3.3G   10% /run
```

## どこが容量を食っているか調べる

あれ？どこもたいして容量食ってなくない？っていうか全然数字が合わなくない？

```sh
# du -sh /*
0	/bin
88M	/boot
0	/dev
34M	/etc
221M	/home
0	/lib
0	/lib64
0	/media
0	/mnt
1.6G	/opt
0	/proc
200K	/root
337M	/run
0	/sbin
0	/srv
0	/sys
96K	/tmp
2.0G	/usr
1007M	/var
```

## 原因を調べる

`ls`でも出てこないし、どういうことだ・・・と思って、ファイルディスクリプタを確認。

`google-fluentd`お前か！

```
# ls -al /proc/*/fd/* | grep deleted

l-wx------ 1 root    root    64  2月 23 15:31 /proc/6733/fd/7 -> /var/log/google-fluentd/google-fluentd.log.1 (deleted)
```

## 対応方法

`google-fluentd`を再起動

```shell
# systemctl restart google-fluentd
```

## 解決

```shell
# df -h
ファイルシス   サイズ  使用  残り 使用% マウント位置
/dev/sda1         50G  4.8G   46G   10% /
devtmpfs         3.6G     0  3.6G    0% /dev
tmpfs            3.6G     0  3.6G    0% /dev/shm
tmpfs            3.6G  337M  3.3G   10% /run
tmpfs            3.6G     0  3.6G    0% /sys/fs/cgroup
tmpfs            732M     0  732M    0% /run/user/1007
tmpfs            732M     0  732M    0% /run/user/1002
tmpfs            732M     0  732M    0% /run/user/0
```


## それでもダメな場合・・・

google-fluentdを停止して、削除する

```shell
systemctl stop google-fluentd
rm　-f /var/log/google-fluentd/google-fluentd.log
systemctl stop google-fluentd
```
Kaggle APIで楽にGCPにデータをダウンロード

####GCP(Google Cloud Platform)でkaggleコンペにチャレンジしていますが、コンペのデータ量が大きいためkaggle APIを使ったデータダウンロードをやってみました。もっと賢いやり方があるかもしれないですが、自分は以下のように行いました。

#1. API トークンの生成とダウンロード

Kaggleのアカウントページ（https://www.kaggle.com/ username /account）の
ページ下部のAPIでAPI tokenを生成します。
![api.PNG](https://qiita-image-store.s3.amazonaws.com/0/328424/49edb502-9b1a-1ca5-4b55-3cae70568a64.png)


#2. APIトークンをGCPのstorageにアップロード
直接手元のPCからGCPのCompute Engineにファイルをアップロードする方法を知らないので、一旦storageにアップロードします。

#3. GCP Compute Engineでkaggle APIをインストール
GCPのCompute Engineのインスタンスを起動し、コンソールで、
`pip install kaggle`
kaggle APIをインストールします。
すると、ディレクトリ直下に .kaggle　という名称のディレクトリが生成されます。
![apitoken.PNG](https://qiita-image-store.s3.amazonaws.com/0/328424/4bcaf3dd-69aa-4242-ef70-e09333482bf1.png)
先ほどAPIトークンを生成したkaggleのページでは、APIトークン生成後に上記のように、
「.kaggleというディレクトリにkaggle.jsonのAPIトークンを配置するように」という注意が出ますので、
これに従って、GCPのstorageにアップロードしたAPIトークンをこのディレクトリに移動させます。
APIトークンがStorage直下、移動させる先のディレクトリは.kaggleとすると下記コマンドで移動できます。
`gsutil cp gs://バケット名/kaggle.json ./.kaggle`

#4.Kaggle APIでコンペデータをGCP Compute Engineのディレクトリにダウンロード
コンペのページの「Data」タブに、データダウンロードのAPIがあるので、それをコピーして
GCP Compute Engineのコンソールで実行します。
![dd.PNG](https://qiita-image-store.s3.amazonaws.com/0/328424/69f588de-8a41-aea6-7512-0e4905a2dff6.png)
例えば、今回はLANLの地震予測のコンペのデータで、それをCompute Engineの/inputというディレクトリにダウンロードしたいときのコマンドは下記です。
`cd input`
`kaggle competitions download -c LANL-Earthquake-Prediction`
すると、2GBにも及ぶコンペデータが30秒足らずでGCPに移行出来ました。
![dl.PNG](https://qiita-image-store.s3.amazonaws.com/0/328424/96719588-8368-461a-8d35-f8d6af200225.png)
Gitリポジトリの内容を別のマシンに送る時にgit bundleを使う

手元のマシンでgitで管理しているファイルを別のマシンに送りたいと思ったときに、以下の3つが自分の中にはあった。

- 一旦リモートリポジトリにpushして別マシンからcloneする
- `git reset --hard`した後、zip圧縮して送る
- `git clone project-name copy-of-project-name`した後、`copy-of-project-name`を圧縮して送る

ただ、どれも微妙な気がしていた。

そこで`git bundle`というものを知ったので試した。
ざっくりいえば、gitリポジトリのある範囲の内容を1ファイルにまとめる的な事をやってくれるらしい。

### 手順

今回はmasterブランチの内容をまとめて持っていく感じで使う。

まず、`master`ブランチを対象に `project-name.bundle` というバンドルファイルを作る。

``` bash
git bundle create project-name.bundle master
```

これで同ディレクトリに`project-name.bundle`というバンドルファイルができあがる。
これをリモートマシンへどうにかして送る。（scpとかftpとかUSBメモリとか）

受け取ったら以下のようにして取り込む。

``` bash
# バンドルファイルからcloneする
git clone project-name.bundle project-name

# git cloneによりディレクトリが作られるので移動
cd project-name

# HEAD(masterブランチ)をorigin/masterに移動し、ワーキングツリーもreset
git reset --hard origin/master
```

ちょっと違うのが、git clone直後のHEADは何も指してない状態になっている。つまりワーキングツリーも空っぽの状態になっている。（`.git`しかない状態）
なので、`git reset --hard origin/master`で無理やりワーキングツリーの状態をorigin/masterの状態にする。なお、origin（リモート）はバンドルファイルを指している。

バンドルファイルの扱いは色々あるみたいで、これで良いのかはわからないけど、多分これが一番楽だと思います。

ただ、ある程度大きいプロジェクトだと辛いかもしれない。そもそも今時のプロジェクトはリモートリポジトリがあるはずですし、わざわざこんな方法は取る必要はないでしょう。

あと言うまでもないですが、信頼できるバンドルファイルに対して使いましょう。

### その用途にgitはいらないのでは

「必要なファイルをコピーして送れるなら、わざわざgitを使わなくてもいいのでは」といえばそうなんですが、この方法は以下の点が良いです

- **commitした時点の綺麗な状態を間違いなく作れる**のが良い
- 履歴をさかのぼりたくなる時をカバーできる

逆に、もしここら辺にメリットに感じなかったら、この方法は使わなくてよいと思います。


### 参考にしました

[7.12 Git のさまざまなツール - バンドルファイルの作成](https://git-scm.com/book/ja/v2/Git-%E3%81%AE%E3%81%95%E3%81%BE%E3%81%96%E3%81%BE%E3%81%AA%E3%83%84%E3%83%BC%E3%83%AB-%E3%83%90%E3%83%B3%E3%83%89%E3%83%AB%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB%E3%81%AE%E4%BD%9C%E6%88%90)

ここではbundle create時にHEADを含めていたが、含めてもcloneした時点でワーキングツリーがmasterの時点になる事はなかった。`.git/refs/heads/master`が無いのでそれが原因なような気はする。
[CarrierWave]RSpec実行後の画像ファイルを削除する

#はじめに
RSpecでテストを何度も実施していたら画像ファイルが膨大に保存されており、自動で削除されるように設定したのでメモします。

##参考にしたサイト
[How to: Cleanup after your Rspec tests](https://github.com/carrierwaveuploader/carrierwave/wiki/How-to%3A-Cleanup-after-your-Rspec-tests)
[Rspecのcarrierwaveを実行した後のファイルを削除](https://qiita.com/hsu/items/e3430b036d6abf83cc09)
[画像周りの扱い方](https://qiita.com/jiggaman0412/items/64cb44592923bde2e8ff#-uploader%E3%81%AE%E8%A8%AD%E5%AE%9A)
[CarrierWave + RSpec ディレクトリ問題](http://noodles-mtb.hatenablog.com/entry/2013/08/06/153002)

##手順
###1. 環境
```
ruby                  : 2.5.1
rails                 : 5.2.2
device                : 4.6.1
carrierwave           : 1.3.1
rspec-rails           : 3.8.2
```
###2. development時とtest時で画像が保存されるディレクトリを分ける
Carrierwaveをインストールした際に`rails g uploader Photo`をしてapp/uploaders/photo_uoloader.rbが作成されているので、ここに画像の保存場所を設定します。

```ruby:app/uploaders/photo_uoloader.rb
class PictureUploader < CarrierWave::Uploader::Base
# 省略
def store_dir
  if Rails.env.test?
    "uploads_#{Rails.env}/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}"
  else
    "uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}"
  end
end
# 省略
```
###3. テスト終了後にファイルを削除する
spec/rails_helper.rbに以下を追加します。

```ruby:spec/rails_helper.rb
RSpec.configure do |config|
# 省略
config.after(:all) do
    if Rails.env.test?
      FileUtils.rm_rf(Dir["#{Rails.root}/public/uploads_#{Rails.env}/"])
    end
  end
end
```
超初歩的なRubyのスクリプトで残業代を計算する。


元ネタはこちら
[Rubyでユーザのキーボード入力を対話的に受け取るRubyスクリプト]
(https://qiita.com/na0AaooQ/items/65005f51c2430f74d2f0)

最近、仕事する時間が長くなってきて、コンソール上でこっそり残業代を計算するスクリプトが欲しいなーと思ったのでRuby超初心者が書いてみました。

## やりたかったこと

- スマホを取り出して電卓アプリを起動するものもはや面倒なのでなるべくキーボードから手を離さずになにか計算したい。
- RubyのMatzさんの講演会を聞いたのでとりあえずなんでもいいからRubyでなにか書きたかった。
- まあ、とりあえずやることが大事というモチベーションを維持したい。

## 実行環境
OS： MacOS
Ruby： ruby 2.3.7

特にOSによる環境差異はないと思うのでRuby入れれば動くはず

## ちょっと時間がかかったこと

問題点

`getｓ.chomp`で対話的に入力値を取れるかな思ったけどString型になってしまうことを理解していなったので計算実行時こんなエラーが起きた

```
How_much_money.rb:51:in `calc_money': undefined local variable or method `"\u201D\u3042\u306A\u305F\u306E\u6B8B\u696D\u4EE3\u306F"' for #<HowMuchMoneyClass:0x00007fc50a8c4e58> (NameError)
        from How_much_money.rb:58:in `<main>'
MacBook-Pro:Ruby pcuser$ ruby How_much_money.rb
How_much_money.rb:51: syntax error, unexpected tIDENTIFIER, expecting keyword_end
```

解決策

計算のためには整数でないといけないのでInt型に変換するように`gets.to_i`で数値を受け取って上げればおK



## スクリプト本体

コンソールで使う場合は以下のように実行

```
$ ruby How_much_money.rb
```

今のこんな感じで出力されます。（要改良）

```
----------------------------
自分の残業代を計算しますか?
計算する場合は yes、キャンセルする場合は no と入力して下さい.
yes
  計算を実行します.
----------------------------
基準とする時給を入力してください
入力例：）1250
900
----------------------------
仕事をした時間を入力してください。
入力例：）80
40
あなたの残業代は 36000 円です
```
今の所こっそり感はゼロですが、まあ気にしない

特にひねりはないですがソースはこんな感じ

```ruby　How_much_money.rb

#!/bin/env ruby

## ----------------------------
# ユーザからのキーボードの入力を受け取り、
# yes と入力されたらスクリプトを実行する、no と入力されたらスクリプトを終了します.
## ----------------------------

class HowMuchMoneyClass

  def initialize

    puts <<-EOT
----------------------------
自分の残業代を計算しますか?
計算する場合は yes、キャンセルする場合は no と入力して下さい.
    EOT

  end

  def get_keyboard_input_yes_no

     case gets.chomp
       when "yes", "YES", "y"
         puts "  計算を実行します."
       when "no", "NO", "n"
         puts "  スクリプトを終了します."
         exit 1
       else
         puts "  yes または no を入力して下さい."
         confirm = HowMuchMoneyClass.new
         confirm.get_keyboard_input_yes_no
     end
   end

   def calc_money
        # 計算する場所
        puts <<-EOT
----------------------------
基準とする時給を入力してください
入力例：）1250
   EOT
        base_monoey = gets.to_i
        puts <<-EOT
----------------------------
仕事をした時間を入力してください。
入力例：）80
   EOT
        money_time = gets.to_i
       #計算結果を返す
       result = base_monoey * money_time
       puts "あなたの残業代は #{result} 円です"
   end
end


confirm = HowMuchMoneyClass.new()
confirm.get_keyboard_input_yes_no
confirm.calc_money

```
## 感想

コンフィグファイル的なやつを入れれば、コンソールに金額とかの情報を載せずともできそうなので今度改良してみようかなと思いました。

シェルとかPythonとか自分の好きな言語でこういうツールを作ってみるのもいいかもしれないですね。

他の人みたいにエクセレントな設計とかできないので思いついたものから地味にやっていくのがいいかな
Webスクレイピング

#インストール
Beautifulsoupとurllibをインストールしましょう。

```
pip3 install beautifulsoup
pip3 install urllib3
```
#インポート
次にインストールしたモジュールをインポートします。

```
# coding: UTF-8
import urllib.request, urllib.error
from bs4 import BeautifulSoup
```

# htmlの取得
つづいて、htmlを取得したいurlを指定します。今回は日本経済新聞のウェブサイトを指定します。
そのあとにBeautifulSoupで扱える形にします。

```
url = "https://www.nikkei.com/"
html = urllib.request.urlopen(url)
soup = BeautifulSoup(html, 'html.parser')
```
このsoupには、全htmlが格納されています。

#特定の情報の取得
いよいよ、情報を取得していきます。
##titleを取得

```
soup.find("head").find("title") 
もしくは
soup.find("title")
```
#h1を取得(最初に出てきたタグのみ)

```
soup.find("body").find("h1")
もしくは
soup.find("h1")

#textを取得
soup.find("body").find("h1").text
```
##h1のタグをすべて取得
上記の場合、最初に出てきたタグしか出てこない。なので、すべてのタグを取得するには以下のように書く

```
soup.find_all("h1")

#リストとして取得するには[]で囲む
h1s = soup.find_all(["h1"])

#テキストを取得するにはforで回す
h1s = soup.find_all(["h1"])
for h1 in h1s:
 print(h1.text)
オブジェクト指向/オブジェクト指向設計とはなんぞや？

本投稿は書籍[『オブジェクト指向設計実践ガイド ~Rubyでわかる 進化しつづける柔軟なアプリケーションの育て方』](https://amzn.to/2TjKliU)を読んだ際にまとめた備忘録です。

###オブジェクト指向設計とは「オブジェクト同士の依存関係を管理する」こと

**【オブジェクト】**
=>「それぞれが自身の振る舞いを持ち、そして互いに作用し合うもの」

**【アプリケーションの設計が解決する問題】**
=> アプリケーションの変更を容易にする

**【アプリケーションの変更が困難な理由】**
=> オブジェクト間の依存が変更の邪魔をする

**【オブジェクト間の依存】**
=> 部品Aが部品Bを「知っている」という状態のこと
=> 相手にメッセージを送るためにはこの「相手を知っている」状態である必要がある

**【設計の実用的な定義】**
=>「未来を受け入れるための選択肢を保護する」もの
=>「あとにでも」設計をできるようにすること、第一の目標は変更コストの削減

###オブジェクト指向の設計者の道具 = 原則とパターン

**【設計原則】**
=> SOLID
1.単一責任(Single Responsibility)
2.オープン・クローズド(Open-Closed)
3.リスコフの置換(Liskov Substitution)
4.インターフェース分離(Interface Segregation)
5.依存性逆転(Dependency Inversion)

**【設計（デザイン）パターン】**
>「オブジェクト指向ソフトフェア設計において遭遇する様々な問題に対して、簡単でかつ明瞭な解を与える」ものであり「設計プロダクトの柔軟性、モジュール性、再利用性、および理解のしやすさをより高める」ために使えるもの

**【設計が失敗する原因】**
1.設計が十分でない <= 設計が失敗する最初の原因
2.「良かれと思って設計しすぎる」 <= 多少の経験を積んだプログラマの失敗
3.設計の行為と実装の行為が乖離した時 <= 設計とは漸進的な発見のプロセスであり、繰り返しのフィードバックを頼りに進んでいくもの

**【設計を行うタイミング】**
=>詳細設計はしない。小さな追加の繰り返しで作っていくべきで、開発を繰り返すことで本当に必要なものに近づけていく（アジャイル開発？）

*詳細設計
=>提案されたアプリケーションのすべての機能、想定される未来の内部動作をすべて特定し、完全に文書化したもの

**【詳細設計における問題点】**
=>本当に必要な機能は作っていく中で新たに見つかるもので、詳細設計のような事前に考えたものでは本当に顧客に必要なものを満たせない

**【「設計を判断する」】**
=>設計の損益分岐点に従ってその程度を判断すること

```
例)
初学者の場合 => 設計努力をする意味はほとんどない
熟練者の場合 => 設計努力の意味は濃い 
```
=>設計者の目標は、機能あたりのコストが最も低い方法でソフトウェアを書くことであり、この決断は「プログラマのスキル」と「結果が出るまでの時間」による

###オブジェクト指向/オブジェクト指向設計の理解しやすい方法を考える
様々な書籍でオブジェクト指向について触れられていますが、よく見かけるのが「オブジェクト指向は手順ではなく操作するように扱えるもの」「ものとして扱う」みたいな記述が多くて「ん？」となることもあったので、自分なりの例をあげて今回のオブジェクト指向/オブジェクト指向設計の理解を確認してみます。

オブジェクト指向はサッカーゲームを例に考えてみると、理解しやすい気がします。

```例:サッカーゲームの場合
オブジェクトA = 操作する選手
オブジェクトB = 自チームの操作している以外の選手
オブジェクトC = 敵チームの選手
オブジェクトD = 観客
オブジェクトA~Cの振る舞い = パス、シュート、ドリブル、ダッシュ、クリア、スライディングタックル..etc
オブジェクトDの振る舞い   = オブジェクトAが所属するチームを応援する

オブジェクトAは味方であるオブジェクトBにはメッセージは送れる（Bにパスする、等)
オブジェクトCは敵であるオブジェクトAにメッセージを送れる（Aにスライディングタックルする、等）
オブジェクトAは観客であるオブジェクトDにはメッセージを送れない（Dにパスする、等）
⇨選手であるオブジェクトAは観客であるオブジェクトDについての知識は持たせる必要はない

```
図書館駆動読書

# 図書館駆動読書とは
図書館に行き、本を借りて、読んで、返却する、返却時にまた借りる。
このサイクルを繰り返すことです。
名前の通りです。

もともと本をたくさん読むことができる能力者には全く役に立ちません。

本を読む習慣がない私でも本を読む習慣をつけることができそうな感触を得たので
この方法におけるメリットやデメリットなどを言葉にまとめきたいと思います。

# なぜはじめたか？
そもそも私も図書館に行く習慣はありませんでした。
きっかけは色々あって

* 息子の散歩のため毎日外に出るようになった
* そんな中、妻が息子のために図書館に行って絵本を借りてきた
* さらに[静岡の勉強会](https://devlove.doorkeeper.jp/events/84426)で、カイゼンジャーニーの著者が来るとのことで読もうかなと思った

# 図書館の予約システム
静岡市の図書館は予約システムがある、おそらくどこの図書館もあると思う。
ここで予約すればわざわざ自分で行って探す必要がない。借りるだけで済む。
お世辞にも使いやすいとは言えないが、目的の本が決まっていればそんなに苦労することがない。
<img width="500" alt="静岡市図書館予約システム" src="https://qiita-image-store.s3.amazonaws.com/0/48738/b18390d5-8eee-2878-b607-d331f1c04568.png">
「アジャイル」での検索結果画面

# 図書館駆動読書のポイント

## デメリット？
まずはデメリットからまとめてみる。

* 締め切りが決まっている
* 持ち歩くのには重い
* 書き込みができない
* 本が古い（初版）である可能性がある

ただ、これらは見方を変えればメリットになると感じている。

## デメリット？ -> メリット
デメリットをメリットとして捉えてみた。

### 締め切りが決まっている
私のような本を買ってそこで満足するような人間、積んでおくだけの人間は締め切りがないと行動を起こそうとしない。
「２週間」のような返却期限があることでそこを目標に読み進めることができる。

「期日までにとりあえず読んでみよう」という気持ちが生まれて、先頭からじっくり読み進めることがなくなる。
まずはサーっと目を通し、ちょっと読み込みたいところに付箋紙を貼って、読み終えてからじっくり読み返すことができる。
今回やった感覚だと、数百ページある中でも、本当に押さえておきたいなと思うところは１０％程度でそこをちゃんと読み込むことが理解につながると思う。

### 持ち歩くのには重い

重いし、カバンのスペースもとる。正直持ち歩きたくない。
だからこそ、早く読み終えなきゃいけない気持ちにさせてくれる。

### 書き込みができない

ペンを引くとなんだか読んだ気持ちになる。
読んだ気持ちになるのは大事なことだけど、それだけではかなり揮発性の高い知識になってしまう。
書き込めないからこそ、付箋紙を貼ったポイントを読み返し、自身のブログやナレッジとしてまとめる。
そうすることで、ただ読むより知識を定着させることができる。

### 本が古い（初版）である可能性がある

初版本は誤字脱字があったり、情報が古くなっていたりする。
しかし、改訂版ではなく初版に巡り会えたことは喜ばしいことだと考えられる。
元々著者がどういうことを言っていたのか、を理解することができる。
おそらく手元に残しておきたいと思ったら最新の版を購入することになるだろう。
その時に差分を把握できる。
初版から変わっていない大事な要素は何か。
逆に初版から変わったところはどこか、なぜ変わったのか
これら把握し、考えることでより深い理解につながる。

## 他にもメリット

### 紙媒体である

図書館で借りられるものは電子書籍ではなく紙媒体の本。
電子書籍をこれまでいくつか購入したけど、みる媒体はスマホ。
スマホを持つとついつい twitter や facebook 、ゲームなどを開いてしまうのが私。
本は読む以外の機能を提供していない、読むことに集中できるのは大きなメリットである。

最近 PCとスマホの見過ぎか、目がとても疲れているのだが、紙媒体は目にも優しい。

### タダで読める
タダでとりあえず読んでみることができる、しかも長い時間。図書館って画期的だ！
手元に残しておきたいと判断したら購入すればいいし、そうでなければ返却しておしまい。

## 図書館駆動読書にちょっと向いてないかな本

**５００ページくらいあるやつ**
おそらく読み切る前に締め切りが来てしまう。。。


**言語入門系の本**
実際にコードを書きながら読むべきで、読んでポイントを抑えるという方法で少し物足りない。
それでも一度借りて、サーっと読んで、良さそうなら購入してしまえばいい

# 最後に
ビスマルクさんの言葉を引用すると
「愚者だけが自分の経験から学ぶと信じている。私はむしろ、最初から自分の誤りを避けるため、他人の経験から学ぶのを好む。」
読書は他人の経験を学ぶことができる非常にいい習慣なので、継続していきたいところである。
BeagleBoneGreenを動かす02

#BeagleBoneGreenをUpdateする。
リンク先の通りにやれば良いです。SDへのイメージ書き込みツールが双方で違いますがお好きなものを。
http://wiki.seeedstudio.com/BeagleBone_Green/#update-to-latest-software
https://beagleboard.org/getting-started#update


##1.最新イメージをダウンロードする
https://beagleboard.org/latest-images からダウンロードできる。
GUIが必要なければIoTイメージ
GUIが必要であればLXQTイメージをダウンロードする。
今回はGUIは必要ないのでIoT(Debian 9.5 2018-10-07 4GB SD IoT )をダウンロード
![image.png](https://qiita-image-store.s3.amazonaws.com/0/366164/760e43d0-4fcc-76eb-436a-c4f39d404fff.png)

##2.SDカードへの書き込みツールをインストールする
Etcherをダウンロードしてインストールする。
https://www.balena.io/etcher/
![image.png](https://qiita-image-store.s3.amazonaws.com/0/366164/0e61d841-dc24-ded7-9972-f82e57ad3bfb.png)

![image.png](https://qiita-image-store.s3.amazonaws.com/0/366164/4eaabe76-2a83-3036-458e-5660cb94c0d4.png)
インストールが完了するとEtcherが起動する。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/366164/a2bac3da-8b78-3529-aec1-5261d92be604.png)

##3.microSDカードをPCに接続する
AmazonでSanDisk microSDHC 32GB (SDSQUAR-032G-GN6MA)を購入。914円。しばらくSDカードを買っていなかったが安くなった。microSDカードリーダライタに挿入して接続。
![001.png](https://qiita-image-store.s3.amazonaws.com/0/366164/bdcf0439-0ef0-ec9b-e0ae-211250a7e072.png)


##4.イメージをmicroSDカードに書き込む
ダウンロードしたイメージファイルを解凍してできたbone-debian-9.5-iot-armhf-2018-10-07-4gb.imgをEtcherで選択。書き込み先のmicroSDカードドライブを選択して[Flash!]をクリック。ユーザーアカウント制御画面がでた場合は[はい]をクリックしてしばらく待つ。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/366164/20b84442-889c-4ac4-cbf8-df5fb9923253.png)
ファイル&ドライブ選択

![image.png](https://qiita-image-store.s3.amazonaws.com/0/366164/95bc5d67-d3fa-f0e9-96df-098157e51c64.png)
書き込み中

![image.png](https://qiita-image-store.s3.amazonaws.com/0/366164/13e15b89-9ef0-8b01-658b-57fff12d1294.png)
書き込み完了

##5.microSDカードをBeagleBoneに挿入する
BeagleBoneの電源は切った状態でmicroSDカードを挿入する。
![002.JPG](https://qiita-image-store.s3.amazonaws.com/0/366164/42e3c549-700d-eb18-2bbb-431b4d315ef0.jpeg)
ちなみにケースはSeeedのこれ
https://www.seeedstudio.com/beaglebone-c-954/Acrylic-Case-for-BeagleBone-Green-p-2515.html

##6.電源を入れる
電源を入れます。

##7./boot/uEnv.txtを編集する。
/boot/uEnv.txtを編集してeMMC書き込みモードにします。
viで編集する例

```
cd /boot
sudo vi uEnv.txt
```
sudoでないとReadonlyになった。
uEnv.txtの一番下に以下のような文があります。

```
##enable BBB: eMMC Flasher:
#cmdline=init=/opt/scripts/tools/eMMC/init-eMMC-flasher-v3.sh
```

下の行の#を削除して以下のようにします

```
##enable BBB: eMMC Flasher:
cmdline=init=/opt/scripts/tools/eMMC/init-eMMC-flasher-v3.sh
```
viの使い方の参考
https://webkaru.net/linux/vi-editor/
h,j,k,lまたは矢印でカーソル移動
xで1文字削除
:wqで保存して終了

##8.電源を入れ直す&書き込み開始
電源を入れ直すとOS起動後に書き込みが始まります。
しばらくして4つのLEDが行ったり来たりする光り方をすると書き込み中です。
https://raw.githubusercontent.com/SeeedDocument/BeagleBone_Green/master/images/flashing.gif

##9.書き込み完了&自動シャットダウン
書き込みが完了すると自動的にシャットダウンします。
電源を入れ直す前にmicroSDカードを抜きます。
ダウンロードしたイメージと同じバージョンか確認。

```
cat /etc/issue
```

![image.png](https://qiita-image-store.s3.amazonaws.com/0/366164/0df05a11-b23f-7835-5a53-a72c47e4b06a.png)
表示される値がアニメーションしながら変わるUILabelを作ってみた

## はじめに

アプリを作っていると

UILabelで表示される値がぱっと切り替わると機械的だなー

と感じる箇所がちょいちょい出てきました。

なめらかに変わったら見るの楽しくなるなー、変わってる感もわかりやすいなー

と、ふと思ったので、作ってみることにしました。

## 結果

変化方法等、諸々はご自由に変化していただくとして()

![Feb-28-2019 21-34-05.gif](https://qiita-image-store.s3.amazonaws.com/0/81434/2a458097-858b-c2da-90b5-aa83d8be2f54.gif)

## 実装

まず実装を見せますぜ。

```swift

final class AnimateValueLabel: UILabel {

    private var loop         : CADisplayLink?
    private var startTime    : TimeInterval    = 0.0
    private var currentValue : Int             = 0
    private var newValue     : Int             = 0

    func setData(value: Int, animated: Bool = false) {
        self.newValue = value
        if animated && self.currentValue != self.newValue {
            self.animateValue()
        }
        else {
            self.currentValue = value
            self.setText(value: self.currentValue)
        }
    }

    private func animateValue() {
        self.startTime = Date.timeIntervalSinceReferenceDate
        self.loop      = CADisplayLink(target: self, selector: #selector(self.update))

        if #available(iOS 10.0, *) {
            self.loop?.preferredFramesPerSecond = 60
        }
        else {
            self.loop?.frameInterval = 1
        }

        self.loop?.add(to: .current, forMode: .common)
        self.loop?.isPaused = false
    }

    @objc
    private func update(displayLink: CADisplayLink) {
        let duration : TimeInterval = 0.3
        let elapsed  : TimeInterval = Date.timeIntervalSinceReferenceDate - self.startTime

        let progress: Int = Int(Easing.easeIn.quart.getProgress(elapsed: elapsed, duration: duration, startValue: CGFloat(self.currentValue), endValue: CGFloat(self.newValue)))

        self.setText(value: progress)

        if duration < elapsed {
            self.loop?.isPaused = true
            self.loop?.invalidate()
            self.currentValue = self.newValue
        }
    }

    private func setText(value: Int) {
        self.text = value
    }
}

```

CADisplayLinkやEasingに関しては過去記事を参考にしていただくとして、

https://qiita.com/haguhoms/items/c87d335756042bc867c4
https://qiita.com/haguhoms/items/abc5635e8fa95719cb12

これで、setDataに渡したvalueを、アニメーションしながら表示することに成功しました。

(コンマがついているのは、ここに書いたコードにはない機能です←)

## 最後に

もちろん、機械的が悪いとかそういう話では一切ありません。

し、全てがアニメーションすることが正しいわけでもないと思います。

が、抱いた不満や思いついたことを試してみて、体験価値的に良さげだったらプロダクトに導入する、そんな試みをひたすらやる旅も悪くないなって、つまりはそういうことです。
AWS Session Managerを使用して30分でSSHログインをやめることができた話 〜JAWS DAYS 2019〜

# はじめに

JAWS DAYS 2019に初めて参加してきました！！

![iOS の画像.jpg](https://qiita-image-store.s3.amazonaws.com/0/207081/67b13d62-49a2-3c1a-2f20-bf90c1a9631f.jpeg)

すごい盛り上がりで、約2000人が参加されたそうです！キャンセル待ちも多数いたとか！！！
朝から参加しましたけど、内容が濃すぎて後半は頭がパンクしておりました…
自分が参加したセッションの中でも特に多くの聴講者がいたと感じたのは、EKS、CI/CDでした。
EKSは皆さん注目しているんでしょうね！弊社も本番環境docker化計画で密かに検討中です！

[JAWS DAYS 2019とは？](https://jawsdays2019.jaws-ug.jp/)
[JAWS DAYS 2019 資料まとめ](https://qiita.com/hayao_k/items/91c19480948f26b71705)

# タイトルと注目のサービスが違うじゃん…

そうなんです。ですが、今回はタイトルにある通りAWS Session Managerについてお話しようと思っております。
JAWS DAYS 2019でもAWS Session Managerのセッションがありました。
弊社の環境では、踏み台サーバを経由してEC2インスタンスにSSHログインする、という流れになっていたのですが、セッションのタイトルに __1日でSSHをやめることができた話__ と書いてあるのを見つけ、すぐに __僕が作った最強のタイムテーブル__ に追加しました。

セッションの資料：[1日でSSHをやめることができた話 ~AWS Systems Manager Session Manager 導入と運用Tips~](https://speakerdeck.com/3utama/1ri-tesshwoyamerukotokatekitahua-number-jawsdays)

# セッションを聞いてみて

- SSHログインが不要
  - 踏み台サーバが不要で余計なEC2インスタンスが減らせる！
  - 公開鍵・秘密鍵の管理が不要！
  - SSHのインバウンドポートが不要
- IAMで一元管理できる
  - 人が増えてもサクッと追加できる！
- コンソールでの実行履歴が残せる
  - S3 or CloudWatchLogsに送れる！
  - CloudWtachLogs→lambdaとかでSlackに通知もできる！

マジかよ…メリットしかないやんけ…




というわけで、すぐにStaging環境で試してみました！

# 試した結果

1日というか、 __30分__ でシェルアクセスが出来ました！！！
登壇者の方も「1日と言っていますが、実際かかったのは3時間くらいです。」と仰っていましたが、それ以上の簡単さでした！

というわけで、自分が設定した手順を説明します。

## 手順
1. EC2に割り当てられているロールに __AmazonEC2RoleforSSM__ をアタッチする

以上でした。


<img width="1550" alt="スクリーンショット 2019-03-01 15.39.22.png" src="https://qiita-image-store.s3.amazonaws.com/0/207081/92adf626-8e3f-42aa-405e-91663a10a372.png">

え…？マジで…？





実際に最小限これで出来ました。本当はよりセキュアにする設定もあるのですが、とりあえずお試しなのでよしとします。

本来の手順であれば、

1. EC2にSSMエージェントをインストール
1. IAMインスタンスプロファイルロールの作成
1. EC2に上記のロールを割り当てる
1. その他、よりセキュアな設定

とするのですが、弊社の環境はElasticBeanstalkを使用して、オートスケールするようにしています。
EC2にはすでに専用のロールが設定されており、そこに __AmazonEC2RoleforSSM__ をアタッチしました。
また、SSMエージェントは2017年9月以降のAmazon Linux AMI に標準インストールされています。

そのため、たった1ステップでインスタンスにシェルアクセスができるようになったというわけです！
（セキュアな設定…？Staging環境だから大丈夫！！）

## それだけで30分はかかりすぎでしょ…

ポリシーをアタッチしてもすぐに反映されてなくて…色々調べてから戻って来たら表示されてて…


# 今後の予定
Staging環境でしばらく使ってみて、問題がなければセキュアな設定をしたのち、本番環境にも適用しようと思います！

# おわりに

JAWS DAYS 2019に行けてとてもよかったです！！
運営の皆さま、登壇者の皆さま、スポンサーの皆さま、本当にありがとうございました！！
この流れで頑張ってEKSを使って本番環境docker化していきたいと思います！！

# 追記
その後セキュアな設定をした際に色々調べた結果、弊社のEC2は全てNATゲートウェイを通って外に出ていたので、1ステップでシェルアクセスができていたことが分かりました…
セッション時のコマンドとかの情報が外にダダ漏れしていた訳ですね…壊れるなぁ…
セキュアな設定（VPCエンドポイントの設定）をすることで、VPC内に閉じた通信経路でセッションマネージャを使用することができるため、ちゃんとその設定をしてから使いましょう！！！
Goで、DBレコードから良い感じにJSON生成する

こんな感じのレスポンスを期待されている時に、JSONをどう生成したかという話。

```bash
$ echo '{"books": [{"id":"1","title":"Story about Ruby","amount":20,"created_at":1551354984},{"id":"2","title":"Story about Pearl","amount": -30,"created_at":1551354984}]}' | jq .
{
  "books": [
    {
      "id": "1",
      "title": "Story about Ruby",
      "amount": 20,
      "created_at": 1551354984
    },
    {
      "id": "2",
      "title": "Story about Pearl",
      "amount": -30,
      "created_at": 1551354984
    }
  ]
}
```

なんか変なデータ構造だけど、実際のプロジェクトコードの構造体名を変えてたりなので、まぁ気にせず😀

```go
// 複数テーブルからのデータを統合した情報
type BookWithAmount struct {
	Book  *models.Book
	Amount int64
}

// 蔵書一覧レスポンス
type booksResponse struct {
	Books []bookRecord `json:"books"`
}

// 蔵書一覧レスポンスに含まれるレコード
type bookRecord struct {
	ID          string `json:"id"`
	Title       string `json:"title"`
	Amount      int64  `json:"amount"`
	CreatedAt   int64  `json:"created_at"`
}

// レスポンス用に蔵書レコードを整形して返す
func getBooksResponse(books []BookWithAmount) booksResponse {
	records := []bookRecord{}
	for _, b := range books {
		r := bookRecord{}
		r.ID = strconv.FormatInt(b.Book.ID, 10)// 文字列希望
		r.Title = b.Book.Title
		r.Amount = map[bool]int64{true: b.Amount, false: -b.Amount}[b.Book.Type == Order]// 場合によってマイナス値に
		r.CreatedAt = b.Book.CreatedAt.Unix()// タイムスタンプ希望
		records = append(records, r)
	}
	return booksResponse{Books: records}
}

func main() {
	// ごにょごにょ...（DBからレコード取得）

	// レスポンス整形
	booksResponse := getBooksResponse(books)
	json, err := json.Marshal(booksResponse)
	if err != nil {
		return
	}

	// ゴニョゴニョ...（レスポンスとして返す）
}
```

複数テーブルから必要な情報を抜き出して、クライアントが期待する形式にできました👨‍💻🥤
MongoへGO！

##mongo-go-driverを使ってMongoDBに接続##
[MongoDB Go Driver Tutorial](https://www.mongodb.com/blog/post/mongodb-go-driver-tutorial)に従ってもできなくて苦労したが、Mongoと接続できたので学習記録を残す。


##### システム環境
* Win10
*  [Mongo](https://docs.mongodb.com/manual/tutorial/install-mongodb-on-windows/) version v4.0.6
*  [Go](https://golang.org/doc/install) version go1.12 windows/amd64


##### 作業記録
環境変数GOPATH/src下にmongo/mongodb-test.goを作成。

```go:mongodb-test.go
package main
import (
	"context"
	"fmt"
	"log"
	"go.mongodb.org/mongo-driver/mongo"
)

func main() {
	// Rest of the code will go here
	client, err := mongo.Connect(context.TODO(), "mongodb://localhost:27017")
	if err != nil {
		log.Fatal(err)
	}
	// Check the connection
	err = client.Ping(context.TODO(), nil)
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println("Connected to MongoDB!")
}
```
[MongoDB Go Driver Tutorial]((https://www.mongodb.com/blog/post/mongodb-go-driver-tutorial))に従ってcmd window で　`go get github.com/mongodb/mongo-go-driver` を実行すると次のようなエラーが。

<pre>
can't load package: package github.com/mongodb/mongo-go-driver: no Go files in C:/....
</pre>


そこで同マニュアルの　`dep ensure --add....` も試したが解決せず。
ネットで色々調べてwin-cmd, [git bash](https://gitforwindows.org/)でdep versionをチェックしたがdepが入っていないことがわかり、`dep install`を実行。(https://github.com/golang/dep/issues/1353).


#解決したときの手順#
1.  環境変数GOBINを設定
2.  GOPATH/srcで 
	`go get -u github.com/golang/dep/cmd/dep`
	`go get -u github.com/mongodb/mongo-go-driver`を実行。
しかし、また`#could not find project Gopkg.toml, use dep init to initiate a manifest#`のエラーが出たので`dep init ./mongo`を実行。
3. Fetching sources... は遅いのでじっと待つとmongoフォルダに
         vendor,
         Gopkg.lock,
         Gopkg.toml
がつくられた。
4.      `cd ./mongo`
	`go run mongodb-test.go`
5. `#Connected to MongoDB!#` が表示され、接続できた！:relaxed:



次はデータベースを作成する予定です。
【個人用まとめ】git flowを使った開発

# はじめに

コマンドラインからgit flowを使って開発をしたときにコマンドや手順を調べるのが面倒だったのでまとめます。
個人開発なので、複数人での開発とは違う部分もあるかと思います。
間違い等ありましたらご指摘お願いします。

# git flow のインストール

`yum install git-flow`でインストールできるというのを見かけたのですが、できないっぽいので他のやり方でインストールします。

```
$ cd /usr/local/src
$ sudo bash
$ wget -q -O - --no-check-certificate https://github.com/nvie/gitflow/raw/develop/contrib/gitflow-installer.sh | bash
$ exit
```

# git flowの初期化

管理したいリポジトリで下記コマンド実行。

```
$ git flow init
# いろいろでてくるけどとりあえず全部EnterでOK
```

ちなみに`-d`オプションを付けると自動で初期設定をしてくれます。

リモートリポジトリがあるなら初期化した後`git push --all`してもいいかも。

# 開発手順

## featureブランチ

developブランチからfeatureブランチを切って機能の追加を行います。

```
$ git flow feature start hogehoge
```

これでfeature/hogehogeブランチが作成され、チェックアウトされます。

作業が終わったら

```
$ git add .
$ git commit -m "hoge"
$ git flow feature finish hogehoge
```

でdevelopブランチにマージされてfeature/hogehogeブランチは削除されます。

developブランチにマージされた後、developブランチをpushします。

## releaseブランチ

リリース作業をする際は、developブランチからreleaseブランチを切ります。

```
$ git flow release start v1.0
```

リリース作業が終わったら

```
$ git add .
$ git commit -m "hogehoge"
$ git flow release finish v1.0
```

を実行すると、masterブランチとdevelopブランチにマージして、masterブランチにタグをつけてくれます。

タグはreleaseブランチの名前が付くようです。

また、releaseブランチは削除されます。

この作業が終わったら`git push --all`ですべてリモートリポジトリにあげます。

## hotfixブランチ

緊急性の高いバグなどを修正する際に利用します。
master ブランチからhotfixブランチを切ります。

```
$ git flow hotfix start v1.1
```

作業が終わったら

```
$ git add .
$ git commit -m "hogehoge"
$ git flow hotfix finish v1.1
```

でmasterとdevelopブランチにマージされて、masterブランチにタグが付きます。

# 余談

~~Cmderを利用しているのですがreleaseブランチを終了させて、masterブランチにマージする際のコメント記入を何もしないで:wqとすると画面がバグります。
少し書き換えればバグらずに済むのですが、ちょっとめんどうなのでどうにかして直したいですね…~~

2019年3月10日追記:上記のバグはCmderを一度削除し、再度ダウンロードしたところ直りました。
# 参考

[コマンドラインで Git Flow をインストールして使ってみる](https://qiita.com/CarlBrown23/items/84a6c1ce82f602eaa5a6)
[git-flow を試す](https://qiita.com/tanishi/items/09e72c65c0a0c9e1cc10)
[git-flow cheatsheet](https://danielkummer.github.io/git-flow-cheatsheet/index.ja_JP.html)
[git-flow コマンド説明和訳](https://gist.github.com/Getaji/f5fa9b588bf1bfa6e21a)

# さいごに

個人的に便利なツールだと思います。
この記事には載っていないコマンドもあり、理解するにはまだ勉強が足りないようです。
【Kubernetes】Workloadsリソースについて


# 概要
Kubernetesの*Workloads*リソースについてメモ

##Pod
    k8s上の最小単位。１つ以上のコンテナのこと。

##ReplicaSet
    セルフヒーリングが出来る。設定したレプリカ数(Pod数)を常に維持してくれること
    各nodeのリソース状況に合わせて、Podを配置してくれる。各nodeへ配置されるpod数が等しくなるとは限らない
##DaemonSet
    ReplicaSetの「各nodeのリソース状況に合わせて、Podを配置してくれる」のではなく、「各nodeにひとつずつPodを配置する」
    レプリカ数（Pod数）の指定はできないし、１つのNodeに２つPodを配置することもできない。
    ローリングアップデートも可能。
    ondeleteアップデートで、マニフェスト変更時にアップデートするのではなく、podが再作成されるときに更新させることができる
    具体的には死活監視など。
## StatefulSet
    データベースなどのステートフルなワークロードに対応するリソース
    作成されるpod名のサフィックスは、数字のインデックスが付与されたものになる。そのためサフィックス前のPod名は変わらない。
    Persistant Volume（永続化領域）を使っている場合には、podの再起動時に同じディスクを利用して再作成される


## Deployment
    マニフェストに変更があると即時、古いReplicaSetのpod数を減らしながら、新しいReplicaSetのpod数を上げてアップデートしてくれる。
    （ローリングアップデート）
    ⇨ 新しいPodがきちんと立ち上がったか確認しながら、updateをk8sがやってくれる
    ⇨ Podを使用しているサービスに影響はない。つまりサービスを停止せずにアップデートができる。
    ⇨ 新しいReplicaSetでエラーが起きたなら、古いReplicaSetへ戻すようにロールバックをしてくれる。
    ローリングアップデートをしても古いReplicaSetが削除されるわけではない。紐づくPodは削除される。
    ⇨ マニフェストの、spec.template配下に変更があれば自動的にローリングアップデートされる。

## Job
    並列でPodを実行しながら、一度限りの処理を実行させるリソースのこと。
    ReplicaSetとの違いは、「起動するPodが停止することが前提」で作られている点。
    そのためバッチ処理に向いている。
    障害発生時にPodを新規作成するか（restartPolicy: Never）、
    同一のPodを利用するか（restartPolicy: OnFailure）を指定できる。

## CronJob
    cronでスケジュールされたJobのこと。
    正確にはJobをcron単位で管理するリソースがCronJob。
    cronの設定次第ではJobを作り続けるため、Jobの同時実行に関する設定を行うことが可能。
    CronJobは時刻になるとKubernetes MasterがJobを立ち上げるため、Masterがダウンしていた時の許容時間を設定することができる。
Vue.jsでグラデーションのアニメーション表示をしよう！Granim.js

# Granim.js
Granim.jsはグラデーションをアニメーション表示させることができるJavaScriptライブラリです。
これを使うと、リッチなWebサイトを作ることができます！

どのようにアニメーション表示されるかは公式サイトの[トップページ](https://sarcadass.github.io/granim.js/)や[Examples](https://sarcadass.github.io/granim.js/examples.html)をご覧ください。
<img width="1680" alt="Screenshot_2019-02-28 20.44.37_XuGUDd.png" src="https://qiita-image-store.s3.amazonaws.com/0/149212/ca98e537-b8fe-5fec-2536-f9d0185a34e5.png">

このGranim.jsをVue.jsのアプリケーションで使ってみます。

# 手順
## 1.Gramin.jsのインストール
```
npm install granim
```

## 2.コンポーネントの作成
```granim.vue
<template>
  <div>
    <canvas id="granim-canvas"></canvas>
  </div>
</template>

<script>
import Granim from 'granim'

export default {
  name: 'granim',
  data () {
    return {
      GObj: Object
    }
  },
  mounted () {
    this.GObj = new Granim({
      element: '#granim-canvas',
      name: 'granim',
      opacity: [1, 1],
      states: {
        'default-state': {
          gradients: [
             ['#29323c', '#485563'],
             ['#FF6B6B', '#556270'],
             ['#80d3fe', '#7ea0c4'],
             ['#f0ab51', '#eceba3']
          ]
        }
      }
    })
  }
}
</script>

<style scoped>
#granim-canvas {
  width: 100vw;
  height: 100vh;
}
</style>

```
キモは**コンポーネントのmountedライフサイクルフックでGranimをnewする**ところです。
mounted()に記述するコードは[公式サイト](https://sarcadass.github.io/granim.js/examples.html)の通りに記述すればOKです。
newするときのオプションでスピードや色の指定など様々な表現ができます。

※上のサンプルコードではESLintのエラー回避のためにdataにnewしたGranimのインスタンスを代入しています。

## 3.完成!
![ezgif.com-video-to-gif (2).gif](https://qiita-image-store.s3.amazonaws.com/0/149212/822da883-4d34-cb80-be4d-9b8c8fb4a888.gif)



# バリエーション
Granim.jsを使うとただのグラデーションだけではなく、画像と組み合わせたり、文字に対してグラデーションのアニメーションをつけることができます。[公式サイト](https://sarcadass.github.io/granim.js/examples.html)にやり方が載っています。
<img width="1175" alt="Screenshot_2019-02-28 20.55.56_RaImf3.png" src="https://qiita-image-store.s3.amazonaws.com/0/149212/a30444e1-f1ff-a697-6940-398ca6cc9017.png">
<img width="1177" alt="Screenshot_2019-02-28 20.56.03_dPpNVJ.png" src="https://qiita-image-store.s3.amazonaws.com/0/149212/fa2f91a7-3a59-1164-a8a8-5fb4b6c2d79b.png">
bsh-#!/bin/sh

# Shellにある#!/bin/shについて
shellの１行目に書く#!/bin/shとか#!/bin/bashをおまじないのまま終わらせておくと
モヤモヤが残るので勉強がてら記事にしました。

## #!/bin/shを書く理由
shellと言っても様々なタイプのshellがいます。bash,csh,bsh,kshなどなど
unix環境に応じて使用されているshellは様々です。
しかしながら、様々なunix環境に必ず入っているshellがbshなのです。
そのため、どんなunix環境で動作できるようにshellの1行目で#!/bin/shと書いて、bshのshellを書くのです。

## #!/bin/shを書かないと
１行目に#!/bin/shを書かないとshellは動かないのでしょうか？
実は動きます。以下のコマンドを叩いてみてください。　　
```　
echo $SHELL
```
ログインシェルと言われているタイプのシェルで動作します。
つまり、unix環境に応じて、どんなシェルで動くかわからないのです。

## まとめ
全てのunix環境で動くように#!/bin/shと書きましょう。
プログラミング～学習記録～


<h1>プログラミングスタート</h1>
　これまで、IT全般に対して漠然とした興味を持っており、幅広い媒体から情報収集、また、プログラミングそのものを体験
　してみる為にProgateを通じて勉強を進めています。

　勉強を始めた当初は、「やはり難しいなぁ？」、「言葉の意味自体がわかんねぇ。。。」という思いもありましたが、
　簡単なコードを書いたりして、「自分が思った通りに動く事が単純に面白い」という感情が沸き、
　本格的に勉強をスタートさせる事にしました。

　また、多くの先輩が、学習内容等を記録に残す事大切であると述べておりましたので、
　見習って、この「Qiita」を通じてアウトプットを　していこうと考えています。

<h2>目標：　</h2>
　2019年度中にエンジニアとして就職

<h2>理想像：</h2>
　フルスタックエンジニア

<h2>言語</h2>
<ul>・pytyon</ul><ul>・Ruby</ul><ul>・HTML.CSS</ul><ul>・Ruby on Rails</ul><ul>・swift.java</ul>

　上記の言語を使用したエンジニアと目標を達成出来るように進めたいと思います。

<h2>学習ツール：</h2>
<ul>・Progate</ul><ul>・Udemy</ul><ul>・有料プログラミングスクール　AIコース</ul>

<h2>その他学習内容：</h2>
<ul>・簿記、会計</ul><ul>・アフィリエイト</ul><ul>・読書</ul><ul>・英語、数学、国語</ul>

<h2>時間：</h2>
　プログラミングには5時間/1日で確保しつつ、その他の学習も進める


<h2>現在の心境</h2>
　勉強したいなと考えていた事を羅列した状態となっていますが、ほんの少し長いスパンで学習を進めたいと思います。
gccメモ

Makefileに書かれたgccのコードを調べた時のメモを残しておく。

#### Makefile

- [Makefile文法ミニマム](http://auewe.hatenablog.com/entry/2017/02/09/070446)
- [Makefileでソース、ヘッダファイルの依存関係を処理](http://auewe.hatenablog.com/entry/2017/02/08/195625)

#### common

- `-fPIC` Generate position-independent code if possible

#### ディレクトリ探索のためのオプション

- [ディレクトリ探索のためのオプション](http://www.asahi-net.or.jp/~wg5k-ickw/html/online/gcc-2.95.2/gcc_2.html#SEC14)
- `-Idir` ヘッダ・ファイルを見つけるために探索するディレクトリ
- `-Ldir` `-l`により指定される静的ライブラリのパスを追加

#### リンカオプション

- [リンク処理用のオプション](http://www.asahi-net.or.jp/~wg5k-ickw/html/online/gcc-2.95.2/gcc_2.html#SEC13)
- `-Wl,-rpath` `-l`により指定される共有ライブラリのパスを追加
- `-shared` 共用オブジェクトを作成
  - 共有ライブラリを作成する場合は`-c`をつけない 
  - https://qiita.com/YusukeSuzuki@github/items/6a19d79f523ddf6fb440
- `-rdynamic` すべてのシンボルを動的シンボル・テーブルに追加
  - http://kaworu.jpn.org/kaworu/2008-11-25-1.php

#### プリプロセッサオプション

- `-D NAME` マクロを定義する（値は1）

#### その他

- `-std=c++11` C++11の機能を使用する
- `-fsanitize=leak` メモリリークの検出
- `-fsanitize=address` 不正なメモリアクセスの検出

#### pkg-config

- [pkg-config の手引き](http://goutou.mamagoto.com/手引き/pkg-config%20の手引き)
- https://ja.wikipedia.org/wiki/Pkg-config
  - 環境変数`PKG_CONFIG_PATH`のパスに存在する`*.pc`ファイルに記録された情報を元に、ビルドの際に必要な文字列を返す
  - Ubuntu なら`/usr/lib/pkgconfig/`以下？
- `--libs` output all linker flags
- `--cflags` output all pre-processor and compiler flags
- `./configure --prefix=dir` してインストールした場合、`PKG_CONFIG_PATH`に`dir/lib/pkgconfig` を指定する？
#### ldconfig

- sonameをファイル名とするシンボリックリンクを作成する
- [Linux共有ライブラリの簡単なまとめ](https://www.wagavulin.jp/entry/20091026/1256577635)

#### CUnit

- コンパイル
  - `gcc ./src.c ./tsrc.c -Wall -Wl,-rpath /usr/local/lib -lcunit`
  - `export LD_LIBRARY_PATH=/usr/local/lib gcc ./src.c ./tsrc.c -Wall -lcunit`