OmniAICreator/Qiita-1.07M huggingface dataset:
vue-analyticsを取り敢えずTypeScript対応する

2018.11.28

vue + TypeScriptのプロジェクトで、定義ファイルの無いライブラリに対応する。
この記事ではvue-analytics。

https://github.com/MatteoGabriele/vue-analytics
https://github.com/MatteoGabriele/vue-analytics/issues/161
issueは上がってるけどPRもまだない。自前でPR出せるくらい対応できるならいいんだけど、時間もないので取り敢えずコンパイル通る様にしたい場合。


# 前提

```sh
$ vue create ts-project
# TypeScript対応以外は適当
# vue-cli3, vue2.5.17, typescript3.1.6
```

# 対応

* tsconfig.jsonに1行追加

```diff:tsconfig.json
~~ 省略
    "paths": {
      "@/*": ["src/*"],
+      "vue-analytics": ["src/types/vue-analytics"]
    },
~~ 省略
```

* type定義ファイル追加

```ts:src/types/vue-analytics.d.ts
import _Vue, { PluginFunction } from 'vue';

declare class VueAnalytics {
  static install(Vue: typeof _Vue, options: any): void;
  analyticsMiddleware: any;
  onAnalyticsReady: any;
  event: any;
  ecommerce: any;
  set: any;
  page: any;
  query: any;
  screenview: any;
  time: any;
  require: any;
  exception: any;
  social: any;
}
export default VueAnalytics;

declare module 'vue-analytics' {

}

declare module 'vue/types/options' {
  interface ComponentOptions<V extends _Vue> {
    ga?: VueAnalytics;
  }
}

declare module 'vue/types/vue' {
  interface Vue {
    $ga: VueAnalytics;
  }
}
```

あとは通常通り使う。

```ts
// main.ts
import Analytics from 'vue-analytics';
Vue.use(Analytics, {/*options*/});

// in components
this.$ga.event('category', 'action', 'label', 123);
```

必要に応じて`src/types/vue-analytics.d.ts`に定義を付け足す。

vue-analyticsが正式にサポートしたら、定義ファイルとtsconfig.jsの1行を削除して、プロジェクトの定義ファイル（`shims-vue.d.ts`とか）で、`import 'vue-analytics';`とかしとけばok
ノイズアニメーションをワンタッチで実現する

