OmniAICreator/Qiita-1.07M huggingface dataset:
SwiftでのSingletonを用いた共通データの値渡し

# SwiftでのSingletonを用いた共通データの値渡し

今回デザインパターンの１つであるSingletonを勉強したいと思いまとめてみると共に、
簡単なデータ受け渡しのアプリを作ってみました。

別画面間でのデータの受け渡しや共通データを扱う際に便利なものになります

## Singletonとは？
まずは概要。
ググればすぐに出てきますが、簡単に言うと、

「そのクラスのインスタンスが1つしか生成されないことを保証する」

デザインパターンです。

- Singletonクラスは、staticなSingletonクラスのインスタンスを1つ持つ
- pointとしてはinitをprivateにすること

~~(後半に記述するがswift4ではoverrideしないといけない？)~~
ご指摘があった通り、関係ありませんでした。

※実装を見てもらえばわかりますが、親クラスがinit()を実装している場合はoverrideしないとエラーになります。


## 作ったもの
textFieldとTextViewにそれぞれテキストを入れて、
別画面においても保存したデータを読み込んだり更新できるような簡易アプリを作成しました

![スクリーンショット 2017-07-02 15.53.27.png](https://qiita-image-store.s3.amazonaws.com/0/186277/cd4fca64-75d8-f7e1-5b62-28c70bdaea3f.png)![スクリーンショット 2017-07-02 15.53.59.png](https://qiita-image-store.s3.amazonaws.com/0/186277/92ea7e06-e514-c6cd-b9c1-9872da7f0afb.png)




## Singletonの作成
大事な部分

swift3だとoverrideいらないのにswift4環境だと必須になったみたいです

```
static let sharedInstance: Singleton = Singleton()
private override init() {}
```

``` Singleton.swift
import Foundation

class Data {
    var title: String
    var contents: String

    init(title: String, contents: String) {
        self.title = title
        self.contents = contents
    }

}

class Singleton: NSObject {
    var data = Data(title: "", contents: "")

    static let sharedInstance: Singleton = Singleton()
    private override init() {}
}
```

## オブジェクト生成

``` ViewController.swift
let singleton :Singleton =  Singleton.sharedInstance
```

## 値の設定

viewcontroller側でデータに変更などがあった時に用いる

``` Singleton.swift
func saveTitle(title: String) {
    data.title = title
}

func saveContents(content: String) {
    data.contents = content
}
```

``` ViewController.swift
@IBAction func tappedButton(_ sender: UIButton) {
    guard
        let title = textField.text,
        let content = textView.text else { return }

    singleton.saveTitle(title: title)
    singleton.saveContents(content: content)
}
```

## 値の呼び出し
設定したデータを呼び出す際に用いる

プロパティにアクセスするといよりはクラスメソッドを呼び出すイメージです。

``` Singleton.swift
func getTitle() -> String {
    return data.title
}

func getContents() -> String {
    return data.contents
}
```

``` ViewController.swift
@IBAction func tappedLoad(_ sender: UIButton) {
    textField.text = singleton.getTitle()
    textView.text = singleton.getContents()
}
```

## 完成

![スクリーンショット 2017-07-02 15.57.22.png](https://qiita-image-store.s3.amazonaws.com/0/186277/2634fde1-dc97-01b5-e17d-e5497c7e3ea0.png)![スクリーンショット 2017-07-02 15.57.32.png](https://qiita-image-store.s3.amazonaws.com/0/186277/71a49404-b906-836b-b882-676f815a7946.png)

無事別画面においても入力したテキストの内容を渡すことができました。
まぁこの程度なら遷移の際に渡せば十分ですが、実際にアプリを作る際に扱うデータはこんなに少なくないですし、
Singletonがインスタンスを保証してくれているので管理も楽ですね。

## 今回の実装内容
こちらにあります
https://github.com/mcz9mm/Singleton/tree/master
[mbed] FXOS8700のRegister header

今mbedを使ってFXOS8700センサーをテスト中です。

- [FXOS8700 DATASHEET](https://cache.freescale.com/files/sensors/doc/data_sheet/FXOS8700CQ.pdf)

REGISTERの数が圧倒的に多いので、必要なことだけ。


```cpp

#define FXOS8700_I2C_ADDRESS (0x1E<<1) //pins SA0,SA1=0

#define FXOS8700_STATUS     0x00
#define FXOS8700_MDR_STATUS 0x32
#define FXOS8700_WHO_AM_I   0x0D
#define FXOS8700_CTRL_REG1  0x2A
#define FXOS8700_M_CTRL_REG1 0x5B
#define FXOS8700_WHO_AM_I_VALUE 0xC7

#define FXOS8700_OUT_X_MSB  0X01
#define FXOS8700_OUT_X_LSB  0X02
#define FXOS8700_OUT_Y_MSB  0X03
#define FXOS8700_OUT_Y_LSB  0X04
#define FXOS8700_OUT_Z_MSB  0X05
#define FXOS8700_OUT_Z_LSB  0X06
#define FXOS8700_F_SETUP    0X09
#define FXOS8700_TRIG_CFG   0X0A

```
貓王運算子 - Elvis Operator

> ?:

就是這個玩意兒

看 Kotline 的書看到這個運算子，
就決定查一下他叫什麼

似乎是從 Java 拿過來的一個運算子

## 作用

```kotlin
var a = left-expression() ?: right-expression()
```

他的用法就是，

- 當 `?:` 的左側 **不是** null 的時候會回傳左側的運算結果
- 當 `?:` 的左側 **是** null 的時候會回傳右側的運算結果

所以其實也可以理解成是 `?:` 的右側為左側 nullable 的運算結果提供了一個「預設值」

### Swift - Optional Chain

在 Swift 的話，就是這個符號

```
??
```

可以為 optional type 提供一個預設值

## 名字的由來 - 貓王？

頭稍往左旋轉 90 度，
就可以發現這個符號變成一個有著飛機頭的臉

似乎是這樣就被叫做 Elvis Operator 了 :laughing: 

## 參考

- [kotlinlang.org - Reference - Elvis Operator](https://kotlinlang.org/docs/reference/null-safety.html#elvis-operator)
- [維基百科 - Elvis Operator - cite note #2](https://en.wikipedia.org/wiki/Elvis_operator#cite_note-2)
raspberrypiで作る、chiptune目覚まし

## raspberry piでオリジナル目覚まし時計を作成

- 最近chiptune熱が再発
- 毎朝chiptuneを聞いて仕事に行きたい
- けど、おんなじ曲だと飽きる
- オンラインラジオから流せばいいじゃないか！？

てな感じで作りました

## 1.  mplayer
#### 先ずは、mplayerをインストール
```
apt-get install mplayer
mplayer -h
```

##2.  url取得
#### オンラインラジオを配信しているURLを取得

ググると、下記のサイトが有名どころのよう
[rainwave](https://chiptune.rainwave.cc)
[chipbit](http://chipbit.net)

- rainwave
    - urlは簡単に取得できたが、mplayerで実行できなかった
- chipbit
    - jsを読み解くと、「 http://stream.chipbit.net:8000/live 」これっぽい
<img width="866" alt="スクリーンショット 2017-07-02 15.25.09.png" src="https://qiita-image-store.s3.amazonaws.com/0/158393/f209b599-87e9-0a9a-9920-8d04b7fa2c59.png">

今回は、[chipbit](http://chipbit.net)から音源を取得することにしました

## 3. ラズパイでテスト実行
テスト実行

```
$ mplayer http://stream.chipbit.net:8000/live
MPlayer2 2.0-728-g2c378c7-4+b1 (C) 2000-2012 MPlayer Team
Cannot open file '/home/pi/.mplayer/input.conf': No such file or directory
Failed to open /home/pi/.mplayer/input.conf.
Cannot open file '/etc/mplayer/input.conf': No such file or directory
Failed to open /etc/mplayer/input.conf.
Playing http://stream.chipbit.net:8000/live.
Resolving stream.chipbit.net for AF_INET6...
Couldn't resolve name for AF_INET6: stream.chipbit.net
Resolving stream.chipbit.net for AF_INET...
Connecting to server stream.chipbit.net[138.68.142.162]: 8000...
Name   : ChipBit
Genre  : Electronic, Electronic, Breakbeat
Website: http://chipbit.net
Public : yes
Bitrate: 128kbit/s
Cache size set to 320 KiB
Cache fill:  0.00% (0 bytes)   
ICY Info: StreamTitle='Josh Zimmerman - Flourescent Sun, Neon Moon';
Detected file format: Audio only
Selected audio codec: MPEG 1.0/2.0/2.5 layers I, II, III [mpg123]
AUDIO: 44100 Hz, 2 ch, s16le, 128.0 kbit/9.07% (ratio: 16000->176400)
AO: [pulse] Init failed: Connection refused
AO: [alsa] 44100Hz 2ch s16le (2 bytes per sample)
[AO_ALSA] Unable to find simple control 'Master',0.
Video: no video
Starting playback...
A:   3.3 (03.2) of 0.0 (00.0)  1.9% 19% 
```
鳴ってる！！！！チュンチュン鳴ってる！！！

- スペースキーで中断/再開
- qまたはetcで終了
- *または/でボリューム調整

てな感じです

## 4. cronに登録
cronに登録すると、決まった時間・日にちにプログラムが実行されます

まずはchkconfigを登録
    `sudo apt-get install chkconfig`

cronが動いているか確認
`sudo chkconfig cron`
**cron on**が出れば、動いている

cronに登録`crontab -e`
vim/nanoなどテキストエディタを選択（環境によって省略されているかも）
筆者はnanoがオススメです

最後尾に、以下の文言を追記。手前の数字から、**(分)　(時間)　(日にち)　(曜日)　(月) (実行内容)**を表している
`30 8 * * * timeout 3600 mplayer  http://stream.chipbit.net:8000/live`

要するに、毎朝8時30分に目覚ましを起動するということです

実行内容= `timeout 3600 mplayer  http://stream.chipbit.net:8000/live`
これは、
`timeout (秒数)`で記述し、*(秒数)が経過しても、プログラムが終了していない場合は、強制的にプログラムを終了する*

という内容です、
つまり、

**毎朝8時30分にmplayerを起動し、ラジオからchiptuneを流し、3600秒(1時間)が経過したら、自動でプログラムが終了する**
ということです、
### 課題
- timeoutで実行を中断しただけでなく、電源を切るべきなのでは？？

### まとめ
小一時間で意外と簡単にできてびっくりしました、

わたしの環境では、自動でスピーカーを読み込んだので、スピーカーからの出力方法などは、また別の機会に書きたいと思います。(書くとは言っていない)

ではでは
Waffleで4-Digit Diaplayに表示してみる

Waffleを使って実際にGroveセンサーを試してみています。
今回は入力系ではなく表示位で、4桁の数字を表示する「4-Digit Display」を使ってみます。
![DSC_0011.JPG](https://qiita-image-store.s3.amazonaws.com/0/130771/be6a89cf-fd59-ac72-2df4-6cb43a673f3f.jpeg)

# Waffleとは
Arduino互換のマイコンボードです。
詳しくは[こちら](https://dotstud.io/docs/waffle/)をご覧ください。

※だんだん説明が雑になっていくｗ

# 準備
各自、必要なものを準備しておいてください。
開発は、Arduino IDEを使用します。

# ライブラリの準備
今回の「4-Digit Display」では、LED操作チップである「TM1637」のライブラリを使用します。
ライブラリである「DigitalTube.zip」を[ここ](https://raw.githubusercontent.com/SeeedDocument/Grove-4-Digit_Display/master/res/DigitalTube.zip)からダウンロードします。

次に、Ardiono IDEの「.zip形式のライブラリをインストール...」からインストールを行います。
![image1.png](https://qiita-image-store.s3.amazonaws.com/0/130771/b8e82248-2f71-73da-da83-388ca6ff55ff.png)

何も起こらず心配になりますが、ちゃんとメニューに「DigitalTube」が増えています。
![image2.png](https://qiita-image-store.s3.amazonaws.com/0/130771/cefb0357-bd4a-13c8-de80-cee67fac0ccf.png)

# プログラミング
seeedの[Wiki](http://wiki.seeed.cc/Grove-4-Digit_Display/)にあるサンプルを動かしてみます。

```C
/*
 * TM1637.cpp
 * A library for the 4 digit display
 */
#include "TM1637.h"
#define CLK 39 //pins definitions for TM1637 and can be changed to other ports
#define DIO 38
TM1637 tm1637(CLK,DIO);
void setup()
{
    tm1637.init();
    tm1637.set(BRIGHT_TYPICAL);//BRIGHT_TYPICAL = 2,BRIGHT_DARKEST = 0,BRIGHTEST = 7;
}
void loop()
{
    int8_t NumTab[] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15};//0~9,A,b,C,d,E,F
    int8_t ListDisp[4];
    unsigned char i = 0;
    unsigned char count = 0;
    delay(150);
    while(1)
    {
        i = count;
        count ++;
        if(count == sizeof(NumTab)) count = 0;
        for(unsigned char BitSelect = 0;BitSelect < 4;BitSelect ++)
        {
            ListDisp[BitSelect] = NumTab[i];
            i ++;
            if(i == sizeof(NumTab)) i = 0;
        }
        tm1637.display(0,ListDisp[0]);
        tm1637.display(1,ListDisp[1]);
        tm1637.display(2,ListDisp[2]);
        tm1637.display(3,ListDisp[3]);
        delay(300);
    }
}
```

# 接続する
Waffleと4-Digit Displayを繋がなくてはいけないのですが、ソースを見た感じ「38」「39」というところに繋がなくてはいけなさそう。
しかしそんな番号のポートはない。
おそらく4-Digit Displayはデジタルなので、D5とD9しかない。

とりあえずD5に繋いでみる。
．．．何も表示されない。

次に、D9に繋いでみる。
．．．何も表示されない。

Wikiを見ると「D2/D3に繋げ」と書いてある。
ないし。2つって意味わかんないし。

# いじってみる
あるのはD5とD9なので、とりあえずD9狙いでソース変更してみる。

```C
#define CLK 9 // 39->9
#define DIO 10 // 38->10
```

．．．動いた！
![DSC_0010.JPG](https://qiita-image-store.s3.amazonaws.com/0/130771/f2097830-eef1-dcc6-5cda-5c5cf1691e78.jpeg)
なぜだかわからないけど動いた！！（笑）

※なんでDIOが8じゃダメで10だといいのかはわかっていない．．．

★回路図、マジ重要！　→Waffleのgithubにある[回路図](https://github.com/hamatani63/Waffle/blob/master/img/schematic.png)


# まとめ
これでWaffleからの表示手段が出来ました。
Unityのパーティクル生成を一元化するライブラリ作ってみた

# ライブラリURL
https://github.com/ryonakao/ParticleCreator

# 使い方
```ParticleManager.cs
/// <summary>
/// 使い方
/// ①Resourcesディレクトリ配下に生成したいパーティクルを配置
/// ②Instantiate(ParticleManager.Instance.Create("パーティクル名"));
/// </summary>
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class ParticleManager : SingletonMonoBehaviour<ParticleManager> {

	public GameObject Create(string name){
		return (GameObject)Resources.Load (string.Format("Particles/{0}", name));
	}
}
```
```SingletonMonoBehaviour.cs
using UnityEngine;
using System;

public abstract class SingletonMonoBehaviour<T> : MonoBehaviour where T : MonoBehaviour{

	private static T instance;
	public static T Instance
	{
		get{
			if (instance == null) {
				Type t = typeof(T);

				instance = (T)FindObjectOfType (t);
				if (instance == null) {
					Debug.LogError (t + " をアタッチしているGameObjectはありません");
				}
			}

			return instance;
		}
	}

	virtual protected void Awake(){
		// 他のゲームオブジェクトにアタッチされているか調べる
		// アタッチされている場合は破棄する。
		CheckInstance();
	}

	protected bool CheckInstance(){
		if (instance == null) {
			instance = this as T;
			return true;
		} else if (Instance == this) {
			return true;
		}
		Destroy (this);
		return false;
	}
}
```
Visual Studio/ IDE > Window(WPF)の名前変更の手順

```txt:動作環境
Windows 8.1 Pro (64bit)
Microsoft Visual Studio 2017 Community
```

ソリューションエクスプローラー上で「名前の変更」をWindow(WPF)に対して行う手順。

1. 名前の変更
   - 変更前例: Window1.xaml
   - 変更後例: ItemWindow.xaml
2. プロジェクトから除外
3. 追加 > 既存の項目、より１のファイルを追加しなおす

2,3の手順を踏まないと「不明なビルドエラー [変更前の名前]が見つかりませんでした」になる。

xamlがつかないcsファイル(例: ViewModel.cs)は手順1だけで問題がない。
[checkio] Brackets

今回のは簡単だった~~(テストする度に例外的パターンを突きつけられた)~~
お題は与えられた文字列に含まれる(){}[]の括弧たちがそれぞれのスコープを守りつつ、キャッキャできているかを調べるというもの。
一人ぼっちやthird wheelがいてはいけない。

###自分の回答
```js
function brackets(expression){
    let openBrackets = [];
    
    for (let i of expression) {
        if (i.match(/[\(\{\[]/)) {
            openBrackets.push(i);
        }
        else if (i.match(/[\)\}\]]/)) {
            if (couples(openBrackets[openBrackets.length-1], i)) {
                openBrackets.pop();
            } else {
                return false;
            }
        }
    }
    if (openBrackets.length != 0) {
        return false;
    }
    else {
        return true;
    }
    
    
    //see if they are lovers
    function couples(a,b) {
        switch (a) {
            case "(":
            if (b!=")") return false;
            else return true;
            break;
            
            case "{":
            if (b!="}") return false;
            else return true;
            break;
            
            case "[":
            if (b!="]") return false;
            else return true;
            break;
            
            default:
            console.log(a+b+", something is wrong with these idiots!");
            return false;
        }
    }
}
```
相変わらず冗長。正規表現とswitch文を使って見て多少なりとも短くなるよう努力はしたんだけど・・・

###すごいとおもったかいとう
```js
function brackets(expression){
    let exp = expression.replace(/\d|[+\-*/]/g, ''),
        prev = '';
        
    while ( exp.length !== prev.length ) {
           prev = exp;
           exp = exp.replace('()', '')
                    .replace('{}', '')
                    .replace('[]', '');
    }
    
    return exp.length === 0;
}
```
すごくみじかいとおもいます！
2行目で数字と演算記号を除いたexp変数を定義。
3行目は空の変数。
5-10行目のwhileブロックは空のブラケットのカップルを見つける度に退場させていく。仲睦まじくなければそのカップルは戦場に残ってしまう。
全ての仲睦まじいカップルが退場したらおしまい。

例1) brackets("((({[(((1)-2)+3)-3]/3}-3))")
exp ... (({[((()))]})
１回目のwhile
  exp ... (({[(())]})

例2) brackets("[1+1]+(2*2)-{3/3}")
exp ... \[]\()\{}
1回目のwhile
  exp ... //全て退場

###学び
string.match()

- 引数に正規表現パターンを受け取って、stringにマッチするかtrue/falseを返す。

array.pop()

- 配列の最後の要素を削除する。引数は特に取れないぽい。

正規表現でエスケープしなければいけない文字列について

- +-*/や()などのブラケットなど、予約語としてそもそも機能を持っているものは文字列として受け取ってもらうために`\`(バックスラッシュ)を加える。ブラケット系以外のものに限っては、[]の一番最初の文字はエスケープしなくていいみたい。

###反省
自分のとすごい人のではアプローチが違った。もっと柔軟にあれこれ考えられることが必要かも。
gRPCをRubyで試してみる

# 対象読者
- gRPCの概要は理解しているが、Rubyでの実装に困っている

概要はこちら→http://qiita.com/oohira/items/63b5ccb2bf1a913659d6

# ゴール
- サービス定義を自由にカスタマイズできるようになる

# 参考
http://www.grpc.io/docs/quickstart/ruby.html

# 環境
- macOS Sierra 10.12.5
- Ruby 2.4.1

# 手順
## gRPCリポジトリをクローン
```
git clone https://github.com/grpc/grpc.git
```
- 実際使うのはこのディレクトリだけ→
```
grpc/examples
```

## Ruby用Gemインストール
```
$ gem install grpc
$ gem install grpc-tools
```

## サービス定義の説明
```/examples/protos/helloworld.proto
// サービスの振る舞いを定義
service Greeter {
  // nameというフィールドを持ったHelloRequestを受け取って、messageを持ったHellowReplyを返す
  rpc SayHello (HelloRequest) returns (HelloReply) {}
}

// メッセージを定義
message HelloRequest {
  string name = 1;
}

// メッセージを定義
message HelloReply {
  string message = 1;
}
```

## サービス定義を変更
```/examples/protos/helloworld.proto
// 大豆から豆腐を作る
service Greeter {
  rpc CreateTofu (Daizu) returns (Tofu) {}
}

// 大豆を定義
message Daizu {
  string name = 1;
  int32 count = 2;
}

// 豆腐を定義
message Tofu {
  string name = 1;
  int32 size = 2;
}
```

## 変更したサービス定義を適用
```
$ grpc_tools_ruby_protoc -I ../protos --ruby_out=lib --grpc_out=lib ../protos/helloworld.proto
```

## サーバーの定義を変更
```/examples/ruby/greeter_server.rb
class GreeterServer < Helloworld::API::Service
  def create_tofu(daizu, _unused_call)
    name = "#{daizu.name}_tofu" # リクエストのフィールドはドットで呼び出せる
    size = daizu.count * 2
    return Helloworld::Tofu.new(name: name, size: size) #レスポンスはメッセージのインスタンス生成をするだけ
  end
end
```

## クライアントの定義を変更
```/examples/ruby/greeter_client.rb
def main(name, count)
  stub = Helloworld::Greeter::Stub.new('localhost:50051', :this_channel_is_insecure)
  tofu = stub.create_tofu(Helloworld::Daizu.new(name: name, count: count))
  p "豆腐の名前は#{tofu.name}"
  p "豆腐の大きさは#{tofu.size}"
end
p 豆腐の名前は?
input_name = gets.chomp
p 豆腐の数は?
input_count = gets.to_i
main(input_name, input_count)
```

## 起動
### サーバー
```
$ ruby examples/ruby/greeter_server.rb
```
### クライアント
```
$ ruby examples/ruby/greeter_client.rb
```

# 【番外編】REST機能を持ったサーバー実装してみた
- https://github.com/ryonakao/gRPC_test
PEP3102が私から数時間を奪い去った日

python3.6 わりと好きです。[PEP498](https://www.python.org/dev/peps/pep-0498/) すてきです。
しかし今回の主犯は[PEP3102](https://www.python.org/dev/peps/pep-3102/)、keyword only argument です。

# イテレーション開発のおともに、keyword only argument

ざっくり説明すると、

```
def ham(a1, a2, *, kw1, kw2='にゃーん', kw3):
    pass
```

こんな感じで、単独の`*`以降が keyword only になり、
`kw1`がpositionalに渡せなくなったり、`kw3`のようにデフォルト値ついてる`kw2`の後にデフォルト値を持たない引数を追加出来たりします（3.0から）。

という訳で、クラスメソッドに機能がふわふわと変化することの多い~~無計画な~~柔軟な開発では、引数を並べる順番を間違えて事故ることがないように、ほとんど全てを keyword only にしてしまいたくなります。

```
class A:
    def ham(
            self, *,
            all, the, arguments,
            may, as_well, be, kwargs
    ):
            print(f"{all} {the} {arguments} {may} {as_well} {be} {kwargs}")
```

```
>>> A().ham(**{name: name.upper() for name in A.ham.__code__.co_varnames if name != 'self'})
ALL THE ARGUMENTS MAY AS_WELL BE KWARGS
```

こんな感じです。

# ある日突然いじめに

そんなこんなでPEP3102を愛して止まなかった私は、その日もいつも通り

```
class B:
    def egg(
            self, *
            first, argument,
            not_recognized="＼^o^／"
    ):
        print(first, argument, not_recognized)
```

こんな感じのものを書いていました。すると、

```
>>> B().egg(first=1, argument=2)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: egg() got an unexpected keyword argument 'first'
```

！？？
`first` が unexpected keyword だと言われてしまいました。


1. first のスペル間違えたのだろうか？
  - 間違ってなかった。

1. egg のスペル間違えたのだろうか？
  - 実際は `B.egg` はスーパークラスから呼ばれるオーバーライドメソッドであったため、`egg`（本当はもっと長ったらしい名前）のスペルを間違ったのではと推測するも、残念ながら(?)合ってた。
 
1. なぜだ。内部情報を見てみる。

```
>>> B.egg.__code__.co_varnames
('self', 'argument', 'not_recognized', 'first')
>>> B.egg.__code__.co_kwonlyargcount
2
```

`first` は引数ですが、keyword only argument は２個（`argument` と `not_recognized`）で、やはりなんかおかしいです。
（実際は上記2.を確かめるために呼び出し元の logger に投げてました）


なんかおかしいのはわかったのですが、結局わからないまま一日が終わり、眠れぬ枕を涙で濡らしました。

# 天祐

翌朝気づきました。

```
class B:
    def egg(
            self, *
            first, argument,
            not_recognized="＼^o^／"
    ):
        print(first, argument, not_recognized)
```

L3: `*`の後に`,`がありません。

つまり、

```
class B:
    def egg(self, *first, argument,　not_recognized="＼^o^／"):
        print(first, argument, not_recognized)
```

こういうことになっていました ＼^o^／

flake8さん、教えてよ。。。
まあflake8さんにとって、これは

```
apple_pen = (
    apple
    + pen
)
```

のようなものの、単項演算子バージョンに過ぎないということなのだろう。

# まとめ

linter だいじ。
『小学生でもわかるRuby on Rails入門』で初学者が躓いたことメモ〜後編〜

#こちらの記事について
超初学者が、[『小学生でもわかるRuby on Rails入門』](https://openbook4.me/projects/92/)
を使用して、初めてRuby on Railsを動かしてみたときに、躓いたり調べたりしたことの備忘録です。OSはmac OSX Yosemite、Ｒｕｂｙのバージョンは2.2.2です。

[→前編はこちら](http://qiita.com/Chinatsu_K/items/b83f57222437d90f9f0d)

##users_controller.rb　の書き換えミス…
[『第7章 ルーティングからコントローラーへ』](https://openbook4.me/projects/92/sections/492)
app/controllers/users_controller.rb　を書き換えるとこんなエラーが出ました。

```ruby:エラー内容
500 Internal Server Error
If you are the administrator of this website, then please read this web application's log file and/or the web server's log file to find out what went wrong.
```
単純な記述漏れでした…。defshowのendのさらに下に、元々ファイルに書いてあったclass UsersController < ApplicationControllerのendが必要でした。
これで正常に動作しました。

```ruby:users_controller.rb
class UsersController < ApplicationController
  def index
  end

  def show
    @user = Hash.new
    if params[:username] == 'ryooopan'
      @user[:name] = 'Ryo Suzuki'
      @user[:username] = 'ryooopan'
      @user[:location] = 'Kanagawa, Japan'
      @user[:about] = 'Hello, I am Ryo.'
    elsif params[:username] == 'moyahima'
      @user[:name] = 'Shohei Aoki'
      @user[:username] = 'moyahima'
      @user[:location] = 'Tottori, Japan'
      @user[:about] = 'Nice to meet you.'
    end
  end

end
```

##rakeのエラー
[『第11章 作ってわかるデータベース』](https://openbook4.me/projects/92/sections/496)でデータベースを生成しようとしたらrakeのエラーが発生しました。

```ruby:コマンド
rake db:create
```
```ruby:エラー内容
rake aborted!
Gem::LoadError: You have already activated rake 10.4.2, but your Gemfile requires rake 12.0.0. Since rake is a default gem, you can either remove your dependency on it or try updating to a newer version of bundler that supports rake as a default gem.
```
rakeのバージョンが異なるようなので指示通り12.0.0.にする。

```ruby:ターミナル
gem install rake -v 12.0.0
```
ちゃんと指定のバージョンになっているか確認する。

```ruby:ターミナル
rake --version
```

参照記事↓
[Cannot Install Older Version of Rake Gem in Rails
](https://stackoverflow.com/questions/7838858/cannot-install-older-version-of-rake-gem-in-rails)

##最後に…
第12章以降はスムーズに進めることができました。躓いたのは主にバージョンの相違と記述ミスと考え方の部分なので、慣れている方には当然かもしれませんが、**まずはRubyのバージョンと使用するGemのバージョンを確認すること**を忘れずに。
年末に作った目標管理システムをRails 5.1にアップデートした

## Rails 5.1
[年末に作った目標管理システム](http://qiita.com/croquette0212/items/dff2fead8663f7323376)のフロントにVue.jsを導入しようと思っていたのだが、ちょうどこのタイミングで正式にリリースされたRails 5.1でWebpackがサポートされたため、先にRails 5.1にアップデートをしてからVue.jsを導入することにした。

5.0から5.1への変更内容は[Ruby on Rails 5.1リリースノート](https://railsguides.jp/5_1_release_notes.html)に詳しく記述されているが、フロントエンド周りのアップデートが主となっている。今回のシステムの場合、フロントエンドのこだわった実装がほとんどない状態だったこともあり、Rails 5.0から5.1へのアップデートはほとんど問題なくスムーズに進んだのだが、一応記録として残しておく。

## Rails 5.1へのアップデート
### Railsのアップデート
Gemfileを編集して、`rails`のバージョンを`5.1.2`に書き換え`bundle update`を実行すると、Railsを含むライブラリ一式がアップデートされる。

```ruby:Gemfile
gem 'rails', '~> 5.1.2'
```

```
bundle update
```

#### Rails以外のライブラリのアップデートについて
単純に`bundle update`を実行すると、`rails`以外でもバージョンを指定していない`gem`はアップデートされてしまう。アップデートで不具合が発生してしまう場合は、各`gem`のバージョンを明示的に指定する。

今回の場合`twitter-bootstrap-rails`で問題が発生してしまった。2017年2月に`4.0.0`がリリースされたのだが、そこで`font-awesome`のサポートがドロップされてしまったのが原因だった。(2016年年末時点では3.2.2が最新だった)

参考: https://github.com/seyhunak/twitter-bootstrap-rails/issues/889

`font-awesome-rails`gemなどを使うことで、引き続き`font-awesome`を使うことは可能だが、コードの変更を伴う箇所が多数あるため、今回は明示的に`twitter-bootstrap-rails`の`3.2.2`を使うように指定する形にした。

### アップデートタスク
`rails app:update`コマンドで、設定ファイルなどの自動アップデートを行う。
gitコマンドで、差分をチェックする。

routesの中身が消されてしまったので、そこだけ元に戻した。

### unknown asset対策
Rails 5.1から存在しないAssetをコンパイルしようとした場合にエラーが発生するようになった。

`config`で`Rails.application.config.assets.unknown_asset_fallback = false`を設定することで、以前と同じような挙動にすることもできるが、なるべく標準の挙動に従っておきたいので設定しないことにした。

前回Rails 5.0で生成したコードでは、`favicon`を指定している箇所が何箇所かあるが、favicon自体が存在しないのでエラーになってしまう。本来ならfaviconを用意した方がいいのだろうが、面倒くさいので今回はfaviconの指定個所を削除することにした。

### form_withへの置き換え
`form_tag`と`form_for`が今後deprecatedになった。変更しなくても問題なく動くのだが、`form_with`への置き換えが推奨されているため、置き換えた。特に問題もなく、難しい箇所もなかった。

### その他
Rails 5.1では他にも秘密情報の暗号化やルーティング周りの強化が追加されているが、今回のシステムでは使う場面がなかったので影響はなかった。フロントエンドJSの部分に関しては、この後Vue.jsの導入と合わせて活用していく予定。

## 参考
* [Ruby on Rails 5.1リリースノート](https://railsguides.jp/5_1_release_notes.html)
* [ReactやwebpackもサポートしたRails 5.1の新機能・変更点](http://qiita.com/ryohashimoto/items/a8ba7bb8d6f340894188)
* [[Rails 5.1] ‘form_with’ APIドキュメント完全翻訳](https://techracho.bpsinc.jp/hachi8833/2017_05_01/39502)
Arch Linuxインストール時のDiskまわりの設定（UEFI, GPT, GRUB）

## はじめに
Arch Linuxのインストールガイドは非常によくできているので、それ読みながら進めれば基本的には問題ない。

[インストールガイド](https://wiki.archlinuxjp.org/index.php/%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%AB%E3%82%AC%E3%82%A4%E3%83%89)

しかし、ディスクのパーティショニングあたりの設定については省略が多く、また各ページに分散されて記述されているため、慣れていないと手こずる部分だ。

そこでこの記事では、UEFIモードでOSを起動し、ディスクのパーティショニング（GPT）とブートローダ(GRUB)のインストールを行う手順を記す。

## 構成
### ディスクレイアウト

|ディスク|パス|ファイルシステム|容量|
|:--:|:--:|:--:|:--:|
|/sda1|/boot|FAT32|512MB|
|/sda2|swap|-|2000MB|
|/sda3|/|ext4|残り|

※boot領域はFAT系にする必要がありFAT32が推奨されている。
※boot領域の容量は512MBが推奨されている

## 手順
### UEFIモードで起動していることを確認

```
# ファイルの一覧が表示されることを確認
ls /sys/firmware/efi/efivars
```

もしディレクトリが存在しなかったらBIOSモードで起動している。

この記事ではUEFIモードでインストールしたいので、BIOSモードで起動している場合は、BIOS/UEFIの設定を見直す必要がある。

私の環境でもBIOSモードで起動していたため、修正して起動しなおした。

具体的にやったことは、PCの起動時にF11を押しBIOS/UEFIの設定画面に入り、Boot Optionが「Legacy + UEFI」になっていたため「UEFI」に変更した。
※設定方法は使用しているシステムによるだろう

### パーティションの作成
注意：ディスク上の既存のデータはすべて無くなる。

```
# parted /dev/sda

(parted) mkpart ESP fat32 1MiB 513MiB
(parted) set 1 boot on

(parted) mkpart primary linux-swap 513MiB 2513MiB

(parted) mkpart primary ext4 2513MiB 100%
```

#### 参考
https://wiki.archlinux.org/index.php/GNU_Parted
http://qiita.com/Gen-Arch/items/da296b7cbe5d87abc5a4

### ファイルシステムの作成など

```
## Partedが実行済みで不要かもしれない
# mkfs.fat -F32 /dev/sda1

# mkswap /dev/sda2
# swapon /dev/sda2

# mkfs.ext4 /dev/sda3
```

#### 参考
https://wiki.archlinux.org/index.php/EFI_System_Partition

### ブートローダーをインストール

```
# pacman -S grub efibootmgr
# grub-install --target=x86_64-efi --efi-directory=/boot --bootloader-id=grub
# grub-mkconfig -o /boot/grub/grub.cfg
```

私の環境では上記の手順で問題なかったが、環境によっては下記が必要かもしれない。

```
# grub-mkconfig -o /boot/grub/grub.cfg
# cp /boot/EFI/arch_grub/grubx64.efi /boot/EFI/boot/bootx64.efi
```

#### 参考
https://wiki.archlinuxjp.org/index.php/GRUB
http://note.kurodigi.com/archlinux-uefi-install/
https://wiki.gentoo.org/wiki/Handbook:AMD64/Installation/Disks/ja

### 起動確認
再起動して、起動することを確認。
UITabBar.unselectedItemTintColor を iOS9 以下でも使えるようにする

``UITabBar``の非選択時の色を指定したい時、iOS10からは``var unselectedItemTintColor: UIColor?``というプロパティが使えます。

https://developer.apple.com/documentation/uikit/uitabbar/1648949-unselecteditemtintcolor

これをOSのバージョンを意識せずに使えるようになるExtensionです。

```UITabBar+.swift
import UIKit

extension UITabBar {

    private struct AssociatedKey {
        static var unselectedItemTintColor = "UITabBar.UnselectedItemTintColor"
    }

    @nonobjc
    var unselectedItemTintColor: UIColor? {
        get {
            return objc_getAssociatedObject(self, &AssociatedKey.unselectedItemTintColor) as? UIColor
        }
        set {
            objc_setAssociatedObject(self, &AssociatedKey.unselectedItemTintColor, newValue, objc_AssociationPolicy.OBJC_ASSOCIATION_RETAIN_NONATOMIC)
            
            if let color = newValue {
                setUnselectedItemTintColor(color)
            }
        }
    }

    private func setUnselectedItemTintColor(_ color: UIColor) {
        items?.forEach {
            $0.image = $0.image?.withRenderingMode(.alwaysOriginal)
            $0.setTitleTextAttributes([NSForegroundColorAttributeName: color], for: .normal)
            $0.setTitleTextAttributes([NSForegroundColorAttributeName: tintColor], for: .selected)
        }
    }
}
```

このように、``#available``で分岐せずに使え、タブ非選択時には元画像の色で表示されます。

```ViewController.swift
import UIKit

class ViewController: UIViewController {

    @IBOutlet weak var tabBar: UITabBar!

    override func viewDidLoad() {
        super.viewDidLoad()
        tabBar.selectedItem = tabBar.items?.first
        tabBar.tintColor = .red
        tabBar.unselectedItemTintColor = .blue
    }
}
```

うーん...🤔
これだとただ上書きしてるだけな気がするから微妙かも...
objcだったらバージョンによって動的にプロパティ追加できて、良さそう💡

### 参考
http://techblog.kayac.com/8_ios_version.html
http://bricklife.hatenablog.com/entry/2012/03/19/130011
http://bricklife.hatenablog.com/entry/2011/12/20/092539
jQuery で、json を　csv に変換してダウンロード

参考にしたページ
[jQuery だけで CSVファイル作成とダウンロードを実装する](http://qiita.com/t_furu/items/31c5bc3a1573ef4049e2)

Chrome では動くのですが、Firefox では動きません (2018-5-27 に確認）

![csv_download_jul02.png](https://qiita-image-store.s3.amazonaws.com/0/179446/c6de52b7-c82b-8d49-cf0d-816667c619b2.png)


```html:index.html
<!DOCTYPE html>
<html lang="ja">
<head>
<meta http-equiv="Pragma" content="no-cache" />
<meta http-equiv="Cache-Control" content="no-cache" />
<meta http-equiv="CONTENT-TYPE" content="text/html; charset=utf-8" />
<script src="/js/jquery-3.2.1.min.js"></script>
<script src="/js/jquery.csv.min.js"></script>
<script src="csv_download.js"></script> 
<title>CSV ダウンロード</title>
</head>
<body>
<h2>jquery.csv.min.js</h2>
<pre id="json"></pre>
<p />
<pre id="preview"></pre>
<button id="download">CSV ダウンロード</button><p />

<p />
<div id="contents"></div>
<hr />
<div id="outarea_aa">outarea_aa</div>
<div id="outarea_bb">outarea_bb</div>
<div id="outarea_cc">outarea_cc</div>
<div id="outarea_dd">outarea_dd</div>
<div id="outarea_ee">outarea_ee</div>
<div id="outarea_ff">outarea_ff</div>
<div id="outarea_gg">outarea_gg</div>
<div id="outarea_hh">outarea_hh</div>
<hr />
Jul/02/2017<p />
</body>
</html>
```

```js:csv_download.js
// -------------------------------------------------------------------
//	csv_download.js
//
//					Jul/02/2017
// -------------------------------------------------------------------
jQuery (function ()
{
	jQuery("#outarea_aa").text ("*** csv_download.js *** 開始 ***")

	const json_file = "in01.json"
	const csv_file = "aaa01.csv"

	jQuery.getJSON(json_file,function (res)
	{
	jQuery('#json').text(JSON.stringify(res,undefined,4))

	const content = jQuery.csv.fromObjects(res)
	jQuery('#preview').text(content)

	jQuery("#download").click (function ()
		{
		const blob = new Blob([ content ], { "type" : "text/csv" })
		jQuery("<a></a>", {href: window.URL.createObjectURL(blob),
			download: csv_file,
			target: "_blank"})[0].click()
		})
	})

	jQuery("#outarea_hh").text ("*** csv_download.js *** 終了 ***")
})

// -------------------------------------------------------------------
```

```json:in01.json
[
	{"key":"AAA","v1":"Good","v2":"Morning"},
	{"key":"BBB","v1":"Good","v2":"Afternoon"},
	{"key":"CCC","v1":"Hello","v2":"Everybody"},
	{"key":"DDD","v1":"See","v2":"you"}
]
```
WaffleでGrove Light Sensorから値を取得する

せっかく手元に[Waffle](https://dotstud.io/docs/waffle/)があるので、いろいろなセンサーと繋いでいきたいと思います。
第1段は、「Grove Light Sensor」です。
![DSC_0004.JPG](https://qiita-image-store.s3.amazonaws.com/0/130771/2ce9f580-dcb8-8448-dd00-68d6215fbadb.jpeg)

※ちなみに私は初心者です（爆）

# Waffleとは
ざっくり言うと、Arduino互換のマイコンボードです。
Groveコネクタが4つついており、はんだ付け等をせず、お気楽にセンサーデバイスと接続できます。
また、USBコネクタがありますので、PCからプログラムを転送したり、スマホ経由でインターネットに接続することも簡単にできます。
まさにお気楽にIoTができます。
Waffleはツクモのロボット王国で購入できます。

# 準備
とりあえず、以下は省略します。

- Waffleの購入
- Arduino IDEのインストール
- Grove Light Sensorの購入
- USB変換コネクタの購入

# 繋いでみる
早速、PCにつなぎます。

　PC－USB変換コネクタ－Waffle－Grove Light Sensor

![DSC_0005.JPG](https://qiita-image-store.s3.amazonaws.com/0/130771/93237aae-61e2-3bad-48ff-7c4773109cda.jpeg)
Grove Light SensorはWaffleのA0コネクタにつなぎます。
（値はアナログの値で取得できます）

# プログラミング
とか言いつつ、サンプルをそのまま使います ^^;

スケッチ例の「AnalogReadSerial」を読み込みます。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/130771/00b4c692-27f4-720e-d70e-16611d6b5df8.png)

```C
/*
  AnalogReadSerial
  Reads an analog input on pin 0, prints the result to the serial monitor.
  Graphical representation is available using serial plotter (Tools > Serial Plotter menu)
  Attach the center pin of a potentiometer to pin A0, and the outside pins to +5V and ground.

  This example code is in the public domain.
*/

// the setup routine runs once when you press reset:
void setup() {
  // initialize serial communication at 9600 bits per second:
  Serial.begin(9600);
}

// the loop routine runs over and over again forever:
void loop() {
  // read the input on analog pin 0:
  int sensorValue = analogRead(A0);
  // print out the value you read:
  Serial.println(sensorValue);
  delay(1);        // delay in between reads for stability
}
```

これをWaffleに書き込むと、センサーの値が送られてきます。
（シリアルモニタに表示されます）
![image2.png](https://qiita-image-store.s3.amazonaws.com/0/130771/72717246-6c78-b7e2-afc9-efa6310b3976.png)

暗くすると0に近づき、明るくすると1,023に近づきます。

# まとめ
とりあえず、なんの苦労もなく使うことができました。
何らかの閾値で処理を切り替える、なんて感じで使うイメージでしょうか。
CMakeでビルドしているコードにclang-tidyを実行する

clang-tidyはC++向けの良い感じに自動修正までしてくれるLinterです。
Linterとしてどのくらい良い感じなのかは[冬休み到来! clang-tidy で安心安全な C/C++ コーディングを極めよう! - Qiita](http://qiita.com/syoyo/items/0e75410c44ed73d4bdd7)を確認していただくとして、ここではCMakeを使って簡単に実行する手順をメモしておきます。

## 確認した環境
Ubuntu16.04(をVirtualBoxで動かしたもの)
未確認ですが新しめのUbuntuだとCMakeの更新が省けるはず。

## 準備
以下が必要か不要か忘れたけども、もしかしたら必要。

``` bash:clang,clang-tidyインストール
sudo apt install clang clang-tidy
```

## CMakeの更新(3.6以上にする)
cmake3.6以降であれば、cmake自身がclang-tidyに対応しているので簡単に導入できる。
最新のcmakeを持ってくる(tar.gz)
https://cmake.org/download/

例えば、下記のようにごちゃごちゃやるとできる。

``` bash:CMakeをダウンロードしてからパスを通す
mkdir ~/temp
cd ~/temp
wget https://cmake.org/files/v3.8/cmake-3.8.2-Linux-x86_64.tar.gz
tar -xvzf cmake-3.8.2-Linux-x86_64.tar.gz
sudo mv cmake-3.8.2-Linux-x86_64 /opt/
sudo ln -s /opt/cmake-3.8.2-Linux-x86_64/bin/cmake /usr/local/bin/cmake
cmake --version
# cmake version 3.8.2と表示されればOK!
```

参考：[c++ - How to install latest cmake version in Linux/Ubuntu from command line? - Ask Ubuntu](https://askubuntu.com/questions/355565/how-to-install-latest-cmake-version-in-linux-ubuntu-from-command-line?noredirect=1&lq=1)

## CMakeを使ってclang-tidyする
`-DCMAKE_CXX_CLANG_TIDY`を使ってなんか適当にやればうまくいく。

### 環境の例

``` :Direcroty構成
.
└── Qiita
    ├── CMakeLists.txt
    └── main.cpp
```
```cmake:Qiita/CMakeLists.txt
cmake_minimum_required(VERSION 3.5)

set(CMAKE_CXX_FLAGS "-std=c++14")

set(SOURCE_FILES
    ${CMAKE_CURRENT_SOURCE_DIR}/main.cpp
    )

add_executable(Hello ${SOURCE_FILES})
```
```cpp:Qiita/main.cpp
#include <iostream>

int main(){
    std::cout << "Hello World!" << std::endl;

    float f = 0.0F;
    int i = (int)f;
    std::cout << i << std::endl;
}
```

### ビルド

``` bash:clang-tidyつきのビルドする
mkdir build
cd build
cmake -DCMAKE_CXX_CLANG_TIDY="clang-tidy;-checks=-*,google-readability-casting;-fix;-fix-errors;-header-filter=/home/yoyomion/Qiita" ../Qiita
make
```
``` bash:参考：普通にビルド
mkdir build
cd build
cmake ../Qiita
make
```

### 確認
開いてみると、指摘された箇所が自動で修正されています。
C++スタイルのキャストになっています。

``` cpp:Qiita/main.cpp(clang-tidy実行後)
#include <iostream>

int main(){
    std::cout << "Hello World!" << std::endl;

    float f = 0.0F;
    int i = static_cast<int>(f);
    std::cout << i << std::endl;
}
```

### 説明
先頭にclang-tidy実行コマンドを書いて、以降はセミコロン区切りでclang-tidy向けのオプションを並べます。

|書いてあること|説明|
|------------|---------|
|clang-tidy|clang-tidy実行コマンド。cmake用。|
|-checks=-*,google-readability-casting|clang-tidyのオプション。今回は、`-*`で全部のチェッカーを無効にしてから、`google-readability-casting`チェッカーを指定している。|
|-fix|clang-tidyのオプション。修正提案を自動適用する。|
|-fix-errors|clang-tidyのオプション。ビルドエラーになったとしても修正提案を適用する。|
|-header-filter=/home/yoyomion/Qiita|clang-tidyのオプション。ユーザーが用意したヘッダーファイル置き場を絶対パス指定する。このディレクトリ以下のヘッダーはシステムヘッダーとみなされず、clang-tidyで指摘してもらえる。|

参考：
[Clang-Tidy &#8212; Extra Clang Tools 5 documentation](http://clang.llvm.org/extra/clang-tidy/index.html)
[[cmake-developers] Integration of clang-tidy](https://cmake.org/pipermail/cmake-developers/2016-April/028215.html)
Vagrant プロビジョニング設定 - Docker

プロビジョニングには 環境設定のためのスクリプトを実行することができます。
Dockerの環境をインストールするスクリプトを作成したので、メモとして残しておきます。

---

## 概要
仮想マシン起動後に、プロビジョニングを実行して、Dockerの利用環境を自動構築する。

**[インストールするソフト]**

- 各種ツール （vim, git)
- [Docker](http://docs.docker.jp/linux/step_one.html)
- [Docker-Compose](https://docs.docker.com/compose/install/)

---

## 仮想マシン(CentOS7)を起動する
下記のコマンドにて、仮想マシンを起動する。

### BOX追加
[CentOS7](https://app.vagrantup.com/centos)のBOXを追加する


### 初期化
```sh:コマンドプロンプト
$ mkdir -p ~/Documents/Vagrant/ && cd ~/Documents/Vagrant/
$ mkdir opt
$ vagrant init centos/7
```

### Vagrantfile修正
```ruby:Vagrantfile
# -*- mode: ruby -*-
# vi: set ft=ruby :

Vagrant.configure("2") do |config|
  config.vm.box = "centos/7"
  config.vm.hostname = "centos7"
  config.vm.network "forwarded_port", guest: 80, host: 8080
  config.vm.network "private_network", ip: "192.168.33.10"
  config.vm.synced_folder "./opt/", "/home/vagrant/opt/"
  config.vm.provision :shell, :path => "provision.sh"
end
```

### 実行するコマンドを作成(プロビジョニング)
仮想マシンの初回起動（vagrant up）時には、自動で実行されます。
ただし、２回目以降は、実行されないようです

```sh:コマンドプロンプト
$ vi ~/Documents/Vagrant/provision.sh
```
```sh:provision.sh
# Tool
sudo yum -y install vim git

# Docker
sudo curl -sSL https://get.docker.com/ | sh
sudo systemctl enable docker
sudo gpasswd -a vagrant docker
sudo systemctl start docker

# Docker Compose
sudo curl -L https://github.com/docker/compose/releases/download/1.14.0/docker-compose-`uname -s`-`uname -m` > /usr/local/bin/docker-compose
sudo chmod +x /usr/local/bin/docker-compose
```

### 仮想マシンを起動する
```sh:コマンドプロンプト
$ vagrant up
```

### ネットワーク確認
```sh:コマンドプロンプト
$ ping -c 1 192.168.33.10
PING 192.168.33.10 (192.168.33.10): 56 data bytes
64 bytes from 192.168.33.10: icmp_seq=0 ttl=64 time=0.555 ms
```

### プロビジョニングの実行状況確認
```sh:コマンドプロンプト
# ssh接続
$ vagrant ssh

# Git
[vagrant@localhost ~]$ git --version
git version 1.8.3.1

# vim
$[vagrant@localhost ~] vim --version
VIM - Vi IMproved 7.4 (2013 Aug 10, compiled Dec 21 2016 17:00:20)

# Docker
[vagrant@localhost ~]$ docker --version
Docker version 17.06.0-ce, build 02c1d87

# Docker Compose
[vagrant@localhost ~]$ docker-compose --version
docker-compose version 1.14.0, build c7bdf9e
```

---

## プロビジョニングを任意に実行する
初回起動時以降に、プロビジョニングを実行したい場合は、下記のコマンドにて実行可能です。

```
# プロビジョニング実行
$vagrant provision

# 起動時に一緒に実行
$vagrant up --provision

# 再起動時に一緒に実行
$vagrant reload --provision
```

---

## 参考文献

- [Vagrant で CentOS7 + PHP + MySQL の仮想環境を構築する](http://fnya.cocolog-nifty.com/blog/2015/12/vagrant-centos7.html)
トランザクションマネージャーオブジェクトストアがデータを格納するディレクトリを指定する

トランザクションマネージャーオブジェクトストアが
データを格納するディレクトリを指定する方法です。

大量の書込みが発生してディスクI/Oがボトルネックになった場合に、
RAMディスクに書き込むようにしたりする時のstandalone.xmlの設定例です。

managementの上あたりに以下をまず書きます。

この時トランザクションマネージャーオブジェクトストアがデータを格納する
ファイルディレクトリの相対または絶対パスをpathに指定してあげてください。
nameは何でも良いと思いますよ。ここでtxdirとしました。

```
<paths>
	<path name="txdir" path="/hogehoge/xxxxx/yyyy/wildfly10"/>
</paths>
<management>
```

～省略

recovery-environmentの下あたりに以下を書きます。
先ほど用意した、txdirを指定してあげて下さい。

```
<recovery-environment　....>
<object-store path="tx-object-store" relative-to="txdir"/>
```

これでできるはずです。出来なかったらすみません。
[chrome拡張]編集画面内の文字列を一括置換

#カラーミーの常時SSL化をしようとして結局全てを諦めた方たちへ捧げます....あんまりいなさそうだけど！
ことのおこりは**「カラーミーの常時SSL化」**

小規模な店舗さんは特に問題ないんですが、大量の商品を扱っていて、かつよくある楽天的なLPを作り込むために画像サーバーを別なところに設置している店舗さんは全ての画像リンクをhttpsにする必要があります。

- 商品データはCSVでダウンロードして一括変換
- テンプレートの修正（これは大した数じゃない）
- 大量にあるカテゴリーのフリースペースを編集画面を1つづつ開きながら手作業で修正
- フリーページも編集画面を1つづつ開きながら手作業で修正

カテゴリーは数えなかったけど300以上あったし（?）
フリーページに至っては2000近く現存を確認...
昔のはてぶのシェアボタンがhttpだったりとか...
これ全部画面開いて一つ一つ変更しなければいけないやつ...

退職がきまっていたので私の勤務の残り時間はその時点ですでにのこり4日でもはや絶望しかない

でももう動き始めてしまっていたし
どーーーーーーーーーーしてもやりたかったので粘る

1件づつ編集したらどう考えても間に合わない。
ダメ元でカラーミーさんになんとかならないか問い合わせて聞いてみる

結局ダメだったんですがめっちゃ良い方でした、一緒にすごい悩んでくれました...感謝

むーん...手詰まりか...

クローム拡張でなんかいいのないかなーとふと思い探したら発見！
http://webmist.info/search-and-replace/

編集画面を開いて検索置換条件を入力
カラーミーの場合は「Input fields only」にチェックをいれて一括置換！

ただし、条件は一つしか入れられないので、複数条件が発生するフリーページは他の方法でやりました。
自分で拡張機能をちゃんとつくれたらもっと簡単だったなぁ...超簡単なのしかつくれない...

ちなみにどうやってやったかというと
STEP 1 ただ編集画面を開いて必要なページの内容をエクセルにコピペ（途中で気が遠くなります）
STEP 2 エクセルで一括変換（データさえ取れてしまえばこの方法以外にも結構あります）
STEP 3 エクセルから編集画面にコピペし直し（ここで何度か気が遠くなります）

##結論
chrome拡張は作れた方がいい!

今まで結構画面確認してポチッと押す的な動作をぶつぶついいながらやってる同僚をよく見ていたので
受託じゃなくて自社運用の場合はこういうの意外と発生するんですよね...
たぶん外部サービスを利用したECだったり自社にエンジニアがいない場合のWPだったりは意外とあるはず...


ちなみによく作る簡単なのは、画像の置き場所を変更した際に、画面で確認しても目視できないので
旧ドメインにあるものは赤いボーダーをつけてぱっと見でわかるようにしてスピードUPとか...
簡単なので自分で作れちゃう（参考にしたのは↓）

「[今から３分で，Chromeブラウザの独自アドオンを自作してみよう （jQueryを使ったクローム拡張機能を，開発および動作テストする入門）](http://language-and-engineering.hatenablog.jp/entry/2015/10/22/%E4%BB%8A%E3%81%8B%E3%82%89%EF%BC%93%E5%88%86%E3%81%A7%EF%BC%8CChrome%E3%83%96%E3%83%A9%E3%82%A6%E3%82%B6%E3%81%AE%E7%8B%AC%E8%87%AA%E3%82%A2%E3%83%89%E3%82%AA%E3%83%B3%E3%82%92%E8%87%AA)」

サイトから大量に特定の情報取ってこなきゃいけない時に
条件設定してコピーしてくれるとか全然できそうですよね...
はー...がんばって勉強しよー
ACCESS テーブル クエリ で任意の順列を設定する

#テーブルの場合

[ユーザー設定の順序でレコードを並べ替える](https://support.office.com/ja-jp/article/%E3%83%A6%E3%83%BC%E3%82%B6%E3%83%BC%E8%A8%AD%E5%AE%9A%E3%81%AE%E9%A0%86%E5%BA%8F%E3%81%A7%E3%83%AC%E3%82%B3%E3%83%BC%E3%83%89%E3%82%92%E4%B8%A6%E3%81%B9%E6%9B%BF%E3%81%88%E3%82%8B-af750db5-67df-4dee-8da8-cc3facc9a75e):::[魚拓](https://megalodon.jp/2017-0702-1012-22/https://support.office.com:443/ja-jp/article/%E3%83%A6%E3%83%BC%E3%82%B6%E3%83%BC%E8%A8%AD%E5%AE%9A%E3%81%AE%E9%A0%86%E5%BA%8F%E3%81%A7%E3%83%AC%E3%82%B3%E3%83%BC%E3%83%89%E3%82%92%E4%B8%A6%E3%81%B9%E6%9B%BF%E3%81%88%E3%82%8B-af750db5-67df-4dee-8da8-cc3facc9a75e)

 Iif 関数 ([タイトル] =「営業部長」、1、 IIf ([タイトル] =「販売マネージャー」、2、 IIf ([タイトル] =「営業担当者」、3、 IIf ([タイトル] ="内側販売計"4、5))) 
あやまりです。
IIF([タイトル] = "営業部長",1,IIF([タイトル] = "販売マネージャー",2,IIF([タイトル] ="内側販売計"4、5)))

#query
SwitchまたはIIFを使います。
[Switch 関数/IIF 関数を Access で使用する方法](https://support.microsoft.com/ja-jp/help/882955):::[Archive.is](http://archive.is/lcXrW)
式フィールドにSwitchまたはIIFを使います。
Vagrant エラー（Guest Additions - vboxsf）

vagrantを使っていてエラーで困った時に調べた内容をメモしておきます。

---

## 共有フォルダがマウントできない
vagrant upコマンドを打つと下記のようなエラーが表示される場合の対応。

```sh:コマンドプロンプト
$ vagrant up
     ・
     ・
     ・
Vagrant was unable to mount VirtualBox shared folders. this is usually
because the filesystem "vboxsf" is not available. This filesystem is
made available via the VirtualBox Guest Additions and kernel module.
Please Verify that these guest additions are properly installed in the
guest. This is not a bug in Vagrant and is usually caused by a faulty
Vagrant box. For context, the command attempted was:

mount -t vboxsf -o uid=1000,gid=1000 home_vagrant_opt_ /home/vagrant/opt

The error output from the command was:

mount: unknown filesystem type 'vboxsf'
```

### 原因
ホスト ⇔ ゲスト間のフォルダ共有機能は、Guest Additionsが提供しており、
ホスト(VirtualBox)とゲスト(Guest Additions)でバージョン不一致があると
マウントエラーが起きるとのことらしい。

### 対策
「vagrant-vbguest」というプラグインをインストールして対応する。

```
$ vagrant plugin install vagrant-vbguest
$ vagrant vbguest
$ vagrant vbguest --status
GuestAdditions 5.0.16 running --- OK.
$ vagrant reload
```

### その他
逆にvbguestにて自動更新するとエラーになる場合もあるようです。
そういった場合は、下記のようにVagrantfileに追記して、自動更新をストップする方法もあるようです。

```ruby:Vagrantfile
# -*- mode: ruby -*-
# vi: set ft=ruby :

Vagrant.configure("2") do |config|
  config.vm.box = "centos/7"

  # auto update off
  if Vagrant.has_plugin?("vagrant-vbguest") then
    config.vbguest.auto_update = false
  end
end
```

### 参考文献
- [Vagrantで共有フォルダのマウントに失敗するときの対処方法](http://qiita.com/ozawan/items/9751dcfd9bd4c470cd82)

---
[VBS32bit]Access2016 64bit Windows 10 でAccess97のテーブルのデータを吸い出す

#Vbscript
```vbnet:C:\hoge\DbConnect.VBS
'%SystemRoot%\SysWow64\cscript.exe //NoLogo "C:\hoge\DBConnect.vbs"
Const DN= "F:\"
Const FN = "TESTType97.mdb"
Dim dbe
Dim db
Dim rs
Dim fld
Dim i
    Set dbe = CreateObject("DAO.DBEngine.36")
    Set db = dbe.OpenDatabase(DN & FN)
    Set rs = db.OpenRecordset("SELECT * From TestType")
do while rs.eof =false
For i = 0 To rs.Fields.count-1
Wscript.Echo rs.Fields(i).Name & ":::" & rs.fields(i).value
Next
Wscript.Echo "-----"
rs.MoveNext
Loop
db.close
```
32bit で強制起動します。
C:\hoge にファイルがあるとすると
Cmd.exeでコマンドプロンプトを開き
%SystemRoot%\SysWow64\cscript.exe "C:\hoge\DBConnect.vbs"
と入力します
mdbファイルは F:\TESTType97.mdb
テーブル名は TestTypeです。

#参考
[Hello, DAO World!-CX's Hello, World!](http://cx20.main.jp/blog/hello/category/access/):::[Webarchive](http://web.archive.org/web/20160309002313/http://cx20.main.jp:80/blog/hello/category/access/)
ただし Dao系統のスクリプトは全て上記のように32ビットで起動する必要がある。
【Angular.io】Displaying Data まとめ

# Displaying Data

この章ではモデルからビューへどのようにデータを出力するかの説明をします。

- インターポレーション (Interpolation)
- テンプレート or テンプレートファイル
- コンストラクタ or 変数の初期化
- *ngForを使ったデータ出力
- クラスを用いたデータ出力
- NgIfで条件分岐


## インターポレーション (Interpolation)
インターポレーションでは、テンプレート内でクラスのプロパティを表示する場所を指定する。以下では、 `AppComponent` の `title` と `myHero` を ビュー側で `{{ title }}`、`{{ myHero }}` と書くことによって各プロパティの値をビューに反映させることができる。

```
import { Component } from '@angular/core';

@Component({
  selector: 'my-app',
  template: `
    <h1>{{title}}</h1>
    <h2>My favorite hero is: {{myHero}}</h2>
    `
})
export class AppComponent {
  title = 'Tour of Heroes';
  myHero = 'Windstorm';
}
```

Angularは自動的にコンポーネントから `title` と `myHero` の値を取得してビューに反映させる。プロパティの値が変更されたら、その変更された値を検知して都度ビューへ渡す仕組み。

`AppComponent` のインスタンスはどのタイミングでできるかというと、html内にある `<my-app></my-app>` が読み込まれたときに、`AppComponent` クラスのインスタンスを生成して、それに紐づくテンプレートを `<my-app>` 内に出力する。

## テンプレート or テンプレートファイル?
コンポーネントのメタデータとして指定するテンプレートは、インラインで記述する方法とファイルパスで指定する方法がある。

インラインで指定する方法

```
@Component({
  selector: 'my-app',
  template: `
    <h1>{{title}}</h1>
    <h2>My favorite hero is: {{myHero}}</h2>
    `
})
```

ファイルパスで指定する方法

```
@Component({
  selector: 'my-app',
  templateUrl: ‘my-app.component.html'
})
```

## コンストラクタ or 変数の初期化？
コンストラクタ内でクラスのプロパティに初期値を代入することができる。

```
export class AppCtorComponent {
  title: string;
  myHero: string;

  constructor() {
    this.title = 'Tour of Heroes';
    this.myHero = 'Windstorm';
  }
}
```

## *ngForを使ったデータ出力
配列をビュー側で出力するには、`*ngFor` を使用することができる。

```
export class AppComponent {
  title = 'Tour of Heroes';
  heroes = ['Windstorm', 'Bombasto', 'Magneta', 'Tornado'];
  myHero = this.heroes[0];
}
```

`heroes` リストをビューで表示させる

```
template: `
  <h1>{{title}}</h1>
  <h2>My favorite hero is: {{myHero}}</h2>
  <p>Heroes:</p>
  <ul>
    <li *ngFor="let hero of heroes">
      {{ hero }}
    </li>
  </ul>
`
```

## クラスを用いたデータ出力
実際のデータはただの配列だけでなく複雑なオブジェクトを含むことがある。そのようなデータも `*ngFor` で出力可能。

`heroes` をクラス化させる

```
export class Hero {
  constructor(
    public id: number,
    public name: string) { }
}
```

`heroes` にインスタンスを生成

```
heroes = [
  new Hero(1, 'Windstorm'),
  new Hero(13, 'Bombasto'),
  new Hero(15, 'Magneta'),
  new Hero(20, 'Tornado')
];
myHero = this.heroes[0];
```

ビューで出力

```
template: `
  <h1>{{title}}</h1>
  <h2>My favorite hero is: {{myHero.name}}</h2>
  <p>Heroes:</p>
  <ul>
    <li *ngFor="let hero of heroes">
      {{ hero.name }}
    </li>
  </ul>
`
```


## NgIfで条件分岐
`ngIf` を使用すると、データの出力を与えられた条件のもと操作することができる。

```
<p *ngIf="heroes.length > 3">There are many heroes!</p>
```

`heroes` が4つ以上だったら出力して、`heroes`が3以内だったら出力しない。`*ngIf` はfalseだったときは、DOM自体を消してしまうが、`[hidden]` を使用するとDOM自体は存在する。

```
<p [hidden]="heroes.length < 3">There are many heroes!</p>
```

参考:
https://angular.io/guide/displaying-data
Vagrantについてのメモ

Vagrantについて学んだことをメモとして残しておきます。

---

## 概要
- Rubyで作成されている
- 昔はRubyGemsで配布していたが、現在は各OSごとのパッケージがある

---

## 事前準備
Vagrantを使う前に行うことを記載します。

- [VirtualBox](https://www.virtualbox.org/) のインストール
- [Vagrant](https://www.vagrantup.com/) のインストール
- 初期化

```sh:コマンドプロンプト
$ mkdir -p ~/Document/Vagrant/
$ cd ~/Document/Vagrant/
$ vagrant init centos/7
```

---

## Vagrantの構造
下記のフォルダにインストールされるようです。

**[ファイル構造]**

```
├ opt
│  └ vagrant
│     └ bin
│        └ vagrant
│
└ usr
   └ local
      └ bin
         └ vagrant -> /opt/vagrant/bin/vagrant
```

**[Vagrant本体]**

```
$ ls -la /opt/vagrant/bin/
total 4072
drwxr-xr-x  3 root  wheel      102  7  1 21:57 .
drwxr-xr-x  4 root  wheel      136  9  3  2016 ..
-rwxr-xr-x  1 root  wheel  2084288  6 27 01:22 vagrant
```
**[シンボリックリンク]**

```
$ ls -la /usr/local/bin/ | grep vagrant
lrwxr-xr-x  1 root admin 24 7 1 21:57 vagrant -> /opt/vagrant/bin/vagrant
```

---

## 関連メモ
- [Vagrantについてのメモ（コマンド）](http://qiita.com/reflet/items/81d401534f1674df8edd)
- [Vagrantについてのメモ（エラー対応）](http://qiita.com/reflet/items/98fd548a6ef341f685bb)
- [Vagrant プロビジョニング設定 - Docker](http://qiita.com/reflet/items/9aa1ee959a863fa20363)

## 参考資料

- [HashiCorpのツール - vagrant](https://www.creationline.com/hashicorp/products)
- [今から始めるVagrant入門 #1](https://www.fl-ops.com/mori-dojo/archives/21)
Python3 > round(a - b, 7)

@ 科学技術計算のためのPython入門 ――開発基礎、必須ライブラリ、高速化 by 中久喜 健司さん
( 対象環境: Python 3.5以降 )

unittestの関数において`assertAlmostEqual(a, b)`の処理として`round(a-b, 7) == 0`が紹介されていた。

関連: http://qiita.com/aomidro/items/3e3449fde924893f18ca

round()はまだ身についていない。

### link

https://docs.python.jp/3/library/functions.html#round
**注釈の事項は要注意** 

### code

使ってみた。

http://ideone.com/6lVook

```py3
#       12345678
in1 = 3.1415926
in2 = 3.14159265
dif = round(in1 - in2, 7)
print("%.8f" % dif)

#       123456789
in1 = 3.14159265
in2 = 3.141592653
dif = round(in1 - in2, 7)
print("%.8f" % dif)
```

```txt:run
-0.00000010 
-0.00000000
```