OmniAICreator/Qiita-1.07M huggingface dataset:
【C#】C#から%d（変換指定子）を呼び出す【F#】

# 【C#】C#から%d（変換指定子）を呼び出す【F#】
C#ではCやC++、Pythonなどで利用されている変換指定子が直接利用できないため、
C#上からF#のライブラリを呼び出し、変換指定子付きの書式フォーマットを利用します。

C++で作成されているシステムのC#への移行を行う場合等、何かしら今後利用することがありそうな気がするので、
私的メモとしてここに残しておきます。

## 環境
VisualStudio 2015
FSharp.Core 4.4.0.0

## 経緯

### 変換指定子（書式化文字列）って？
変換指定子とは、

    %[flags][width][.precision][modifier]type

のような形を用いて、出力するデータの書式を指定します。
例としては__%d__や、__%.3f__のような形で用いられ、それぞれ「10進数での表示」、
「小数点以下3桁までの表示」となります。変換指定子の詳しい記法等は下記参照。
<http://www.tamasoft.co.jp/lc/hlp/F056.html>

### それってC#でもできんじゃね？
C#のToString()を用いて、書式指定の文字列変換を行うことはできますが、
これはCやC++で利用される変換指定子利用とは全く違う形です。ですので、今までC++で作成してきたシステムの
何かを利用する場合、同じように利用できない場合が多いでしょう。

### じゃあC++でやればいいじゃん。
確かに、C++のライブラリを作成してC#から呼び出すこともできますが、
stringの扱いや、型の扱い（floatの場合、intの場合、decimalの場合、stringの場合・・・）等、
ライブラリを呼び出す制御作成自体が少し大変であり、時間が掛かってしまいます。

勿論、元がC++のコードで、それを移行するだけであればその方法の方が良いかとは思いますが、
現実的にはそうできない場合も多いため、今回はF#での実装を行いました。

## ソースコード

### F#部分

~~~c#
namespace SprintFTest.Formatter

module Format = begin
    /// 変換指定子を用いて文字列を変換する
    let SprintF style value : string =
        // 受け取った書式文字列をPrintFormat型にキャスト
        let f = Printf.StringFormat<_>(style)
        // sprintfで書式変更した結果を返却
        sprintf f value
end
~~~
変換指定子を利用するために、F#のsprintfメソッドを利用します。
引数の型指定はせず、返り値のみの指定とし、あくまでF#のsprintfを呼び出すだけのメソッドとしています。

これをC#側から呼び出せばokです。参照に追加するのを忘れないように！
### C#部分
~~~C#
using System;

namespace SprintFTest
{
    class Program
    {
        /// <summary>
        /// メインエントリ
        /// </summary>
        /// <param name="args"></param>
        static void Main(string[] args)
        {
            //変換指定子
            string format = "%.2f\n";       //小数点以下2桁までとし、行末改行
            string format2 = "%.5finch";    //小数点以下5桁までとし、inchを付加
            string format3 = "%x";          //符号なし16進数として出力する

            //変換指定子を使って数値を変換したい！
            Console.WriteLine(Format(format, 3.1415926535));
            Console.WriteLine(Format(format2, 3.1415926535));
            Console.WriteLine(Format(format3, 269));

            //結果表示
            Console.ReadLine();
        }

        /// <summary>
        /// F#を呼び出して書式変換を行う
        /// </summary>
        private static string Format<T>(string style,T value)
        {
            return Formatter.Format.SprintF(style, value);
        }
    }
}
~~~

Format<T>(string style,T value)というラッパーを用意し、F#のSprintFメソッドを呼び出します。
F#側では動的型付けを用いて変換を行っているので、第二引数にはジェネリック __T__を用いています。
これにより、変換対象となるデータがintであっても、floatであっても、意識することなく変換を行うことが出来ます。

※変換対象データと書式が合わない場合（変換指定子が.3fなのにデータがintの場合）などは適切な制御が
必要と考えられます。その場合は、Mainから呼び出されFormatを呼び出す仲介メソッドを作成し、
そこでキャスト処理等を加えてやるとよいでしょう。