![sample.png](https://qiita-image-store.s3.amazonaws.com/0/248832/37bb4539-a1cb-0356-ffea-83eee9d8a209.png)
[ゾンビランドサガの公式サイト（の一部）](https://zombielandsaga.com/story/)でノイズアニメーションが使われているのを見て、「これはライブラリ化できそうだな」と思い立ち、衝動的に作ったのがこちらです。

[Noise Maker - デモ](https://mimonelu.github.io/sandbox/noise-maker/)
[Noise Maker - リポジトリ](https://github.com/mimonelu/sandbox/tree/master/noise-maker)

## ノイズアニメーションのロジック

ゾンビランドサガでは[こんな画像](https://zombielandsaga.com/images/mask.png)を別途用意して使っていますが、これを Canvas で動的に生成することで利便性と汎用性を高めることにしました（言い回しが大げさ）。

1. 仮想 Canvas を作成
2. 1 ピクセルごとにランダムな RGBA 値を設定
3. 指定された DOM ノードの背景画像に Data URI として設定
4. アニメーションループ内で `background-position` をランダムに設定

## NoiseMaker クラスについて

上記のロジックに基づいて作ったのが NoiseMaker クラスです。以下特徴。

* 複数の DOM ノードに異なるノイズアニメーションを設定可能
* ノイズアニメーションを削除可能
* ノイズ画像のサイズを設定可能
* 各ピクセルの RGBA 値に対して最小乱数値と最大乱数値を設定可能
* Firefox では若干遅い（ `background-position` の反映が遅い？）

以下コード。

```javascript
class NoiseMaker {
  constructor () {
    this.configs = {};
    this.configId = 0;
    setInterval(() => {
      for (let key in this.configs) {
        this.configs[key].target.style['background-position'] = `${this.irandom(0, this.configs[key].width)}px ${this.irandom(0, this.configs[key].height)}px`;
      }
    }, 1);
  }
  make (config) {
    const canvas = document.createElement('canvas');
    canvas.setAttribute('width', config.width);
    canvas.setAttribute('height', config.height);
    const context = canvas.getContext('2d');
    const imageData = context.getImageData(0, 0, canvas.width, canvas.height);
    for (let y = 0; y < imageData.height; y ++) {
      for (let x = 0; x < imageData.width; x ++) {
        const index = (imageData.width * y + x) * 4;
        imageData.data[index] = this.irandom(config.r[0], config.r[1]);
        imageData.data[index + 1] = this.irandom(config.g[0], config.g[1]);
        imageData.data[index + 2] = this.irandom(config.b[0], config.b[1]);
        imageData.data[index + 3] = this.irandom(config.a[0], config.a[1]);
      }
    }
    context.putImageData(imageData, 0, 0, 0, 0, canvas.width, canvas.height);
    config.target.style['background-image'] = `url(${canvas.toDataURL()})`;
    this.configs[this.configId.toString()] = config;
    return this.configId ++;
  }
  remove (configId) {
    this.configs[configId].target.style['background-image'] = null;
    this.configs[configId].target.style['background-position'] = null;
    delete this.configs[configId];
  }
  irandom (min, max) {
    return Math.floor(Math.random() * (max - min + 1)) + min;
  }
}
```

使い方。

```javascript
// オブジェクトの作成
const noiseMaker = new NoiseMaker();
// ノイズアニメーションの作成
let configId = noiseMaker.make({
  target: document.querySelector('.target'),
  width: 320,
  height: 320,
  r: [ 0, 255 ],
  g: [ 0, 255 ],
  b: [ 0, 255 ],
  a: [ 0, 255 ]
});
// ノイズアニメーションの削除
noiseMaker.remove(configId);
```

なお、デモでは二箇所に異なるアニメーションを設定しています。

## 終わりに

即興で書いたので色々アレですが、大体こんな感じで良いと思います。α値を低めに抑えるのがコツですね。あとはアイディア次第で。
データ解析コンペ等でCSVファイルを提出するとき，Pandasから直接サブミットする

# はじめに
データ解析コンペに出たりすると，予測結果を専用のフォームからCSVで提出することって多いですよね．
そんなとき，予測結果を一旦CSVで保存して，マウスでポチポチやるのは面倒くさいかと思います．
ここでは，スクリプト中でPandasから直接CSVファイルをPOSTする方法を紹介します．

# 手順
### 1. 提出APIを解析する

まず，どのような形式でPOSTするかを解析します．
ブラウザの開発者ツールを使って，トラフィックやソースを見て推測します

### 2. requestsを使って投げる
`requests.post`は，ファイルのストリームを渡すとmultipartで投げてくれます．
http://docs.python-requests.org/en/master/user/quickstart/#post-a-multipart-encoded-file
ここを，BytesIOのストリームに置き換えることでスクリプトから提出します．

```python
import io
import requests

def submit(df, filename, url, headers={}):
    # CSV形式の文字列を取得
    csv = df.to_csv(header=True, index=False)
    # byte型に変換して，BytesIOでstreamにする
    stream = io.BytesIO(csv.encode())
    # requestsでPOSTする
    response = requests.post(url, files={'file': (filename, stream)}, headers=headers)
    return response

# 例えばJWTトークンで認証を行っている場合
url = 'https://data-competition.example.com/submit'
token = 'xxxx.xxxxxxxxx.xxxxxxxxxxx'
res = submit(df, filename='submission.csv',
             url=url, headers={'authorization': token})
print(res)
```
C#インスタンス化ついでにＬＩＮＱしてみた件

```c#:InstanceLinq.cs
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace linqMaxMin
{
    public partial class Form1 : Form
    {
        List<Test> tests = new List<Test>
        {
            new Test{Subj="数学", Points=80, Name="田中一郎", ClassName="A"},
            new Test{Subj="英語", Points=70, Name="田中一郎", ClassName="A"},
            new Test{Subj="国語", Points=60, Name="鈴木二郎", ClassName="A"},
            new Test{Subj="数学", Points=50, Name="鈴木二郎", ClassName="A"},
            new Test{Subj="英語", Points=80, Name="鈴木二郎", ClassName="A"},
            new Test{Subj="国語", Points=70, Name="佐藤三郎", ClassName="B"},
            new Test{Subj="数学", Points=80, Name="佐藤三郎", ClassName="B"},
            new Test{Subj="英語", Points=90, Name="佐藤三郎", ClassName="B"},
        };

        public class Test
        {
            public string Subj { get; set; }
            public int Points { get; set; }
            public string Name { get; set; }
            public string ClassName { get; set; }
        }

        public Form1()
        {
            InitializeComponent();
            InstanceLinq();
        }

        public void InstanceLinq()
        {
           //List<T> リスト名 = new List<T> { LINQ文};
            List<Test> hquerymin =new List<Test>
           {
           //ＬＩＮＱで最低点数の人のデータのみを取得
               tests
                .OrderBy(x => x.Points)
                .First()
           };

            //表示
            dataGridView1.DataSource = hquerymin;
        }

       
            
        
    }
}

```
Twitter の Bearer Token を取得 (Node.js)

Consumer Key (API Key) と、Consumer Secret (API Secret) を使って、Bearer Token を取得する方法です。
.env ファイルにキーを入れます。

```js:get_bearer.js
#! /usr/bin/node
// ---------------------------------------------------------------
//  get_bearer.js
//
//						Apr/25/2019
// ---------------------------------------------------------------
const request = require('request');
const dotenv = require('dotenv');
//
dotenv.config()
const consumer_key = `${process.env.CONSUMER_KEY}`
const consumer_secret = `${process.env.CONSUMER_SECRET}`
//
const credentials = consumer_key + ":" + consumer_secret
const credentialsBase64Encoded = (Buffer.from(credentials)).toString('base64')

console.error ("*** 開始 ***")

request({
	url: 'https://api.twitter.com/oauth2/token',
	method:'POST',
	headers: {
	  'Authorization': `Basic ${credentialsBase64Encoded}`,
	  'Content-Type':'application/x-www-form-urlencoded;charset=UTF-8'
	},
	body: 'grant_type=client_credentials'
}, function(err, resp, body) {
	console.log(body)
	console.error ("*** 終了 ***")
})

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

```text:.env
CONSUMER_KEY = '******'
CONSUMER_SECRET = '***********'
```
Symplify\CodingStandardを素のPHP-CS-Fixerで動かす方法

[Symplify\CodingStandard](https://github.com/Symplify/CodingStandard)は、クリーンアーキテクチャに注力するPHPプロジェクトのための、30以上のコード標準検査ルールを束ねたリポジトリだ。

検査ルールは、PHP CodeSnifferのSniffやPHP-CS-FixerのFixerを実装する形で作られているものの、姉妹ツールの[EasyCodingStandard](https://github.com/Symplify/EasyCodingStandard)で実行することが推奨されている。

Sniff系の検査ルールはPHP CodeSnifferに問題なく組み込むことができる。しかし、Fixer系の検査ルールはPHP-CS-Fixerに組み込むことができない。何故かと言うと、PHP-CS-Fixerが期待する形の命名規則でCodingStandardが作られていないためだ。

もうすでにPHP-CS-Fixerを使っていて、EasyCodingStandardを入れるのは面倒な場合がある。そんなときな[symplify-cs-fixer](https://github.com/suin/symplify-cs-fixer/)をインストールするといい。これはSymplify\CodingStandardのFixer系ルールをPHP-CS-Fixerで動くようにしてくれるライブラリだ。

なお、symplify-cs-fixerをインストールすれば、symplify/easy-coding-standardもsymplify/coding-standardも入れる必要はない。

## symplify-cs-fixerのインストール

composerでいれる:

```
composer require --dev suin/symplify-cs-fixer
```

## .php_cs.distを設定する

ちょっと書き方がどうしても特殊になってしまうが、`$symplifyFixers = new SymplifyFixers()`して、`$symplifyFixers()`にSymplify/CodingStandardのルール名を渡すと、PHP-CS-Fixerが認識してくれるようになる。

```php:.php_cs.dist
<?php

declare(strict_types=1);

use SymplifyCsFixer\SymplifyFixers;

$symplifyFixers = new SymplifyFixers();

return PhpCsFixer\Config::create()
    ->registerCustomFixers(
        [
            $symplifyFixers('standalone_line_in_multiline_array'),
            $symplifyFixers('block_property_comment'),
            $symplifyFixers('remove_empty_doc_block'),
            $symplifyFixers('remove_superfluous_doc_block_whitespace'),
            $symplifyFixers('remove_useless_doc_block'),
            $symplifyFixers('require_followed_by_absolute_path'),
            $symplifyFixers('line_length'),
            $symplifyFixers('property_name_matching_type'),
            $symplifyFixers('method_order_by_type'),
            $symplifyFixers('class_string_to_class_constant'),
            $symplifyFixers('array_property_default_value'),
            $symplifyFixers('final_interface'),
            $symplifyFixers('blank_line_after_strict_types'),
        ]
    )
    ->setRules(
        [
            ... 他のルール ...
            'Symplify/standalone_line_in_multiline_array' => true,
            'Symplify/block_property_comment' => true,
            'Symplify/remove_empty_doc_block' => true,
            'Symplify/remove_superfluous_doc_block_whitespace' => true,
            'Symplify/remove_useless_doc_block' => true,
            'Symplify/require_followed_by_absolute_path' => true,
            'Symplify/line_length' => [
                'line_length' => 80,
                'break_long_lines' => true,
                'inline_short_lines' => true,
            ],
            'Symplify/property_name_matching_type' => true,
            'Symplify/method_order_by_type' => true,
            'Symplify/class_string_to_class_constant' => true,
            'Symplify/array_property_default_value' => true,
            'Symplify/final_interface' => true,
            'Symplify/blank_line_after_strict_types' => true,
        ]
    )
    ->setFinder(
        ...
    );
```

あとは、php-cs-fixerの普通の使い方どおり:

```
vendor/bin/php-cs-fixer fix --dry-run --diff --diff-format=udiff --verbose
```
AdaでFizzbuzz

##なぜにAda
初投稿Adaだったのにずっと手つけてなかったので。
色々文法試したかったので、無駄に長いコードになってるよ。

##コード

[ada_online_compiler](https://rextester.com/l/ada_online_compiler)

```sql

--GNAT 4.9.3

-- 使用するライブラリの宣言with Ada.Text_IO;
use Ada.Text_IO;
with Ada.Integer_Text_IO;

-- mainとなる関数名は何でもよい
procedure FizBuz is
   -- サブプロは宣言部に記載
   function ModFB(I: in Integer) return Integer is
      ret: Integer := 0;
   begin
      if I mod 3 = 0 and i mod 5 = 0 then
         ret := 3;
      elsif I mod 3 = 0 then
         ret := 2;
      elsif I mod 5 = 0 then
         ret := 1;
      end if;
      return ret;
   end ModFB;

   procedure FizzBuzz(I: in Integer) is
   begin
      -- パターン網羅出来てないとコンパイラが怒る。なかなかやるやん。
      case ModFB(I) is 
         when 3      => Put_Line("FizzBuzz");
         when 2      => Put_Line("Fizz");
         when 1      => Put_Line("Buzz");
         when Others => Ada.Integer_Text_IO.Put(I,1);
                        New_Line(1);
      end case;
   end FizzBuzz;
begin
   for I in Integer range 1 .. 100 loop
      FizzBuzz(I);
   end loop;
end FizBuz;
```


##実行結果
```
1
2
Fizz
4
Buzz
Fizz
7
8
Fizz
Buzz
11
Fizz
13
14
FizzBuzz
16
17
Fizz
19
Buzz
Fizz
22
23
Fizz
Buzz
26
Fizz
28
29
FizzBuzz
31
32
Fizz
34
Buzz
Fizz
37
38
Fizz
Buzz
41
Fizz
43
44
FizzBuzz
46
47
Fizz
49
Buzz
Fizz
52
53
Fizz
Buzz
56
Fizz
58
59
FizzBuzz
61
62
Fizz
64
Buzz
Fizz
67
68
Fizz
Buzz
71
Fizz
73
74
FizzBuzz
76
77
Fizz
79
Buzz
Fizz
82
83
Fizz
Buzz
86
Fizz
88
89
FizzBuzz
91
92
Fizz
94
Buzz
Fizz
97
98
Fizz
Buzz
```

##感想
なかなか読みやすいね。リファレンスは読みにくいけど。
[このサイトがなければ即死だった](http://d.hatena.ne.jp/carver/20100227/p1)

一番時間かかったのは、サブプロをどう定義するかで、悩みまくり。
[このサイト](http://develop.inforle.com/2010-08-09-08-48-39/36--ada-programming/95--ada95-tutorial-section4-3-1.html)を見つけるまでが長かった。

ClassとかGenericsとかもあるみたいなので、
そのあたりうまく使ってDomemo作ろうかしら。
【WEBエンジニアとASVS 弐（V2）】

[前回](https://qiita.com/scn7188/items/3a6d1a7f0726fa7e9cbf)の続き（V2）からです。

今回の記事を書くにあたっての経緯などです。
[ASVSとは](https://qiita.com/scn7188/items/e108b812efb869a2747d)
本記事で紹介している内容（各No）は自分で作った資料のNoをもとにしています。
※資料は最下部に記載
※前回からマークダウン記法を変更しました。
#V2：認証に関する検証要件
### No.6 アカウントへのアクセス回復に使用できるすべてのアカウントID認証機能(プロファイルの更新機能，パスワードの再設定，トークンの無効化や紛失，ヘルプデスク，IVRなど)が，一義的な認証機構として攻撃耐性を持つ
>アカウントの乗っ取りがされた場合の救済措置しての上記機能が、
ハッカーによる攻撃でシステムダウンしないこと
ここが潰されてしまうとアカウントの復旧ができなくなります。

### No.7 パスワード変更機能に，古いパスワード，新しいパスワード，パスワードの確認が含まれている
>一部を除く（メールアドレスからの変更）は上記3項目でパスワード変更を承認すること。
これはログイン中に限っての話になります。
ログイン前では「古いパスワード」がそもそもわからないので、
メールアドレスによる変更機能を用意してあげる必要があります。
（もしくは、サポートセンターなど）

### No.9 アカウントパスワードに十分な強度を持つ暗号化ルーチンを使われており，この暗号化ルーチンがブルートフォース攻撃に耐えられる
> レベル２の項目です。
パスワードを平文でDBに入れることはまず無いので、
その際の暗号化ルーチン（hashやcryptなどなど）がブルートフォース（総当たり）攻撃に耐えられるか。
ログイン画面はWEBサービスの入り口なのでブルートフォース攻撃を受けやすいです。
そのため、複雑な暗号化（2重3重など）をしていると返って、
その箇所が脆弱になります。（システムダウンなど）
対策としては、
・堅牢かつ軽い処理で暗号化を行う。
・暗号化ルーチンに入る前にアカウントロックの処理を行う。

### No.10 認証情報は暗号化された適切なリンクを使用して転送され，ユーザに資格情報の入力を求めるすべてのページや機能は暗号化されたリンクを使用して転送されている
> 「暗号化された適切なリンク」はおそらく「https」のことだと思います。
もし「http」でアクセスされた場合は、
「https」にリダイレクトするか、4xx系の画面を表示すれば問題ありません。

### No.11 パスワード再設定機能やその他のパスワード回復経路から現在のパスワードが露呈せず，
新しいパスワードが平文でユーザに送信されない
> 「現在のパスワードが露呈せず」はパスワード変更画面にて、
現在のパスワードをもう一度設定した場合のエラーメッセージで
「現在と同じパスワードは設定できません」のようなに意味のメッセージを出さないこと。
これにより現在のパスワードが判明し乗っ取りが行われる可能性があります。
なので、エラーメッセージとして表示するのであれば「過去に使用された～」などとした方が良いかもしれません。
（そもそもメッセージの表示をせずにエラーとしても問題ないと思います。）
「新しいパスワードが平文でユーザに送信されない」について、パスワードの通知はしなくて結構です。

### No.12 ログイン機能，パスワード再設定機能，またはアカウントを忘れた場合の機能を使ってアカウント情報の取得はできない
> 上記の機能からアカウントの情報（氏名、住所、電話番号）が取得できないこと。
アカウント情報はあくまでもログイン後以降で表示させましょう。

### No.13 アプリケーションのフレームワークやアプリケーションが使用するすべての構成要素でデフォルトパスワード("admin/password"など)を使用しない
> 管理者権限などのアカウントにはWEBサイト独自のものを使用しましょう。
ブルートフォース攻撃により突破される可能性があります。

### No.14 ブルートフォース攻撃やDoS攻撃など認証機構に対する一般的な自動攻撃を防止するために，リクエスト制限機能が存在する
> アカウントロックやIP制御を掛けれる仕組みを作っておきましょう。
外部ファイル形式で実装できればなお良しです。

### No.16 パスワードの再設定やその他のパスワード復帰方法において，ソフトトークン，モバイルプッシュ，またはオフラインのパスワード回復機構が使用されている
> ネットワークを使った回復機構以外にSMSなどを使った認証方法を用意する。
メールアドレスや外部アプリなどの使用でも大丈夫かも？


またV2の続きは次回で～


  ▼▽▼▽▼▽▼▽▼▽▼▽▼▽▼▽▼▽▼▽▼▽
  [ASVS 3.0.1まとめ - Google スプレッドシート](https://docs.google.com/spreadsheets/d/1wGC9sF2gZoHnGKJt2mIJrb_Cr0bqETl9r07s_YQFWK8/edit?usp=sharing)
  ▲△▲△▲△▲△▲△▲△▲△▲△▲△▲△▲△
世界2位のユニコーンで8兆円の評価額「ByteDance」のAIリコメンドを用いたパーソナライズ戦略

■概要
中国北京に拠点を置く「ByteDance」は現在「Ant Financial」に次ぐ世界二番目の評価額のユニコーン企業となっている。数多くのアプリケーションを開発しており、中国国内で人気を誇るニュースSNSアプリ「Toutiao」や日本でも多く知られる「TikTok」など数多くのヒットアプリを生み出している。この会社は自社でAIの研究開発組織「ByteDance AI Lab」を持っており、各ユーザーの求めるコンテンツをリコメンドするアルゴリズムを駆使し、爆発的なヒットを生み出している。現在ショートムービーの市場はFacebook,Tencent,Alibabaを含め多くのTech企業が参入しているが、MAU500Mという圧倒的ユーザー数で成長を続けている。

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
■戦略
ByteDanceのアプリケーションは一貫してAIによるリコメンドを組み込んでいる。ユーザーの各コンテンツに対するInsightを分析し、各々の端末でカスタマイズされたコンテンツが閲覧できる状態を整えている。このリコメンドによるユーザー満足度は高く、統計では１日あたりの「Toutiao」ユーザーの平均アプリ滞在時間は80分、「TikTok」ユーザーの平均アプリ滞在時間は50分と長期にわたる。
ここまでのユーザー体験を実現する上で、ByteDanceは多くのAI人材を抱えており、最先端のイノベーションを生み出していく環境を整えている。

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
■技術に関する考察
・ショートームービでは画像認識の技術力も高く、識別機能を生かしたeditorとしての技術力も若者から人気を集める要因の一つとなっている。
・AIによる機械学習によってリコメンドされるコンテンツの変化はとても早く、ユーザーの変化にいち早く対応してコンテンツを提供している。

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
■今後の展望
現在グローバル展開を進め、世界150市場、75カ国語で利用されている。このように中国初のアプリでローカライズに成功し、展開を続けている例は他になく今後グローバルアプリケーションを多方面に展開していくと考えられる。NBAとのパートナーシップ契約も2018年11月末に報道され、これまで若い層を中心にユーザー拡大を行なっていたが、今後は様々な年齢層に受け入れられるサービスとして浸透していく。
更に、多数アプリケーションを展開しているByteDanceは、AIの機械学習によるリコメンドを行うデータをアプリを横断して活用していき、更にユーザーに密着したコンテンツの提供を行なっていくと考えられる。
Wallet機能などもまだ実用化されていないが、機能として実装されており、今後ECなどの分野においても利益を拡大していくと予想できる。
NLuaを使ってみる 2

[前回](https://qiita.com/amutou/items/b22809d885d009fbf9d6)、関数を登録する際に`RegisterFunction`を使っていたが、Luaに直接C#のインスタンスを渡せるらしいので、その方法を使ってみた。
ついでなので、テーブルのやり取りもやってみた。

```c#:テストコード
static void Main(string[] args)
{
    using (NLua.Lua instance = new NLua.Lua())
    {
        instance["cls1"] = new Class(instance, "def");
        instance["cls2"] = new Class(instance, "ghi");

        instance.DoString("tbl = cls1:func1()");
        instance.DoString("for i, j in pairs(tbl) do print(i, j) end");

        instance.DoString("tbl = cls2:func1()");
        instance.DoString("for i, j in pairs(tbl) do print(i, j) end");

        instance.DoString("cls1:func2(tbl)");
        instance.DoString("cls2:func2(tbl)");
    }
}

public class Class
{
    private readonly NLua.Lua instance;

    private string str;

    public Class(NLua.Lua instance, string str)
    {
        this.instance = instance;
        this.str = str;
    }

    public object func1()
    {
        Dictionary<string, object> dic = new Dictionary<string, object>();

        dic["a"] = 12.34;
        dic["x"] = str;

        return (CreateLuaTable(dic));
    }

    public void func2(NLua.LuaTable table)
    {
        Console.WriteLine("***");

        foreach (string key in table.Keys)
        {
            Console.WriteLine(key + " : " + table[key] + " ( " + table[key].GetType().ToString() + " )");
        }

        Console.WriteLine("***");
    }

    protected NLua.LuaTable CreateLuaTable(Dictionary<string, object> dic)
    {
        StringBuilder sb = new StringBuilder();
        sb.Append("return({");

        foreach (var v in dic)
        {
            if (typeof(string) == v.Value.GetType())
            {
                sb.Append(v.Key + "=\"" + v.Value + "\",");
            }
            else
            {
                sb.Append(v.Key + "=" + v.Value + ",");
            }
        }

        sb.Append("})");

        return ((NLua.LuaTable)(instance.DoString(sb.ToString())[0]));
    }
}
```

```:結果
a       12.34
x       def
a       12.34
x       ghi
***
a : 12.34 ( System.Double )
x : ghi ( System.String )
***
***
a : 12.34 ( System.Double )
x : ghi ( System.String )
***
```

Luaにインスタンスを渡せば、名前空間を維持したままで使うことができる。
ただし、変数と関数で`.`と`:`を使い分ける必要がある。

テーブルの扱いはちょっと面倒。
C#で受け取るだけなら`NLua.LuaTable`を引数にすればいいが、C#から返すのはかなり面倒。うまいやり方を見つけられなかった。
とりあえず、今回は`DoString`でテーブルを作るメソッドを作った。また、その際は、別のLuaインスタンスからテーブルを持ってくると例外が発生するので、コンストラクタで受け取ったLuaインスタンスで`DoString`を行っている。

例外が発生するのは`pairs`のあたりだが、例えばLuaインスタンスを2つ作り、その間でテーブルを移動して`pairs`を行っても例外は発生しないので、必ずテーブルを作ったインスタンスの中で`pairs`を実行しなければならない、ということではないはず。
もう少し詳しく調べてみたい気もするけど、テーブルをうまく扱うのが目的ではなく、他にやりたいことがあるので、今回はこのあたりで妥協。
iDempiere4.1(JPiere4.1)のSSL対応




## 1.秘密鍵の生成

```
# openssl genrsa -aes128 -out idempiere.key 2048
```
パスフレーズを入力を求められるので、入れる(確認もあるので2回)

```
Generating RSA private key, 2048 bit long modulus
.........................+++
...............+++
e is 65537 (0x10001)
Enter pass phrase for idempiere.key:パスフレーズを入力する
Verifying - Enter pass phrase for idempiere.key:パスフレーズを入力する
```



## SAN対応

openssl.cnf を作業用ディレクトリにコピーして、subjectAltName にサイトURLを指定します。

*Ubuntuだと/etc/ssl/openssl.cnf
*CentOSだと/etc/pki/tls/openssl.cnf　


```

# cp /etc/ssl/openssl.cnf openssl4idempiere.cnf
# vi openssl4idempiere.cnf

```


```
[ SAN ]
subjectAltName = @alt_names

[ alt_names ]
DNS.1 = abc.japanwest.cloudapp.azure.com
DNS.2 = def.japanwest.cloudapp.azure.com
```

## CSRの作成

```
openssl req -new -key idempiere.key -sha256 -subj "/C=JP/ST=Tokyo/L=xxxx/O=xxxx/CN=abc.japanwest.cloudapp.azure.com" -out idempiere.csr

Enter pass phrase for idempiere.key:秘密鍵のパスフレーズを入力する

```

req       CSRファイルを作成
-new      新規にCSRを作成する
-key      秘密鍵ファイルを指定する
-sha256   署名ハッシュアルゴリズムとして SHA-2 を使用する。
-subj     Subjectを指定 C=国名 ST=都道府県名 L=市町村名 O=組織名 CN=サイトのURL


## 証明書（公開鍵）の作成

```
openssl x509 -req -days 3650 -sha256 -in idempiere.csr -signkey idempiere.key -extfile openssl4idempiere.cnf -extensions SAN -out idempiere.crt

Enter pass phrase for idempiere.key:秘密鍵のパスフレーズを入力する

```


## keystoreの作成
Jettyでは、PKCS12フォーマットでないと使えないので、サーバの秘密鍵ファイル、サーバ証明書からPKCS12形式のファイルを作成します。

```
$ openssl pkcs12 -inkey idempiere.key -in idempiere.crt -export -out idempiere.pkcs12

Enter pass phrase for idempiere.key:秘密鍵のパスフレーズを入力する
Enter Export Password:エクスポートのパスワードを入力する
Verifying - Enter Export Password:エクスポートのパスワードを入力する

```

####  PKCS12形式のファイルをkeystoreに変換します

```
keytool -importkeystore -srckeystore idempiere.pkcs12 -srcstoretype PKCS12 -destkeystore keystore

$ keytool -importkeystore -srckeystore idempiere.pkcs12 -srcstoretype PKCS12 -destkeystore keystore
キーストアidempiere.pkcs12をkeystoreにインポートしています...
出力先キーストアのパスワードを入力してください:キーストアのパスワードを入力する
新規パスワードを再入力してください:キーストアのパスワードを入力する
ソース・キーストアのパスワードを入力してください:エクスポートのパスワードを入力する

別名1のエントリのインポートに成功しました。

```


最後にkeystoreをjettyのetc以下に設置します。

mv keystore idempiere_home/jettyhome/etc/

mv keystore /opt/idempiere-server/jettyhome/etc/


## 参考サイト
https://blog.fileshelfplus.com/security/312

http://choice-site.com/2016/08/03/jetty-9-3-10%E3%81%AEssl%E3%81%AE%E8%A8%AD%E5%AE%9A/
RSpecのSpecの種類とそれぞれのテストの目的および概要


*この記事はRSpecのバージョンが3.8の時(現時点最新版)の[RSpecの公式Documentation](https://relishapp.com/rspec)を元に作成しました。

Ruby on Railsで開発をしていく中で、どの場合にどのテストを書くべきなのか筆者の中ではっきりしなかったので、調べてみました。


#Controller specs　
controller specsはRailsのFunctionalテストのためのRSpecラッパーである。
Controller specsでは、それぞれのexampleの中で一つのhttpリクエスト(GET,POST等)をシミュレーションすることを許し、そのリクエストに対して特定の結果が得られるかどうかのテスト、つまり単体のテスト（Unit test）を行う。
##### テストの例
- テンプレートがレンダリングされているか
- 意図したページにリダイレクトされているか
- コントローラの中でviewと共有するための変数（インスタンス変数）が意図したものになっているか
- リクエストに対するレスポンスとともに意図するCookieが送られているか

#Request specs
Request specはRailsの統合テストの周りをカバーするためのラッパーを提供するものである。
Request specはルーティングを含め全ての階層（コントローラー、モデル、ビュー等）を通してテストできるようにデザインされている。
しかし、スタブを使うことは推奨されていない。（スタブは統合テストではよく利用される）
RequestSpecではControllerSpecと同じように１つのリクエストに対してのテストもできるが、さらに複数のコントローラーを通したリクエストのテストの評価や複数のセッションを通したテストの評価も可能である。
##### テストの例
- 会員登録機能のテスト

#Feature specs
Feature specsは一つのアプリケーションを通し、それぞれの機能が意図した通りに動くかを確認するハイレベルなテストである。
このテストでは実際に外部インターフェイス（通常はwebページ）を通してアプリケーションが動くか確認するのが良いとされている。
Feature specsでは[Capybara](https://www.rubydoc.info/github/jnicklas/capybara/master#using-capybara-with-rspec)というGemが必要である。
CapybaraではブラウザのHTTPリクエストを通してシミュレーションすることを意図している。
ちなみにFeature specでは多くのエイリアスを用意しており、それはFeature　specが[Customer tests](http://wiki.c2.com/?CustomerTest) や[acceptance tests](http://wiki.c2.com/?AcceptanceTest)として読めるようにしているため。

###テストの例
- あるアプリケーションのトップ画面を最初に訪れ、そこから会員登録をするまでの流れのテスト
- ecサイトで商品を買い物カートに入れて、購入するまでの流れのテスト

#####*Customer testとは？* 
*Unit testは機能をテストするために開発者によってモデリングおよびコーディングまでされるものに対して、Customer testは実務に適したテストができるようにカスタマーによって少なくともモデリングされ、またコーディングまでされる可能性の高いtestのこと。
Feature specではエンジニア以外の人が利用する可能性も考えて、様々なバックグラウンドを持つ人が理解しやすいように様々なエイリアスを持っている。*

*現在、筆者が使っているspecは以上なので、今後別のspecを使うことになった場合、順次追加していきます

##参考
- Controller specs
 https://relishapp.com/rspec/rspec-rails/v/3-8/docs/controller-specs
- Request specs
 https://relishapp.com/rspec/rspec-rails/v/3-8/docs/request-specs/request-spec
- Feature specs
　　https://relishapp.com/rspec/rspec-rails/v/3-8/docs/
GitHub Desktop was unable to store the account token in the keychain. Please check you have unlocked access to the 'login' keychain.


GitHub Desktopでサインインしようとしたら題名のエラーが出た。

## 解決策
下記フローで解決した。

1. キーチェーンアクセスの「ログイン」を右クリする
2. 「キーチェーン"ログイン"をロック」を選択する
3. キーチェーンアクセスの「ログイン」を右クリする
4. 「キーチェーン"ログイン"をロックを解除する」を選択する
5. 再度サインインする

## 参考資料

https://github.com/desktop/desktop/blob/master/docs/known-issues.md#the-username-or-passphrase-you-entered-is-not-correct-error-after-signing-into-account---3263
サンダーバードとライブメールのデータをバックアップするバッチ

#Outlook以外のメーラー使用禁止
社内のメーラーがOutlook以外使用禁止になった。
ThunderbirdやWindows Live Mailのユーザーが多くいたのだが
全員Outlookへ移行し半年後、Outlook以外のメーラーの強制削除が実施されることになった。
対象ユーザーが数十名もいて、メーラー毎にバックアップ方法をいちいち説明するのは大変なので、自動でバックアップするバッチファイルを作成し公開した(OSはWindows用)
注意点としてThunderbirdはデータファイルのコピーだけで移行できるがWindows Live MailはExport,Importの作業が必要だと思うのでデータを保存しただけでは読めないかも知れない。
##Thunderbird用

```:Thunderbird_backup.bat
:===================================================================================
:内容：サンダーバードのメールデータを保管するバッチファイルです
:使用方法：このバッチファイルをダブルクリックして実行する
:実行結果：以下のBACKUP_PATHに記載のフォルダ内に自分のPC名のフォルダが作成される。
:          そのフォルダ内にメールデータが保存される
:注記：保存先を変える場合はBACKUP_PATHの値を変更してください。
:
:改定履歴
:DATE       VER   NAME     COMMENT
:2018/11/28 V1.00 HANTANI  新規作成
:===================================================================================

set BACKUP_PATH=C:\MAIL_BACKUP

xcopy  /D /E /C /I /R /Y  %APPDATA%\Thunderbird  %BACKUP_PATH%\%COMPUTERNAME%
echo 終了
pause
```


##Windows Live Mail用

```:Windows_Live_Mail_backup.bat
:===================================================================================
:内容：ライブメールのメールデータを保管するバッチファイルです
:使用方法：このバッチファイルをダブルクリックして実行する
:実行結果：以下のBACKUP_PATHに記載のフォルダ内に自分のPC名のフォルダが作成される。
:          そのフォルダ内にメールデータが保存される
:注記：保存先を変える場合はBACKUP_PATHの値を変更してください。
:
:改定履歴
:DATE       VER   NAME     COMMENT
:2018/11/28 V1.00 HANTANI  新規作成
:===================================================================================

set BACKUP_PATH=C:\MAIL_BACKUP

xcopy  /D /E /C /I /R /Y  "C:\Users\%USERNAME%\AppData\Local\Microsoft\Windows Live Mail"  %BACKUP_PATH%\%COMPUTERNAME%
echo 終了
pause
```
AWS S3のバケットポリシーの編集で「アクセス拒否」と出てしまったとき

# そこまでの行き方
S3トップ -> バケット名 -> アクセス権限タブ -> バケットポリシー

# 解決
S3トップ -> バケット名 -> アクセス権限タブ -> パブリックアクセス設定
で全てのチェックを外す。
Chromeのオフラインインストーラのダウンロード(32/64bit)

# Chromeのオフラインインストーラのダウンロード(32/64bit)

自己メモ。
Chromeのオフラインインストーラ(スタンドアロンインストーラ)のダウンロードURL
通常はアクセス元に合わせてリンクされるインストーラが変わるが、`platform=`のGETパラメータを付けると任意で切り替えることができる。


## 32bit版
https://www.google.com/chrome/browser/desktop/index.html?standalone=1&platform=win

→　**ChromeStandaloneSetup.exe**


## 64bit版
https://www.google.com/chrome/browser/desktop/index.html?standalone=1&platform=win64

→　**ChromeStandaloneSetup64.exe**
C++ Builder XE4 > TMonthCalendar > 1日から4日をBold表示 > Boldかどうか分かりにくい

```txt:動作環境
C++ Builder XE4
Windows 7 Pro (32bit)
```

### 処理概要

- TMonthCalendarに関して、1日から4日をBold表示する

RadStudioのヘルプを見たが、意味が分からなかった。

### 参考

- https://stackoverflow.com/questions/12794009/bolddays-with-tmonthcalendar

### 実装

```Unit1.h
//---------------------------------------------------------------------------

#ifndef Unit1H
#define Unit1H
//---------------------------------------------------------------------------
#include <System.Classes.hpp>
#include <Vcl.Controls.hpp>
#include <Vcl.StdCtrls.hpp>
#include <Vcl.Forms.hpp>
#include <Vcl.ComCtrls.hpp>
#include <Vcl.Grids.hpp>
#include <Vcl.Samples.Calendar.hpp>
//---------------------------------------------------------------------------
class TForm1 : public TForm
{
__published:	// IDE で管理されるコンポーネント
	TMonthCalendar *MonthCalendar1;
	void __fastcall MonthCalendar1GetMonthBoldInfo(TObject *Sender, DWORD Month, DWORD Year,
          DWORD &MonthBoldInfo);



private:	// ユーザー宣言
public:		// ユーザー宣言
	__fastcall TForm1(TComponent* Owner);
};
//---------------------------------------------------------------------------
extern PACKAGE TForm1 *Form1;
//---------------------------------------------------------------------------
#endif

```

```Unit1.cpp
//---------------------------------------------------------------------------

#include <vcl.h>
#pragma hdrstop

#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
	: TForm(Owner)
{
}
//---------------------------------------------------------------------------
void __fastcall TForm1::MonthCalendar1GetMonthBoldInfo(TObject *Sender, DWORD Month,
		  DWORD Year, DWORD &MonthBoldInfo)
{
	unsigned int bolddays[] = {1, 2, 3, 4};
	unsigned int days;
	MonthCalendar1->BoldDays(bolddays, 4, days);
	MonthBoldInfo = days;
}
//---------------------------------------------------------------------------

```

### 実行例

11月
![2018-11-28_16h22_22.png](https://qiita-image-store.s3.amazonaws.com/0/32870/2d690ca8-38a9-21b9-c796-9692f1cdb3d6.png)

12月
![2018-11-28_16h22_34.png](https://qiita-image-store.s3.amazonaws.com/0/32870/d1bd1832-7a2b-9c74-4b45-0bc3816325c5.png)

- Boldかどうか分かりにくい
- 月を変えた時、その月で1日から4日がBold表示
- 設定していない日もBoldになっているような
Composer: ローカルのパッケージをrequireする方法

Composerはオンラインのレポジトリである[Packagist](https://packagist.org/)にホスティングされたパッケージをrequireするのが通常の使い方だが、ローカルのパッケージをrequireすることもできる。この機能は、自作のライブラリをPackagistに公開する前に、composerでインストールを試して使ってみたりする用途に使える。

## Composerでローカルのパッケージを使用する方法

Composerでローカルのパッケージを使用するには、ローカルのパッケージを使いたい側のcomposer.jsonに`repositories`を足す。`repositories`は配列で、その中に`type`が`"path"`のリポジトリ設定を追加する。`url`は絶対パスでも相対パスでも構わない。相対パスの場合は、ローカルのパッケージを使いたい側のcomposer.jsonからの相対パスにする。`options.symlink`は`false`にすると、ローカルパッケージを`composer install`したときにシンボリックリンクではなく、コピーして持ってくるようになる。

```ローカルパッケージを使いたい側のcomposer.json
{
    "name": "suin/main-project",
    "repositories": [
        {
            "type": "path",
            "url": "../LocalPackage",
            "options": {
                "symlink": false
            }
        }
    ],
    "require": {
        "suin/local-package": "dev-master"
    }
}
```

一方のローカルパッケージのcomposer.jsonは特に細工する必要はない。

```ローカルパッケージのcomposer.json
{
    "name": "suin/local-package",
    "autoload": {
        "psr-4": {
            "Suin\\ComposerUsingLocalRepository\\LocalPackage\\": "src/"
        }
    }
}
```

ローカルパッケージを使いたい側のcomposer.jsonを書いたら、composer installすればローカルパッケージが入ってくる:

```console
$ composer install
Loading composer repositories with package information
Updating dependencies (including require-dev)
Package operations: 1 install, 0 updates, 0 removals
  - Installing suin/local-package (dev-master): Mirroring from ../LocalPackage
Writing lock file
Generating autoload files
```

ちなみに完全なサンプルコードは[GitHubに公開している](https://github.com/suin/php-playground/tree/master/ComposerUsingLocalRepository)ので、参考にされたし。
2018/4以降 Eloquentでサブクエリをjoinする正しい方法 joinSub

なんか DB::raw 使えって記事ばっかりなんですよ

https://qiita.com/sato_ryu/items/1033fe51b886622a6dda
https://teratail.com/questions/99379
https://teratail.com/questions/106851

2018/4/23、Laravel 5.6.17 にてjoinSubって関数が実装されました。
https://laravel-news.com/laravel-5-6-17

ちなみに、内部で as を決め打ちしているので、oracleでは使えません

https://twitter.com/kituneponyo/status/1067677537558392833
新入社員がLinuxのルーティングを調査した時にお世話になったコマンド集

#　じょうきょう　と　ちゅういがき
マルチキャストでパケットをDebian(GW)→CentOS(仮想マシン)に投げた時に、何故か届かなかった。
その原因を調査するときに、ネットワーク知識0の新入社員がお世話になったコマンド集です。
なのでめっちゃ偏ってると思います。

#　おねがい
前述した通り、ネットワーク知識0の人間が調べながらまとめたものなので、用語の説明などが間違っていたり、語弊があったりするかもしれません。
間違いはコメントや編集リクエストでどんどんご指摘ください。間違えたまま覚えてるのは恥ずかしいし、誤った知識をネット上で公開するのはとても罪なので……。

#　こまんど　しゅう

##　ネットワークの設定と確認
### `ifconfig`
**説明**：ネットワーク環境の状態確認や設定確認、設定のためのコマンド(引用元：http://www.atmarkit.co.jp/ait/articles/0109/29/news004.html)

**オプション**：
-a … 使用してないインターフェイスも含めて全部表示

**マルチキャスト・フラグを有効にする**
`ifconfig <インターフェイス名> multicast`

**マルチキャスト・フラグを無効にする**
`ifconfig <インターフェイス名> -multicast`

**全マルチキャストモードを有効にする**
`ifconfig <インターフェイス名> allmulti`

**全マルチキャストモードを無効にする **
`ifconfig <インターフェイス名> -allmulti`

### `ip`
**説明**…ネットワークデバイスやルーティング、ポリシーなどの表示と変更を行うコマンド(引用：http://www.atmarkit.co.jp/ait/articles/1709/28/news029.html)

**インターフェイスとマルチキャストアドレスのルーティングを確認**
`ip maddr`

### `route`
**説明**…IPパケットをルーティングするためのルーティングテーブルの内容表示と設定を行う(引用：http://www.atmarkit.co.jp/ait/articles/0111/01/news002.html)

**ルーティングテーブルに直接IPをルーティングする**
`route add -net <ルーティングするIP> netmask <ネットマスク> <インターフェイス名>`

### `nmcli`
**説明**…Network ManagerのCLIコマンド

**SORACOM SIMでインターフェイスを作成する**
`sudo nmcli connection add type gsm ifname ttyACM0 apn soracom.io user sora password sora`

**既存のインターフェイスに対して固定IPとデフォルトゲートウェイとDNSを振る**
`nmcli connection modify <インターフェイス名> ipv4.method manual ipv4.addresses <固定IP>/<サブネットマスク> ipv4.gateway <デフォルトゲートウェイ >  ipv4.dns <DNS>`

### `netstat`
**説明**：ネットワーク接続、経路テーブル、インターフェースの状態、マスカレード接続、 netlink メッセージ、マルチキャストのメンバーシップを表示する (引用：https://kazmax.zpp.jp/cmd/n/netstat.8.html)

**オプション**:
-g … インターフェイスに対応したマルチキャストグループが見られる

### `netcat`
**説明**：CLIで指定した場所にパケットを送る
`netcat -u <送信先IP> <ポート番号>`
上記の`-u`はUDPの意。

### `nmap`
**説明**…どのポートが空いてるかを確認できる。ポートスキャナー。外部サーバに対してやっちゃうと不正アクセス禁止法に抵触する恐れがあるらしいので気をつける。
`nmap <調査対象IP>`

同じネットワーク内で使用されているIPをみる
`nmap -sP 192.168.0.*`

## ファイアウォール
### `firewalld`
**説明**…ファイアウォール

**特定のポートを永続的に解放**
`firewall-cmd —add-port=<ポート番号>/<プロトコル> —zone=public —permanent`

### `ufw`
**説明**…ファイアウォール

**特定のポートを解放**
`sudo ufw allow <ポート番号>/<プロトコル>`

## ファイル
### `chmod`
**説明**…ファイル権限の変更

**オプション**:
u…所有者
+…選択したアクセス権を加える
x…実行権限
Rc.localが実行できるように権限を変更する
`chmod u+x /etc/rc.d/rc.local`
Google Assistantアプリで位置情報を取得する

Actions on Google ではパーミッションを適切に求めることで、
位置情報を初めとしたユーザーの情報を取得することが可能です。

# 大まかな流れ
大きく分けるとこんな感じです。

1. fulfillment で許可を求める処理を動かす
2. 許可を求めた結果を Intent で受ける
3. 取得した情報を自由にゴニョゴニョする


# 1. fulfillment で許可を求める処理を動かす
許可を求める処理はnpmパッケージの `actions-on-google` で定義されている `Permmision` クラスを用います。
`Permission` クラスはレスポンスの一種で以下のように記述します。

```js
import { Permission } from 'actions-on-google'

app.intent('TestIntent', conv => {
  const context = '「位置情報を使ってもいいですか」の前に喋ってほしい内容'
  const permission = ['DEVICE_PRECISE_LOCATION']

  conv.ask(new Permission({ context, permission }))
})
```

上記のコードを動かすと `TestIntent` に入った場合に、位置情報を取得していいかユーザーに質問するようになります。

位置情報以外の許可を求めたい場合はこちらを見てください。位置情報以外にもユーザー名などがいくつかあります。
https://developers.google.com/actions/reference/rest/Shared.Types/Permission


# 2. 許可を求めた結果を Intent で受ける
ユーザーに許可を求めた後は `actions_intent_PERMISSION` というイベントが発火しますので、それを Dialogflow で捕まえます。
新しいインテントを作り下図のように設定しましょう。

<img width="811" alt="confirm.png" src="https://qiita-image-store.s3.amazonaws.com/0/102044/2629a2ed-d8b2-4233-7432-bbd9b7445f6f.png">


許可を求めた情報は fulfillment からアクセスしますので、インテントの下部にある fulfillment の設定を Enable にするのを忘れずに。


# 3. 取得した情報を自由にゴニョゴニョする
2で示した画像と同じインテント名を付けていたら下記のコードで位置情報にアクセスできます。

```js
app.intent('PermissionConfirm', (conv, params, confirmationGranted) => {
  if (!confirmationGranted) { // ユーザーが承認したかどうか
    conv.close('位置情報が取得できませんでした')
  }

  console.log(conv.device.location) // 位置情報が入っているオブジェクト
  conv.close('位置情報が取得できました')
})
```

今回許可を求めた `DEVICE_PRECISE_LOCATION` の場合は `conv.device.location` の中に情報が入っていますが、
他のパーミッションの場合は `conv.user` など違う場所に情報が入っています。

下記のページにリクエストに含まれる情報は記載されていますので、許可を求めた情報に合わせて確認してください。
https://developers.google.com/actions/reference/rest/Shared.Types/AppRequest


# 注意点
一度聞いたパーミッションでも毎回許可を求めなくてはいけません。
名前など一度得た情報をユーザーごとに覚えておきたい場合は以下の二点を行う必要があります。

* アカウントリンキングでスキルを使っているユーザーを識別できるようにする
* Firestore などのどこかしらにユーザーの情報を保存する
PHPでSQLに接続して、データベースに登録した順番でコンテンツを全て表示する

```php
<!DOCTYPE html>
<html lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta name="keywords" content="XXX">
<meta name="description" content="XXX">
<title>XXX</title>
<link rel="stylesheet" href="/main.css">
</head>

<body>
<?php
try {
//DB名、ユーザー名、パスワード
$dsn = 'mysql:dbname=データベース名;host=サーバー名';
$user = 'ユーザー名';
$password = 'データベース接続のパスワード';

$PDO = new PDO($dsn, $user, $password); //MySQLのデータベースに接続
$PDO->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); //PDOのエラーレポートを表示
$sql = 'SELECT * FROM contents'; //SELECT文を変数に格納
$stmt = $PDO->query($sql); // SQLの命令文を実行し、結果を変数に格納

// foreach文で配列の中身を一行ずつ出力
foreach ($stmt as $row) {
    echo $row['name'];
    echo nl2br($row['description']); //nl2br関数でデータベース登録時の改行を反映する
}

} catch (PDOException $e) {
exit('データベースに接続できませんでした。' . $e->getMessage());
}

?>

<?php echo $rows; ?>
</body>
</html>

```
ド・モルガンの正体

ド・モルガンの法則
---
正体いっても、そんなにたいそうなモノではありません。ド・モルガンの法則について軽く解説しておきます。
論理回路を扱う上でド・モルガン言ったら、次のような意味です。

　**入力と出力を全部反転すれば、ANDとORは互いに置き換え可能**

例をあげると
![どもるがん](https://qiita-image-store.s3.amazonaws.com/0/136856/f48c80b1-35ae-d098-6698-d33a7ac0600a.jpeg)
こういう事です。
それぞれ、２つの入力と１つの出力がありますが、３つとも反転してANDとORを入れ替えると、その動作は最初と同じになります。

　※論理演算では二重反転（反転して、さらに反転する）は元に戻ります。０の反転の反転は必ず０、１の反転の反転は必ず１です。
自動テストがやりにくかったSQLServerに対して、CircleCIで自動テストをする道のり

# はじめに

弊社システムはAWSで動いているものやAzureで動いているものなど色々な物があります
今回は、Azureで動いているSQLServerについてとりあげてみたいと思います

# やりたいこと

単体テストをいっぱい書いたけど、SQLServerが個人の環境にしかないので、CI上でテストが通ることを確認したい

# SQLServerについて

+ imageはここから利用する
    + https://hub.docker.com/r/microsoft/mssql-server/

__注意点__

+ CircleCI上でWindowsを使うのは、ムリ
  + https://support.circleci.com/hc/ja/articles/115015871087-Windows-と-NET-のサポート

+ Linux版 は 2017 から
    + それ以前のものはない

# 実際の利用方法

```.circleci/config.yml
ersion: 2

jobs:
  build:
    docker:
      - image: microsoft/mssql-server-linux:2017-CU8
        environment:
          - ACCEPT_EULA: Y            # 認証をパスさせる
          - SA_PASSWORD: 1234abcD     # rootのパス
```

# 使ってみようとして気づいた事

あれ。。これ、立ち上げただけでDBないじゃん。。。。
プログラムから利用しようとしても出来ないじゃん。。。

# そんなわけでDB作成スクリプト

```php
<?php
$sql = <<<SQL
IF DB_ID(N'testing') IS NULL
  CREATE DATABASE testing;
SQL;

$username = getenv('DB_USERNAME');
$password = getenv('DB_PASSWORD');

$pdo = new PDO('dblib:host=localhost', $username, $password);
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

$pdo->query($sql);
```

# PDOで入れたので、SQLにつなぐライブラリもインストール

```yaml
- run: sudo ln -s /usr/lib/x86_64-linux-gnu/libsybdb.a /usr/lib/
- run: sudo pecl install sqlsrv-5.3.0 pdo_sqlsrv-5.3.0
- run: echo -e "extension=pdo_sqlsrv.so" | sudo tee /usr/local/etc/php/php.ini > /dev/null
- run: echo -e "extension=sqlsrv.so" | sudo tee /usr/local/etc/php/php.ini > /dev/null
```

うーん。結構面倒だった。。。
ループにまつわる高速化の話

プログラムを高速化したいときは、時間計測結果を元に戦略を立てるのが前提であるべきだと思うけど、傾向としてループ部分がクリティカルな状況はよくある。

1回だけ呼ばれる処理を100ms高速化するより、
100万回呼ばれる処理を0.01ms高速化する方が効果が大きくてハードルが低い（ことが多い）

平たく言えばこういうのをどう高速化するかの話。

```cpp
for(auto &&obj: objects) {
	obj.update();
}
```

実際にこう書くと速くなるというよりは高速化手法のバリエーションの話だと思って欲しい。
これ意味ないとか逆効果とかの指摘歓迎します。

# ループ内を高速化するアプローチ

`Object::update`内を速くするのが大前提なんだけど、一般的な議論は難しいのでよくある状況を書いとく。

## フラグチェックを外に出す

もしこんなコードがあったら

```cpp
void Object::update() {
	if(this->shouldUpdate()) {
		// updateの内容
	}
}
for(auto &&obj: objects) {
	obj.update();
}
```
これの方が無駄な関数呼び出しがない分速い（ことが多い）

```cpp
void Object::update() {
	// updateの内容
}
for(auto &&obj: objects) {
	if(obj.shouldUpdate()) {
		obj.update();
	}
}
```

加えて`shouldUpdate`関数を`inline`指定しておくと速い（ことがある）

```cpp
inline bool Object::shouldUpdate() {
	return is_awake;
}
```

## 実体を使う

下記は前者よりも後者の方が、ポインタのデリファレンス分有利。
実体で良いならそもそもポインタを使う設計にしてないと思うので、使う場面はほぼないとは思う。

```cpp
std::vector<Object*> objects;
for(auto &&obj: objects) {
	obj->update();
}
```
```cpp
std::vector<Object> objects;
for(auto &&obj: objects) {
	obj.update();
}
```


# ループ対象を厳選するアプローチ

`shouldUpdate`みたいなフラグがあるとしたら、それが`false`のやつはループから除外すれば良い。

- フラグチェックのコストが高い
- sleep状態（updateを呼ぶ必要がない）にして良いオブジェクト数が多い
- awakeとsleepの切り替わりが頻繁でない

など、フラグチェックよりもコンテナへの出し入れの方がコストが安い場合は有効（なことが多い）

```cpp
ObjectArray awakeObjects, sleepObjects;

void update() {
	for(auto &&obj: awakeObjects) {
		obj.update();
	}
}
void sleep(Object &obj) {
	awakeObjects.remove(obj);
	sleepObjects.add(obj);
}
void awake(Object &obj) {
	awakeObjects.add(obj);
	sleepObjects.remove(obj);
}
```


# ループ自体にかかるコストを減らすアプローチ

ループ内のコストが十分安いと、ループ自体にかかるコストが無視できなくなってくる。
例えばよくある

```cpp
std::vector<Object> objects;
for(int i = 0; i < objects.size(); i++) {
	objects[i].update();
}
```

みたいなコードだと`Object::update()`の他に

- `vec.size()`の呼び出し
- `i`と`vec.size()`の戻り値との比較
- `i`のインクリメント
- vector要素へのランダムアクセス

がループ回数分呼ばれるので、このあたりに無駄がないか考えてみると良い。

## コンテナを選ぶ

[[C++] STLの型の使い分け](https://qiita.com/h_hiro_/items/a83a8fd2391d4a3f0e1c)
この記事でほぼ話は終わってるので読むと良いと思います。

イテレーションの速度に関してだけいうなら、`vector`か`deque`を使っとくと良いと思う。

## 一度だけで良い処理はループから出す

これより

```cpp
for(std::size_t i = 0; i < objects.size(); ++i) {}
for(auto it = std::begin(objects); it != std::end(objects); ++it) {}
```

これの方が速い（ことが多い）

```cpp
for(std::size_t i = 0, end = objects.size(); i < end ++i) {}
for(auto it = std::begin(objects), end = std::end(objects); it != end; ++it) {}
```

よくあるこれも

```cpp
for(int y = 0; y < image.getHeight(); ++y) {
	for(int x = 0; x < image.getWidth(); ++x) {
	}
}
```

こうすると速くなる（ことが多い）

```cpp
int w = image.getWidth();
int h = image.getHeight();
for(int y = 0; y < h; ++y) {
	for(int x = 0; x < w; ++x) {
	}
}
```

# ループ回数を減らすアプローチ

これは半分冗談だけど、発想としてはあっても良いと思う。

## ループ内をひらく

```cpp
for(std::size_t i = 0, end = objects.size(); i < num; i += 4) {
	objects[i].update();
	objects[i+1].update();
	objects[i+2].update();
	objects[i+3].update();
}
```

## ループ頻度を減らす

```cpp
static std::size_t counter = 0;
const std::size_t skip_length = 4;
for(std::size_t i = counter%skip_length, end = objects.size(); i < end; i += skip_length) {
	object[i].update();
}
++counter;
```


# 再掲
これ意味ないとか逆効果とかの指摘歓迎します。
Go+GAE+外部MySQLで躓いたはなし

GAE上でGOを動かして、そこから外部のMySQLに接続するのに躓いたのでメモをしておきます。
どうやら、GAEからはSocketAPIなるものを使わないと外部には接続できないようです。
ローカルで動作しましたが、GAEにアップするとヌルポがでるので、最初はわかりませんでした。
解決コードはあっさりしてます。
importは省いています。
### サンプル
```go:sample.go（抜粋）
dsn :=  con.User + ":" + con.Password + "@external(" + con.Address + ":" + strconv.Itoa(con.Port) + ")/" + con.Name
dial := func(addr string) (net.Conn, error) {
  return socket.Dial(appengine.NewContext(r), "tcp", addr)
}
mysql.RegisterDial("external", dial)
db, err := sql.Open("mysql",dsn)
```
externalという名前のDialを作成し、mysqlに登録するだけです。
DSNではいつもは、@tcpとなるところが登録名@externalになるだけです。

Go+GAEではvendor関係とかつまづきまくっていますが、総じてGo言語の生産性と実行速度は十分に満足がいくものです。

###追加
Go1.11でなんとかなるかもしれないので、今度試してみます
https://github.com/gcpug/nouhau/tree/feature/id/76/app-engine/note/gaego19-migration-gaego111
【Flow】Object.valuesでエラーです


## 現象

`Object.values`を使った場合、返り値が`Array<mixed>`だとflowに認識されてしまいます。

```jsx
const obj = {
  data: {
    title: 'hoge',
    label: 'fuga',
  },
}

const fromValue = Object.values(obj).map(data => console.log(data.title)); // fails
```

## 解決法
`Object.keys`を使用するとでエラーを回避できます

```jsx
const fromKeys = Object.keys(obj).map(key => console.log(obj[key].title)); // works
```

（[Try Flow](https://flow.org/try/#0PQKgBAAgZgNg9gdzCYAoAxnAdgZwC5hwBGAVmALxgDeqYYAJgIZ6MBc1tdYeAlnjAFN2AcgAWcAOYDhAGk50YjIgJgioAVwmNZnAL5zdqDNnxgoAJzgBbAGqMY6gRTAB5UgPR4AdADd7jnAAKYhIASi8rRgAHQKYWCgA+MExcOEEveAlY5kYvXn4BUNCAbjBgYDNGHhgcY1wCC2sAaQEATxxnNxIPbwBrNqCQ8MiY-tbE5JM0gQzJYNIAbTGAXTy+QSLS8rAEOHNenCA)で実際に動かしてみてください）

reactで以下の様に`Object.values`を使うときは、

```jsx
  {Object.values(obj).map((data) => (
    <CustomContainer
      title={data.title}
      label={data.label}
    >
  )}
```

`Object.keys`に置き換えたらFlowエラーがでなくなります。

```jsx
  {Object.keys(obj).map((key) => (
    <CustomContainer
      title={obj[key].title}
      label={obj[key].label}
    >
  )}
```

### 参考資料
- [Object.values() doesn't take into account indexed properties : no inference + type error · Issue #4771 · facebook/flow](https://github.com/facebook/flow/issues/4771)
#2 PostgreSQL on Kubernetesが目指すところ

本記事は[PostgreSQL on Kubernetes Advent Calendar 2018](https://qiita.com/advent-calendar/2018/postgresonk8s)の2日目です。
昨日は「[データベース on Kubernetesの現在地点](https://qiita.com/tzkoba/private/1847d4ff138ca823fb08)」ということで、Kubernetesの現状とデータベースの対応状況を整理しました。
本日は今回主題として取り上げるPostgreSQL on Kubernetesの具体的構成と目指すところについて書きたいと思います。

# TL;DR
+ PostgreSQL on Kubernetesって複雑すぎない？
+ データの冗長化はストレージレイヤで。
+ PostgreSQL on Rookの紹介。

# 問題点：現在のPostgreSQL on Kubernetes
昨日は事例として[Stolon](https://github.com/sorintlab/stolon)をご紹介しました。
同様の事例として、[Crunchy DataのPostgreSQL on Kubernetesの事例](https://www.crunchydata.com/products/crunchy-postgresql-for-kubernetes/)があります。

これらはいずれもPostgreSQLのレプリケーション機能を用いて、1台のmasterと2台以上のstandbyをKubernetes上に展開しています。
これらの構成のメリットとして、以下があげられるでしょう。

+ 複数DBインスタンスによる耐障害性の確保
+ standbyのスケールアウトによる読み取り性能の向上

しかし、一方で問題点として複雑な構成（＝**障害ポイントの増加**）とそれによる運用性の低下があげられると思います。

[Vitess](https://vitess.io/)の例も挙げましたが、Youtubeほどスケールさせる必要は多くのシステムでないでしょうし、リードレプリカさえ必要ないというシステムも多いでしょう。

# PGEconsが提示するPostgreSQLの代表的な構成
少し古い資料になりますが、PGEconsという団体が「[PostgreSQLの代表的な構成](https://www.pgecons.org/wp-content/uploads/PGECons/2013/WG3/pgecons-wg3-2013-report.pdf#page=22)」を整理しています。

この中でまとめられているのは、大きく分けて以下の5つのパターンになります。

1. シングルサーバ構成
2. HAクラスタ構成（共有ストレージ方式）
3. HAクラスタ構成（シェアードナッシング方式）
4. ストリーミングレプリケーション
5. pgpoolやSlony-Iを利用したソフトウェアレプリケーション

StolonはいわばKubernetesと上記の4.を合わせた構成です。
PostgreSQLのレイヤでデータの冗長性を担保しています。

しかし、**より低レイヤで冗長性を担保し、よりシンプルな構成を取ることは出来ないのでしょうか？**
つまり、上記の2.や3.とKubernetesを掛け合わせた構成は取れないのでしょうか。

# PostgreSQL on Rookの実装
今回、Kubernetes上にシェアードナッシング型の分散ストレージである[Rook](https://rook.io/)を稼動させ、それをPostgreSQLのストレージとして利用する方式を検討してみました。

![pg-rook-archi.PNG](https://qiita-image-store.s3.amazonaws.com/0/54853/512b503b-9488-ed53-5523-785535430f4b.png)

上図にあるようにPostgreSQL自体は単純なStatefulSetとしてスケジューリングされ、他にoperatorなどを必要としません。
詳細は後日説明しますが、RookによってデプロイされたCeph RBDのボリュームをPVとしてマウントすることで、データの冗長性を担保します。

RookやCephを含むこと自体がシンプルなのか？という疑問はあると思いますが、複数DBインスタンス間でプロモーション時の調停が不要になるなど、メリットは大きいと考えます。

もちろん、現時点ではジャストアイデアで実際の稼動イメージを抱くには検証が必須ですが、それを今回のAdvent Calenderで少しずつ紹介していければと思います。

# まとめ
昨日に引き続き、今回も概念的な話が多くなりました。
明日からは今回お話しする構成に必須の、Rookを稼動させる準備をしていきたいと思います。

よろしくお願いします。
[Node.js][PM2] Vagrant 共有フォルダのファイルを watch する方法

宮崎在住エンジニアのジョウ(@JotarO_Oyanagi) です。

Vagrant を Node.js の実行環境として使用していて、ホットリロードとして PM2（Node アプリをデーモン化してくれる）の watch を使う場合、普通の設定だとホットリロードが効かないので、その解決策メモです。

# TL;DR
- 環境：centos 7.5, node 8.11.4
- `pm2 start ` を **ecosystem.config.js** または **config.json** を使用して実行
- **watch_options** に `usePolling: true` を設定

# 書き方の例

```javascript:ecosystem.config.js
module.exports = {
  apps : [{
    name: 'MyApp',
    script: 'app.js',
    watch: true,
    watch_options: {
      usePolling: true
    },
    env: {
      NODE_ENV: 'development',
      name: 'MyApp_dev',
      PORT: 3000,
      TZ: "Asia/Tokyo"
    }
  }]
};
```

```json:config.json
{
  "name": "MyApp",
  "script": "./app.js",
  "watch": true,
  "watch_options": {
    "usePolling": true
  },
  "env": {
    "NODE_ENV": "development",
    "name": "MyApp_dev",
    "PORT": 3000,
    "TZ": "Asia/Tokyo"
  }
}
```

これだけです。カンタンですね！

# 終わりに

色々探し回った結果、これだけでよかったのかよ！という複雑な気持ち。
SwiftのEnum型のrawValueが使えない時

#Enum型のrawValueが使えない!?
SwiftでEnumを使用している時にrawValueを使用して生の値を取得しようとしてもエラーが出て生の値を取得できず困っていたことがありました。
つまるところはObjective-CやC言語からの癖のせいによる記述漏れでした。

##rawValueが使えないコード
以下のように記述しても、「rawValueなんてメンバーいないよ」ってエラーで怒られます

```
enum enums
{
    case one, two, three
}

func hoge()
{
    var value:enums = .three
    print("\(value.rawValue)")//Error:Value of type 'enums' has no member 'rawValue'
}
```

##rawValueが使えるコード
以下のように編集すると、エラーが消えます。

```
enum enums:Int
{
    case one, two, three
}

func hoge()
{
    var value:enums = .three
    print("\(value.rawValue)") // -> 2
}
```
enumsに型としてIntを指定しているのがミソ。
SwiftではEnumにStringが指定できたりと、いろいろ拡張されているみたいで、それが影響して型未定義だと内部の情報が決まらず、rawValueで生の値にアクセスできない感じなのでしょうか。
【Linux】先頭にハイフン（-）がついたディレクトリやファイルを消す(操作する)方法

間違えて

-p

っていうディレクトリを作ってしまいエスケープの仕方がわからなくて泣いてたのです。


## 解決方法


```shell
rm -r -- -p
```

コマンドの途中で
`--`

とうつと、それ以降のハイフンはパラメータとして認識されない模様。

長い間linuxと戯れてきたつもりですが知らなかったのでメモしておくのでした。
【WP-Members】 radioの値がアップデートできません

現在WP-Membersを使用しており、「wp_update_user」の機能を使って
フィールドの値のアップデートを試みています。
項目には「text」や「radio」等があり、「radio」の値がアップデートできず困っております。
![radiobutton.PNG](https://qiita-image-store.s3.amazonaws.com/0/320524/18db6978-5917-ad43-715e-93e01ff89847.png)


textの値を更新する際には、以下のようにphpから命令すると上手くいきます。

    $test = array ( 'ID' => $id,'first_name' => $first_name);

しかし、radioの値を更新しようとすると上手く行きません。。

    $test = array ( 'ID' => $id,'plan' => $plan);
$plan はStringの値です。

[planの設定][1]

  [1]: https://i.stack.imgur.com/RJIGa.png

どのようにすれば「radio」の値をアップデートできるのでしょうか?
BigQuery – 過去のクエリが見つからない？探したい？ QueryHistoryから検索できるぞ！

# 全然知らなかった！

何やら便利そう。

# 旧UIの例

なにやらタグ式っぽい。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/89618/0b282c55-128f-a887-5185-41d5e43a0f4f.png)








<!-- Update From Qiita API -->

# チャットメンバー募集


何か質問、悩み事、相談などあればLINEオープンチャットもご利用ください。

https://line.me/ti/g2/eEPltQ6Tzh3pYAZV8JXKZqc7PJ6L0rpm573dcQ





# Twitter


https://twitter.com/YumaInaura


<!-- Update From Qiita API -->
EgretEngine Signupできない

#現象

2018/11/26-27現在、EgretLauncherを新規にダウンロード

EgretLauncherからサインアップすると以下のエラーがでます

![image.png](https://qiita-image-store.s3.amazonaws.com/0/302078/4081584f-8826-bcbf-5ba8-df4e963a410b.png)

#対応
## Webサイトで登録
http://account.egret.com/sso/register

## メールアドレスを認証

## EgretLauncherにログイン