OmniAICreator/Qiita-1.07M huggingface dataset:
XamarinでiOSリモートシミュレータを使ってみた(Visual Studio Community)

# XamarinでiOSリモートシミュレータを使ってみた

本記事は、[[初心者さん・学生さん大歓迎！] Xamarin その1 Advent Calendar 2017](https://qiita.com/advent-calendar/2017/xamarin-student) の7日目となります。埋めますよ～！

## iOSリモートシミュレータとは

WindowsでXamarinを使用してiOSアプリ開発していると、iOSアプリの動作確認を行う場合、同一ネットワークにあるMacで次のどちらかを行います。

* iOSシミュレータを使用する
* iOS実機を使用する

今回はシミュレータを使用する場合のお話です。

Macが近くにないとき、隣りの机にMacはあるけど（椅子が回転しないので）体の向きを変えるのがつらい＆めんどくさいとき、など、Windows上でiOSシミュレータが確認できれば便利です。

それを実現してくれるのが、`iOSリモートシミュレータ（Remoted iOS Simulator）`です！

この仕組自体はもともとVisual Studioに搭載されていましたが、`Enterprise Edition`のみで使用できました。
つまり、`Community Edition`等では使えません。残念。

しかし！
つい先日のアップデートで、**`Community Edition`でも使用できる**ようになりました！

## というわけで

本記事では、今までiOSリモートシミュレータを使用できなかった方向けに、使用手順をまとめました。

### 前提

Windowsと同一ネットワーク上にMacがあり、今までで使用している前提とします。

## 確認環境

* Windows 10
* Visual Studio 2017 Community (**Ver15.5**)
* Visual Studio 2017 for Mac Community (**Ver7.3**)

![01.png](https://qiita-image-store.s3.amazonaws.com/0/203323/5faead5a-6c34-c19a-c208-9ec4d8b8db2b.png)

バージョンの右側が豆腐になっていますね。。。

## 手順

### バージョンアップ

まずはVisual Studioのバージョンアップを行いましょう。

#### Windows

Visual Studioを起動し、`ツール`の`ツールと機能を取得`を選択します。

![02.png](https://qiita-image-store.s3.amazonaws.com/0/203323/b62dfd51-fb04-c1ee-755a-198bffc9e5ad.png)

下記の画面が表示されたら、更新しましょう。なお下記は更新後の画像となります。

![03.png](https://qiita-image-store.s3.amazonaws.com/0/203323/7bb046f7-5c75-15f2-f839-0b3d3c774a7c.png)

#### Mac

Visual Studio for Macを起動し、左上の`Visual Studio Community`の`更新の確認`を選択し、更新しましょう。

![04.png](https://qiita-image-store.s3.amazonaws.com/0/203323/480cea04-2036-2e9c-9966-302676fde4ac.png)

### 必要ツールのインストール

[こちら](https://developer.xamarin.com/guides/cross-platform/windows/ios-simulator/)にアクセスし、ツールをダウンロード＆インストールします。

![05.png](https://qiita-image-store.s3.amazonaws.com/0/203323/99c88b24-804d-d02a-79f0-288888a8c4c6.png)

### 接続準備(Windows)

#### Macとの接続確認

WindowsでVisual Studioを起動し、適当なXamarinプロジェクトを開きます。

同一ネットワーク上のMacと接続されていることを確認してください。

下記のようになっていればOKです。

![06.png](https://qiita-image-store.s3.amazonaws.com/0/203323/63e95eed-8096-59ca-9bc4-f11de133bec5.png)

Macと接続できていない場合は、

* 切断→再接続
* Visual Studioの再起動
* 更新がないか再度確認してみる
* Mac上に「接続を許可しますか？」というメッセージが出ていれば許可する

など試してみてください。

#### オプション変更

`ツール`の`オプション`を選択し、`Xamarin`の`iOSの設定`を選択します。
続いて、`リモートSimulatorからWindowsへ`にチェックを入れます。

![07.png](https://qiita-image-store.s3.amazonaws.com/0/203323/ca4fe765-5a81-48ad-e728-cf1c54c7b7ba.png)


以上です！

なお、このチェックを外せば、今まで通りMac上で起動します。

### あとは

今まで通り、iOSシミュレータを選択してビルド＆起動すればOKです！

次のようになります。

![08.png](https://qiita-image-store.s3.amazonaws.com/0/203323/bd4b58e0-f008-b2d1-b0e0-f5b899cdb2da.png)

でかい。

### 参考

* <https://developer.xamarin.com/guides/cross-platform/windows/ios-simulator/>
* <http://www.nuits.jp/entry/2016/04/28/233203>

## 最後に

お疲れ様でした。よいXamarinライフを送りましょう！

明日はtomopy03さんです。よろしくお願いします。
JavascriptでスマートにObservableする 改

# 前回
スマートだと思っていたらスマートじゃなかった
https://qiita.com/angeart/items/c1ec1c59b66d5b57773a

# やりたいこと
javascriptでMVVMのObservableのような通知を送る実装を書きたい

# 継承を利用してもっとスマートに
前回は利用クラスのconstructorの中でObservableクラスに包みましたが
よくよく考えたらinstanceofが利用出来ないですし、別物のクラスとして実体化してしまうのでスマートじゃないです
なので継承で利用できるようにしました。

# 実装
```js
var $ = require('jquery');
class Observable {
  constructor() {
    return new Proxy(this, {
      set: function(obj, prop, value) {
        if (obj[prop] === value) return true;
        obj[prop] = value;
        $(obj).trigger("onchanged", {
          prop: prop
        });
        return true;
      }
    });
  }
}

class Test extends Observable {
  constructor() {
    super();
    $(this).on("onchanged", function(e, data) {
      console.log("changed : " + this[data.prop]);
    });
  }
}

var tester = new Test();

tester.hoge = "hoge";
tester.hoge = "hoge";
tester.hoge = "fuga";

if (tester instanceof Test) {
  console.log("ok");
}
```

イベントの設定にjQueryを用いています

# 実行結果
```
changed : hoge
changed : fuga
ok
```

#repl.it
https://repl.it/@Angeart/Observable-on-Javascript-2
3次元ライフゲーム

空いていたので雑に埋めます。真のクソアプリをみせてやる。

## 作ったもの

ライフゲームの3次元版です。

https://eduidl.github.io/3d-game-of-life/

![image.png](https://qiita-image-store.s3.amazonaws.com/0/141207/499db310-6099-a295-9809-fde58b40489d.png)

## 使い方

開始でスタート
停止でストップ
更新で初期化
1世代後で1step実行します

あと一応各種設定できて、生死の条件と、セルの数(1辺)と初期状態で生きたセルが何パーセントいるかをそれぞれ決められます。
設定を反映させるためには、更新ボタンを押す必要があります。

定常状態になると停止します。

眺めていると穏やかな気持ちになるかもしれません。

## 生死の条件

最初は隣接セルの生きたセルが4-7のとき生存可能、6のとき誕生可能となっていますが、学術的裏打ちはありません。
経験上、停止せずに結構動き続けるので、悪い値ではないかなあという感じです。ベストかは知りません。

## 諦めたところ

Three.jsを使っており、元々はParticleではなく `THREE.BoxGeometry` を使っていたのですが、ガベージコレクションがうまくできず、動かしていくとメモリ使用量がどんどん増加してブラウザがフリーズするので、Particleにしました。
Three.jsは本業でないので、まあいいかとなりました。妥協の産物です。

というかそもそも4次元版を作りたかったんですよね。妥協&妥協の産物でした。
「ねぇこれ見積もっといて！」に対応するシステムエンジニアにも必要なフェルミ推定


「これから作るシステムはどれくらいのユーザにニーズがある？」
「非機能要件を定義しているけど、構築するシステムのトランザクション件数ってどれくらいになる？」
など、システムエンジニアである限り、『何かを見積もる』という仕事は避けては通れません。

今回は、そんな『何かを見積もる』ときに役立つ**フェルミ推定**を紹介します。

# フェルミ推定とは

フェルミ推定について、Wikipediaでは以下のように説明されています。

> 実際に調査するのが難しいようなとらえどころのない量を、いくつかの手掛かりを元に論理的に推論し、短時間で概算することを指す。

フェルミ推定で検索すると、「都内にあるマンホールの数はいくつ？」や「日本にいる猫の数は？」など、突拍子も無い数字を求めさせる例が多く出てきます。
これらは就活生向けに、論理的思考を問うために出題される問題ですが、実際のシステムエンジニアの現場でもフェルミ推定が役に立つことが多くあります。
たとえば、本記事の冒頭で書いたような『システムの利用数』は、実際に事前に調査することが難しく、いくつかの手がかりを元に推測していくしかありません。
現時点で取得できるデータから、論理的に予測値を求めるために、フェルミ推定が役に立ちます。

# フェルミ推定のやり方

フェルミ推定は以下の手順で進めていきます。

1. 仮説をたてる
2. 問題をいくつかの要素に分解する
3. 既知のデータを活用する
4. 推定量を決定（算出）する
5. 総合し、計算して推定していく

## 今回求めてみる数字

では、数字を見積もっていきましょう。
今回は、話題のメガバンクのシステムリプレースにおいて、個人情報の変更手続きのシステムのスケールを推定してみたいと思います。

「だいたいどれくらいだと思いますか？」と聞いても、パッと推察はなかなか出来ないと思います。

## 1. 仮説をたてる
まずは、仮説をたてて、それを前提として検討をすすめていきます。
今回は、以下を仮説として見積もりをすすめていきます。

* 届出の内容は、住所変更と名前変更を対象とする。
* 住所・名前が変わった人は必ず届出を出す。
* 名前変更は結婚・離婚時のみ考慮する。（結婚・離婚時は必ず名前が変更されると定義する。）

## 2. 問題をいくつかの要素に分解する
問題を、いくつかの要素に分解します。
「1. 仮説をたてる」の結果から、今回は以下の要素に分解しました。

* Ⅰ. 銀行の個人口座数
* Ⅱ. 年間の結婚する人の割合
* Ⅲ. 年間の離婚する人の割合
* Ⅳ. 年間の引っ越しする人の割合

## 3. 既知のデータを活用する
「2. 問題をいくつかの要素に分解する」で定義した項目のうち、具体的な数値を得られるものを調べます。
今回は、たまたま全ての項目について情報を得ることができました。[^1]

* Ⅰ. 銀行の個人口座数
  * 個人顧客数は2,400万
  * ホームページから値を取得しました。
* Ⅱ. 年間の結婚する人の割合[^2]
  * 0.50%
  * http://www.garbagenews.net/archives/2013777.html
* Ⅲ. 年間の離婚する人の割合[^2]
  * 0.17%
  * http://www.garbagenews.net/archives/2013777.html
* Ⅳ. 年間の引っ越しする人の割合
  * 5.8%
  * https://fromportal.com/kakei/household/life-events/moving-percentage.html

[^1]: 実際に仕事で調査するのであれば、もう少しソースとなるサイトは選ぶ必要があるでしょうが、今回はこれくらいで…。
[^2]: 銀行の口座数を計算するのに、結婚・離婚などの割合が総人口なのはおかしいのでは！年齢によるバッファはないのか！などあると思いますが、今回はこれくらいで…。

## 4. 推定量を決定（算出）する
今回は、推察する要素はありませんが、要素一つ一つに対しての考察であれば、ある程度の推察が可能ではないかと思います。

例えば、前提を「届出は出す人と出さない人がいる」と変えてみると、「実際に届出を出す人と出さない人の割合」など、推察する必要がある項目が出てきます。
また、「実際にシステムが使われる時間帯」を考慮してもいいかもしれません。

## 5. 総合
最後は、実際に収集した値を使って計算していきましょう。
トランザクション数を求める計算は以下の通りです。

個人顧客数 × (結婚による名前変更の人の割合 + 離婚による名前変更の人の割合 + 引っ越しによる住所変更の人の割合 ) / 一年の分数 = 届出の件数(件/分)
2,400万 × (0.50% + 0.17% + 5.8%) / (60 * 24 * 365) = 約2.95(件/分)

いかがだったでしょう。
上記の数字は、業務時間や営業日を考慮していない、完全にフラットな値になっています。
この辺りのばらつきなどは、「4. 推定量を決定（算出）する」で推察してみてもいいかもしれません。

# 最後に

あくまでも、フェルミ推定の目的は、正確な値を出すものではありません。
フェルミ推定によって、自分が得られるデータを使って、論理的に「だいたいの値」を求めることが出来ます。
システムを開発・運用していくうえで、その、フェルミ推定で推察した数値と、実際の数値を比較して検討することが大切です。

引用になりますが、

> 「実験には２つの結果がある。もし結果が仮説を確認したなら、君は何かを計測したことになる。もし結果が仮説に反していたら、君は何かを発見したことになる。」

という言葉をフェルミが残しています。

最近はデータ解析の方法やツールも様々なものがあると思うので、是非推察と検証を繰り返してみてください。
そこに、新しい発見や気づきがあるかもしれません。

👨「なんでコレってこうなってるの？」
👩「えっ、、、いやぁ…、ざっくりとこれくらいかなと…」
👦「（＾ω＾）」
とならないように、フェルミ推定を身につけましょう！

# Input

https://www.scc-kk.co.jp/scc-books/book_data/B-385/9784886472427_sample.pdf
2018年走行体EV3way(二輪倒立)について 前編

本記事はETロボコン[Advent Calendar 2017](https://qiita.com/advent-calendar/2017/etrobo)のエントリです。

チャンピオンシップ大会で発表されたとおり2018年はタイヤが大径に変わります。
<img width="338" alt="DSC_6757_.jpg" src="https://qiita-image-store.s3.amazonaws.com/0/123504/046ed7bf-764d-4192-cac4-234ca14d7efd.jpeg">


走行体の検討は2017シーズンが始まった頃から動いていたのですが、当時多忙で自分は参加できずにいました。
ところが、地区大会の頃にCS大会でデモ走行をやって欲しいというお話しをいただきました。

急遽タイヤを送っていただいて作業に着手したのが9月末頃。
ここから一週間あれば倒立できるようになって、あとはレプリカコースで調整かなと思っていましたが、

**立たない！倒立パラメータを微調整しても、元から再計算しても立てない！**

倒立もままならないままコースを借りられる当日現場に来てようやく
組み方が悪くタイヤの遊びが多すぎて立てないことが分かりました。

(動画)　[EV3way-ET 2018年仕様走行体 開発当時の様子 20171007時点](https://youtu.be/TuI4doVCeMo)

ようやく倒立ができた当日の走行です。倒立制御が不安定で運良く完走できたというレベル。
これではとても難所攻略などできません。

**インスタ映え**する二輪倒立走行体は残したいところですが、
プライマリークラスもHackEVにする案も出てきてEV3way **大ピンチ**

*[後編](https://qiita.com/pulmaster2/items/903f055721e9f66ed13a)に続く*
Xamarinの種類など

この前、初心者向けのXamarinハンズオンに参加してきて学んだ内容を、忘れないように記事にしようと思います。

##Xamarinの種類
スマホアプリ開発用のXamarinには、「Xamarin.Forms」と「Xamarin Native」の２種類があります。以下、それぞれの説明です。  

###Xamarin.Forms
Xamarin.Formsでは、ロジックとUIを共通化することができます。なので、1つ作成できればAndroidとiOSの両方のアプリとして使うことができます。しかし、複雑なUIになると共通化したUIで実現することは難しい為、複雑なUIのアプリを作成するのには向いていません。  
※ロジックは **C#**、UIは **Shared XAML**でコーディングします。
Shared XAMLと聞いて、私は最初すごく心配でしたが、XMLに形式が似ているので、そこまで意識しなくても簡単に理解できました。(体験談)

###Xamarin Native
Xamarin Nativeではロジックのみ共通化することができ、UIに関しては個別に実装します。UIを各プラットフォームごとに作成しないといけないので大変ですが、共通化をしていないので複雑なUIも実現することができます。Android SDKなどを用いた時と同じ様に開発をできるらしいですが、私はまだ初心者なので詳しくは分かりません。

##Xamarinのメリット
1. コードをより多く再利用することができる。
2. シンプルなアプリを素早く作成することができる。
3. XcodeやAndroid SDKなど、開発するアプリごとに開発環境を使い分ける必要がない。(Xamarinで完結する。)

##Xamarinのデメリット
1. ソースコードをC#に変更しないといけないので、swift, Java等ネイティブ開発の知識が必要。
2. 複雑なUIになってくると、FormsではなくNativeで個別にUIを実装しなければいけないので、ネイティブ開発との差が無くなる。

##Xamarinを初めて触ってみた感想
ハンズオンに参加して初めてXamarinを触ってみて、想像していたよりはコーディングをしないといけないことが分かりました。しかし、Javaに書式が似ているC#で開発ができるので、個人的にとっつきやすかったです。  

分からなかったら、Xamarin界隈の人がきっと優しく教えてくれると思うので、少しずつ学んで行きたいです。
Android Things Setup Utillityの使い方

Android Thingsを簡単にセットアップできるUtillityが公開されたのでその使い方メモです。
今回は、Raspberry Pi3用のセットアップから、Wifi設定までを行います。

# Android Things Setup Utilityでできること

Android Thingsイメージの焼き込みと、Wifiの設定ができます。

**【対応OS】**
　Windows、Mac、linux
**【対応機種】**
　Raspberry Pi3、NXP Pico i.MX7D、NXP Pico i.MX6UL

# ダウンロード方法

以下のURLよりダウンロードしてください。
https://partner.android.com/things/console/#/tools 

<img width="1031" alt="ダウンロード画面" src="https://qiita-image-store.s3.amazonaws.com/0/189829/8b2d6780-6729-8bfe-8ba7-b86b08107724.png">

# イメージの焼き方について

#### 起動方法
ダウンロードしたファイルを展開すると、以下のファイルが入っていますので
利用しているOS合わせたファイルを実行します。

Mac版で動かす場合は、必ず`su`で実行してください。
実行しない場合は、sdカードの書き込みで失敗します。

アプリを起動すると以下のような画面が表示されます。

<img width="566" alt="起動時" src="https://qiita-image-store.s3.amazonaws.com/0/189829/4806c6ea-797a-b0aa-94eb-9f8e6380f179.png">

新規でインストールする場合は、`[1]`キーを押下します。

#### 機種の選択

<img width="565" alt="機種の選択" src="https://qiita-image-store.s3.amazonaws.com/0/189829/290f37c3-1a52-f098-60ef-adbc097c7265.png">

選択すると、対象となる機種の一覧が表示されますので
お使いの機種の番号のキーを押下します。
今回はRasberryPiがターゲットなので`[1]`キーを押下します。

#### イメージの選択

<img width="565" alt="イメージ選択" src="https://qiita-image-store.s3.amazonaws.com/0/189829/16fde5cf-a53f-e8a4-7065-99036b0b2dca.png">

専用のツールがダウンロードされ、使用するイメージの設定を方法を選択します。
`[１]`を選択すると、自動的に最新イメージがダウンロードされます。
Android Thingsのコンソールからイメージをダウンロードされている場合は`[２]`を選んでください。
※今回は`[１]`選択

<img width="561" alt="イメージの書き込み" src="https://qiita-image-store.s3.amazonaws.com/0/189829/cd95f419-973d-b55a-f4a6-8a0332adaa2e.png">

イメージファイルが自動的にダウンロードされ、展開されます。
２回目以降はダウンロードされず同じファイルが使用されているようです。
SDカードを入れ、`[Enter]`キーを押してください。

#### 書き込みの開始

<img width="564" alt="SDカードの確認" src="https://qiita-image-store.s3.amazonaws.com/0/189829/d454d262-b1d4-d39e-a774-f33443041c30.png">

書き込み先の確認が表示されますので、問題ないようでしたら何かキーを押下します。

<img width="563" alt="書き込み確認" src="https://qiita-image-store.s3.amazonaws.com/0/189829/8653067c-f523-b1f6-58ef-9758ee7a6ccd.png">

SDカード内のデータを消しますか？と聞かれますので問題かければ`[y]`キーを入力し、
`[Enter]`キーを押下すると書き込みが開始れます。

<img width="566" alt="書き込み" src="https://qiita-image-store.s3.amazonaws.com/0/189829/5f8f00a6-2974-561d-3872-e4875bc8c50a.png">

正常に完了すると、以下のようなメッセージが出力されます。
メッセージに従いRaspberry Pi3をSDカードに入れて起動させます。

<img width="567" alt="書き込み完了" src="https://qiita-image-store.s3.amazonaws.com/0/189829/1c13c781-2590-2c48-e2d6-8ac036ee7421.png">


#Wifiの設定

イメージの書き込みが終わったら、Wifiの設定に移ります。
Raspberry Pi3は、必ず`有線LAN`に接続してください。

<img width="566" alt="Wifi設定" src="https://qiita-image-store.s3.amazonaws.com/0/189829/af1ace86-f845-563b-2330-5b376e91359f.png">

`[y]`キーを押下して、Wifi接続に進みます。

<img width="567" alt="SSIDの入力" src="https://qiita-image-store.s3.amazonaws.com/0/189829/cb7d639b-fea3-8a7d-feba-706f42f801f2.png">

同一LAN環境に、Raspberry Pi3が見つかった場合は、network名の入力画面になります。
※もし見つからない場合は、IPアドレスを指定する画面になります。

<img width="649" alt="PASSの入力" src="https://qiita-image-store.s3.amazonaws.com/0/189829/47b065c1-8600-a2c9-dee0-fa9692f20bff.png">

network名が入力されると、続いてpasswordの入力を行います。
passwordが登録されると、Wifi環境への接続が始まり、`Successfully`が表示されたら無事に接続完了です！

あとは、adb connectで接続して、Android Studioを使って開発してください！
laravel プロジェクトで RuntimeException No application encryption key has been specified.

Laravel のプロジェクトを Homestead 環境で 起動させました。
`http://localhost:8000/` にアクセスするとエラーがでました。

# RuntimeException がでる

```
RuntimeException
No application encryption key has been specified.
```
`encryption key` がないとあります。

# key を生成する

```
php artisan key:generate
Application key [base64:Wdhku6YSePiOh0XjqauthSaeOhzwRKxasFjbuuHXz0w=] set successfully.
``` 
`Application key` が生成されました。

# 再度アクセス
`http://localhost:8000/` にアクセスすると Laravel の初期画面が表示されました(☝ ՞ਊ ՞)

# 参考

* https://laracasts.com/discuss/channels/general-discussion/laravel-xampp-no-application-encryption-key-has-been-specified
xcode-select --install で失敗した時は手動でインストールする

##xcode-select --install で何かエラーが出て止まった場合は手動でインストール

[このリンク](https://developer.apple.com/download/more/)を開き、検索欄に 'command line tools' と入力。自分のMacの環境に沿ったファイルをダウンロードしてインストールできます。
ネットワークに弱いプログラマがvagrantの導入でハマったところ

#vagrant upでエラー
自分でVirtualBoxのGUIで作ったboxをupしようとしたらエラーに。。。

    default: Warning: Authentication failure. Retrying...

というログが無限に出続けるパターンです。
これ、ゲストOSにsshdが入っていませんでした。。

#vagrant box addでSSLのエラー

    Error: SSL certificate problem: unable to get local issuer certificate

というエラーです。
力技ですが、--insecureオプションを追加することでhttpで取得できます。

    vagrant box add --insecure -c ubuntu/trusty64

#proxy環境下でvagrant plugin installができない時の対処法
基本はset http_proxyで環境変数を設定すれば問題ありません。
が、なぜか設定が反映されません。
私、PowerShellで実行していたのですが、setはSet-Variableコマンドのaliasでまさかの環境変数ではなくシェル変数を設定していました。
それに気づかずに編み出したのが、**gemrcにプロキシの情報を書いちゃう**というものです。
というのもvagrant plugin installの中身はgem installだからです。
HashiCorp\Vagrant\embedded\etc\gemrcに以下の行を追加します。

    http_proxy: http://<HOST>:<PORT>
    https_proxy: http://<HOST>:<PORT>
ビット演算入門

# ビット演算入門
プログラムの基本であるビット演算ですが、はっきり言って知らなくても何とでもなります。
ですが、知っている事によってプログラムの選択肢を広げる事ができ、実際に使うと便利な場面もあります。
さらにビット演算は多くのコンピューター言語で使用する事ができるため、一度覚えれば様々な環境で使う事ができます。
本稿ではビット演算を知らない人向けに、ビット演算がどんな物であるかと簡単な実例を解説します。

## ビット演算とは
### まずビット(bit)とは何か？
コンピューターは無数のON/OFFのスイッチの集合体で、このスイッチの事をビットと呼び、スイッチ１個を１ビットと呼びます。
そしてこのスイッチは８個セットで運用されており、この８個のグループの事をバイト(byte)と呼び、グループ１組で１バイトです。
プログラムは0と1の集合体だと話を聞いた事があるかもしれませんが、ここから来ています。
表記するときには00000000のように表記し、右側から0ビット目、1ビット目...とカウントしていきます。
※1からカウントする事も多々あるので注意
### ビット演算とは
無数のスイッチのON/OFFの切り替えを制御するのがビット演算です。
ON/OFFと一言で済んでしまいますが、様々なシチュエーションの為に複数の命令が用意されています。

そしてON/OFFの制御ですが、基本的に８の倍数個をまとめて行います。
つまりバイト単位です。
各言語で１バイト変数・２バイト変数など様々ありますが、その変数全てのバイト全てにまとめて命令を出す形になります。


## 演算子
演算子とは+や-などの計算する時に使う計算記号の事です。
ビット演算は数学では使用しない特殊な計算記号で、６つあります。
基本的に帰ってくる結果は1ビット目同士・2ビット目同士と順にチェックしていき、その結果が1ビット目・２ビット目に結果がそれぞれ入ります。

### &（AND）
２つスイッチを比較して、どちらも1なら1、どちらか片方でも0の場合は0を返します。
フラグをビット管理している時に、そのフラグが立っているのかを調べたりするのに使います。
例：c = a & b
a 11110000
b 10101010
　　↓
c 10100000

### |（OR）
２つスイッチを比較して、どちらかが1なら1、どちらも0の場合は0を返します。
フラグをビット管理している時に、そのフラグを立てる時などに使います。
例：c = a | b
a 11110000
b 10101010
　　↓
c 11111010
### !（NOT）※~の場合も
スイッチのON/OFFの状態をすべて逆転させ、0は1に、1は0に変えます。
真逆の状態にしたいときに使います。
例：c = !a
a 11110000
　　↓
c 00001111

### ^（XOR）
２つスイッチを比較して、どちか片方だけ1なら1、どちらも0またはどちらも1の場合は0を返します。
どこが違うか調べるときなどで使います。
例：c = a ^ b
a 11110000
b 10101010
　　↓
c 01011010

### >>（右ビットシフト）
スイッチのON/OFFの状態を、右に1個ずらします。
ずらした事により空いた枠には0が入り、決められた桁数からはみ出た分は消えます。
このはみ出たらら消える事を、オーバーフローと呼びます。
ループを使ってビット操作するときになど使います。
記：c = a >> 1
a 11110000
　　↓
c 01111000

### <<（左ビットシフト）
スイッチのON/OFFの状態を、左に1個ずらします。
こん部分以外は右ビットシフトとほぼ同じです。
記：c = a >> 1
a 11110000
　　↓
c 11100000

## まとめ
以上がビット演算の基本になります。
これらを組み合わせる事により、単なる+-×÷ではできないようなコンピューター特有の計算をする事ができます。
実際に使いだすと、変数が何バイトなのか等気にする事も多いですが、オーバーフローを意図的に使ったりと工夫のし甲斐があります。
世の中はビットコインで白熱していますが、たまにはビット演算の事も思い出してくださいね！
続・Windows 10 Fall Creators Updateで発生しているリスト ビューでスクロールバーが出ている場合、マウスの範囲選択での複数選択をするとカーソルが画面の端っこに吹っ飛んでしまうという不具合の対策

[前回の対策](https://qiita.com/tablacus/items/1f9b62647cdafa8287ff)を全体に利かせるにはマウスのグローバルフックを使えばOKなんじゃないかと思いついたので早速作ってみました。

[Tablacus Windows 10 Fall Creators Update(RS3) のバグ対策](https://tablacus.github.io/TablacusWindows10FCUBugFix/jp.html)

DLLの対策部分はこんな感じです。

```C++
LRESULT CALLBACK MouseProc(int nCode,WPARAM wParam,LPARAM lParam)
{
	if (nCode >= 0 || nCode != HC_NOREMOVE) {
		if (nCode == HC_ACTION){
			MOUSEHOOKSTRUCTEX *pmse = (MOUSEHOOKSTRUCTEX *)lParam;
			switch (wParam) {
				case WM_MOUSEMOVE:
					if (GetKeyState(VK_LBUTTON) < 0 || GetKeyState(VK_RBUTTON) < 0) {
						WCHAR pszClass[MAX_CLASS_NAME];
						if (GetClassName(pmse->hwnd, pszClass, MAX_CLASS_NAME)) {
							if (PathMatchSpec(pszClass, L"*listview*")) {
								RECT rc = {0, 0, 1, 1};
								RedrawWindow(GetParent(pmse->hwnd), &rc, 0, RDW_NOERASE | RDW_INVALIDATE);
							}
						}
					}
					break;
			}
		}
	}
	return CallNextHookEx(g_hHookMouseWnd, nCode, wParam, lParam);
}

DllExport HHOOK CALLBACK MouseHookInstall(void)
{
	if (g_hDll) {
		ChangeWindowMessageFilter(WM_MOUSEMOVE, MSGFLT_ADD);
		return g_hHookMouseWnd = SetWindowsHookEx(WH_MOUSE,(HOOKPROC)MouseProc, g_hDll, 0);
	}
		return NULL;
}

DllExport void CALLBACK MouseHookUninstall(void)
{
	if (g_hHookMouseWnd){
		UnhookWindowsHookEx(g_hHookMouseWnd);
	}
}
```
WM_MOUSEMOVEが来たら、左右のボタンが押されているかチェック
押されたら、クラス名に「listview」が含まれているかチェック
（VC++等ではリストビューのクラス名は「SysListView32」、Delphi等では「TShListView」等になるので）
含まれていたら、(0,0)-(1,1)の範囲の親ウインドウを`RedrawWindow`で再描画しています。
(0,0)-(1,1)の範囲に狭めているのが前回からの改良点です。何でこんなので直るのかは不明ですが…
(0,0)-(0,0)にすると上手く動きません。
一応、管理者権限で実行したときの事を考えて`ChangeWindowMessageFilter(WM_MOUSEMOVE, MSGFLT_ADD);`を入れています。

マウスのグローバルフック、Windows 10 Fall Creators Updateでテストした感じ、64ビット版で32ビットも64ビットも拾えるし、逆に32ビット版でも32ビットも64ビットも拾えた。32ビットは32ビットじゃなきゃフックできないみたいな仕様だと思ってました。

ソース全体はGitHubで公開しています。
https://github.com/tablacus/TablacusWindows10FCUBugFix

**2018年1月19日 追記**
[しらいとブログ/Windows 10 Fall Creators Update (非公式)バグ修正パッチ](http://silight.hatenablog.jp/entry/win10fixPatch)
この不具合の原因と解決方法が書かれている上記ブログを教えてもらいました。
AIXで10桁以上のユーザ名を登録する

#はじめに
AIX7.1の場合、デフォルトで9桁までしかユーザIDを付与できない。
この制限値を拡張し、10桁以上の桁数のユーザを作成する手順を紹介。

#問題発生状況
以下のように、10桁以上のユーザを追加しようとするとエラーになる。
`useradd -s /usr/bin/ksh user567890`
　⇒3004-694 "user567890"　を追加するときにエラーが発生しました　：　名前が長すぎます。

#修正
ユーザID桁数上限を拡張する。

######(1)変更前確認
`lsattr -El sys0 -a max_logname`
　max_logname 9
　⇒これがユーザIDの最大桁数になる。

######(2)変更
`chdev - sys0 -a max_logname=50`
　sys0　を変更しました

######(3)変更後確認
`lsattr -El sys0 -a max_logname`
　max_logname 50

######(4)OSリブート
`shutdown -r now`
※OS再起動しないと、変更したパラメータが反映されないので注意！

再起動後、冒頭のuseraddコマンドで、ユーザが作成できることを確認する。
RPAで作業からの開放されよう

##**RPAとは？**
RPA = Robotic Process Automation

人間が行う画面上の操作を、ロボットが自動的に実行する技術です。

ま、簡単に言うと『ロボットが人間の業務を代行してくれる』的な感じです:stuck_out_tongue_winking_eye:


##**何が出来るの？**
データ化されているものを加工したり、システムにデータを入力したり、
人間がルールに基いて行っている『定型作業』はロボット化が可能です

例えば...
　・データ連携
　　　　社外サイトからデータをダウンロードし、社内システムにインポート

　・データ収集
　　　　ブラウザ上のデータを、Excelにひたすらコピペ:dizzy_face:

逆に言うと、人間の判断が必要で、ルール化できない処理は、ロボット化には向きません。
例えば、稟議の承認作業 ...等々


##**RPA導入のメリットは？**
　・開発コストの削減
　　　　データ連携など、高額なシステム開発を行わなくても実現可能
　　　　社内システムと社外システムなど、そもそものシステム連携が困難なものでも対応可能

　・プロセスの可視化
　　　　ロボット化するには、現在の手順の整理・書き出しが必要です
　　　　可視化する事で、そもそも不要な業務や作業に気づく事も。

　・ユーザ部門で作れる
　　　　多少の慣れは必要ですが、情シスなどIT部門が関与しなくてもロボット作れます

　・業務の効率化
　　　　休日なし！24時間働いてくれます（笑


##**注意する事は？**
　・野良ロボット:robot:
　　　　ユーザ部門でも作れる反面、色んなロボットが社内に氾濫する恐れ
　　　　作った当人が異動し、ロボットの中身が良く分からない...。

　・製品選定
　　　　製品により特徴や価格にバラつきあります
　　　　ROIの見合わない製品を選定してしまう恐れ
　　　　ロボット化して削減できた工数より、製品代の方が高くね...!?
rbenvの役割

前にバージョンの問題でエラーが出た時に調べたメモ

[参考記事(ザリガニが見ていた)](http://d.hatena.ne.jp/zariganitosh/20141101/what_does_rbenv)

[参考記事(rails環境構築を分かりやすく解説)](https://tech-camp.in/note/programming/9614/)
# rbenvとは
rbenv lets you easily switch between multiple versions of Ruby. It's simple, unobtrusive, and follows the UNIX tradition of single-purpose tools that do one thing well.
（rbenvを使用すると、複数のバージョンのRubyを簡単に切り替えることができます。シンプルで邪魔にならず、UNIXの伝統を継承している。）

# 役割
~/.rbenv/以下で、インストールした様々なRubyバージョンを管理し、状況に応じて必要になるRubyのバージョンを切り替えて提供してくれる。

# 構成

~/.rbenv/　（ルートフォルダ　）

~/.rbenv/shims/ （rubyやgemがインストールしてくれるコマンドのラッパーを保存するフォルダ）

~/.rbenv/version （グローバルに設定しているRubyバージョンを記録するファイル）

~/.rbenv/versions/ （その他のインストールした各種Rubyバージョンをインストールするフォルダ）

```
＊　実際の実行コマンド：　rake,gem,railsなど 
~/.rbenv/versions/2.4.0//bin

＊　標準のライブラリや、gemコマンドでインストールしたライブラリなど
~/.rbenv/versions/2.4.0/lib

＊　gemでインストールしたバージョン全てを見たい時は、
~/.rbenv/versions/2.4.0/lib/ruby/gems/2.4.0/gems　以下で確認できる

＊　マニュアルなど
~/.rbenv/versions/2.4.0/share

```

まとめると、
・上記フォルダ構造の中に、標準ライブラリやgemで追加インストールしたライブラリ、実行コマンドなどがすべて保持されている。

・OS内部に散らばらず、バージョンごとに一つのルートフォルダにまとめられる。

# インストールと各種設定
```
＊　インストール
$ brew install rbenv ruby-build

# 初期化
$ echo 'eval "$(rbenv init -)"' >> ~/.bash_profile

＊　上記の設定を有効にする
$ source ~/.bash_profile

# 必要なrubyバージョン一覧をみる
$ rbenv install -l

＊　必要なrubyバージョンをインストール
$ rbenv install 2.4.0

# リハッシュする
$ rbenv rehash

＊　グローバル（デフォルトと思ってもらったらいいです）で使うバージョンを指定
$ rbenv global 2.4.0

＊　インストールできたか確認
$ ruby -v

```
bundle instalで発生したエラーの解決

Ruby on Railsをインストールしていた際に
bundle instalで以下のエラーが発生した。

---
root@LAPTOP-54LE8E00:/mnt/c/Users/maruyama/rails/twins_community# bin/rails s
/root/.rbenv/versions/2.4.2/lib/ruby/site_ruby/2.4.0/bundler/runtime.rb:84:in `rescue in block (2 levels) in require': There was an error while trying to load the gem 'uglifier'. (Bundler::GemRequireError)
Gem Load Error is: Could not find a JavaScript runtime. See https://github.com/rails/execjs for a list of available runtimes.
Backtrace for gem load error is:
・・・・・・
・・・・・・

---


therubyracerが必要らしいので、
Gemfileに以下のgemを追加することで解決しました。
```gem 'therubyracer'
```

上記を追加後にbundle instalを実行することで
問題なく実行！
Redmineで日本語でリポジトリを検索できるかもしれない

Redmineでリポジトリ検索する機能を提供するプラグインは自分が知る限りでは **2個** あります。

## 1.  [redmine_reposearchプラグイン](https://github.com/Surgo/redmine_reposearch/wiki/Document-ja)
説明: "Hyper Estraier"という検索エンジンを使ってリポジトリを全文検索します。しかし残念ながらプラグインの更新が止まっていて Redmine 3.xに対応していません。プラグインのRedmine 3.x対応に期待します。

## 2.  [redmine_xapianプラグイン](https://github.com/xelkano/redmine_xapian)
説明: [Xapian](https://xapian.org)という検索エンジンを使ってリポジトリを全文検索します。ファイル管理のプラグインである[redmine_dmsfプラグイン](https://github.com/danmunn/redmine_dmsf)にもXapianが使用されてます。Redmineの最新バージョンにもちゃんと対応してます。しかし残念ながら日本語に対応していません。プラグインがサポートする言語の一覧の中に日本語がありません。

上記のとおり、最新のRedmineに対応した、日本語でリポジトリを検索できるプラグインは、一見無いです。

**ああ、残念**と思っていた所ですが………**もしかするとredmine_xapianプラグインでは日本語検索ができるのでは？！**と思う材料を得ました。

「(検索エンジンの)Xapianがサポートする言語」のサポート内容ですが、[公式ページの機能紹介](https://xapian.org/features)には"Supports stemming of search terms (e.g. a search for "football" would match documents which mention "footballs" or "footballer").  "という説明があります。この「語幹検索(stemming of search terms)」とは"football"という単語を検索すると、語幹を拾って、"footballs"や"footballer"もヒットするものです。この検索手法のサポート対象に日本語は含まれません。

しかしそれとは別に、XapianはCJK(中国語、日本語、韓国語）向けのサポートとして、単語単位ではなく文字単位で検索する手法(N-Gram)で検索用インデックスを作れます。(Xapian-1.2.8から)
「N-Gramって何？？」ですが、英語等は単語がスペースやカンマで区切られます。これを「わかち書き」というそうです。これに対し、CJKでは文字列に単語間の区切り文字がありません。そのため、単語単位ではなく文字単位の検索が必要で、それに対応した検索手法が　N-Gram だそうです。

「Redmineで日本語でリポジトリを検索する」に話を戻すと、redmine_xapianプラグインは、語幹検索は日本語に対応していないものの、N-Gramには対応しているので、**日本語でリポジトリを検索ができるのではないか** という予測ができます。

<del>手段は、1. まずはXapianのバージョンを1.2.8以上にする 2. 検索用インデックス作成時に環境変数にXAPIAN_CJK_NGRAM=1を設定("export XAPIAN_CJK_NGRAM=1")してインデックスを作成する。の2点です。</del>

近日中に、redmine_xapianプラグインにより（<del>N-Gramで検索用インデックスを作れば</del>）日本語でリポジトリを検索できるか、確認したいと思います。

【追記】
「Redmine3.3＋Xapian1.2.8-1」で、**環境変数を何も変更しなくても**、 Redmine_Xapianプラグインにより全角スペースに囲まれた日本語の単語の検索がある程度できる事を確認しました。 しかし、以下のように不便な点がいくつかありました。

* プラグインが対応するエンコードがUTF-8のみのため、Shift-JISの日本語は対象外。（事前にutf-8変換を入れられれば何とかなるかも）
* Word(.docx)、Excel(.xlsx)ファイルはunzipでXMLに変換した内容をテキストとして読むため、xmlのタグが混ざって検索できない場合がある。  
例） Word本文の「あいうえお」がXML化により「あいう<タグ>えお」のようにタグが混じると、「あいうえお」では検索にヒットしない
* <del>PDF, word(.doc)のファイルの文字列が日本語だけでなく英語も検索できない。（プラグインの不具合？）</del>
→ プラグイン開発者に不具合を報告したところ、数日後に修正して下さりました。(早い！)正式にはv1.6.8のリリースで修正が入ります。
https://github.com/xelkano/redmine_xapian/issues/88
* (リポジトリ検索でなく添付ファイル検索のケースで) Internal 500エラーが発生する場合がある。（常にではなくファイルの文字列中にutf-8に変換できない文字コードがある場合のみ）
Pythonでデバッグする方法


##Pythonで簡単にデバッグする方法
下記のコードをデバッグしたい箇所に追記するだけで良い。

```
import pdb; pdb.set_trace()
```

下記sample.pyの例の様に追記する

```py:sample.py
import pdb

pdb.set_trace()

for i in range(10):
    print(i)
```

sample.pyを実行するとターミナルがデバッグのコマンド待ち状態になる


```
-> for i in range(10):
(Pdb)
```
->で示されている行が次に実行される
実行後にprint(i)とかでiの中身を見ることができる

##デバッグ時のコマンド
s　 次の実行可能なものが現れたら停止
n　次の行に進んだら停止
c　最後まで実行
l　周辺のコードを確認
Filebase FunctionでLineBotを作ろう（失敗）

#Filebase FunctionでLineBotを作ろうとした失敗メモ
Firebase FunctionのHttpトリガーを使ってLineBotを作ろうとしたが、
~~課金しなければLineAPI（Google外のサービス）をコールできなかったので途中までの経過をメモする。~~
(2017/12/27編集)
有効な請求先アカウント（クレジットカード等の登録）がなければLineAPI（Google外のサービス）をコールできなかったため途中までの経過をメモする。

有効な請求先アカウント（クレジットカード等の登録）があれば従量課金プランの無料枠で動くはず。

キーワード
linebot Firebase FirebaseCloudFunctions 

#FirebaseFunctionでコーディング
LINE SDKとFirebaseFunctionのチュートリアルのコピペだが、
LINE SDKのmiddlewareにリクエストのrawBodyを渡さなければLINE SDKでエラーが発生したので、暫定で修正。
LINE SDKのmiddlewareはBODYにストリームか文字列が設定されていることを期待しているが、Firebase側で自動的にBodyParseを行っているためBODYがJSONオブジェクトとなっている。
そのため、以下のタイプエラーが発生していた。

```
TypeError: Data must be a string or a buffer at TypeError (native) at Hmac.update
```


なんでかFirebaseFunctionの[日本語ページ](https://firebase.google.com/docs/functions/http-events?hl=ja) にはrawBodyの記述がなかったので躓いた。[英語ページ](https://firebase.google.com/docs/functions/http-events?hl=en) には載ってる。

かなり無理やりだが、元のrawBodyを設定したJSONオブジェクトを作成してmiddlewareをコールすることで問題を回避してみた。

```index.js
const functions = require('firebase-functions');
const express = require('express');
const line = require('@line/bot-sdk');

// create LINE SDK config from env variables
const config = {
  channelAccessToken: '***',
  channelSecret: '***'
};

// create Express app
const app = express();

// create LINE SDK client
const client = new line.Client(config);


let middle = line.middleware(config);

// register a webhook handler
app.post('/handler', (req, res) => {
  console.log("handler");
  // middlewareにはrawBodyと署名を渡す。
  middle({body:req.rawBody,headers:{"x-line-signature":req.headers["x-line-signature"]}},res,()=>{
     console.log("next");
  });
  Promise
    .all(req.body.events.map(handleEvent))
    .then((result) => {
      res.end()
  });
});

// event handler
function handleEvent(event) {
    console.log(event);
  if (event.type !== 'message' || event.message.type !== 'text') {
    // ignore non-text-message event
    return Promise.resolve(null);
  }

  // create a echoing text message
  const echo = { type: 'text', text: event.message.text };

  // use reply API
  return client.replyMessage(event.replyToken, echo);
}


// Expose Express API as a single Cloud Function:
exports.widgets = functions.https.onRequest(app);

```

#発生するエラー
LineAPIをコールしようとして以下のエラーが発生する。
有効な請求先アカウント（クレジットカード等の登録）がなければLineAPI（Google外のサービス）を呼べないらしいのであきらめた。

```
Error: getaddrinfo ENOTFOUND api.line.me api.line.me:443 at RequestError
```
オーバーロード条件分岐メモ

#コードだけバーン
うまく解説できる気はしません・・・。

要はfuncという名前のオーバーロードメソッドを実装しているかを検査し、実装していなければ呼び出しが起きません。これはfuncというメソッドがfunc(int, int);でもfunc(string);でも実装しているものとして呼び出されます。

これの良いところは呼び出し側はfunc(int, int);としてもfunc(string);としてもfunc(string, const UserClass&);としても関係のあるクラスにさえ実装しておけばOKというところです。

```c++:has_func.h
////////////////////////////////////////////////////////////////////////////////
//
// Light Wings GameProject
//
// (C) 2009 Light Wings GameProject.
//
// https://github.com/LightWings-GameProject
//
////////////////////////////////////////////////////////////////////////////////

// funcオーバーロード関数を定義されたクラスであるかどうかを確認する
template < typename T, typename ...Args >
struct has_func
{
private:
	template < typename U >
	static auto Check(U& x, Args&& ...args)->decltype(x.func(std::declval<Args>()...), std::true_type{});
	static std::false_type Check(...);

public:
	static const bool value = decltype(Check(std::declval<T>(), std::declval<Args>()...))::value;
};

// funcオーバーロード関数が定義された時だけ呼び出す
template < typename T, typename ...Args>
auto CallFuncIfExists(T&& instance, Args&& ...args)->typename std::enable_if<has_func<T, Args...>::value>::type
{
	instance.func(std::forward<Args>(args)...);
}

// 未定義の時は何もしない
template < typename T, typename ...Args>
auto CallFuncIfExists(T&& instance, Args&& ...args)->typename std::enable_if<!has_func<T, Args...>::value>::type
{
	// Do Nothing...
}
```

```c++:sample.cpp
CallFuncIfExists(instance, std::forward<Args>(args)...);
```
```
The MIT License (MIT)
Copyright (C) 2009 Light Wings GameProject.
```

#確認環境
Visual Studio 2015で動作確認。
UE4でも動く。Windows(Steam)、PS4、Xbox Oneでもコンパイル通って動く。
何か問題起きたら対処は出来ないかもしれないけど、このコードの利用者は嬉しいかもしれません。

#参考
[decltypeとSFINAEによるオーバーロード条件分岐](https://qiita.com/_EnumHack/items/e831a359338e5f134325)
[C++メタ関数のまとめ](https://qiita.com/_EnumHack/items/ee2141ad47915c55d9cb)
[std::enable_ifを使ってオーバーロードする時、enablerを使う？](https://qiita.com/kazatsuyu/items/203584ef4cb8b9e52462)
[C++のパラメータパック基礎&パック展開テクニック](https://qiita.com/_EnumHack/items/677363eec054d70b298d)
numpy.meshgrid

```python
Z = np.zeros((5,5), [('x',float),('y',float)])
print(Z)
Z['x'] = np.meshgrid(np.linspace(0,1,5))
print(Z)
Z['x'], Z['y'] = np.meshgrid(np.linspace(0,1,5),
                             np.linspace(0,1,5))
print(Z)
```
```
[[( 0.,  0.) ( 0.,  0.) ( 0.,  0.) ( 0.,  0.) ( 0.,  0.)]
 [( 0.,  0.) ( 0.,  0.) ( 0.,  0.) ( 0.,  0.) ( 0.,  0.)]
 [( 0.,  0.) ( 0.,  0.) ( 0.,  0.) ( 0.,  0.) ( 0.,  0.)]
 [( 0.,  0.) ( 0.,  0.) ( 0.,  0.) ( 0.,  0.) ( 0.,  0.)]
 [( 0.,  0.) ( 0.,  0.) ( 0.,  0.) ( 0.,  0.) ( 0.,  0.)]]
[[( 0.  ,  0.) ( 0.25,  0.) ( 0.5 ,  0.) ( 0.75,  0.) ( 1.  ,  0.)]
 [( 0.  ,  0.) ( 0.25,  0.) ( 0.5 ,  0.) ( 0.75,  0.) ( 1.  ,  0.)]
 [( 0.  ,  0.) ( 0.25,  0.) ( 0.5 ,  0.) ( 0.75,  0.) ( 1.  ,  0.)]
 [( 0.  ,  0.) ( 0.25,  0.) ( 0.5 ,  0.) ( 0.75,  0.) ( 1.  ,  0.)]
 [( 0.  ,  0.) ( 0.25,  0.) ( 0.5 ,  0.) ( 0.75,  0.) ( 1.  ,  0.)]]
[[( 0.  ,  0.  ) ( 0.25,  0.  ) ( 0.5 ,  0.  ) ( 0.75,  0.  )
  ( 1.  ,  0.  )]
 [( 0.  ,  0.25) ( 0.25,  0.25) ( 0.5 ,  0.25) ( 0.75,  0.25)
  ( 1.  ,  0.25)]
 [( 0.  ,  0.5 ) ( 0.25,  0.5 ) ( 0.5 ,  0.5 ) ( 0.75,  0.5 )
  ( 1.  ,  0.5 )]
 [( 0.  ,  0.75) ( 0.25,  0.75) ( 0.5 ,  0.75) ( 0.75,  0.75)
  ( 1.  ,  0.75)]
 [( 0.  ,  1.  ) ( 0.25,  1.  ) ( 0.5 ,  1.  ) ( 0.75,  1.  )
  ( 1.  ,  1.  )]]
```
pi and arctan2 in numpy

```python
Z = np.random.random((10,2))
print(Z)
X,Y = Z[:,0], Z[:,1]
print(X)
print(Y)
print(np.tan(np.pi/4))
t = np.arctan2(np.sqrt(3),1)
r = t*3
print(np.pi, r)
print(np.allclose(np.pi, r))
R = np.sqrt(X**2+Y**2)
T = np.arctan2(Y,X)
print(R)
print(T)
print(T/np.pi)
```
* e.g.

```
[[ 0.3059635   0.11279336]
 [ 0.99213694  0.70904914]
 [ 0.4863001   0.59119289]
 [ 0.17257894  0.86010688]
 [ 0.16350432  0.67312375]
 [ 0.72789583  0.41819254]
 [ 0.27758441  0.43846711]
 [ 0.52287092  0.78472806]
 [ 0.60692598  0.44147906]
 [ 0.72934469  0.70356892]]
[ 0.3059635   0.99213694  0.4863001   0.17257894  0.16350432  0.72789583
  0.27758441  0.52287092  0.60692598  0.72934469]
[ 0.11279336  0.70904914  0.59119289  0.86010688  0.67312375  0.41819254
  0.43846711  0.78472806  0.44147906  0.70356892]
1.0
(3.141592653589793, 3.1415926535897931)
True
[ 0.32609202  1.21946152  0.76550429  0.87724988  0.69269708  0.83947445
  0.5189475   0.94296984  0.75050843  1.01338685]
[ 0.35319171  0.62050298  0.88244131  1.37277753  1.33250751  0.52147536
  1.00640832  0.98304178  0.62888071  0.76741174]
[ 0.11242441  0.19751223  0.28088979  0.43696866  0.42415031  0.16599076
  0.32034972  0.31291192  0.20017895  0.24427474]
```
# Refs.
* [atan2](https://docs.python.jp/3/library/math.html)
* [PI](https://oshiete.goo.ne.jp/qa/4700751.html)
* [直交座標系:cartesian coordinates](https://ja.wikipedia.org/wiki/%E7%9B%B4%E4%BA%A4%E5%BA%A7%E6%A8%99%E7%B3%BB)
* [極座標系:polar coordinates](https://ja.wikipedia.org/wiki/%E6%A5%B5%E5%BA%A7%E6%A8%99%E7%B3%BB)
CentOSから名前付きインスタンスでdatabase名が日本語のSqlServerへ接続する

かなり特殊な状況ではありますが...

## 環境

- CentOS release 6.5 (Final)
- PHP 5.6.31 (cli) (built: Jul  6 2017 08:16:47)
- Laravel Framework version 5.3.31

## freetdsのインストール

https://qiita.com/arachan@github/items/026091e69e1aba7b0918

```shell-session
$ cat /etc/freetds.conf
.
.
.
[dbname]
host = 123.123.123.123
instance = INSTANCE_NAME
```

## phpドライバのインストール

- phpのインストールは他ドキュメント参照
- ここではremiリポジトリを参照する

```
$ sudo yum install --enablerepo=remi-php56 php-mssql
```

## laravelのconfig/database.php

```php
.
.
        'SqlServer' => [
            'driver'   => 'sqlsrv',
            'host'     => 'dbname',
            'database' => '',
            'username' => 'username',
            'password' => 'password',
            'charset'  => 'utf8',
            'prefix'   => '',
        ],
```

- hostにはfreetdsで指定したものを指定
- databaseには空文字を指定
    - `config/database.php`で日本語データベースを指定すると、文字コードの違いでうまくよみとってくれなかった


## 汎用ライブラリの用意

- 自分の周辺ではSqlServerの文字コードがShift-JISであることが多く、文字コード周りを処理するために汎用ライブラリを作成
- Eloquent Modelのみで実装することも可能だと思われる

```php
<?php

namespace App\Service;

use DB;

class SqlServer
{
    protected static $connection = 'SqlServer';

    /**
     * execute select query. return results
     *
     * @param string $sql
     * @return array
     */
    public static function select($sql)
    {
        // クライアント、サーバの文字コードの設定次第では
        // クエリ送信前にも文字コード変換が必要な場合がある
        // static::u2s($sql);

        $rows = DB::connection(static::$connection)->select($sql);
        static::s2u($rows);

        return $rows;
    }

    /**
     * encoding utf8 to sjis
     *
     * @param string
     */
    public static function u2s(&$str)
    {
        static::encoding($str, 'sjis', 'utf8');
    }

    /**
     * encoding sjis to utf8
     *
     * @param string
     */
    public static function s2u(&$str)
    {
        static::encoding($str, 'utf8', 'sjis');
    }

    /**
     * encoding character or object
     *
     * @param mix string/array/object
     * @param string to_character
     * @param string from_character
     */
    public static function encoding(&$str, $to, $from)
    {
        if (is_object($str)) {
            $str = (array)$str;
        }

        if (is_array($str)) {
            array_walk_recursive($str, function(&$v) use ($to, $from) {
                static::encoding($v, $to, $from);
            });
        }
        else {
            if (! is_null($str)) {
                $str = mb_convert_encoding($str, $to, $from);
            }
        }
    }
}
```


## クエリ実行

```php
use App\Service\SqlServer;

$sql    = 'select * from [データベース].dbo.table';
$result = SqlServer::select($sql);
```

- 日本語データベースはクエリ内で直接指定する。
gnuplot の基本的な使い方

#環境
* Linux Mint MATE 18.2
* gnuplot 5.0 patchlevel 3

#gnuplotについて
gnuplotはフリーのグラフ描画ソフトです。WindowsやMac、Linuxで広く使えます。
gnuplotのインストール方法は以下のサイトが参考になると思います。

* [gnuplotのインストール(Windows)](http://www.yamamo10.jp/yamamoto/comp/gnuplot/inst_win/index.php)
* [gnuplotのインストール(Linux)](http://www.yamamo10.jp/yamamoto/comp/gnuplot/inst_linux/index.php)
* [LinuxにGnuplotをインストール](https://qiita.com/haya_walker/items/0307cda7299608c6bb21)

#基本的な使い方
最初に基本的な使い方を説明したあと、グラフの細かい設定を説明したいと思います。ターミナルから「gnuplot」と入力することでgnuplotを起動します（ターミナル上の表示が「gnuplot>」に変わる）。
###グラフを描画する
sin波を描画することを考えます。そのためには、

```bash
gnuplot> plot sin(x)
```
と入力します。すると別ウィンドウが立ち上がってsin波が描画されます。
<img src="https://qiita-image-store.s3.amazonaws.com/0/226092/c4be9ef6-a99b-2182-a145-dc0d20cf9a42.png" width=70%>

複数のグラフを描画するには、

```bash
gnuplot> plot sin(x)
gnuplot> replot cos(x)
```
と、「replot」を使います。

### グラフをファイルに出力する
描画したグラフをファイルとして出力することができます。ファイルの種類としては.pngファイルと.epsファイルがあります。

```bash
gnuplot> plot sin(x)
gnuplot> set terminal pngcairo
gnuplot> set out "sin.png"
gnuplot> replot
```
2行目は「set terminal png」でもいけますが、**「pngcairo」とすることで解像度がぐっと良くなります**。

最後の**replot**を忘れないようにしてください。3行目の「set out」の段階で、.pngファイルは生成されますが中身は空です。（ファイルが出力されるディレクトリは**pwd**で確認することができます）

コマンド以外でも、グラフが表示されたときの画面の左上にあるフロッピーのアイコンを押すことでもグラフの保存をすることができます。

#グラフの体裁を整える

上でグラフの書き方と保存の仕方を書きました。このグラフを利用するのが自分だけならここまでの情報でほぼ足りるのですが、他人に見せるとなるとグラフの体裁を整える必要があります。

**それぞれの操作をしたあとにreplotをすることで変更が反映されます**。

###軸の設定
x軸、y軸の範囲を変更するには、

```bash
gnuplot> set xr[0:1]    #0<=x<=1
gnuplot> set yr[-1:1]    #-1<=y<=1
```
軸を対数スケールにするには、

```bash
gnuplot> set logscale y    #y軸をlogスケールに
```

### グラフの形状

アスペクト比を変更するには

```bash
gnuplot> set size ratio 2    #縦が横の2倍
gnuplot> set size square    #縦横比１
gnuplot> set size nosquare    #縦横比１を解除
```
サイズを変更するには、

```bash
gnuplot> set size 0.6, 0.4    #横を画面の0.6倍、縦を画面の0.4倍
gnuplot> set bmargin 6    #グラフの下の余白を6に広げる
```
グラフ自体の調整は、

```bash
gnuplot> plot sin(x) lw 10    #sin(x)のグラフを線の太さを10にして描画
gnuplot> plot sin(x) lt rgb "red"    #sin(x)のグラフを赤線で表示
gnuplot> plot sin(x) with lines    #sin(x)を線で描画（デフォルト）
gnuplot> plot sin(x) with points    #sin(x)を点で描画
```

### 目盛りの調整

```bash
gnuplot> set xtics 2    #2ごとに主目盛りを入れる
gnuplot> set mxtics 5    #主目盛り間を5等分するように副目盛りを入れる
gnuplot> set tics font "Arial, 24"    #目盛りの数字のフォントをArial、サイズを24に
```

### 軸ラベル

```bash
gnuplot> set xlabel "t [s]"    #ｘ軸のラベルをt [s]にする
gnuplot> set ylabel "x [m]"    #y軸のラベルを x[m]にする
gnuplot> set xlabel font "Arial, 24"    #x軸のラベルのフォントをサイズ24のArialに
gnuplot> set xlabel offset 0,-1    #x軸のラベルを(0,-1)方向に動かす
```


#最後に

ここまで書いてきたことだけを使って、最初に示したsin(x)のグラフを調整してみます。
![sinx.png](https://qiita-image-store.s3.amazonaws.com/0/226092/fa1f5d86-4919-51f4-8b6a-4f867616f762.png)

だいぶ綺麗になりました。論文等に使うとなると、ラベルのtやxを斜体にするなど細かい調整が更に必要になりますが、一般的な用途ならこれでも十分でしょう。

更に細かい調整は[gnuplotスクリプトの解説](http://www.ss.scphys.kyoto-u.ac.jp/person/yonezawa/contents/program/gnuplot/index.html)のケーススタディが参考になると思います。

#参考サイト

* [gnuplotの初歩](http://graph.pc-physics.com/)
* [gnuplotコマンド集](http://www.gnuplot-cmd.com/index.html)
* [Gnuplotに関するいろいろメモ](http://www.eng.kagawa-u.ac.jp/~haruna/memo/gnuplot/gnutips.html)
一人もくもく会にQiitaと同じタグチャートを作ってみる

[一人もくもく会](https://mokumoku.alphabrend.com/) にそこそこ自分の記事が溜まってきたので、Qiitaと同じタグチャートを作ってみた。
Google Chart APIを使うだけ。

ちなみにQiitaのは下記。（丁度トレンドにいた方の）

![Screenshot from 2017-12-26 22-56-39.png](https://qiita-image-store.s3.amazonaws.com/0/136506/923c182d-912e-aaf5-0413-3b44c885d87f.png)

Vueで。

```html
<template>
  <div ref="chart"></div>
</template>

<script>
export default {
  props: ['tags'],

  mounted() {
    google.charts.load("current", { packages: ["corechart"] });
    google.charts.setOnLoadCallback(this.drawChart.bind(this));
  },

  methods: {
    drawChart() {
      const tags = this.tags.map(tag => {
        return [tag.tags.name, tag.cnt];
      });
      const data = new google.visualization.DataTable();
      data.addColumn("string", "Tag");
      data.addColumn("number", "Count");
      data.addRows(tags);
      const options = {
        width: 360,
        height: 256
      };
      const chart = new google.visualization.PieChart(this.$refs.chart);
      chart.draw(data, options);
    },
  }
};
</script>
```

呼び出し

```html
<user-tag-chart :tags="<?= h(json_encode($tagSummary)) ?>"></user-tag-chart>
```

出来た。

![20171224234434.png](https://qiita-image-store.s3.amazonaws.com/0/136506/f134f48e-a2f3-1d8d-cae9-0fa6b7332443.png)

すごく気持ち悪いのでQiitaと同じように(?)10位以下をまとめた。

![20171224234434.png](https://qiita-image-store.s3.amazonaws.com/0/136506/fc975ad8-8b44-0a83-a04e-e21475418f3e.png)

成果が目に見えると気持ちが良い。

[一人もくもく会](https://mokumoku.alphabrend.com/)
webカメラ2台で距離測定

この記事は[高知工科大 Advent Calendar 2017](https://adventar.org/calendars/2305#list-2017-12-24) 25日目の記事です。

## はじめに
メリークリスマス:christmas_tree::tada::tada::tada:
まあ、卒論の追われる私には関係ない話ですが:innocent: 
この記事では卒論の一部になる予定のステレオカメラによる距離測定について書きます。

ところで皆さん、[ROBO-剣](http://www.robo-one.com/kens/index/27)というロボット競技をご存知でしょうか？ロボットに剣道をさせるといういたってシンプルなロボットの大会です。Robocupと同じように将来は人と剣道できるロボットを目指すのだとか。
このROBO-剣というい競技はいつぞやのロボミントンのように手動制御と自動制御が混在する大会で、自動制御の場合、相手の位置を検出する必要があります。そのため叩くとポイントになる面・胴・小手にはそれぞれ赤・青・黄の色がついています。そこで今回は赤色の面を認識するためにステレオカメラで距離測定をやってみました。

## 実験環境
<img src="https://qiita-image-store.s3.amazonaws.com/0/147601/63ed409d-ff0f-93fa-9d81-ebee384ecf3c.jpeg" width=80%>

アマゾンで適当に購入したLogicoolのwebカメラをLアングルで挟むことで、平行になるようにしています。
カメラ間の距離とかは実験しながら調節する予定。

## とりあえず距離を測る
距離を測定するまでにカメラの歪みを補正したりステレオカメラのキャリブレーションとかいろいろありますが、このカメラでチェストボードを映してみた感じ、いけそうだったのでとりあえず測定をしてみることに

処理の手順として

  1. カメラから画像を取得
  2. 色抽出＆二値化
  3. 平滑化処理
  4. 対象の重心位置の推定
  5. 左右の画像から得られた対象の重心位置の差を求める
  6. 重心位置の差から距離を求める

今回は検出する物体が赤色の物体と決まっていたのでこのような手順で試してみました。
ステレオカメラで距離を測る場合、三角測量の考え方で距離を求めることができます。
![s1.gif](https://qiita-image-store.s3.amazonaws.com/0/147601/93420f85-6fc2-0449-f1c7-8cf52523bbda.gif)

このとき以下の式でDを求めることができます。
$D = \frac{B*f}{Z}$
このときZが左右の画像から得られた重心位置の差、Bがカメラのレンズ間の距離、fが焦点距離になります。

ここまでの処理で、実際の距離と計算によって算出された距離がどうなるか実験してみます。
![グラフ.png](https://qiita-image-store.s3.amazonaws.com/0/147601/59db796b-5811-95c4-72b4-8738d8d1153c.png)
軸ラベルがないのですが、横軸は実際の距離[mm]、縦軸は計算結果です。
何かがおかしいですが、線形なグラフができたのでひとまず良しとしましょう。

## 値を補正する
先ほど出てきた
$D = \frac{B*f}{Z}$
の式を変形させてグラフを表示させると、なんとなく距離ごとの誤差が線形近似できる気がします。
![なんか行けそうな気がする.png](https://qiita-image-store.s3.amazonaws.com/0/147601/dd1549b3-d2c2-1ca3-2c06-4d4b015a18d6.png)
そこで、エクセルで計算された近似式をもとに先ほどと同じように距離を測定してみます。

<blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr">前回上げたやつが見づらかったので上げ直し <a href="https://t.co/sSfFBvS3fU">pic.twitter.com/sSfFBvS3fU</a></p>&mdash; ringo (@Malus_Mill_) <a href="https://twitter.com/Malus_Mill_/status/945674390972198912?ref_src=twsrc%5Etfw">2017年12月26日</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

動画の中で僕が動かしているあらびき塩こしょうの頭の距離を端末に表示しています。あらびき塩こしょうに表示されている点が重心位置になります。
映像ではわかりにくいですが、プラスマイナス2,3cmぐらいの精度で距離を測定することができました！！

## おわりに
クリスマスまでに記事書きたかったけど間に合わず申し訳ない
なんとなくステレオカメラで距離を測定することができました。
今後は精度の向上や、実際にロボットの制御にこの記事の測定システムを組み込むことを目標にしたいと思います。
Azure上にRedmineを立てる

#VMの作成

1. `Redmine Certified by Bitnami`を AzureMarketPlace　から選択
1. サイズは`A1v2 Standard` (1Core, 2G Memory)を選択
1. http://<仮想マシンのIPアドレス> にブラウザでアクセス
1. 管理者ユーザでログイン
    * ログイン方法は、ログイン画面右下のアイコンをクリックすると参照できる。  
    * ユーザ名：`user`
    * パスワード: 以下の方法で確認する
        * AzureポータルでVMを選択し、`ブート診断`→`Serial log`を選択
        * 下までスクロールし、以下のように表示されている箇所にパスワードが出力されている
        
```
#########################################################################

#                                                                       #

#        Setting Bitnami application password to '<パスワード>'   　　　　　　      #

#                                                                       #

#########################################################################
```

#初期ユーザ名・パスワードの変更
1. 画面上部の`Administration`を選択
1. `Users`を選択し、デフォルト管理者ユーザの`user`を選択
1. ログイン名、名・姓、Email、表示言語、パスワードを入力し、`Save`をクリック
1. 一旦ログアウトされるので、指定したログイン名で再度ログインする

#メールサーバの設定

1. `/opt/bitnami/apps/redmine/htdocs/config/configuration.yml`を編集

```configration.yml
      address: <smtp host>
      port: 587
      domain: example.net
      authentication: :login
      user_name: <login username>
      password: <login password>
```
　　参考：　SendgridのSMTPを使用する場合は、以下を参考にする
　　　　[SMTPの接続情報を教えてください。 – サポート](https://support.sendgrid.kke.co.jp/hc/ja/articles/204187885-SMTP%E3%81%AE%E6%8E%A5%E7%B6%9A%E6%83%85%E5%A0%B1%E3%82%92%E6%95%99%E3%81%88%E3%81%A6%E3%81%8F%E3%81%A0%E3%81%95%E3%81%84-)
　　  　　※　認証情報にAPIキーを使用する場合、ユーザ名は`apikey`固定、パスワードは生成されたAPIキーとなるので注意

2\. VM再起動
3. 管理者でログインし、`管理`→`設定`→`メール設定`で画面下部の`テストメール送信`を押して、メールが送信されることを確認する

# 記法をTextileからMarkdownに変更

* `管理` →　`全般` → `テキスト書式` を `Textile`から`Markdown`に変更

　　参考：[Redmine 2\.5新機能紹介: Markdown記法の試験的なサポート \| Redmine\.JP Blog](http://blog.redmine.jp/articles/2_5/markdown-support/)

　　参考:[RedmineでのMarkdown記法 - misc.log](http://backyard.hatenablog.com/entry/20160613/1465781734)

# 次のステップ
* [AzureマーケットプレースのRedmineにLet’s Encryptの証明書を設定する \- Qiita](https://qiita.com/sunack/items/9d9fef36cfa387174f3c)

# （参考）その他
* Azure MarketplaceのRedmineのbitnami公式ヘルプ
  * [Bitnami Redmine for Microsoft Azure
](https://docs.bitnami.com/azure/apps/redmine/)

* メールの件名・本文中のリンクをカスタマイズする
  * [Redmineの通知メールの「件名」を変更する方法 | OTSUKARE-TION （おつかレーション）](http://otsukare-tion.com/2013/11/redmine_sendmail_subject/)
ACLとかあれこれ

#ACLとは
アクセスコントロールリスト。
通信アクセスを制限するためのリストのこと。フィルタリング。
ACLを定義することで、ルータを通過するパケットに対して、通信を許可するパケットと、通信を拒否するパケットのルールを決めることができる。

**ファイアウォールとは何が違うの？**
→応答パケットへを許可するかどうかがちがう。

1. ファイアウォールの場合    
クライアント　→(リクエスト)→　ファイアウォール(許可)　　　　　→(リクエスト)→　サーバ
　　　　　　　←(レスポンス)←　ファイアウォール(**無条件に**許可)　←(レスポンス)←  

※リクエストがルール上許可された通信の場合、応答パケットはルールに明記されていなくても許可する  


1. ACLの場合  
クライアント　→(リクエスト)→　ファイアウォール(許可)　　　　　→(リクエスト)→　サーバ
　　　　　　　　　　　　　　　　ファイアウォール(拒否)　　　　←(レスポンス)←  
※リクエストがルール上許可された通信の場合でも、応答パケットはルールに明記されていない場合は拒否する  

#ACLの処理順序
例えば以下のようなACLがあるとする。

1行目　送信元アドレス192.168.0.1　拒否
2行目　送信元アドレス192.168.0.0/24　許可
3行目　暗黙のdeny any

ACLの処理は、**上から順に**行われる。ここがポイント。
例えば　
192.168.0.1　の送信元アドレスからパケットを受信した場合、1行目のルールに合致するため「拒否」となる。
2行目のルールにも合致するが、ルールに1つ合致した時点で以降のルールはチェックされないため、適用されない。
つまり、限定的な条件ほど、始めのほうに記述すること。
**順番を間違えると、思っている通りの動きにならないため注意！**

#暗黙のdeny
上のACLの3行目にある、「暗黙のdeny any」の記述について。

ACLの最終行には「暗黙のdeny」と呼ばれる、**全てのパケットを拒否する**ルールが追加される。
これはリストには表示されていないが、自動的に追加されるので注意する。

このため、ACLには最低1行は許可するルールが記述されていない場合は、全パケットが拒否されることになる。

#ACLの種類
一般に使用されるACLとして、以下の2つがある(Cisco製品）。

1.標準ACL  
送信元IPアドレスをもとにフィルタリングを行う。    

![image.png](https://qiita-image-store.s3.amazonaws.com/0/185546/b78f247a-dc6e-fd57-aa4d-7e054674c772.png)

上の図では、R1に設定すると、送信元のIPアドレスしか見れないため20.1.1.1への通信もできなくなってしまう。
通常、標準ACLは宛先に近いところで設定することが望ましい。　　

2.拡張ACL  
送信元IPアドレス、宛先IPアドレス、プロトコル番号、送信元ポート番号、宛先ポート番号。。などでフィルタリングできる。標準ACLよりも柔軟に制御可能であるため、こちらのほうがよく使われている。  

![image.png](https://qiita-image-store.s3.amazonaws.com/0/185546/f65ea5d5-9a06-e906-4237-f0e609817d31.png)
上の図では、拡張ACLは宛先のIPアドレスが見れるので、R1でもR2でもどちらに設定しても条件は満たせる。
しかしR2に設定した場合、その分無駄なトラフィックが生じることになるので、R1で設定するほうが良い。

通常、標準ACLは送信元に近いところで設定することが望ましい。


#参考
[ACL - Check Rule](http://www.infraexpert.com/study/aclz2.html)
Swift：OpenALでcaf音源を鳴らす方法

# はじめに

ゲームなど速いレスポンスが必要な場合OpenALで音を鳴らすのが良いらしいことを知ったので、OpenALでcaf音源を鳴らすクラスを作成した。

# ソースコード

```swift:OpenALUtil.swift
import OpenAL
import AudioToolbox

class OpenALUtil {
	var buffer: ALuint = 0
	var source: ALuint = 0

	init(fileName name: String) {
		let device = alcOpenDevice(nil)
		let context = alcCreateContext(device, nil)
		alcMakeContextCurrent(context)

		alGenBuffers(1, &buffer)
		let error: ALenum = alGetError()
		if error != AL_NO_ERROR {
			Swift.print(error.description)
			return
		}

		//open audio-file
		var fileId: AudioFileID? = nil
		let url: CFURL = URL(fileURLWithPath: Bundle.main.path(forResource: name, ofType: "caf")!) as CFURL
		let _: OSStatus = AudioFileOpenURL(url, .readPermission, kAudioFileCAFType, &fileId)

		//get byte-size of audio-file
		var byteCount: UInt64 = 0
		var propertySize = UInt32(MemoryLayout.size(ofValue: byteCount))
		let _: OSStatus = AudioFileGetProperty(fileId!, kAudioFilePropertyAudioDataByteCount, &propertySize, &byteCount)

		//read audio-file
		var bytesRead = UInt32(byteCount)
		let audioData = malloc(Int(bytesRead))!
		let _: OSStatus = AudioFileReadBytes(fileId!, false, 0, &bytesRead, audioData)

		//close audio-file
		let _: OSStatus = AudioFileClose(fileId!)

		//data into buffer
		alGenBuffers(1, &buffer)
		alBufferData(buffer, AL_FORMAT_MONO16, audioData, ALsizei(bytesRead), 44100)

		//write buffer to source
		alGenSources(1, &source)
		alSourcei(source, AL_LOOPING, AL_TRUE)
		alSourcei(source, AL_BUFFER, ALint(buffer))
	}

	public func play() {
		alSourcePlay(source)
	}

	public func pause() {
		alSourcePause(source)
	}

	public func stop() {
		alSourceStop(source)
	}
}
```

# このClassの使い方

```swift:ViewController.swift
let sound = OpenALUtil(fileName: "click") //click.cafを指定
sound.play() //再生
sound.pause() //一時停止
sound.stop() //停止
```