## 出力結果
![1.PNG](https://qiita-image-store.s3.amazonaws.com/0/131683/e99d895e-5ad7-5503-2752-e10f9a6ed290.png)

## プロジェクトの全体構成
![C.PNG](https://qiita-image-store.s3.amazonaws.com/0/131683/2f7ef057-425c-b811-db5e-f642b7d57305.png)

## 感想
ニッチなメモになってしまいましたが、そのうち使う機会が訪れる・・・かも・・・？
とりあえず、表示に%d使えないからC#やめてC++で開発しよう！とかそういう判断はしたくないので、
忘れないようにします。

## 参考リンク
<http://www.tamasoft.co.jp/lc/hlp/F056.html>
【Swift】Swiftのversionを確認しよう

最近Swiftの勉強を始めて，ライブラリ等Swiftのversionごとに使えるversionが異なるので戸惑ってしまいました．（冷静に考えれば当然なんだけど...）
その点Obj-Cは楽だったな，と思ったり...

そんなわけでSwiftのversion確認の必要性に気づいたので，確認方法を備忘録として記事にします．

# ターミナルでコマンドを入力すれば簡単に確認できます！
ターミナルを起動して以下のコマンドを入力すると，Swiftのversionを確認できます．

```text
$ /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/swift -v
```
実行結果はこのようになります．
<img width="450" alt="スクリーンショット 2016-11-01 10.06.41.png" src="https://qiita-image-store.s3.amazonaws.com/0/139470/1509392e-5145-a3cd-dc2b-5498acb550c6.png">

**※上記のコマンドで最後の -v を --version にするとSwiftのversionだけ確認できます**
上図の最後の行のように，:exitと入力すればターミナルに戻ることができます．


Swiftの学習を始めたばかりの方は僕みたいにversionの確認をしていない人もいると思うので参考になれば幸いです．
MySQL 読み物

参考になった/珍しい/面白い記事などのまとめです。
おすすめの記事がありましたら、教えて頂けるとうれしいです:smile:

リンクの補足は、頂いたコメントの丸パクリが多いです。すみません:sweat_drops:


# 読み切り
個人的に興味深かった単発の記事です。
下に行くほどコアな話になるよう並べています。

<i class="fa fa-leanpub"></i>[【基礎編】社内向けMySQL勉強会](http://www.slideshare.net/yujiotani16/mysql-26318245)
> ライト向けな記事で、MySQLの歴史やインデックスについて書かれています。

<i class="fa fa-leanpub"></i>[MySQL道普請便り　第1回　MySQLの利用に役立つ情報源](http://gihyo.jp/dev/serial/01/mysql-road-construction-news/0001)
> 連載系にもある「MySQL道普請便り」の第一回記事です。
> ※日本オラクル梶山さんが、MySQLの情報源について書かれています。

<i class="fa fa-leanpub"></i>[MySQLのNOW関数はどのようにして安全にスレーブでリプレイされるのか](https://yoku0825.blogspot.jp/2016/12/mysqlnow.html)

<i class="fa fa-leanpub"></i>[MySQLのトランザクション制御がキモい話](http://atsuizo.hatenadiary.jp/entry/2016/12/05/000000)

<i class="fa fa-leanpub"></i>[MySQL 5.7 InnoDB 日本語全文検索（その１）](http://www.slideshare.net/yoyamasaki/20160209-inno-dbftsjp)
<i class="fa fa-leanpub"></i>[MySQL 5.7 InnoDB 日本語全文検索（その２）](http://www.slideshare.net/yoyamasaki/mysql-57-innodb)
<i class="fa fa-leanpub"></i>[MySQL 5.7 InnoDB 日本語全文検索（その３）](http://www.slideshare.net/yoyamasaki/20160929-inno-dbftsjp)
> 日本オラクル山崎さんのスライドです。

<i class="fa fa-leanpub"></i>[MySQL SQLオプティマイザのコスト計算アルゴリズム（PDF資料）](http://dbstudy.info/files/20120310/mysql_costcalc.pdf)
<i class="fa fa-leanpub"></i>あわせて読みたい - [MySQL InnoDB Deep Talk #1 復習](http://d.hatena.ne.jp/sh2/20120319)

# 連載系
:eyes: 時間があるときに読むと新たな発見があると思います。

<i class="fa fa-leanpub"></i>[Use The Index Luke: 開発者のためのSQLのチューニングへのガイド](https://use-the-index-luke.com/ja/sql/preface)
> Use The Index, LukeはSQLパフォーマンス詳解のWeb上の無料版です。サイトを気に入って頂けたら、ぜひ書籍も購入してみて下さい。

インデックスの仕組みについて詳しく説明されています。
一度は目を通してもらいたい内容です。

<i class="fa fa-leanpub"></i>[「MySQLチューニング虎の巻」連載一覧](http://enterprisezine.jp/article/corner/204)
> 日本オラクル 奥野さんによる

<i class="fa fa-leanpub"></i>[MySQL道普請便り](http://gihyo.jp/dev/serial/01/mysql-road-construction-news)



# ブログ系

<i class="fa fa-leanpub"></i>[漢(オトコ)のコンピュータ道](http://nippondanji.blogspot.jp/)
> 日本オラクル奥野さんのブログです。

<i class="fa fa-leanpub"></i>[日々の覚書 ](https://yoku0825.blogspot.jp/)
> Oracle Ace・yoku0825さんのブログです。

<i class="fa fa-leanpub"></i>[SH2の日記](http://d.hatena.ne.jp/sh2/)
> Oracle ACE(MySQL) のSH2さんのブログです。
> InnoDBのコアなところ多め。

<i class="fa fa-leanpub"></i>[かみぽわーる](http://blog.kamipo.net/)
> Oracle ACE(MySQL) のkamipoさんのブログです。
> yoku0825, SH2さんに比べてアプリケーション(ActiveRecord)寄りのACE

<i class="fa fa-leanpub"></i>[variable.jp [データベース,パフォーマンス,運用] – Database. Operation, Performance](http://variable.jp/)
> MySQLの中の人(Oracleのひと)のブログ。最新機能の「試してみた」系の宝庫。

# その他

<i class="fa fa-leanpub"></i>[Yakst | 人力翻訳コミュニティ](https://yakst.com/ja)
> MySQL特化ではないですが、多くのMySQL関連ブログエントリー(英語)が日本語に翻訳されています。
UIButtonでタイトルを改行する方法 in Swift3.0

#開発環境
Xcode8.1
Swift3.0 + Autolayout
iOS9+

#Autolayoutでハマった
UIButtonのタイトルなんて、簡単に改行できるだろうと思っていました。
ところが、どっこいかなり苦戦し半日程浪費してしまいました。

#実現方法
(1)以下のUIButtonのサブクラスを作成


```swift:MultiLineButton.swift
import UIKit

class MultiLineButton: UIButton {

    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
        
        self.commonInit()
    }
    
    private func commonInit() {
        self.titleLabel?.numberOfLines = 0
        self.titleLabel?.lineBreakMode = .byWordWrapping
    }

    
    override public var intrinsicContentSize: CGSize {
        //...
        return titleLabel?.intrinsicContentSize ?? CGSize.zero
    }
    

    override func layoutSubviews() {
        super.layoutSubviews()
        titleLabel?.preferredMaxLayoutWidth = titleLabel?.frame.size.width ?? 0
        super.layoutSubviews()
    }

}
```
(2)UIButtonのTypeをCustomに変更
(3)Storyboardで改行したいUIButtonのクラスをMultiLineButtonに変更

以上で、完成です。
もしこちらより、良い方法や別の方法があればご連絡ください。

#引用
Multiline UIButton and autolayout
http://stackoverflow.com/questions/23845982/multiline-uibutton-and-autolayout
【自分用】プロセスとかファイルディスクリプタをSwiftからlibcを使って確認してみる

次のような書籍の勉強中なので、
その内容理解とSwiftからCを触ってみる練習のための自分用メモです。

- [なるほどUnixプロセス ― Rubyで学ぶUnixの基礎](http://tatsu-zine.com/books/naruhounix)
- [Linuxシステムプログラミング](https://www.amazon.co.jp/Linux%E3%82%B7%E3%82%B9%E3%83%86%E3%83%A0%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9F%E3%83%B3%E3%82%B0-Robert-Love/dp/4873113628)


以後、全て対話式にSwiftを動かしています。

```bash
$ swift
```

## libcを使う(macOS)

```swift
// macOSの場合
import Darwin
// Linuxの場合
// import Glibc
```

## PID, PPID

#### PID取得

```swift
let pid = getpid()
// -> pid: pid_t = 48846
```

別ウィンドウで取得したPIDのプロセスを確認

```bash
$ ps -p 48846

  PID TTY           TIME CMD
48846 ttys000    0:00.04 /Applications/Xcode.app/Contents/SharedFrameworks/LLDB.framework/Resources/repl_swift
```

対話式で起動しているので、`repl_swift`が動いているよう


#### 親プロセスのPID取得

```swift
let ppid = getppid()
// ppid: pid_t = 48847
```

同じく別ウィンドウで取得したPIDのプロセスを確認

```bash
$ ps -p 48847

  PID TTY           TIME CMD
48847 ttys000    0:00.11 /Applications/Xcode.app/Contents/SharedFrameworks/LLDB.framework/Resources/debugserver --native-regs --setsid --reverse-connect 127.0.0.1:59152
```

### システムコール

```bash
man 2 getpid
# man 2 getppid も同じ
```

### 補足

PIDだけならSwiftのFoundationで可能

```swift
import Foundation
ProcessInfo().processIdentifier
// -> $R12: Int32 = 48846
```

https://developer.apple.com/reference/foundation/processinfo

`getpid()`の返り値は`pid_t`, `ProcessInfo().processIdentifier`の返り値は`Int32`。

```swift
ProcessInfo().processIdentifier == getpid()
// $R16: Bool = true
```

比較できるので、`pid_t`はInt32のエイリアスなのかな？

---


## ファイルディスクリプタ

### 標準入力、標準出力、標準エラー（stdin, stdout, stderr）

標準入力、標準出力、標準エラーのファイルディスクリプタはそれぞれ、 0, 1, 2 と決まっているので、それを確認する。

libcを読み込んだので、stdin, stdout, stderrが使える。

#### - **標準入力**のファイルディスクリプタ


```swift
let stdinFileNo = fileno(stdin)
// -> stdinFileNo: Int32 = 0
```

#### - **標準出力**のファイルディスクリプタ

```swift
let stdoutFileNo = fileno(stdout)
// -> stdoutFileNo: Int32 = 1
```

#### - **標準出力**のファイルディスクリプタ

```swift
let stderrFileNo = fileno(stderr)
// -> stderrFileNo: Int32 = 2
```



ちなみに、stdin, stdout, stderrの型は`UnsafeMutablePointer<FILE>`。

```swift
type(of: stdin)
// -> $R2: UnsafeMutablePointer<FILE>.Type = UnsafeMutablePointer<__sFILE>
```


また、Cライブラリでは、 STDIN_FILENO, STDOUT_FILENO, STDERR_FILENO というマクロが用意されているとのこと。

```swift
// libcを読み込んでいるので、これもSwiftから呼べる
STDIN_FILENO
// -> $R9: Int32 = 0
STDOUT_FILENO
// -> $R10: Int32 = 1
STDERR_FILENO
// -> $R11: Int32 = 2
```


### ファイルを開いてファイルディスクリプタの確認

```swift
let fd = open("test.txt", O_RDONLY)
// -> fd: Int32 = 5
// ファイルディスクリプタ 5 が返ってきた

let fd2 = open("test2.txt", O_RDONLY)
// -> fd2: Int32 = 6
// ファイルディスクリプタ 6 が返ってきた

close(fd)
// -> $R7: Int32 = 0
// ファイルを閉じる
// ファイルディスクリプタ 5 が再利用可能になった

let fd3 = open("test3.txt", O_RDONLY)
// -> fd: Int32 = 5
// 先ほどファイルを閉じたことで再利用可能になったファイルディスクリプタ 5 が使われた
```


`fileno()`関数は Swift Package Manager でも使ってるっぽい。

https://github.com/apple/swift-package-manager/blob/57c5be1db1c1e12e089dff02241ffbce5722fb0e/Sources/Utility/TTY.swift

### システムコール


```bash
man 2 open
man 2 close
```


---

とりあえずここまで。
link > SuperCD (Super Classembly Devices) > IoT向けWinPC?

SuperCD (Super Classembly Devices)

http://www.interface.co.jp/super/index_spec.asp

Windows 7が動作するIoT用パソコンらしい。

パンフレットには以下のような記載がある。

- 型式: VAC-G019(L7X)
- 価格 69,800- (100台購入時単価)
- OS
   - Interface Linux System 7 (L7X)
   - Windows Embedded Standard 7

100台単位の価格記載なので、大量購入向けなのだろうか。

活用方法の半分くらいはRaspberry Pi2あたりでも処理できそうな気がする。
一方で、画像関連の処理など負荷が大きそうな場合の選択肢になるだろうか。
Proxmox VE 4.3 で mdadmを使う

* 普通にやるだけ。
* [ubuntuでソフトウェアRAID1 その2 - Qiita](http://qiita.com/tukiyo3/items/6dd0e686138a9870d81f)
* rootパーティションをRAID1にするには [DebianInstaller/SoftwareRaidRoot - Debian Wiki](https://wiki.debian.org/DebianInstaller/SoftwareRaidRoot)

## インストール

```
apt install -y mdadm
```

![raid.png](https://qiita-image-store.s3.amazonaws.com/0/25728/2d538dd9-8ba0-cd2c-00fe-942a19ff86a7.png)

## RAID1の新規作成

* 以下構成とする
    * sda : 1tb
    * sdb : 500gb
    * sdc : 500gb
    * sdd : 1tb

```rb
mdadm --create /dev/md0 --level=1 --raid-devices=2 /dev/sdb /dev/sdc
mkfs.ext4 /dev/md0
```

```rb
mdadm --create /dev/md1 --level=1 --raid-devices=2 /dev/sda /dev/sdd
mkfs.ext4 /dev/md1
```

## OS起動時にマウントされるようにする

```rb
mdadm --detail --scan
mdadm --detail --scan > /etc/mdadm.conf
```

* /etc/fstabに追記

## リビルド状況確認

```rb
cat /proc/mdstat
```

# DISK障害対応

* 障害HDDを引っこ抜く

```bash:状況確認
mdadm --detail /dev/md0
```

```diff:
- State : clean, degraded
  ...
    Number   Major   Minor   RaidDevice State
       0       8        0        0      active sync   /dev/sdb
-      2       0        0        2      removed
```

```
mdadm --manage /dev/md0 --remove /dev/sdc
mdadm --manage /dev/md0 --fail /dev/sdc
```

* 電源を落とし、DISK交換

```
mdadm --manage /dev/md0 --add /dev/sdc
```


```diff:
+ State : active, degraded, recovering
  ...
    Number   Major   Minor   RaidDevice State
       0       8        0        0      active sync   /dev/sdb
+      2       8       48        1      spare rebuilding   /dev/sdc
```
TensorFlow > link > tf.train.Coordinator() @ github.com/tensorflow

```txt:動作環境
Ubuntu 14.04 LTS desktop amd64
GeForce GTX 750 Ti
ASRock Z170M Pro4S [Intel Z170chipset]
TensorFlow v0.11
cuDNN v5.1 for Linux
CUDA v7.5
Python 2.7.6
IPython 5.1.0 -- An enhanced Interactive Python.
```

TensorFlowというDeep Learningフレームワークを学習中。

TensorFlowを遊び倒す！ 4-1. Convolutional Neural Networks
http://blog.brainpad.co.jp/entry/2016/04/22/170000
https://www.tensorflow.org/versions/master/tutorials/deep_cnn/index.html

cifar10_eval.pyを見ている。


以下が気になった部分。

```cifar10_eval.py
  with tf.Session() as sess:
...
    # Start the queue runners.
    coord = tf.train.Coordinator()
```

https://github.com/tensorflow/tensorflow/blob/master/tensorflow/g3doc/api_docs/python/functions_and_classes/shard6/tf.train.Coordinator.md

queue runners関連は後でまとめて学習することにした。
その足がかりとして上記リンクを記事とする。
python > .split('/')[-1] > /を取り除いて、最後の項目を返すようだ

```txt:動作環境
Ubuntu 14.04 LTS desktop amd64
GeForce GTX 750 Ti
ASRock Z170M Pro4S [Intel Z170chipset]
TensorFlow v0.11
cuDNN v5.1 for Linux
CUDA v7.5
Python 2.7.6
IPython 5.1.0 -- An enhanced Interactive Python.
```

TensorFlowというDeep Learningフレームワークを学習中。

TensorFlowを遊び倒す！ 4-1. Convolutional Neural Networks
http://blog.brainpad.co.jp/entry/2016/04/22/170000
https://www.tensorflow.org/versions/master/tutorials/deep_cnn/index.html

cifar10_eval.pyを見ていた。

以下の部分が気になった。

```cifar10_eval.py
...
def eval_once(saver, summary_writer, top_k_op, summary_op):
...
      # Assuming model_checkpoint_path looks something like:
      #   /my-favorite-path/cifar10_train/model.ckpt-0,
      # extract global_step from it.
      global_step = ckpt.model_checkpoint_path.split('/')[-1].split('-')[-1]
```

ideoneで試してみた。

http://ideone.com/Nwbx1m

```py
# your code goes here
ckpt='/AAA/BBB/CCC/DDD-E'
print ckpt

print ckpt.split('/')[-1]
print ckpt.split('-')[-1]
```

```
/AAA/BBB/CCC/DDD-E
DDD-E
E
```

.split()[-1]とすることで、該当の文字で分割したあとに、-1で最後の項目を取得するようだ。

別途、以下の自分の過去記事を見つけた。
関連　[python > string > split(",")の結果の個数を得る > cmds="set,mon,192.168.10.8,6000".split(",") してから count = len(cmds)](http://qiita.com/7of9/items/499832eec82d47514331)
技術英語 > But this doesn't really [tell the whole story]. / Words cannot express all my feelings.

@ Code Complete (No. 17375 / 36077)

> But this doesn't really <font color=red>tell the whole story</font>.

<hr>
関連して思い出したのは

> Words cannot express all my feelings.

つらい時や非常にうれしい時というのは言葉が出ない時がある。

<hr>
ソフトウェアエンジニアとしては、codeが詳細を述べる(tell)ように作り、それでも足りない意図はコメントとして足すのが良い、などCode CompleteやReadable Codeにて薦められている。
ローカルでのeclipse環境の作り方

最近、eclipseを使ったwebアプリケーションをjavaで作ろうとしたときに、制約があったので、備忘録がてらメモします。

元々PHPの勉強のために、XAMPPをWindowds環境に入れていたので、それを応用すれば、
良いと高を括っていたのですが、なんとXAMPPのTOMCATはeclipseでは使えなかったです・・・

そのため別途TOMCATをローカル環境にインストールしました。
※MySQLはXAMPPのを使えますよ！ただし、Java用のJDBCは必要。

皆さんもeclipseで開発するときには気を付けてください！
preg_replace/preg_filterでループ処理を省略する

# プレフィックスを付加

```php
$before = ['a', 'b', 'c'];
$after = preg_replace('/^/', 'Prefix:', $before);
var_dump($after);
/*
array(3) {
  [0]=>
  string(8) "Prefix:a"
  [1]=>
  string(8) "Prefix:b"
  [2]=>
  string(8) "Prefix:c"
}
*/
```

# サフィックスを付加

```php
$before = ['a', 'b', 'c'];
$after = preg_replace('/$/', ':Suffix', $before);
var_dump($after);
/*
array(3) {
  [0]=>
  string(8) "a:Suffix"
  [1]=>
  string(8) "b:Suffix"
  [2]=>
  string(8) "c:Suffix"
}
*/
```

# プレフィックスとサフィックスを付加

```php
$before = ['a', 'b', 'c'];
$after = preg_replace('/^.*$/s', 'Prefix:$0:Suffix', $before);
var_dump($after);
/*
array(3) {
  [0]=>
  string(15) "Prefix:a:Suffix"
  [1]=>
  string(15) "Prefix:b:Suffix"
  [2]=>
  string(15) "Prefix:c:Suffix"
}
*/
```

# 条件を満たすものだけを加工しながら抽出

```php:大文字だけを対象にする
$before = ['a', 'A', 'b', 'B', 'c', 'C'];
$after = preg_filter('/\A[A-Z]++\z/', 'Prefix:$0:Suffix', $before);
var_dump($after);
/*
array(3) {
  [1]=>
  string(15) "Prefix:A:Suffix"
  [3]=>
  string(15) "Prefix:B:Suffix"
  [5]=>
  string(15) "Prefix:C:Suffix"
}
*/
```
Django(PTVS)によるAzureの外部ストレージMySQLの課題

#MySQLで努力したができなかった
まず、結論から話すと外部ストレージにAzureのMySQLを使おうって記事があったのでやってみたができなかったというお話です。[こちら](https://azure.microsoft.com/ja-jp/documentation/articles/web-sites-python-ptvs-django-mysql/)

#Azure側のMySQLの設定
Azureのポータルにて**【新規】**から検索で**MySQL Database**と検索し、一番上の**MySQLデータベース**を選択し、MySQLデータベースを作成する
![1.png](https://qiita-image-store.s3.amazonaws.com/0/130097/29be2c90-16f3-7d65-8cf1-0492aae810d2.png)

作成したデータベースから**【プロパティ】**を選択して**接続文字列**をコピー
![3.png](https://qiita-image-store.s3.amazonaws.com/0/130097/ebbb567a-f1b9-cf3f-a25c-bd9fc11b83ca.png)

散々使いまわしている[アプリ](http://qiita.com/saiyuki1919/items/96bedd0b9d9a0ed9b01b)があるのですが、アプリのsettings.pyを設定通り書き換えてもうまく行きません。

```Python:settings.py
#Database=<NAME>;Data Source=<HOST>;User Id=<USER>;Password=<PASSWORD>
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': '<NAME>',
        'USER': '<USER>',
        'PASSWORD': '<PASSWORD>',
        'HOST': '<HOST>',
        'PORT': '',
    }
}
```

##Errorの内容

ProgrammingErrorとなるので多分、データベースの位置を見つけてくれないのだと。
Migrate,Migrationsしても無駄！

```Python:実行後
ProgrammingError at /
(1146, "Table 'testdatabase1919.app_check_list' doesn't exist")
```


とどうしたものかと考えたが、Djangoのバージョンが良くないからだと思い
**Django1.8▶︎Django1.10**にした

実行すると

```Python:Manage.py
 ImproperlyConfigured:
 execute_from_command_line(sys.argv)
```
とエラーを吐いて、**excute_from＿command_line**の部分のエラーを解決することができずそもそもアプリが実行しなかった。(1.9も同様)

結局色々試した上手くいかなかったので、諦めました！

#終わりに
誰か**MySQL**でのやり方を教えてください！
[SQLite](http://qiita.com/saiyuki1919/items/96bedd0b9d9a0ed9b01b)はできました！

とりあえず、デフォルトのSQLiteを使ってAzure上にデプロイした方が安全で使いやすいことがわかりました！
Monogameの文字描画でSharpFontを使う

Monogame(XNA Game Studioの有志による後継版)でSharpFont（FreeTypeのC#ラッパー）を使う方法についての記事です。SharpFontで生成した画像をMonogame用に変換して使うだけなので、単にC#でFreeTypeが使いたいというときにも参考になるかなと思います。

# 環境
- Visual Studio Community 2015
- Monogame 3.2

# 動機
Monogameでフォントを使って描画するための標準的な方法はスプライトフォントを生成してそれを用いることです。生成するにはスプライトフォント定義ファイル（中身はXML）に必要な文字のUnicode符号位置を並べたものを変換ソフト（私はXNA Formatterを使っています）に噛ませてやれば良いだけなので簡単といえば簡単です。日本語も使うことはできます。

が、漢字を使おうと思うと非常に面倒なことになります。というのもUnicode上に点在する必要な漢字の一覧を選び出すのも大変ですし、UnicodeコンソーシアムのサイトからJIS X 0208に対応する文字の一覧を持ってくるなどの方法でその点をクリアしたとしても、変換には異常な時間がかかります（私の環境では数時間単位でかかります）。もし必要な文字が入っていなかった場合に再度生成することなど考えたくもありません。

Monogameの最近のバージョンではコンテントパイプラインなるものでもう少しやりやすくなっているらしいのですが、Monogame 3.3以降は32bit Windowsの開発環境では動かない(!)という事情のためにそれに移行することができませんでした。そこで外部のフォントライブラリであるところのFreeType（のC#移植であるところのSharpFont）を使ってみたところ意外と簡単だったのでここに書いておきます。

# SharpFontのインストール
[SharpFontはNugetパッケージを提供してくれている](https://www.nuget.org/packages/SharpFont/)のでインストールは簡単です。VisualStudioのNugetパッケージマネージャでインストールします。
ただ、ここでは

- SharpFont 3.1.0
- SharpFont Dependencies 2.6.0

を用います（SharpFont 4.0.1は挙動が良くわかりませんでした）。

普通にインストールしようとすると私の環境ではなぜかSharpFont Dependencies 2.5.5を入れようとしてエラーで落ちていましたが、先にSharpFont Dependencies 2.6.0をインストールすることで問題なくインストールすることができました。

# FreeTypeが返すビットマップについて
Freetypeはフォントを扱うライブラリであり、それ以上の層のことはやってくれません。具体的に言うと、FreeTypeがやってくれるのはフォントを読み込んで、そこの指定されたグリフのビットマップを返すことだけです（もちろん他にも機能はたくさんありますが、文字を単に描画するというだけの用途ならばこれくらいです）。

しかもFreeTypeが返してくれるビットマップはDIBではなく8ビットでモノクロの256階調が記されただけの純粋なビットマップなので、使うためにはこれにヘッダを付けるなどの処理を自分でする必要があります。

……なのですが、ありがたいことにSharpFontはFTBitmap.ToGdipBitmap()という函数を用意してくれていて、System.Drawing.Bitmap（GDI+のビットマップ形式らしい）に変換することができます。

したがって、あとはこれを[Monogameで読む込める形式にすれば](http://xboxforums.create.msdn.com/forums/t/3051.aspx)使えることになります（再変換していて明らかに無駄なのでパフォーマンスを求めるならまともな方法を考えるべきでしょうが、これは「とりあえず描画する」程度のときに便利です）。

なお、System.Drawing以下は標準では使えないようなので参照を追加してやる必要があります。

#組版
あとは組版です。自力で一から実装するのは大変ですが、これもありがたいことに、SharpFontの公式サンプルに[良さそうなクラス](https://github.com/Robmaister/SharpFont/blob/master/Source/Examples/FontService.cs)があるので使わせてもらうことにします。

FontFormatCollection関連でコンパイルエラーがでますが（おそらくv4で追加された機能でしょう）、不要なのでごっそり削除してしまえば使えるようになります。

ただし、このままでは文字の高さによって文字の位置が変わってしまう（上の空白が詰められる）という仕様になっていて使いづらいため一か所、RenderString(Library, Face, string, Color, Color)の中を変更します。

```
if (glyphTop > top)
	top = glyphTop;
```

の部分を

```
top = (float)face.Size.Metrics.Ascender;
```

に書き換えます。

これでいい感じに使えるようになるはずです。

# 結論
以上で技術的なポイントは書いたはずなので、あとはゲームの設計にあわせていい感じのクラスを作ってくださいということになりますが、参考までに私が使っているクラスを置いておきます。

https://gist.github.com/suzusime/b644eedffba87001427291d79f36a955

"Game1"などのGameクラスのなかで最初に
`FontTool.parent = this;`
としておけば、あとは
`FontTool.DrawString("持っている力を使わないのは公平か？", new Vector2(10, 10), "default", spriteBatch);`
とするだけ、と標準のDrawString()と似たような感覚で文字が描画できます。
コマンド二重起動防止の setlock を ruby に移植してみた

crontab 経由でコマンドを実行するときなど、コマンドの二重起動を抑止したいことがしばしばあります。
二重起動を抑止するコマンドとしては、 Linux で util-linux パッケージが使えれば [flock](https://linux.die.net/man/1/flock) コマンド、それ以外 (macOS とか) では自力でスクリプトを組むか、[こちらで紹介されている setlock](http://qiita.com/mogulla3/items/0a955196c524712f48ba) を使うことになると思います。

setlock は美しいツールだなーと思うのですが、[daemontools](https://cr.yp.to/daemontools.html) をソースからビルドする必要があり、一手間かかります。なんというかコンパイルとかせずにどうにかならないものか...。

と思いまして [setlock.c のソース](https://searchcode.com/codesearch/view/35016123/) を見たところ、超短いソースだったので、 Ruby に移植してみました。Amazon AMI には ruby-2.0 が最初から入ってるから、これならパスの通ったところにコピペで置くだけっ...。

```ruby:setlock.rb
#!/usr/bin/env ruby
require 'optparse'

Version = '1.0.0'
flagx = false
flagndelay = false

parser = OptionParser.new
parser.banner = "Usage: setlock.rb [ -nNxX ] file program [ arg ... ]"
parser.on('-n','No delay. If fn is locked by another process, setlock gives up.'){|v|flagndelay=v}
parser.on('-N','(Default.) Delay. If fn is locked by another process, setlock waits until it can obtain a new lock.'){|v|flagndelay=!v}
parser.on('-x','If fn cannot be opened (or created) or locked, setlock exits zero.'){|v|flagx=v}
parser.on('-X','(Default.) If fn cannot be opened (or created) or locked, setlock prints an error message and exits nonzero.'){|v|flagx=!v}
parser.summary_width=3

begin
	parser.parse!(ARGV)
rescue => e
	abort "#{e.message}"
end

lockfile = ARGV.shift

abort "missing argument.\n#{parser.help}" if ARGV.size == 0
	
f = nil
begin
  f = File.open(lockfile, 'w')
rescue => e
  exit 0 if flagx
  abort "unable to open #{lockfile}"
end

if not f.flock(flagndelay ? (File::LOCK_EX|File::LOCK_NB) : File::LOCK_EX)
  exit 0 if flagx
  abort "unable to lock #{lockfile}"
end

system ARGV[0], *ARGV[1..-1]
exit $?.exitstatus
```

とはいえ、システム系プログラムはそんなに得意でないのと、Ruby あまり詳しくないので、変だったらぜひコメントで教えて下さい。それ以前に実は このパッケージ入れたら setlock 含まれてるよとか、あったらショックですが...。
(swift) firebaseでobserverをremoveするのにハマった

swiftで以下のようにobserveEventを設定した時になんらかのタイミングでobserverをremoveすることがあるのだが、、、

```
.observeEventType(
    .Value,
    withBlock: {
        (snapShots) in
    }
)
```

この時にとりあえず

```
var ref = FIRDatabase.database().reference
ref().removeAllObservers()
```

とやっていればいいと思ったら違ったのでメモ



例えば以下のようにobserveEventを設定した時

```
ref().child("rooms").child("room_id").child(roomId!).child("users").observeEventType(.Value, withBlock: {(snapShots) in
})
```

こういう時は丁寧に

```
ref().child("rooms").child("room_id").child(roomId!).child("users").removeAllObservers()
```
としなければならない



ちなみにreferenceにはこう書いている

> Removes all observers at the current reference, but does not remove any observers at child references. removeAllObservers must be called again for each child reference where a listener was established to remove the observers.
Go のバイナリには -ldflags '-w -s' でコンパイルしてもたくさんパスが埋め込まれていた

Go 使いの人たちには「なにをいまさら」という内容かもしれない。

Go のバイナリをビルドする際に

```console
$ go build -ldflags '-w -s'
```

とコンパイルすることで、 DWARF とシンボルテーブルの情報をバイナリに残さずコンパイルできる。

しかし、自分は気になったので `strings` コマンドを生成後のバイナリにかけてみた。
するとバイナリには

```console
_/Users/kitsuyui/.go/*****/*****.go
_/Users/kitsuyui/develop/*****/*****.go
```

というような行が、まだたくさん残っていた。

どうやら DWARF やシンボルテーブルの情報を削除しても、コンパイルの際のパスなどの情報は残ってしまうようだ。

### 消してみると 10% くらい節約できた

そこで、全て浅いディレクトリでコンパイルしなおしたところ、約 5MB のバイナリが約 4.5MB ほどまで節約できた。
ソースコードを細分化していればしているほど、モジュールを使っていれば使っているほど、含むパスは多くなるので、これらにより節約できるサイズは大きくなる。
Go の単一バイナリを Docker コンテナにするような状況では、 10% の節約は心理的に大きい。 (嬉しい)


## 使い所

- 早すぎる最適化ゲームをしたいとき (ただし `-ldflags '-w -s'` ほどではない)
- 自分の開発環境のパスが配布用のバイナリに含まれるのは生理的に嫌だ、というとき

## でも毎回ディレクトリを配置しなおすの面倒だよね

Docker を使おう。

[tcnksm/gox](https://hub.docker.com/r/tcnksm/gox/) という便利な Docker イメージがあるので、これを自分は使っている。

```console
$ docker run --rm -v "$(pwd)":/foobar -w /foobar tcnksm/gox:latest \
     sh -c "go get -d ./... && gox -ldflags '-w -s'"
```

こんな風にすれば簡単に複数の環境をターゲットに、浅いパスでコンパイルできる。
`go get` は場合によってネットワーク負荷が大きい、時間がかかる処理になりがちなので、ここだけ `Dockerfile` を書いておいたほうがよいかもしれない。


## 補足

この記事を書くにあたって使用した Go のバージョンは `1.7.3` 。
Windowsでの簡易プログラム開発ウインドウ表示用のバッチファイル紹介

小技ですが、JavaやRubyの編集・実行用に便利なバッチファイルを紹介します。
例えば、DドライブのRuby_studyフォルダで開発するとしたら、このフォルダに
移動し、このフォルダでのエクスプローラを開き、コマンドプロンプトを開き
ます。
バッチファイル名 Develop1.bat

~~~
D:
cd \Ruby_study
explorer .
cmd /p
~~~

　このバッチファイルを保存後、ショートカットを作成し、そのショートカットの
表示設定を使って、文字色・背景色・フォント指定・ウイドウズサイズ位置指定
をすると快適さがアップします。
　補足として、start notepad [ファイル名] とか別アプリを起動するのも便利です。
　call notepad では、このメモ帳を閉じるまで次のコマンドが実行されません。
　また、エクスプローラでマウスで指定したフォルダ上でShiftを押しながら
右クリックすると、そのフォルダを選んだコマンドプロンプトを選べる裏ポップアップメニューが出ます。

　統合開発環境に違和感を感じる世代は、これも有用ではないかと思います。
MacでVPNの「接続解除中」が終わらない時の対処法

# 現象
MacでVPNの接続を切る際に「接続解除中」という表示が出続け、いつまで経っても接続解除が終わらなかったのでコマンドでkillすることにした。
# 対処法
以下コマンドを叩く。

`sudo killall -9 pppd`

以上。
これでVPN接続が切れる。

# 参考
[VPNの&#8221;切断中&#8221;が終わらない | めがねをかけるんだ](https://blog.keiji.io/2013/02/forever-vpn-disconnecting.html)
fedoraでGoogleDriveクライアントを使う

fedora24でGoogleDriveクライアントを使えるようにしたのでメモ。

```
sudo dnf copr enable sergiomb/google-drive-ocamlfuse
sudo dnf install google-drive-ocamlfuse
mkdir ~/GoogleDrive
google-drive-ocamlfuse ~/GoogleDrive
```

~/.bash_profileに
google-drive-ocamlfuse ~/GoogleDrive
を追加。
同期はファイルの変更があった時に自動でされるそうです。
fish で bck-i-search

## bck-i-search

bash とか zsh とかで Ctrl-R で発動するアレ。Ctrl-R に続いて過去に実行したコマンドのどこか一部を適当にタイプすると一致するものを探してきてくれる。便利。

ポイントは部分一致なところ。よくあるのは「コマンドじゃなくて、それに続くパラメータの方がユニークなので、そちらで探す方が効率が良い」みたいなパターン。たとえば、こんな感じの履歴があるとしよう。

```bash
$ curl 'http://api.example.com/users?q=foobar' -X GET -H 'Accept: application/json' | jq ".users[] | .name"
```

ここで困ったことに `curl` で始まる履歴はこれ以外にも山ほどある。`^Rcurl` とタイプしても似たようなものがいろいろ出てきて絞りきれない。探したいのは `curl` に渡したパラメーターに `foobar` というキーワードが入っていものである、という場合。慌てず騒がず `^Rfoobar` とタイプすればだいたい見つかる。Ctrl-R は部分一致。

## fish で Ctrl-R

fish だと Ctrl-R しても反応しない。少なくとも、デフォルトの設定では動いてくれない。ヒストリー検索的なものがないのかと言うと、そうではない。むしろ Ctrl-R は要らない。コマンドをタイプし始めると、勝手にヒストリーを検索してきて、まだタイプしていない続きの部分を「これでしょ？」とサジェストしてくれる。

便利なのだけど、一つ問題があって、自動的にサジェストまで出してくれるのは前方一致で履歴が見つかった場合に限るということ。たとえば↑と同様に

```bash
$ curl 'http://api.example.com/users?q=foobar' -X GET -H 'Accept: application/json' | jq ".users[] | .name"
```

という履歴があった場合に `curl` とタイプするとその横から続きの `'http://api.. (以下略)` をサジェストしてくれるのだが、タイプするのが `foobar` だと一見して何も反応がない。ので、fish のヒストリー検索は前方一致しかサポートしてないみたいに見えてしまう。が、実はそうではなかった。

## fish で部分一致な bck-i-search

正解は、

* 履歴のどこか一部をタイプした後、
* Ctrl-P

で部分一致なヒストリー検索が発動する。
↑の例だと `foobar^P` とタイプすれば ok.

キーワードに続いて Ctrl-P を叩くのがポイント。
REST APIからクラウドへGitレポジトリ作成を行う

GithubなどのクラウドサービスへGitレポジトリを利用する時、ついつい画面を利用していました。最近ふと思いました、**クラウド側のGitレポジトリもコマンドベースで作成できないかと**。開発者向けのWEBサービスでは大概REST APIを提供しているので、今回そちらを利用してみました。手っ取り早いBasic認証を扱っています。詳細なAPI仕様については参考をご覧ください。

# Github

どのAPIも`Enter host password for user '%username':`と聞かれるのでパスワードを入力すること。

レポジトリ登録は以下の通り。

	curl -u "%username" -X POST -H "Content-type: application/json" -d '{"name":"%sample_repo", "private":true}' https://api.github.com/user/repos

登録後手持ちのレポジトリにプッシュ先として登録しておく。

	git remote add origin git@github.com:%username/%sample_repo.git

レポジトリ情報参照は以下の通り。

	curl -u "%username" https://api.github.com/repos/%username/%sample_repo

レポジトリ削除は以下の通り。

	curl -u "%username" -X DELETE https://api.github.com/repos/%username/%sample_repo


# Bitbucket Cloud

レポジトリ登録は以下の通り。`%repo_flag`は**小文字の英数字のみ**なので要注意。レポジトリ名は`%name`へ入力しよう。

	curl -u %username:%password -X POST -H "Content-type: application/json" -d '{"scm":"git", "name":"%name", "is_private":true, "fork_policy":"no_forks"}' https://api.bitbucket.org/2.0/repositories/%username/%repo_flag

登録後手持ちのレポジトリにプッシュ先として登録しておく。

	git remote add origin git@bitbucket.org:%username/%sample_repo.git

レポジトリ情報参照は以下の通り。

	curl -u %username:%password https://api.bitbucket.org/2.0/repositories/%username/%sample_repo

レポジトリ削除は以下の通り。

	curl -u %username:%password -X DELETE https://api.bitbucket.org/2.0/repositories/%username/%sample_repo


# 参考

- [GitHub API v3 | GitHub Developer Guide](https://developer.github.com/v3/)
- [Bitbucket API](https://developer.atlassian.com/bitbucket/api/2/reference/)
- [Bitbucket REST APIでターミナルから新規リポジトリ作成 - Qiita](http://qiita.com/zaki-yama/items/4f8eb0db6fc0fa18cdce)
GAEの東京リージョンのレイテンシは？

5年前にGoogleAppEngineを使っていた時には随分悩まされた低レイテンシ問題。
先日東京リージョンが来たことでこの問題の解決を期待していましたが、期待通りでした。

Jmeterでの簡単な結果がこちら。

![jmeter_01.PNG](https://qiita-image-store.s3.amazonaws.com/0/144652/ddfa18ff-7b56-5f8c-90ec-c7ec87687672.png)

ちょっとqps高め（約30qps）にしすぎてスケールアウトでのSpinUpが発生してますが、SpinUpの回を除くと大体10～13msecで返ってきています。

![gae_02.PNG](https://qiita-image-store.s3.amazonaws.com/0/144652/402eee18-cc56-1802-3fa9-fd58c2245ee9.png)

GAE上でサンプリングされている情報を見ると、サーバー側の処理は3msec程度で終わっていそうですので、通信におけるオーバーヘッドは約7～10msecの模様。

十分なパフォーマンスですね！
目指せLinuxマスター(弐) ~suコマンドの権限~

　ここでは，suコマンドの権限を限定する方法を記します．suコマンドはroot権限に昇格したり，他のユーザーとしてログインできる強力なコマンドです．一般ユーザーが簡単に使用できないように設定する必要があります．

※【2016.11.4 追記】　PAMの設定を変更しました．→[追記](#2016114-追記)

# 環境

 * Cent OS 6.8
 * GNOME 2.28.2
 * PAM(/libpam.so) 0.82.2

　より細かい環境については，[ブログ][blogtop]を参考にしてください．
 
　また，今回の内容はブログの第9,12回により詳しく掲載しておりますので参考にしてください．
 
#### [【第9回】目指せLinuxマスター(1) ~sudoersの管理~][a009]
#### [【第12回】目指せLinuxマスター(4) ~suの権限~][a00c]
 
# 管理者ユーザーをwheelグループに入れる
　今回suコマンドを使えるようにするのは**wheel**というグループのメンバーです．それ以外はsuできないようにします．ですから，管理者権限を与えてもよいユーザーをあらかじめwheelグループに入れておく必要があります．
 
　なお，wheelというのはRedHat, CentOS, Fedoraなどで用いられる管理者グループの名前で，UbuntuなどのDebian系ではそのかわりにsudoグループを用います．認証の際にこれらの管理者グループに属しているかを判別するライブラリが用意されているので，慣例に倣ってこちらを利用するのが簡単でしょう．もちろん，管理者グループが容易に特定できるのは嫌だという場合は，独自のグループを作ってもいいかもしれません．その場合は設定方法がより複雑になるかと思います．
 
　ここでは，enryuというユーザーをwheelメンバーにします．

```shell-session
$ su -
# gpasswd -a enryu wheel
```

# ~~ログイン処理の設定~~
※最近のCentOSではlogin.defsにSU_WHEEL_ONLYを設定する必要はなくなったそうです(CentOS6.8にて確認)
　~~今度はlogin.defsをいじっていきます．root権限で開きましょう．~~
 
```shell-session
# vi /etc/login.defs
```

![login_defs_1.PNG](https://qiita-image-store.s3.amazonaws.com/0/144209/f1deb706-fe94-6cf4-b8fe-f52008f31f15.png)

　~~この一番末尾に次の行を追加します．~~
 
```vim:/etc/login.defs
# Only wheel group can su root
SU_WHEEL_ONLY        yes
```
 
 # PAMの設定
 　最後にPAMの設定を行います．今回は`/etc/pam.d/su`を開きます．

![pam_su_1.PNG](https://qiita-image-store.s3.amazonaws.com/0/144209/58a239a7-2ec5-2885-097e-fac096e4c9be.png)

　2つコメントアウトされている行の下側のコメントを外します．
 
```vim:/etc/pam.d/su
# Uncomment the following line to require a user to be in the "wheel" group.
# auth        required        pam_wheel.so use_uid
↑
ここのコメントを外す．dwで1単語削除．
```

　これで，suコマンドでrootに昇格できるのはwheelメンバーに限定されました．もちろん他のユーザーに切り替えることもできません．
 
###### ※[2016.11.4 追記]
　次に，**root_only**オプションをつけます．
 
```vim:/etc/pam.d/su
# root_onlyオプションをつけることで，rootへの昇格のみを制限します
auth        required        pam_wheel.so use_uid root_only
```

　あとは再起動すれば設定がすべて反映されます．
 
```shell-session
# exit
$ sudo shutdown -r now
```

　他のユーザーでsuしようとしても，パスワード入力の前にauth認証で弾かれていますから，何を入力しても「パスワードが違います」と表示されます．
 
# おまけ：wheelグループにsudoを許可
　今回はwheelグループだけがsuコマンドでroot権限に昇格できるようにしましたが，そもそもsuでrootになるのはrootパスワードを入力する必要があるため，**パスワードを盗聴される可能性**が出てきますし，すべての操作をroot権限で行ってしまうので**操作を誤ってしまったときに大惨事になる危険性**があります．そこで，root権限での実行を必要な時だけ許可する**sudo**コマンドの使用が推奨されています．
 
　wheelの設定ついでに，sudoをwheelメンバーに許可しましょう．
 
## wheelをsudoersに追加
　sudoの設定はsudoersファイルに記述していきます．**visudo**コマンドで設定を開きます．
 
```shell-session
$ su -
# visudo
```
 
　操作はviと同じです．編集するポイントまで移動しましょう．コマンドモードで`/wheel`とタイプすると編集ポイントを検索できます．

![visudo_3.PNG](https://qiita-image-store.s3.amazonaws.com/0/144209/adafc36d-a258-5b16-74ab-44bbe15e60a2.png)
 
　コマンドモードでEnterキーを押すと下の行の先頭に移動します．そこで`dw`とし，コメントアウトを外しましょう．
 
　これで，wheelグループに所属するユーザがsudoを行えるようになりました．
 

---- 以上

# 参考資料

##### [suコマンドを実行可能なユーザーを限定するには - IT][1]

# こちらもよろしくお願いいたします．
### [エンリュの迷い森｜トップページ][blogtop]

[blogtop]: http://lost-in-forest.hatenablog.com/entry/toppage
[a009]: http://lost-in-forest.hatenablog.com/entry/a009
[a00c]: http://lost-in-forest.hatenablog.com/entry/a00c

[1]: http://www.atmarkit.co.jp/flinux/rensai/linuxtips/086suwheel.html
swiftで自前デリゲート


swiftで自前のデリゲートを作る方法はObjective-Cのそれとほとんど変わらないという印象です

- - -

```swift:デリゲートを利用する側（デリゲートで通知する側）

// ①プロトコルの定義（classを継承すること！）
protocol JimaeDelegate:class {

    // ②デリゲートメソッドの宣言
    func JimaeDelegateFunc(hikisuu:String)    
}

class HogemogeView:UIView{

    // ③デリゲートオブジェクト（weakである事！）
    weak var  delegate:ButtonUIViewDelegate? = nil
    
    func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
        
        // ④デリゲート先のメソッドが呼ばれる
        self.delegate?.JimaeDelegateFunc(hikisuu:"タッチされたよ")
    }
}

```

- - -

```swift:デリゲートの処理を実装するクラス（デリゲートで通知される側）

// ①デリゲートのプロトコルを実装
class mainViewController: JimaeDelegate {

    // ②デリゲートメソッドを利用する側のクラスのインスタンスを作成
    //（ここではStoryBoardでインスタンスを作成し、IBOutletで変数に紐づけている）
    @IBOutlet weak var haritukeView: HogemogeView!

    override func viewDidLoad() {
        
        super.viewDidLoad()
        
        // ③デリゲートの通知先をこのクラスに設定
        self.haritukeView.delegate = self
    }
    
    // ④デリゲートメソッドの実装
    func JimaeDelegateFunc(hikisuu: String) {
    
        print(hikisuu)
    }

}

```






◼︎参考にさせていただきました
[Swift - delegateを実装する、通知する、通知される](http://blog.euphonictech.com/entry/2014/10/25/190321)
[Swift でデリゲートを実装する方法](https://ez-net.jp/article/BE/OeNCbTlM/NpjEbGA6K2cA/)
GLBoostの設計方針


この記事は[GLBoost Advent Calender 2016](http://qiita.com/advent-calendar/2016/glboost)の２日目の記事です。

# はじめに

今日の記事では、GLBoostの現状と今後の設計について書いていきます。

# GLBoostの目指すところ

GLBoostは、GithubのREADMEにもある通り、一応「CG技術者やゲームプログラマなどのギーク向け」のライブラリを目指してます。（そう宣うお前は果たしてギークなのか、というツッコミは置いといて…）

なぜそうしたかというと、既存のライブラリは便利で簡単に扱える機能は搭載していても、その反面、柔軟性というかなんというか、利用ユーザーが好き放題やれる感じではなかったからです。
例えば、

* レンダリング方式・パイプラインが固定されており、利用者が介入できない。
* 様々なCG技法がすでに完成された形で実装されており、利用者がライブラリのローレベル機能を使って各種CG技法を独自に実装したり実験できない。
* WebGLのリソースにアクセスできず、隠蔽されている（これについてはライブラリによってはできるものありますが）

GLBoostでは、上記の既存のライブラリが「できない」点をできるようにすることを目的としています。

すなわち、

* レンダリングパイプラインを、ユーザー側がカスタマイズできる
* ユーザー側がライブラリが提供するローレベル機能を使って、様々CG技法を実験・実装できる。
* WebGLのリソースにアクセスできる。

ということです。

とはいえ、こうしたことを実現しようとすると、全体的なAPI設計がローレベルになって、扱いにくいライブラリになるのではないか、という懸念される方もいらっしゃると思います。

そこで、GLBoostではライブラリを３層のレイヤーに分けています。すなわち、最下層のレイヤーでライブラリとして最もローレベルの機能を提供し、中位層でシーングラフ等のミドルレイヤー的な機能を、最上位層でより複雑な応用的CG技法をユーザーがワンタッチで使える高レベルAPIを提供する、というものです。

# GLBoostは３つのレイヤーからなる

| Layer | Description | Target Users |
| --- | --- | --- |
| Low | Geometryクラスや数学クラスなど、<br>3Dプログラミングをする上で車輪の再開発を行いたくない<br>ルーチン処理を代行してくれるクラス群。<br>これらを使い、ユーザーはレンダリング機構を<br>独自に作る必要があります。 | 3Dギーク |
| Middle | 中レイヤーでは、シーングラフ機構が提供され、<br>さらにそれらがレンダラーと協調動作します。<br>このことにより、シーングラフにMeshやカメラ、<br>ライトなどを追加するだけで、ほぼ自動的に<br>レンダリング処理が行われます。<br>RenderPassクラスを使うことで、複雑な<br>マルチパスレンダリングも可能です。 | 3Dギーク/中級者 |
| High (Coming Soon) | 初心者向け。マルチパス技法を使った高度なCG技法を<br>ワンタッチで有効にできます。その詳細について、<br>ユーザーは何も知る必要はありません。<br>Unreal EngineやUnity、Three.jsを<br>使っているのと同じ感覚で使えます。 | 3D初心者

ソースディレクトリを見てみると、実際にそれぞれのレベルごとにディレクトリが分かれていたりします。
[https://github.com/emadurandal/GLBoost/tree/master/src/js](https://github.com/emadurandal/GLBoost/tree/master/src/js)

GLBoostの配布形態も、ローレイヤーのみの機能を提供するglboost_low.jsとミドルレイヤーまでの機能を含むglboost_middle.js、ハイレイヤーまで全ての機能を含むglboost.jsの３バージョンを提供しようと思っています（まぁ、ここまでする必要性はあまりないかもしれせんが）

例えば、ユーザーはローレイヤーやミドルレイヤーのAPIを使って、自分独自のミドルレイヤーやハイレイヤーを作ることが可能です。

実際、そこまでカスタマイズしてくれるユーザーが出てくるほどGLBoostが広まって、信頼されるのか、というとまぁ今のところまだわかりませんけど、方向性としてはそういうところを目指しています。

# この３レイヤー階層設計の懸念点

　懸念点としては、やはりここまでレイヤーをはっきり分けると、パフォーマンス低下が気になります。他の一般のライブラリでは、こういう考え方は取らずにいることで、より高密度に最適化ができているはずですので、パフォーマンス面は気をつけて実装しないと、他ライブラリに比べて引けをとる恐れがあります。

# 今後はTypeScriptへの移行を予定

　現在は、BabelとRollup.jsを使って、ECMAScript 2015（ES6）でGLBoostのコードを書いています。
　しかし、そろそろ型がないと辛くなってきました（笑）
　TypeScript2.xで、さらに`--strictNullChecks`付きでセキュアにコーディングしていきたいですね（TypeScriptでのNull安全なコードを書くのがどれくらいの面倒くささで済むのかはちょっと気になりますが）。
Rails5のgem installでnio4rのインストールに失敗する

- macOS Sierra
- Ruby 2.3

`gem install rails --no-ri --no-rdoc` したところ以下のエラーで詰まる

```
Building native extensions.  This could take a while...
ERROR:  Error installing rails:
  ERROR: Failed to build gem native extension.

    current directory: /Users/{username}/.rbenv/versions/2.3.1/lib/ruby/gems/2.3.0/gems/nio4r-1.2.1/ext/nio4r
/Users/{username}/.rbenv/versions/2.3.1/bin/ruby -r ./siteconf20161031-36453-o4rcff.rb extconf.rb
checking for unistd.h... *** extconf.rb failed ***
Could not create Makefile due to some reason, probably lack of necessary
libraries and/or headers.  Check the mkmf.log file for more details.  You may
need configuration options.

Provided configuration options:
  --with-opt-dir
  --without-opt-dir
  --with-opt-include
  --without-opt-include=${opt-dir}/include
  --with-opt-lib
  --without-opt-lib=${opt-dir}/lib
  --with-make-prog
  --without-make-prog
  --srcdir=.
  --curdir
  --ruby=/Users/{username}/.rbenv/versions/2.3.1/bin/$(RUBY_BASE_NAME)
/Users/{username}/.rbenv/versions/2.3.1/lib/ruby/2.3.0/mkmf.rb:456:in `try_do': The compiler failed to generate an executable file. (RuntimeError)
You have to install development tools first.
  from /Users/{username}/.rbenv/versions/2.3.1/lib/ruby/2.3.0/mkmf.rb:587:in `try_cpp'
  from /Users/{username}/.rbenv/versions/2.3.1/lib/ruby/2.3.0/mkmf.rb:1091:in `block in have_header'
  from /Users/{username}/.rbenv/versions/2.3.1/lib/ruby/2.3.0/mkmf.rb:942:in `block in checking_for'
  from /Users/{username}/.rbenv/versions/2.3.1/lib/ruby/2.3.0/mkmf.rb:350:in `block (2 levels) in postpone'
  from /Users/{username}/.rbenv/versions/2.3.1/lib/ruby/2.3.0/mkmf.rb:320:in `open'
  from /Users/{username}/.rbenv/versions/2.3.1/lib/ruby/2.3.0/mkmf.rb:350:in `block in postpone'
  from /Users/{username}/.rbenv/versions/2.3.1/lib/ruby/2.3.0/mkmf.rb:320:in `open'
  from /Users/{username}/.rbenv/versions/2.3.1/lib/ruby/2.3.0/mkmf.rb:346:in `postpone'
  from /Users/{username}/.rbenv/versions/2.3.1/lib/ruby/2.3.0/mkmf.rb:941:in `checking_for'
  from /Users/{username}/.rbenv/versions/2.3.1/lib/ruby/2.3.0/mkmf.rb:1090:in `have_header'
  from extconf.rb:3:in `<main>'

To see why this extension failed to compile, please check the mkmf.log which can be found here:

  /Users/{username}/.rbenv/versions/2.3.1/lib/ruby/gems/2.3.0/extensions/x86_64-darwin-15/2.3.0-static/nio4r-1.2.1/mkmf.log

extconf failed, exit code 1

Gem files will remain installed in /Users/{username}/.rbenv/versions/2.3.1/lib/ruby/gems/2.3.0/gems/nio4r-1.2.1 for inspection.
Results logged to /Users/{username}/.rbenv/versions/2.3.1/lib/ruby/gems/2.3.0/extensions/x86_64-darwin-15/2.3.0-static/nio4r-1.2.1/gem_make.out
```

やったこと
-------
### xcodeコマンドラインツールのインストール
```
xcode-select --install 
```
### gccのライセンスに同意
```
sudo gcc --version
↓
qで最下行表示後、"agree"を入力しEnter
```

### 再度実行

```
gem install rails --no-ri --no-rdoc
```

→無事インストールできた


----

参考: http://easyramble.com/failed-to-build-gem-native-extension.html
[PHP] if文を短くする初歩的なやつ

if文の条件式を短くしたくて、いろいろ探していたらこんなことに今更気づいてしまいました。
PHPマニュアル：[isset](http://php.net/manual/ja/function.isset.php)のところ
>複数のパラメータを渡した場合は、isset() はそれらすべてがセットされている場合にのみ TRUE を返します。 左から順に評価を行い、セットされていない変数があった時点で処理を終了します。

なんと.....知らなかったです。。。。:sweat_smile:

ということは下の条件式長いやつが、

```php:条件式長いやつ
if (isset($hoge1) && isset($hoge2) && isset(hoge3)) {
    //なんらか処理
}
```

こんな感じにっ！！

```php:条件式短いやつ
if (isset($hoge1, $hoge2, $hoge3)) {
    //なんらか処理
}
```

短くなって嬉しかったです:blush:
orgtblを保存時にGitHub Flavored Markdown形式に置き換え

Emacsにはorgtblという素晴らしいマイナーモードがあって
非常に簡単に表を書けるのですが、GitHub Flavored Markdownとは
微妙に書式が異なるので、Markdownで表を書くときに不便です。

## orgtblの場合

```
| aaa | bbb |
|-----+-----|
| 100 | 200 |
| 300 | 400 |
```

この`+`を`|`に置き換える必要があります。

## GFMの場合

```
| aaa | bbb |
|-----|-----|
| 100 | 200 |
| 300 | 400 |
```

# どうするか？

メジャーモードが`markdown-mode`のときだけ、
ファイル保存時にorgtblの書式をGFMに変換します。

init.el等に以下のように記載します。 [^1]


```lisp
(defun convert-orgtbl-to-gfm ()
  "バッファ内のorgtblをGFMのテーブルに変換します。"
  (interactive)
  (save-excursion
    (goto-char (point-min))
    ;; |----+-----+----|の行を見つけたら|----|-----|----|に置き換える
    (while (re-search-forward
            (rx bol (* (syntax whitespace)) "|" ;; 行頭 "|"
                (+ (+ "-") (group "+"))         ;; "---+ の連続 ("+" だけキャプチャ)
                (+ "-") "|"                     ;; 最後の列 "|"
                (* "\s") eol)                   ;; 行末
            nil t)
      (replace-match (replace-regexp-in-string (rx "+") "|" (match-string-no-properties 0))))))

(defun my-markdown-hook ()
  (orgtbl-mode t)
  (add-hook 'before-save-hook
            'convert-orgtbl-to-gfm
            nil
            t    ;; buffer-local
            ))

(add-hook 'markdown-mode-hook 'my-markdown-hook)
```


これで、markdown-modeでファイル保存時に、orgtblがGFMのテーブルに置き換わります。
このテーブルを再びEmacs上で編集し始めると、元のorgtbl形式に勝手に戻るのですが、
また保存時にはGFM形式に変換されるので問題ありません。

## わからなかったこと

正規表現のカッコが２重になっていまして（`\\(-+\\(\\+\\)\\)+-+`）
この真ん中のカッコ内の`+`を`|`に置き換えたいのですが、
`replace-match`などでどうやって真ん中のカッコを指定したらいいか
わかりませんでした。

結局今のところ、該当行を見つけて、その範囲内で`replace-string`する
という微妙な感じの処理をしています。[^1]

ご指導ご鞭撻のほどお願いします！

↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓


[^1]: ※コメント頂いた内容を反映しました。
Python3.5のcgiモジュールを使ってページ間で値を受け渡す

#cgiモジュールを使ってwebアプリを理解する




ページ間で値を渡す処理をpython上でどう書けばいいか不明だったため、cgiモジュールのpythonリファレンスを見ていたら、下記の記述があった。
> 入力されたフォームデータを取得するには、 FieldStorage クラスを使います。
http://docs.python.jp/3.5/library/cgi.html

上記のＵＲＬのサンプルコードも使おうとしたのですが、使い方がわからない。
リファレンスは初心者にはわかりづらいと思う。

というわけで、値の受け渡し方法を調べていたら、pythonのコードとhtmlを組み合わせて書いていた人が多かった。考えてみればわかることでしたね笑

##フォルダ構成
├── cgi-bin
│ └── cgiValueTest.py
└── cgiserver.py
└── index.html

```index.html
<!DOCTYPE html>
<html>
<head>
<title>cgiValueTest.py</title>
</head>
<body>
<form action="/cgi-bin/cgiValueTest.py" method="POST">
  <input type="text" name="text" value="diag" />  
  <input type="submit" name="submit" />
</form>
</body>
</html>
```

```cgiValueTest.py
#!/usr/bin/python3
# -*- coding: utf-8 -*-

import cgi

html_body = """
<!DOCTYPE html>
<html>
<head>
<title>受信したデータを表示</title>
<style>
h1 {
font-size: 3em;
}
</style>
</head>
<body>
<h1>%s</h1>
</body>
</html>
"""

form = cgi.FieldStorage()
text = form.getvalue('text','')

print(html_body % (text))
```
cgiサーバーの動かし方とcgiserver.pyに関しては下記の記事をご覧ください。
>Python3上でcgiを動かしてみる
http://qiita.com/shuichi0712/items/5ddc5b4e30c2373b17fb

実行してみると
![cgiValueTest01.png](https://qiita-image-store.s3.amazonaws.com/0/127391/58daf1f4-6637-36b2-4f18-361470e943aa.png)

![cgiValueTestresult.png](https://qiita-image-store.s3.amazonaws.com/0/127391/fc98566e-2090-fec2-d6d6-ca254ae0653d.png)

という感じになりました。
ローカルプロキシでどんな通信結果になっているかというと・・・
リクエスト
![localpost.png](https://qiita-image-store.s3.amazonaws.com/0/127391/440b39d0-dfb9-f04f-423e-776e1b5cdb90.png)

レスポンス
![res01.png](https://qiita-image-store.s3.amazonaws.com/0/127391/0e225794-3992-367a-4afd-6ff35d6b68be.png)

つまり、cgi.FieldStorage()は値の受け取り側で書く。
ちなみに、FieldStorage()関数はリクエストの内容（ここでいうtext=diagやsubmit=%91%97OM）をPythonの文字列などに変換します。変換されたデータを使って、処理を行います。その結果としてレスポンスでdiagが表示されるんですね。

##まとめ
頭だけで考えるより、実際に動かして見たほうが理解が速い。特に初心者はまずはやってみて、あとからどういうことかを理解していくのが王道ではないかと。

####参考サイト
https://yxshipg.appspot.com/python/python3_cgi/
ハッシュの新記法のキーの仕様が2.2から大分変わっている

Rubyの2から可能になった、ハッシュの新記法。社内では好評です。ですが、
私ははまりました。新記法ってのは

```rb
{:a => 1}
```

を

```rb
{a: 1}
```

と書けます。
しかし、Rubyの2.1までは

```rb
{'a': 1}
```
これができません。えええ！って思ってしまいましたが、できませんでした。
2.2以降はできます。シンボルってのは使える文字列に制約があります。
例えばドットなどは使えません。しかし、コーテーションで括ると使えます。
ただ、2.1以前は新記法のキーはコーテーションで括るのを許してくれません。

今でも2.0とか2.1とか使う機会があるのですが、キーがある程度自由なのは2.2以降なので、
ハマります。できるかぎりハッシュの新記法で書きたい場合は2.2以降を使いましょう。
そうしないと、

```rb
{'a.b': 1, c: 2}
```
を表現できずに

```rb
{:'a.b'=>1, c: 2}
```
みたいな羽目になります。

ちょっと戻って2.1とか2.0とか使ったときにハマらないようにしましょう
というか、進んでバージョンアップしましょう。
Tips: Quickly HTML load

ページが完全に読み込み終わったことを検知するためには load イベントは適切

### load
https://developer.mozilla.org/en-US/docs/Web/Events/load

リンク先のような書き方ではなく、古いプログラムでは下記のような記述が散見される。

```html:onload.html
<body onLoad="alert('hello');">
```

解析が完了したら十分な時には DOMContentLoaded を使い、より速く処理を行うことができる。

### DOMContentLoaded
https://developer.mozilla.org/ja/docs/Web/Reference/Events/DOMContentLoaded

> 最初のHTMLドキュメントの読み込みと解析が完了した時に発火し、 スタイルシートや画像、サブフレームの読み込みが終わるのを待ちません
Firefox開発者ツール 要素に仕込まれたイベントを調べる

##はじめに
今までFirefoxの開発者ツールを使った事がなく、chromeの開発者ツールで調べていましたがFirefoxだとえらく簡単に調べられたのでメモとして残します。

##手順
①開発者(command+option+i)を開く。windowsはF12
画像１
<img width="844" alt="スクリーンショット 2016-10-31 22.46.59.png" src="https://qiita-image-store.s3.amazonaws.com/0/114638/3e8884c4-2872-8882-ef18-fcf38a2ac747.png">
②インスペクタタブを選択（画像１の-①）
③イベントが仕込まれている要素には要素の横にevのマーキングがあるため、そのマーキングをクリック（画像1-②）
画像２
<img width="959" alt="スクリーンショット 2016-10-31 22.53.29.png" src="https://qiita-image-store.s3.amazonaws.com/0/114638/14ff2cc2-284a-1d96-78a6-b89a4501b6de.png">
画像３
<img width="866" alt="スクリーンショット 2016-10-31 23.09.51.png" src="https://qiita-image-store.s3.amazonaws.com/0/114638/4ec8ce79-9f7e-f555-4b08-f6a8277c7459.png">
④evをクリックする事で現在要素に仕込まれているイベントの一覧が表示されます。
　　　また画像２-①のエリアをクリックする事で記載されているjsの内容が表示されます。
⑤デバッグを貼りたい時は、画像３-①がjsファイルへのリンクにもなっているためそこから貼れます。
プロジェクト内にある全角文字の検出

大体これでいいはず

自作アプリの国際化（というか文言管理）で、対象ディレクトリの日本語を含むファイルを洗い出した時に使用。

```bash
ag '[ぁ-ん|ァ-ヴ|一-龠|ー・、。]' /path/to/app/ | less
```

agで特殊文字を制御できなかったので、lessをかませた。
Tips: IE run Edge mode

IE には互換表示モードというのがある。
これは古いプログラムで作られたアプリケーションを古いブラウザの実装で動かすことで古いプログラムを変更せずに動作保証するための機能である。

例えば、 IE に対して下記のような古い HTML 宣言を行うと互換表示モードが作動して古いブラウザの実装で動作する。

```html:legacy.html
<!DOCTYPE html public "-//W3C//DTD HTML 4.01 Transitional//EN">
```

この古いプログラムに変更が入り、互換表示をやめさせて、 IE の最新の実装で動作させるには下記のような宣言をすれば良い。

```html:edge.html
<!DOCTYPE html>
<head>
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
```
Caution: DecimalFormat round by default

DecimalFormat をそのまま使っていると四捨五入されないことがある。
APIを紐解くと

## DecimalFormat
https://docs.oracle.com/javase/jp/8/docs/api/java/text/DecimalFormat.html

> 丸め
> DecimalFormatは、RoundingModeで定義されている丸めモードをフォーマット処理に提供します。デフォルトでは、RoundingMode.HALF_EVENが使用されます。 

## RoundingMode.HALF_EVEN
https://docs.oracle.com/javase/jp/8/docs/api/java/math/RoundingMode.html#HALF_EVEN

> 「もっとも近い数字」に丸める丸めモードです(ただし、両隣りの数字が等距離の場合は偶数側に丸めます)。破棄する小数部の左側の桁が奇数の場合はRoundingMode.HALF_UPのように、偶数の場合はRoundingMode.HALF_DOWNのように動作します。この丸めモードは、連続する計算で繰返し適用される場合に累積エラーを統計的に最小限にします。これは「銀行方式の丸め」としても知られ、主に米国で使用されます。

よって、下記のような具合に四捨五入とは少し挙動が異なる。
0.5 の場合、 1 と 0 の中間で 0 が偶数のためこちらに丸められ切り捨てされているように見え、 1.5 の場合、 2 と 1 の中間で 2 が偶数のためこちらに丸められ四捨五入されているように見えます。

| Input | Output |
|------:|-------:|
| 0.5   | 0      |
| 1.5   | 2      |

必ず四捨五入したい場合は RoundingMode.HALF_UP を指定してあげれば良い。

```java:round.java
DecimalFormat df = new DecimalFormat();
df.setRoundingMode(RoundingMode.HALF_UP);
```
AzureのFunction Appに$_REQUESTがない

## Function App作成

### HTTPトリガーのFunction App作成

コンテナを作る→新しい関数を作る→他はデフォルトのまま作成。
HttpGET-CRUD-PHP1のような名前の関数タブが作られる。

## ブラウザアクセス

開発タブを開くと
https://example.azurewebsites.net/api/HttpGET-CRUD-PHP1?code=abcdefghijklmnopqrstuvwxyz0123456
みたいなかんじのURLが表示されるので、ブラウザでアクセスすると作成したFunctionAppが呼び出される。
デフォルトでは真っ白。

## Function Appの中身

構造としてはHttpGET-CRUD-PHP1という名前のディレクトリが作られ、中にfunction.jsonとrun.phpができる。

#### function.json

function.jsonはどういう条件で起動するかといったメタ設定を記載する
直接変更してもいいけど統合タブから操作した方が無難。
デフォルトではhttpTriggerという項目があり、これが『HTTPリクエストが来たらPHPを実行する』みたいな意味になっている。

#### run.php

index.phpとかではなく、ここが処理の起点となる。
開発タブから操作できるけど、とても非効率なのでFTPとかGitHubとか使った方がいい。

中身は基本的に普通のPHPだが、echoとか書いてもログに出力され、ブラウザ側には何も出ない。
最初から`file_put_contents(getenv('res'), $inTable)`と書いてあるのだが、getenv('res')は実は単なるファイル名。
しかし、そのファイルに書き込むと何故かブラウザに出力されるという仕様になっている。
最初に全体を`ob_start();$inTable=ob_get_clean()`とかで囲んでおけばあとは普通に書ける。

### 設定変更

デフォルトではGETしか受け付けない。
統合→トリガー HTTP(req)→Selected HTTP methods
のPOSTにチェックを入れるとPOSTも受け付けるようになる。
他にDELETE/HEAD/PATCH/PUT/OPTIONS/TRACEもあるけどまあ使わない。


## リクエストパラメータがない

### $_REQUESTがない

GETしようがPOSTしようが`$_REQUEST=[]`になってしまう。


### $_POSTがない

POSTパラメータを送っても`$_POST=[]`になる。
もっと言うと`$_SERVER`にも`$_ENV`にも`$argv`にも無い。

何処にあるかというと、最初に作成したhttpTriggerから回収できる。
`$post = file_get_contents(getenv('req'))`;

なお`hoge=1&fuga=2`って送るとそのまま`$post='hoge=1&fuga=2'`になるので`parse_str()`しないといけない。


### $_GETがない

同じく、URLにいくらパラメータを書いても`$_GET=[]`になる。
URLに`&hoge=1&fuga=2`と入れると、何故か`$_SERVER['REQ_QUERY_HOGE']=1`、`$_SERVER['REQ_QUERY_FUGA']=2`とかいう変なところに入ってくる。
あと`&foo[]=1&foo[]=2`とか書くと死ぬ。


### $_SESSIONがない

`session_start()`がfalseになるのでどうにもならない。
もっとも、そもそもそれ以前にFunction Appはセッションを使うようなサービスではないので、素直にApp Serviceでも使っとけって話だ。


## まとめ

リクエストパラメータの取り出しがやたらめんどい。
セッションが使えないのは元々そういうサービスではないからいいとしても、GET/POSTが簡単に取り出せないのはどうにかしてほしい。


## Function Appとは何か

https://azure.microsoft.com/ja-jp/services/functions/
> サーバー不要のコードを使用してイベントを処理

とかよくわかんねーことが書いてあるけど、
まあ正直MySQLで言うトリガーみたいなものだと思っておけばいい。
直接リクエストが来たとかEventHubにアクセスが来たとかデータベースにINSERTがあったとかの[タイミング](https://azure.microsoft.com/ja-jp/documentation/articles/functions-triggers-bindings/)で呼び出され、ちょっとした後処理を書くとかに使える。
定期起動もあるのでcron替わりにも使える。何故か秒単位指定できる。
メモ：Jinja2のかんたん出力

jinja2を使うときにPython3では色々と出力方法があると思うけども、
よく使う出力方法。

```py3:maketemp.py
import jinja2
def maketemp(filedir,  valuedict):
    with open(filedir) as f:
        temp = jinja2.Template(f.read())
        val = temp.render(valuedict)
    return val
```

こいつにテンプレートとデータを引数で渡してやる。

```py3:hontai.py
import maketemp
#～～～中略～～～
output = maketemp.maketemp('test.txt', dict)
print(output)
```
みたいな感じ。