OmniAICreator/Qiita-1.07M huggingface dataset:
Azure Data Factory のパイプラインにAzure Node SDKからパラメータを渡す方法

## 本記事について
Azure Node SDKを使ってAzure Data Factoryのパイプラインを実行する際に、実行パラメータを渡す方法について記載しました。

## はじめに
Data Factoryのパイプライン実行は、「DataFactoryManagemantClinet」オブジェクトの「pipelines」メンバーの「createRun」メソッドで行います。

しかし、リファレンスを見ても、「createRun」のパラメータは「options?: Object」としか書かれておらず、具体的な渡し方に関する記載がありません。

- https://docs.microsoft.com/ja-jp/javascript/api/azure-arm-datafactory/pipelines?view=azure-node-latest#createrun-string--string--string--object-

```typescript
function createRun(resourceGroupName: string, factoryName: string, pipelineName: string, options?: Object)
```

実際は、パラメータをJSONでoptionsに入れるだけではダメで、下記の手順が必要になります。

## 手順
- ``createRun()``の4番目の引数「options」の「parameters」要素にパラメータをJSONで渡す
- 「parameters」の各パラメータ値はJavaScriptのオブジェクトで渡す

具体的なパラメータの渡し方は下記のような感じになります。

```javascript
// パイプラインパラメータ
const params = {
    val_str: new String('パラメータ値'),   // 'パラメータ値' だけだとダメ
    val_number: new Number(123)  // 123 だけだとダメ
};

const result = await client.pipelines.createRun(
    RESOURCE_GROUP_NAME,
    DATA_FACTORY_NAME,
    PIPELINE_NAME,
    {
        parameters: params
    }
);
```

**「parameters」の各パラメータ値はJavaScriptのオブジェクトで渡すとは？**

パラメータの値は文字列なら「パラメータ値」、数値なら「123」といった直値ではダメで、文字列ならStringオブジェクト、数値ならNumberオブジェクトとしてセットする必要があります。

## 元記事
- [Azure Data Factory のパイプラインにAzure Node SDKからパラメータを渡す方法](https://www.kwbtblog.com/entry/2018/11/28/020431)
とりあえず動くDraft.js

#はじめに
Draft.jsを使うとリッチテキストエディタを簡単に作れるらしいです。
ただ npmがどうのこうの…とか、とりあえず試したい人には余計な情報が多すぎるので、とりあえず動くサンプルコードを置いておきます。

#コード
適当にコピペしてください。

```html:index.html
<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8" />
    <title>Minimal Draft.js</title>

    <script src="https://unpkg.com/react@16/umd/react.development.js" crossorigin></script>
    <script src="https://unpkg.com/react-dom@16/umd/react-dom.production.min.js" crossorigin></script>
    <script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/immutable/3.8.2/immutable.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/draft-js/0.10.5/Draft.min.js"></script>
  </head>
  <body>
    <div id="app"></div>

    <script type="text/babel">
      // 本来は別ファイルに書く
      const {Editor, EditorState} = Draft;

      class MyEditor extends React.Component {
        constructor(props) {
          super(props);
          this.state = {editorState: EditorState.createEmpty()};
          this.onChange = (editorState) => this.setState({editorState});
        }
        render() {
          return (
            <div>
              <h1>Minimal Draft.js</h1>
              <Editor editorState={this.state.editorState} onChange={this.onChange} />
            </div>
          );
        }
      }
      ReactDOM.render(
        <MyEditor/>,
        document.getElementById('app')
      )
    </script>
  </body>
</html>
```

#おしまい
詳しいことは他を当たってください。<br><br>

####おまけ
CDNを使うとき、アクセス先が HTTPレスポンスヘッダに `Access-Control-Allow-Origin : *`とかいうのを持っていないとブラウザではじかれます。なぜかReactのチュートリアルで使われてる`https://unpkg.com/react-dom@16/umd/react-dom.development.js`はダメだったので、`https://unpkg.com/react-dom@16/umd/react-dom.production.min.js`を使っています。
アンケート調査で「全体の比率」と「一部の比率」の差の検定（有意差検定）を行うプログラム

# はじめに
アンケート調査をしたことはありますか。
そして「そのアンケート結果って__有意に__差があるの？」と言われたことはありますか。

### 問題
例えばランダムに集めてきた男女100人にアンケートを取って、
そのうち30人が「このサービスに満足した」と答えたとしましょう。
全体のサービス満足率は__「30％」__となります。

またその100人のうち、男性が50人いて、そのうち男性10人が「満足した」と答えた場合、
男性のサービス満足率は__「20％」__ですね。

さて、__全体の「30%」__と、そのうちの__男性の「20%」__は、
有意な差があるといえるでしょうか。


# 理論
全体のサービス満足率について改めて考えてみます。

100人のうち「30%」が満足したといっても、
改めてアンケート回答者を集めてくるところからもう一度やり直すと…

次は満足率「36％」という結果になるかもしれません。
もしかしたら「25%」になるかもしれません。

標本調査である以上仕方ありませんが、
「30%」という数値には本質的にばらつきが隠れています。

### このばらつきをどう扱うか？
アンケートを何回もやり直した時のばらつき方ですが、
これは中心極限定理により正規分布というものに従ってばらつきます。

その前提と、今回のサンプルサイズ（100人）および割合（30%）から、
「標準誤差」というものを求めることができます。


標準誤差を求めることで、
「信頼度95%の場合、このサービスに満足した人は30±9%いたと思われる」
といった形で全体のサービス満足率を表現できます。

この「30±9%」の範囲が男性の「20%」とかぶっているかいないかで、
「全体の比率と一部（男性）の比率は有意に差があるか」を判定することが出来ます。
この例だと、「30±9％」と「20％」はかぶってないので、
「信頼度95%で有意に差がある」という結論になります。

この信頼区間を毎回求めて、かぶっているかどうかを毎回見るのもいいのですが、
先人はその判定を一撃で行うために、__「統計量T」__という、
一部の割合が全体の信頼区間内に入っているかどうかを計算するのと
同等の意味の式を編み出しました。

### 統計量T
$T=\dfrac {\left| p-p_{1} \right| }{\sqrt {p\left( 1-p\right) \dfrac {n-n_{1}}{n\times n_{1}}}}$[^1]


$n$は全体のサンプルサイズ、$p$は全体の比率、
$n_1$は一部のサンプルサイズ、$p_1$は一部の比率とします。
※上の例なら、$n$は100人、$p$は0.3、$n_1$は50人、$p_1$は0.2。

この統計量Tは
__「pとp1に本来差がない場合」__は中心極限定理により正規分布するので、
この統計量Tが棄却限界値1.96以上であれば、
「この事象は正規分布の端っこの（異常な）出来事だ」ということになり、
結果として「95%の信頼度で有意に差がある」といえます。

ややこしいので一言でまとめると、
> $T\geq 1.96$ ならば95%の信頼度で有意に差がある

です。

# コード
```ztest-type4.py
import sys
import math

def error_usage():
    sys.stderr.write("usage: " + sys.argv[0] + "\n")
    sys.stderr.write("\tこのプログラムは、4つの引数が必要です。\n\n")
    sys.stderr.write(
        "\t1.全体のn数 2.全体における比率 3.ある属性のn数 4.ある属性における比率\n")
    sys.stderr.write("\t例： 150 0.3 100 0.45\n\n")
    sys.stderr.write("\tただし、それぞれn数は30以上かつ比率pは[0<=p<=1]を満たすこと\n")
    sys.stderr.write("\t「1.全体のn数」は「3.ある属性のn数」より大きいこと\n")
    sys.exit(1)

# 引数がちょうど4つあるか？
if len(sys.argv[1:]) != 4:
    error_usage()

n,p,n1,p1 = map(float, sys.argv[1:])

# n数が30以上か？（n数が少なすぎないか？）
if (n < 30) or (n1 < 30):
    error_usage()

# nはn1より大きいか？
if n < n1 :
    error_usage()

# 比率は0から1の間か？
if not (0 <= p <= 1) or not (0 <= p1 <= 1):
    error_usage()

T = math.fabs(p - p1) / math.sqrt((p * (1-p)) * (n - n1)/(n * n1))

if T >= 2.58:
    print("1%有意 (検定統計量:" + str(T) + "）")
elif T >= 1.96:
    print("5%有意 (検定統計量:" + str(T) + "）")
elif T >= 1.65:
    print("10%有意 (検定統計量:" + str(T) + "）")
else:
    print("有意差なし")
```
このプログラムは、5%有意だけでなく、1%有意かどうか、10%有意かどうかも判定します。
ローカルに保存して実行してみましょう。
https://github.com/tochiji/ztest-type4/blob/ea4d5da26650ea0824a90c9ec3f964b297887b13/ztest-type4.py

# 結果
```
$ python3 ztest-type4.py 100 0.3 50 0.2
5%有意 (検定統計量:2.18218)
```
このコードをいつでも実行できるようにしたり、
シェルスクリプト化することで、あなたもすぐに検定ができるようになります。
よい検定ライフを。

### 補足
この検定は「母比率の差の検定／タイプ4」と言われたり、
「一部従属な比率の差の検定」と言われたりします。
あくまで「全体」とその「一部」の割合の差を比べるものなので、
例えば「男性」と「女性」といった、従属関係にないサービス満足度を比較するときは、
また別の統計検定量Tを使用する必要があります。
→[けものフレンズ1期の第一話は、2期の第一話より有意に面白いのか](https://qiita.com/tochiji/items/782b5ca7bd1f0e1c9ecc)
[^1]: どうやってこれを導出するかはどこかで別途…
インデックスやリンクの"はる"は「張る」か「貼る」なのか

# はじめに
社内用のナレッジベースに"インデックスを張る"って書いたわけですが、"はる"という漢字は「張る」なのか「貼る」なのかと思って調べてみたわけです。

このような記事を今更書かなくても検索すればすぐに見つかりますが、そこをあえて書く。
過去記事でも言葉について書いていたりします。

* [必須と必要の違い](https://qiita.com/yaju/items/cccc4753ffefe41a8e12)
* [なぜ「小数点」を「少数点」と間違えるのか](https://qiita.com/yaju/items/be04219f8e0871df1306)
* [押下(おうか)にまつわる話](https://qiita.com/yaju/items/0ceb6a0343561b4d208e)

# 漢字の意味
## 張る
もともとは、「とばり」(寝台の周囲に張り巡らす蚊帳のようなもの)引き延ばしてはる。
イメージとしてはピンと伸ばして固定する

例 足場のシートを張る

## 貼る
べったりとはりつける。へばりつく。
イメージとしては糊でくっつける

例 切手を貼る

### 常用漢字に新規採用
平成22年(2010年)の常用漢字表の改正で「貼」が追加されました。
それまでは常用漢字ではなかったため、ほとんどの新聞では「貼」が使われず代わりに「張」またはひらがなにして使用されていたようです。

コンピューター上のGUIの「ペースト」を和訳で「貼り付け」としたのは常用漢字を無視したことになります。

常用漢字といえば、function の和訳は「函数」でしたが当時は常用漢字でなかったため、「関数」になりました。数学者とかは本来の「函数」を使っていたりします。
[関数の語源](https://qiita.com/yaju/items/d9b8de8414e495f9e289)

# どっちを使うのか
一般的には「張る」を使うのが正しいといえます。

インターネットはWorld Wide Webを略して「web」と言ったりします。 また「web」自身が単語で・織物・くもの巣・くもの巣状のものといった意味があります。世界に広がっているネットワークをくもの巣に例えているわけです。
蜘蛛(クモ)が巣を"はる"は、「張る」を使います。
よって、リンクをはるは「リンクを張る」となります。

では、「貼る」を使うのは正しくないのかというと用法によっては正しいです。
例えばブログなどを書いていて文章上にリンクを貼り付ける場合は、「リンクを貼る」となります。
コンピューター上のGUIを使用した作業上の説明をする場合、画面上に糊付けするイメージがありますから「貼る」を使用するのがいいでしょう。

データベースのインデックスも「インデックスを張る」となります。
先程のリンク同様にコンピューター上のGUIを使用した作業上の説明では「インデックスを貼る」を使用すればいいでしょう。

# 最後に
現代の人はコンピューター上のGUIの「ペースト」の和訳である「貼り付け」のイメージが強いので「貼る」を使用したくなるのですが「貼る」はそれほど用語として使用されません。
相場を張るや強情を張るなど「張」が使われますし、強いて言えば「レッテル貼り」が「貼」を使いますが、これはもともと商品に貼りつけるラベルのことをさす言葉で、レッテルはオランダ語(letter)からきています。

2010年の常用漢字表の改正でやっと追加されたのもコンピューターの普及の影響が大きいからでしょう。迷ったら「張る」を使用すればいい。
「自分に合ったサイズのIssue」を見つけたら、OSS初心者でもコントリビュートできた

# 概要
OSSにコントリビュートしたことがない私が、「自分に合ったサイズのIssue」を見つけ、人生初のコントリビュートをするまでの話

# 準備編

「OSSにコントリビュートしてみよう！」と思い立った私は、自分でもコントリビュートできそうなIssueを探すことにした。
しかし、膨大なIssueのなかから、そのようなIssueをどうやって見分ければいいのか。

## 初心者向けのIssue

OSS関連の記事をいくつか読んで分かったのは、初心者向けのIssueには、それとわかるラベルが貼られているというこだ。
good first issue(初めてに最適)、difficulty:easy(難易度:簡単)といったような。

このような「初心者向けのIssueに貼られるラベル」を調査し、Qiitaにまとめてみた。
[【OSS貢献】初心者向けのGitHub Issueに貼られるラベルまとめ](https://qiita.com/a-r-i/items/e21683ba8936fe965339)

## いざ、Issueを探す
「初心者向けのIssueに貼られるラベル」が分かったので、次に、具体的なIssueを探すことにした。

[Github Help Wanted](http://github-help-wanted.com)は、プログラミング言語とラベルでIssueを絞り込むことができるサービスだ。
これを使って、「Python(馴染みのある言語)」「good first issue」でIssueを検索する。

<img width="950" alt="スクリーンショット 2019-01-29 17.39.39.png" src="https://qiita-image-store.s3.amazonaws.com/0/133133/af81906b-d3fa-f674-ce91-934b3da11a83.png">


## さらにふるいにかける
結果、「good first issue」のラベルが貼られた大量のIssueを見つけることができた。

ここからさらに、以下のような基準でふるいをかける。

- タイトルや説明を理解できるか？
- Issueを解決できそうか？

Issueの内容は千差万別で、自分に合ったサイズ感のものを選別する必要があるからだ。

## 「自分に合ったサイズのIssue」を見つける
最終的に、私はこのIssueを選んだ。

Add requirements.txt · Issue #66 · UEWBot/dipvis
https://github.com/UEWBot/dipvis/issues/66

<img width="928" alt="スクリーンショット 2019-01-26 16.39.40.png" src="https://qiita-image-store.s3.amazonaws.com/0/133133/39cf064d-7ad3-d94c-34ef-1a204ce30425.png">

requirements.txtとは、Pythonのパッケージ管理システムpipの設定ファイルだ。

プロジェクトで使用するパッケージの名前とバージョンをrequirements.txtに書き、以下のコマンドを実行すると、一括でパッケージをインストールすることができる。

`$ pip install -r requirements.txt`

このプロジェクトにはまだrequirements.txtがないので、それを作成し追加することが、このIssueの内容だった。

# やってみる

## コメントで確認
作業に取り掛かるまえに、コメントで「このIssueを引き受けていい？」と確認した。
<img width="773" alt="スクリーンショット 2019-01-27 18.47.34.png" src="https://qiita-image-store.s3.amazonaws.com/0/133133/6afe5d2c-3601-6fda-5ec9-5cfe35cb8c4a.png">

## 作業
OKが出たので、requirements.txtを作成・追加する。
(本Issue固有の処理なので、作業の詳細は省く)

## Pull Request
作業が終わったのでPull Requestを出す。

Pull Requestの手順はこちらが詳しい
[初めてのpull request @ GitHub](https://rcmdnk.com/blog/2013/05/19/computer-git-github/)

## Merge
無事Mergeされ、私の初めてのコントリビュートが終わった。

<img width="778" alt="スクリーンショット 2019-01-29 17.32.03.png" src="https://qiita-image-store.s3.amazonaws.com/0/133133/55f55221-8a08-400a-8b06-1dc2e31ff15c.png">

# まとめ
顔の見えない、機械翻訳なしには言葉も通じない、(おそらくは)海の向こうにいる開発者とのコラボレーションは、インターネットのダイナミクスが感じられる素晴らしい体験だった。

もし、あなたが技術的・心理的な壁に阻まれ、一歩目を踏みだせずにいるなら、私のような方法で「自分に合ったサイズのIssue」を探してみてはどうだろう。
【NCMB】mbaasでデータストアを検索してみた

# 目的
- [前の記事](https://qiita.com/dragonnn/items/38a0228f27cbcdae8d53 "前の記事")にてNCMBでデータストアの登録が出来たので次は検索をやろう。

# クエリを作成しよう

```java
//クエリの作成(データストアのクラス名指定)
final NCMBQuery<NCMBObject> query = new NCMBQuery<>("Testclass");
//データストアのmessageカラムに"ドラゴン"があるか検索
query.whereEqualTo("message", "ドラゴン");
```

# クエリを使って検索しよう

```java
//データ検索
query.findInBackground(new FindCallback<NCMBObject>() {
    @Override
    public void done(List<NCMBObject> list, NCMBException e) {
        if(e != null){
            Toast.makeText(context, "検索エラー。", Toast.LENGTH_LONG).show();
        } else {
            if(list.isEmpty()){
                Toast.makeText(context, "データストアに存在しません。", Toast.LENGTH_LONG).show();
            } else {
                Toast.makeText(context, "データストアに存在します。", Toast.LENGTH_LONG).show();
            }
        }
    }
});
```

# 動作確認
![スクリーンショット 2019-01-30 0.38.42.png](https://qiita-image-store.s3.amazonaws.com/0/344952/2a0c0052-e7f0-730d-cad2-b4005a7dd6dd.png)
![Photo_19-01-30-00-41-11.241.png](https://qiita-image-store.s3.amazonaws.com/0/344952/1aed8576-7470-62b3-56b9-bf835a29ffb4.png)
![Photo_19-01-30-00-41-09.358.png](https://qiita-image-store.s3.amazonaws.com/0/344952/fe938cab-38b7-cb2e-66a0-6e00baa37393.png)

# ソース

```java:MainActivity.java
public class MainActivity extends AppCompatActivity {
    //NCMBにて取得したAPIKEYを記載
    private final String app_key = "hogehoge";
    private final String client_key = "hogehoge";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        //SDKの初期化
        NCMB.initialize(this.getApplicationContext(),app_key,client_key);
        //クエリの作成(データストアのクラス名指定)
        final NCMBQuery<NCMBObject> query = new NCMBQuery<>("Testclass");
        //データストアのmessageカラムに"ドラゴン"があるか検索
        query.whereEqualTo("message", "ドラゴン");
        final Context context = getApplicationContext();
        Button button = findViewById(R.id.button);

        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //データ検索
                query.findInBackground(new FindCallback<NCMBObject>() {
                    @Override
                    public void done(List<NCMBObject> list, NCMBException e) {
                        if(e != null){
                            Toast.makeText(context, "検索エラー。", Toast.LENGTH_LONG).show();
                        } else {
                            if(list.isEmpty()){
                                Toast.makeText(context, "データストアに存在しません。", Toast.LENGTH_LONG).show();
                            } else {
                                Toast.makeText(context, "データストアに存在します。", Toast.LENGTH_LONG).show();
                            }
                        }
                    }
                });
            }
        });
    }
}
```
# まとめ
登録と検索が出来るようになったので、次はランキング実装しよう。
【Unity】初心者を潰すAll compiler errors～に遭遇して詰みかけました【初心者記事】

　出だしの文章ってなかなか考え難いですよね。
　私は一時期ブログで収入を得ていたことがあるのですが、出だしの文章で悩むことが多かったなぁと思い出しました。

　
　さて。

　
　皆様は「All compiler errors have to be fixed before you can enter playmode!」というエラー表示に遭遇した経験はありますでしょうか？　ありますよね、下手したら親の名前より見た文字列という方もいらっしゃるかもしれません。
　
　もちろん私も何度か遭遇したことがあるのですが、今回のコヤツの解決には少し手間取ってしまったので、ここに理由を載せておきます。
　少しでも、ここに辿り着いた同じUnity初心者の手助けになれば幸いです。


#遭遇

　インフルエンザでしばらくゲームの開発を休止し1週間、体調も回復してきたのでいざUnity！　と思いとりあえずゲームを実行してみた際にコヤツが現れました。
　今までの経験では純粋なコードエラーだったので、コンポーネントされているスクリプトにエラーが出ていないかチェック……しかし、**出ない！**

 **エラーが出ないのにエラーが出ている！**

　お、落ち着け、まだ慌てる段階じゃあない。再起動を試さずにして投了を宣言するのは愚の骨頂！　再起動！
　結果……

**エラーが出ないのにエラーが出ている！++**

 一体どうしたものやら。


#解決
　
　All compiler errors have to be fixed before you can enter playmode!を訳すと、「全てのコンパイルエラーを直してからプレイボタンを押してね」という感じである（大体合っているハズ

　この『全て』が今回では鍵となった。

　実はインフルエンザを発症しながらもゲーム開発をしていた時があったのだが、その際に作成したスクリプトが思うように動かなかったため、適当な所（エラーばりばり出る）で保存していたのだが、どうやらこれが原因だったらしい。

　もちろんこのスクリプトはどのオブジェクトにもコンポーネントしておらず、ゲームの動作上で使用されることは無いのだが、それでもAll compiler errors～が発生する条件に当て嵌まってしまった。

　**全てとは、文字通り全てだった！　使ってる使ってない関係ない！**

　このスクリプトを削除すると、ゲームは予定通り動作してくれた。


#雑記

　いやぁ、まさか一切使ってないスクリプトのエラーも治す必要があるとは。
　ゲーム制作の時間が飛んでしまったということもあり、失敗スクリプトを削除するまでに時間を要しました(30分くらい)

　今後は気を付けていきたいですね。

　SNSで見た金言の1つに「エラーはプログラマにとって実績のようなもの、解除すればどうということはない」というのがありまして。
　きっと今後の私はこのパターンのエラーには悩まされないでしょう！　日々成長だ！！

　それでは～！
最新のWordpressのDocker環境が利用できない

2019年1月29日時点の話。

次のコマンドのように、latestのバージョンを指定すると、なぜかwordpress側のコンテナが自動的に停止してしまい、管理画面にアクセスができませんでした。

```
docker run --name wordpress-db -e MYSQL_ROOT_PASSWORD=admin -d mysql
docker run --name wordpress --link wordpress-db:mysql -p 8080:80 -e WORDPRESS_DB_PASSWORD=admin -d wordpress
```

下記のサイトを参考に、安定版と呼ばれる「5.0.3」が動くようにタグを指定してみたところ解決しました。
<https://xakuro.com/blog/wordpress/1299/>

```
docker run --name wordpress-db -e MYSQL_ROOT_PASSWORD=admin -d mysql:5.5
docker run --name wordpress --link wordpress-db:mysql -p 8080:80 -e WORDPRESS_DB_PASSWORD=admin -d wordpress:5.0.3-php7.3-apache
```

原因も理由もわかっていませんが、同じ境遇の人がいれば参考にしていただければ。
【AndroidStudio】Device supports x86, but APK only supports armeabi-v7a

#エラー
**Device supports x86, but APK only supports armeabi-v7a**

#現象
とあるプロジェクトにて、`アプリをエミュレータで起動しようとしたとき`に出てきた謎のエラー。
「実機ではちゃんと動いてんだけど」と思いながらエラー文を読んでみると、`デバイスはx86をサポートしてるけど、APKはarmeabi-v7aしかサポートしてないよ`的なことが書かれてる。armeabi-v7aてなんぞ？
<img width="441" alt="スクリーンショット 2019-01-29 23.53.31.png" src="https://qiita-image-store.s3.amazonaws.com/0/252756/acdec496-bcd9-ae18-8618-6a663af12755.png">


#解決
いろいろ調べたら、つないでるUSBの用途を充電からファイル転送に変更するとか、デバッグモードのオンオフを切り替えるとかで解決した人がいるっぽい。でも今回、実機じゃないのよね。

なんやかんやで`build.gradleのabiFiltersにx86`を追加して解決。楽チン。

```gradle
ndk {
    // armeabi-v7aがサポートされてたのはここに記述されてたから
    abiFilters "armeabi-v7a", "x86" // ついでにx86を追記
}
```

#どゆこと？
解釈通り、`デバイスはx86をサポートしてるけど、APKはarmeabi-v7aしかサポートしてないよ`ってこと。
armeabi-v7aは、ARMのEABIのバージョン7（Embedded Application Binary Interface Version ７）。
abiについては[ここ](https://developer.android.com/ndk/guides/abis)。
このエラーはx86プラットフォームのネイティブライブラリが生成されないことで起きるエラーらしい。
つまり、デバイスがサポートしてるx86用のコードを作ってやればよくて、abiフィルタにx86を設定するとうまいことやってくれる。
PuppeteerでセレクタやXPathを使う

PuppeteerでセレクタやXPath用いてのテキスト取得やアクションの実行を行う例

# テキストの取得

## セレクタ

```js
let selector = 'li.test:nth-child(2) a';
await page.waitForSelector(selector);
let textList = await page.evaluate((selector) => {
  let textList = [];
  let nodeList = document.querySelectorAll(selector);
  for (let index = 0; index < nodeList.length; index++) {
    let value = nodeList[index].href;// href, innerHTML, innerText, etc.
    if (typeof value !== 'undefined'){
      textList.push(value);
    }
  }
  return textList;
}, selector);
```

## XPath

```js
let textList = [];
let xpath = '//li[@class="test"][2]/a[1]';
await page.waitForXPath(xpath);
const elementHandleList = await page.$x(xpath);
for (let index = 0; index < elementHandleList.length; index++) {
  let value = await (await elementHandleList[index].getProperty('innerHTML')).jsonValue();// innerHTML, innerText, etc.
  if (typeof value !== 'undefined'){
    textList.push(value);
  }
}
```

```js:属性
let textList = [];
await page.waitForXPath('//li[@class="test"][2]/a[1]/@href');
const elementHandleList = await page.$x('//li[@class="test"][2]/a[1]/@href');
for (let index = 0; index < elementHandleList.length; index++) {
  let value = await (await elementHandleList[index].getProperty('value')).jsonValue();
  if (typeof value !== 'undefined'){
    textList.push(value);
  }
}
```

# アクション（click）

clickで以下のエラーが出る場合はbrowserにdefaultViewportやsetViewportの設定がうまくいっていない可能性あります。

```
Error: Node is either not visible or not an HTMLElement
```

```js
'defaultViewport' : { 'width' : 1600, 'height' : 1200 }
```


## セレクタ

```js
let selector = 'h2';
await page.waitForSelector(selector);
let elementHandleList = await page.$$(selector);
await elementHandleList[0].click();
await page.waitForNavigation();
```

## XPath

```js
let xpath = '//h2';
await page.waitForXPath(xpath);
let elementHandleList = await page.$x(xpath);
await elementHandleList[0].click();
await page.waitForNavigation();
```

# その他

サンプルが色々あるのでいつかお世話になりそう

[checkly/puppeteer-examples](https://github.com/checkly/puppeteer-examples)
head　書き方

```html:head
<meta charset="UTF-8">
<meta http-equiv="x-ua-compatible" content="ie=edge">
<title>テスト</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="format-detection" content="telephone=no">
<meta name="description" content="テストテストテストテストテスト">

	<meta property="og:url" content="https://test.html">
	<meta property="og:type" content="website">
	<meta property="og:title" content="テスト">
	<meta property="og:description" content="テストテストテストテストテスト">
	<meta property="og:site_name" content="テスト">
	<meta property="og:image" content="https://test/img/test.jpg">
	<meta name="twitter:card" content="summary_large_image">
	<meta name="twitter:site" content="https://twitter/test.html">
	<meta name="twitter:image" content="https://twitter/test/img/twitter-image.jpg">

<link rel="canonical" href="https://test.html">
<link rel="apple-touch-icon" href="img/apple-touch-icon-precomposed.png">
<link rel="shortcut icon" href="img/favicon.ico" type="image/vnd.microsoft.icon">
<link rel="icon" href="img/favicon.ico" type="image/x-icon">
<link rel="stylesheet" href="css/style.css?v12">
<script type="text/javascript" src="//webfont.fontplus.jp/accessor/script/fontplus.js?0KeljQcnfaw%3D&delay=1&timeout=3&pm=1&aa=1&ab=2" charset="utf-8"></script>
<script type="application/ld+json">

</script>
```
Puppeteerでファイルダウンロード

[Question: How do I get puppeteer to download a file?](https://github.com/GoogleChrome/puppeteer/issues/299#issuecomment-435662328)

`Page.FileDownloaded`は今後追加されるみたい

# クリックからダウンロードする

```js
const downloadPath = './download';

await page._client.send('Page.setDownloadBehavior', {
  behavior : 'allow',
  downloadPath: downloadPath
});

await page.goto('https://www.google.co.jp/chrome/', {waitUntil: 'networkidle0'});
await page.waitForSelector('#js-download-hero');
await page.click('#js-download-hero');
await page.click('#js-accept-install');
let filename = await ((async () => {
  let filename;
  while ( ! filename || filename.endsWith('.crdownload')) {
      filename = fs.readdirSync(downloadPath)[0];
      await sleep(1000);
  }
  return filename
})());

function sleep(milliSeconds) {
  return new Promise((resolve, reject) => {
    setTimeout(resolve, milliSeconds);
  });
}
```

# 直接ダウンロードする

`page.goto`で直接ファイルを指定すると上手くいかなかったが、クリックからダウンロードする際はうまくいっていたのでこれを利用してみました。無理矢理ダウンロードリンクを作ってクリックしてしまうことでダウンロード出来ました。[このページ](https://github.com/GoogleChrome/puppeteer/issues/299)ではAjaxでダウンロードしている方法もあったりしました。

```js:Chromeのページに行ってダウンロードするのはVSCodeという暴挙
const downloadPath = './download';

await page._client.send('Page.setDownloadBehavior', {
  behavior : 'allow',
  downloadPath: downloadPath
});

await page.goto('https://www.google.co.jp/chrome/', {waitUntil: 'networkidle0'});
await page.evaluate(() => {
  let body = document.querySelector('body');
  body.innerHTML = '<a id="puppeteer" href="https://code.visualstudio.com/docs/?dv=win">VSCode</a>'
});
await page.waitForSelector('#puppeteer');
await page.click('#puppeteer');
let filename = await ((async () => {
  let filename;
  while ( ! filename || filename.endsWith('.crdownload')) {
      filename = fs.readdirSync(downloadPath)[0];
      await sleep(1000);
  }
  return filename
})());

function sleep(milliSeconds) {
  return new Promise((resolve, reject) => {
    setTimeout(resolve, milliSeconds);
  });
}
```
【GAS】Slack botで対象者に対して一斉連絡　※リマインド/個別連絡に使えるよ

#はじめに
Google Apps ScriptとSlack Botをつかって、対象者に個別の連絡を一斉送信する方法について書きます。
私の仕事上（人事）、社員にやたらとリマインドや個別連絡をすることが多いため、楽にできる方法はないかと思い作ってみました。

GASが何であるか、GASでのスクリプトの書き方等は一旦触れずに記載します（あしからず）

# 手順1/2. Slackのincoming webhooksのアドレスを取得
まずはbotのアカウントを取得します。ここではSlackのincoming webhooksを使用します

この機能を使うには、まず送信先のエンドポイントをSlackで作成する必要があります。
[Slackのアプリページ](https://supership.slack.com/apps)から incoming-webhooks を選択します。

下記画像にしたがってページを進めて、

![スクリーンショット 2019-01-29 23.58.22.png](https://qiita-image-store.s3.amazonaws.com/0/350535/1686153c-6025-645e-2e1b-c48ae79ad3e1.png)
![スクリーンショット 2019-01-29 23.58.27.png](https://qiita-image-store.s3.amazonaws.com/0/350535/c48c6df8-12ae-ef3f-077b-93e6f25fc010.png)
![スクリーンショット 2019-01-29 23.58.32.png](https://qiita-image-store.s3.amazonaws.com/0/350535/5bc6fa7f-4405-3398-1f0e-9ec63ea2b501.png)


下記ページの赤枠のリンクをコピーしておいてください。あとで使います。
![スクリーンショット 2019-01-29 23.58.37.png](https://qiita-image-store.s3.amazonaws.com/0/350535/c92acc66-e2e6-2e3f-ce1e-ddd12f80b62b.png)



# 手順2/2. Googleスプレッドシートとドキュメントを用意。スクリプトを書く
次に送信するためのスプレッドシートとスクリプトを用意します。
まずは下記サンプルにある通りスプレッドシートとドキュメントをコピーして自分のを作ってください

### サンプルURL
スプレッドシート
https://docs.google.com/spreadsheets/d/1XBJX6Zi5G3p-MiDREbQR-Kmm3OXRJC7QLG7I0o5jEpo/edit?usp=sharing
配信ドキュメント
https://docs.google.com/document/d/11200kEtObjbn3fUQdH1Z5n7XN4jktDThMYy6r65gm-s/edit


次にスプレッドシートのスクリプトエディタを開き、下記をコピペください。
なお、// ★★★TODO★★★と書いてある部分はそれぞれ適宜修正ください。

### スクリプト
```javascript:qiita.js
var sheet = SpreadsheetApp.getActiveSheet();
var postUrl   = "xxxxxxxx"; // ★★★TODO★★★ 1.で取得したSlackのLinkを貼っつけてください

function postToSlack() {
  var values = sheet.getDataRange().getValues();

  // 文章を取得
  var text = DocumentApp.openById('xxxxx') // ★★★TODO★★★ 配信するドキュメントのIDを記載
  var letter = text.getText();

    // values.shift();
  for (var i = 3, l = values.length; i < l; i++) {

   // 差し込み情報
  var incertzero = values[i][1];
  var incertone  = values[i][2];
  var incerttwo  = values[i][3];

    var　message　=　letter.replace(/{0}/g,incertzero).replace(/{1}/g,incertone).replace(/{2}/g,incerttwo);   
var username = values[i][0];

    sendHttpPost(message, username);
    sheet.getRange(i+1,5).setValue("Done");
  }
}
function sendHttpPost(message, username)
{
  var jsonData =
  {
     "channel" : username,
     "username" : 'xxxx', //★★★TODO★★★ Botのアカウント名称を記載（なんでも良いです）
     "text" : message
  };
  var payload = JSON.stringify(jsonData);
  var options =
  {
    "method" : "post",
    "contentType" : "application/json",
    "payload" : payload
  };
  UrlFetchApp.fetch(postUrl, options);
}
```

## 送信方法
ここまでできたらあとは送るだけです。
1.上記Googeドキュメントに送信したい文章を書きます。
2.スプレッドシートA列に送信したいSlackのアカウント（@xxxx）やSlackページ（#xxx）を記載ください。何行でも記載できます。
3．スクリプトエディタの「postToSlack」を実行。

以上で画像のように対象者にSlackを一斉送信できます。
![スクリーンショット 2019-01-30 0.07.39.png](https://qiita-image-store.s3.amazonaws.com/0/350535/ac47d370-2267-7a41-e784-606e6df86499.png)


いくつか説明をはしょってる部分ありますが、疑問あればいつでもご質問ください。
zipファイルをアップロードしたら展開してダウンロードする


[Flask サーバに保存せずにファイルをアップロード・ダウンロードする \- Qiita](https://qiita.com/qqhann/items/aadede0a460a01831676)



```py:app.py
# vim:set ts=2 et:
from flask import Flask, render_template, request, send_file
import zipfile
import tempfile
import os

app = Flask(__name__)


@app.route('/', methods=['GET', 'POST'])
def index():
    if request.method == 'GET':
        return render_template('index.html')
    else:
        f = request.files['file']
        # tmpdirに展開して一番目の要素を返す
        with tempfile.TemporaryDirectory() as td:
            with zipfile.ZipFile(f) as existing_zip:
                # 一番目のファイル名を取得
                fname = existing_zip.namelist()[0]
                # 展開
                existing_zip.extract(fname, path=td, pwd=b'1234')
                # フォルダー名を含む場合はファイル名のみにする
                basename = os.path.basename(fname)
                return send_file("{}/{}".format(td, fname),
                                 attachment_filename=basename,
                                 as_attachment=True)


if __name__ == '__main__':
    app.run(debug=True, host='0.0.0.0', port=3000)

```

```html:templates/index.html
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
  <body>
    <form action="/" method="POST" enctype="multipart/form-data">
      <input type="file" name="file">
      <input type="submit">
    </form>
  </body>
</html>
```

送信を実行すると
"1234"のパスワードがかかったzipファイルを展開してダウンロードする


# 参考リンク

[13\.5\. zipfile — ZIP アーカイブの処理 — Python 3\.6\.5 ドキュメント](https://docs.python.jp/3/library/zipfile.html)

[pythonで一時ファイル、一時ディレクトリ\(tempfile\) \- Qiita](https://qiita.com/ymko/items/eb3478967c456b392825)

[Python \- zipfile: how to set a password for a zipfile? \- Stack Overflow](https://stackoverflow.com/questions/43439979/python-zipfile-how-to-set-a-password-for-a-zipfile)
>It is not mentioned in the documentation, but on Python 3, the password should be bytes, not str. So: 
zf.setpassword(b"1234")
モバイルnanaco、WAONの移行時電子マネーの流れ

#まえがき
スマホでFelicaの調子が悪くなり、電子決済ができない状態に。
正確に言うと「運が良ければできる」状態。
内部アンテナがいかれてしまったっぽい。

au携帯サポートサービスで同様の機種を取り寄せ、nanaco、WAONの引き継ぎ番号を発行して交換機種に無事移行完了。
その後アプリのアップデートをしている最中にフリーズ。
無限に再起動が続く状態に。
再度auに電話。再度同機種を取り寄せたが電子マネーは起動しなくなった機体のなかのままなのであった…

#モバイルnanacoの移行手順
1. nanacoアプリのインストール
2. nanacoサポートセンターにTEL
3. 起動直後の画面でTELで聞いた引き継ぎ番号を入力
4. 後日郵送されて来る封筒にサインして返送
5. センター預かり分反映で電子マネーの反映


#モバイルWAONの移行手順
1. WAONアプリのインストール
2. WAONサポートセンターにTEL
3. 旧WAON番号を教えてもらう
4. アプリからWAON再発行申請
5. 「10日後」にアプリからWAON再発行反映

#電子マネーの動き
##機種変更の場合
機種変更時は旧機種で機種変更番号を発番した時点でセンターに電子マネー残高が移り、もとの機体からは電子マネーが消える。
その後新機種で機種変更番号を入力した時点でセンターから電子マネーの残高が移る。

##引き継ぎできない場合
電話口の向こうではオペレータが利用した履歴をすべて把握していたので、日次処理で利用分及び残額（あと使用した店、時間も）がセンターにアップロードされている模様。
電話で控えた引き継ぎ番号と後日郵送される本人確認書類の一致を持って、センターに最終残高を反映している。

旧機種で使われた場合はどうなるんですか？
と聞いたら、「明日以降使えなくします」との回答。
ネガ情報に書き込みを行い、翌日以降にネガ情報を配信している（というより端末から取りに行っている）模様。
電子マネータッチ時にネガ情報を参照し、記載があるカードはNGとしているっぽい。
すぐに電子マネーの移行ができなのはネガ情報がすべての端末に行き渡るまでの時間稼ぎ。

#さいごに
電子マネー、停止処理はリアルタイムで出来ないので紛失には要注意。
OS 応用情報技術者試験 対策日記@12

#OS
OS(オペレーションシステム)について。
ハードウェアを抽象化したインターフェースをアプリケーションプログラムに提供するソフトウェアのこと。


##機能１.ジョブ管理
OSが自動的に起動し、プログラムを立ち上げる一連の流れを**ブートストラップ**という。
**JCL**(Job Control Langageと呼ばれるスクリプト言語を使用して、複数のジョブの起動や終了を制御し、それぞれ絵のジョブの実行や終了の状態を管理する。

##機能2.タスク管理
動作中のプログラムの実行単位であるタスクを行うタイミングや優先順位を制御する。それぞれのタスクは一つ以上の**スレッド**に分割することができ、CPUの利用はスレッド単位で行われる。

タスクの実行では、**実行状態**、**実行可能状態**、**待ち状態**の三つの状態に分けて管理する。
*実行可能状態→実行状態→タスクの消滅* 
が基本的な流れだが、出入力などで待ち時間が発生すると
*実行状態→待ち状態→実行可能状態→実行状態*
となり再びタスクが実行される。
実行状態でタスクを実行中に、制限時間である**タイムクォンタム**を使い切ったり、タスクを中断させる**プリエンション**が発生すると、実行可能状態に戻る。

タスクのスケジューリング方式には以下の様な種類があるよ。
- **到着順方式**　読んで字のごとく。
- 処理時間方式　処理時間の短い順
- 優先度順方式 読んで字のごとく。
- **ラウンドロビン方式** 全てのタスクに同じタイムクォンタムを設ける方式。
- **プリエンプション方式**　タスクに優先度をつけ、実行可能状態になるとプリエンプションで割り込む方式。
- (多段フィードバック待ち行列) 複数の優先度の待ち行列を持ち、高い優先度の待ち行列から順次処理していく方式。
- (イベントドリブンプリエンプション方式) 割り込みによってタスクの切り替えを行うイベントドリブン方式とプリエンプション方式を組み合わせた方式。

##機能3.記憶管理
主記憶装置の領域には限りがあるので、OSが補助記憶装置とのやりとりを行う。
やりとりの方法は以下の三つがある。

###オーバレイ
あらかじめプログラムを分けて補助記憶装置に格納し、必要な部分だけ主記憶装置に置く方法。

###スワッピング
メモリの内容を補助記憶装置のスワップファイルに書き出して、　他のタスクがメモリを使える様に解放する方法。メモリからスワップに取り出すことをスワップアウト、メモリに戻すことをスワップインという。

###ページング
プログラムを可変長のページに分けて、ページごとに補助記憶装置の仮想記憶領域に取り出す方法。メモリから仮装領域に取り出すことをページアウト、メモリに戻すことをページインという。
メモリ上に必要なページがないことをページフォールトといい、そのためにページインとページアウトが頻繁に起こることを**スラッシング**という。スラッシングが起こるとシステムの応答速度が急激に低下する。

ページングにおいて、ページアウトさせるページを選択するアルゴリズムを挙げる。
- **FIFO(First In First Out)方式** 最初にページインしたページを最初にページアウトさせる方式。
- **LRU(Least Recently Used)方式**　最後に使用されてから経過時間が長いページをページアウトさせる方式。
- **LFU(Least Frequently Used)方式** 最も使用頻度が少ないページをページアウトさせる方式。

###プログラム実行時の記憶管理
一時的にデータを置く**スタック領域**と動的に確保可能な**ヒープ領域**が用意されている。ヒープ領域で確保した命令は、メモリ解放命令で解放しないと**メモリリーク**という障害が起こるため、ガーベジコレクションという機能を用いて不要な領域を自動的に解放する。

------
[ホームへ](https://qiita.com/k-y/items/dc2c9a3a8425712253e8)
FireUI App Preview をビルドする

# FireUI Live Preview

Delphi 10.1 Berlin で登場した IDE 上で設計している画面を実端末上で確認出来る [FireUI Live Preview、めっちゃ便利！という記事](https://qiita.com/pik/items/e8f75f5df7238e5c0c73)を前に書きました。

■FireUI ライブ プレビューの主な特徴
http://docwiki.embarcadero.com/RADStudio/Rio/ja/FireUI_%E3%83%A9%E3%82%A4%E3%83%96_%E3%83%97%E3%83%AC%E3%83%93%E3%83%A5%E3%83%BC

## Android 用

**Update 2021/01/07**
Android 用のクライアントが[やっと再公開されました](https://blogs.embarcadero.com/ja/new-fireui-app-preview-on-play-store-ja/)
https://play.google.com/store/apps/details?id=com.embarcadero.fireuiapppreview

以下は公開前の文章をそのまま載せています。

2019/01/29 現在で、Android 用のクライアントが Not found になっています。

■FireUI App Preview
https://play.google.com/store/apps/details?id=com.embarcadero.LivePreview101
![image.png](https://qiita-image-store.s3.amazonaws.com/0/12977/4eccea17-e397-cb5a-66d2-c627f2d63318.png)

おそらく Android Level 26 対応していないために消えたと推測されます。

## iOS 用

iOS 用は App Store に公開されています。
https://itunes.apple.com/us/app/fireui-app-preview-10.1-berlin/id1090861997

![image.png](https://qiita-image-store.s3.amazonaws.com/0/12977/248eaab8-cb2b-849b-b925-0209eb5e8b97.png)

# ビルドしよう

ところで、10.2 Tokyo から FireUI App Preview のソースコードが付いてくるようになりました。
つまり、ストアに無い＆ストアのものが動かないならビルドしちゃえばいいわけです。
このツールは開発者が使うツールなのでアプリさえ手に入れば特にストアに公開されている必要は無いですからね…

FireUI App Preview のソースは

```text
(RADStudioインストールパス)\source\Tools\FireUIAppPreview\
```

です。

これを Delphi 10.3 Rio で読み込んむと↓こんな感じです。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/12977/923cc078-9966-57ec-3759-a9ef88bccd2b.png)

で Android 向けにビルドすると…流石謹製というか何というか特に問題も無く無事ビルド＆インストールできました。

ちなみに、現在 App Store に公開されている iOS 用の FireUI App Preview でも正しく動作しました。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/12977/be3b56fe-f096-9057-88f2-b829e9524eba.png)

**※注意**
FireUI App Preview プロジェクトを開いたまま IDE に接続すると FireUI App Preview の設計画面が表示されるので「あれ！？画面変わらない！ ...Discovering... って表示されて動かない！あれ！？あれ！？」ってなります（FireUI App Preview の設計画面が表示されているので正しい動き）。
別のプロジェクトを開いて確認してみてください。

# まとめ
ストアに無くても構わないとはいえ、10.3 Rio でビルドし直して再リリースして！！
Element から学ぶ Vue.js の component の作り方 その1 (alert)

## alert

## 前提
Elemnt 2.52
公式ページ
https://element.eleme.io/#/en-US

### アラート

![image.png](https://qiita-image-store.s3.amazonaws.com/0/246022/bdeffd0b-a604-7297-f68b-a6c06ed931d5.png)

#### 用意されている機能
* アラートメッセージの表示
* 中央寄せ
* タイプ毎に用意されたアイコンの表示
* 説明分の表示
* アラートをクローズする / クローズさせない
* クローズボタンのカスタマイズ

#### 構成
```
 |-index.js
 |-src
   |-main.vue
```

index.js は install が定義されている。※ 何がどんな風に処理されているかは現時点で不明。
main.vue を上から見ていく。

```
<transition>
```
Vue.js 提供のコンポーネント。
アニメーションなどを追加する事が可能らしい。
CSS がどこかにあるのだろうが、今はどこにあるかわからないので発見次第追記する。

```
<div>
```
1. v-show で表示を制御している。後述する close event で v-show が false になったら非表示となる。
1. class が bind されている。   
指定された type によって、class が決まる。色も class で決まってるはずなので、どこかで CSS で定義されてると思う。
1. 中央寄せにするか、center で制御されている。

```
<i>
```
1. アイコンの表示を制御している。 説明分がある場合はアイコンの大きくする class が設定される。

```
<div>
  <span>
   <slot>
```
title を表示する。説明分がある場合は title を太字にする class が設定される。

```
<slot>
  <p>
````
説明分を表示する。

```
<i>
```
1. 閉じるボタンを制御する。
1. close-text が設定されていない場合は [x] がデフォルトで表示される。設定されている場合は指定された値が close ボタンとなる
1. closable で close ボタンを表示するか制御している。表示しない場合は close できない
1. @click close イベントを実行する。close 時にしたい処理があれば、親で close イベントを設定する。

### 不明点 ※ わかり次第更新予定
```
1. role="alert"
2. $slots.title, $slots.default
3. CSS
```

### 所感
第一回目なので Qiita の書き方含め、わからない事が多い。
今後の更新で改善していこう。
【R】複数のデータを散布図としてまとめて描画する方法

# はじめに

[【R】散布図を描く方法](https://qiita.com/nkojima/items/c008adec58c7834edfc1)では、1つの散布図を描画する方法を記載していますが、今回は複数のデータを散布図としてまとめて描画する方法となります。

今回紹介する方法だと軸のラベルやグラフのタイトルなどが無いので実用的ではありませんが、集めたデータの傾向をまとめて見るのには都合の良い方法だと思います。

# 解析に使うデータ

* 以下のデータは、あるラン科植物の個体ごとに草丈（Height）、葉数（Leaves）、花数（Flowers）を測定した結果です。

```orchids.csv
,Height,Leaves,Flowers
orchid1,35,10,15
orchid2,30,6,5
orchid3,21,7,2
orchid4,18,8,0
orchid5,28,7,3
orchid6,10,4,0
```

# 複数の散布図の描画

* `plot`関数の引数としてデータフレームを指定するだけで、複数のデータ（列）を散布図としてまとめて描画できます。
 * 草丈×葉数
 * 草丈×花数
 * 葉数×草丈
 * 葉数×花数
 * 花数×草丈
 * 花数×葉数

```r:Rのコンソール
orchids <- read.table("C:\\orchids.csv", header=TRUE, row.names=1, encoding="CP932", sep=",")
orchids
        Height Leaves Flowers
orchid1     35     10      15
orchid2     30      6       5
orchid3     21      7       2
orchid4     18      8       0
orchid5     28      7       3
orchid6     10      4       0

# データフレームに含まれる全ての列を使った複数の散布図の描画
plot(orchids)
```

![multi_scatter_plot_01.png](https://qiita-image-store.s3.amazonaws.com/0/312166/443823a2-29d9-4b36-7582-0abfa96dbf41.png)


* 引数にデータフレームそのものではなく、例えば`plot(orchids[1:3])`のように、描画対象となる列を指定することも可能です。
  * `plot(orchids[1:3])`のように全ての列を指定すれば、以下の様に単に`plot`関数を呼び出した時と同じ結果を得られます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/312166/029cb725-e5d4-37f2-efb6-846463018b3c.png)

# 参考URL

* [【R】散布図を描く方法](https://qiita.com/nkojima/items/c008adec58c7834edfc1)
vue-chartjsで自動色割り当て

まずvue-chartjsの簡単な記事は[こちら](https://qiita.com/muramasawani/items/6086ecfcb92034774599)

## これは何？

Qiitaのマイページのグラフっぽいのを作りたくてvue-chartjsで自動色割り当ての方法を探していたら`google-palette`に行き着いたので忘備録

[google-palette](https://github.com/google/palette.js/tree/master)


## インストール

プロジェクト配下で実行

```
$ npm i google-palette
```

## 使い方

グラフ本体

```vuejs:Chart.vue
<script>
import { Doughnut } from 'vue-chartjs'
import * as palette from 'google-palette'

export default {
  extends: Doughnut,
  data() {
    return {
      languages: ['Vue.js', 'C', 'C++', 'Python'],
      chartStatus: [40, 30, 20, 10]
    }
  },
  mounted: function() {
    this.renderChart(
      {
        labels: this.languages,
        datasets: [
          {
            backgroundColor: palette('mpn65', this.chartStatus.length).map(
              function(hex) {
                return '#' + hex
              }
            ),
            data: this.chartStatus
          }
        ]
      },
      { responsive: true, maintainAspectRatio: false }
    )
  }
}
</script>

```

ページ

```vuejs:index.vue
<template>
  <div>
    <chart-graph />
  </div>
</template>

<script>
import Vue from 'vue'
import Chart from '~/components/Chart'

export default {
  components: {
    Chart
  }
}

Vue.component('chart-graph', Chart)
</script>
```

## ブラウザ
出ました。

<img width="559" alt="スクリーンショット 2019-01-29 23.30.07.png" src="https://qiita-image-store.s3.amazonaws.com/0/219624/21fa0308-71b9-8f2f-f181-1902144096fd.png">
NumPyでテンソル代数（共変・反変）

テンソル代数の共変・反変の変換をNumPyでやる方法のメモ。

問題は、[テンソル解析（田代嘉宏・著）](https://www.amazon.co.jp/%E3%83%86%E3%83%B3%E3%82%BD%E3%83%AB%E8%A7%A3%E6%9E%90-%E5%9F%BA%E7%A4%8E%E6%95%B0%E5%AD%A6%E9%81%B8%E6%9B%B8-23-%E7%94%B0%E4%BB%A3-%E5%98%89%E5%AE%8F/dp/4785311258) p154 例1.1 参照。

基底$Σ${$e_1,e_2,e_3$},$Σ'${$e'_1,e'_2,e'_3$}の双対基底の変換式は以下の通り。

```math
e_1 = e_1' + 2e_2' + 3e_3' \\
e_2 = 2e_1' - e_2' +2e_3' \\
e_3 = -4e_1' + 2e_2' - 5e_3'
```

### 反変ベクトルの変換

反変ベクトル$v$の基底$Σ$に対する成分が

```math
\vec{v} =
\begin{pmatrix}
v^1 \\
v^2 \\
v^3
\end{pmatrix}
=
\begin{pmatrix}
3 \\
2 \\
1
\end{pmatrix}
```
の時の基底$Σ'$に関する成分を求める。

基底の変換行列Aは双対基底の変換式より

```math
A =
\begin{pmatrix}
1 & 2 & -4\\
2 & -1 & 2\\
3 & 2 & -5
\end{pmatrix}
```
反変ベクトル$v$の変換式は

```math
\vec{v} =
\begin{pmatrix}
v'^1 \\
v'^2 \\
v'^3
\end{pmatrix}
= A
\begin{pmatrix}
v^1 \\
v^2 \\
v^3
\end{pmatrix}
```
NumPyでは`.dot()`で計算します。

```python
import numpy as np
A = np.array([[1,2,3],[2,-1,2],[-4,2,-5]]).T #変換行列A

v = np.array([3,2,1])
v_dash = A.dot(v)
print(v_dash)

# 出力
# [3, 6, 8]
```
### 共変ベクトルの変換

共変ベクトル$a$の基底$Σ$に対する成分が

```math
\vec{a} =
\begin{pmatrix}
a_1 & a_2 & a_3
\end{pmatrix}
=
\begin{pmatrix}
2 & 1 & -4
\end{pmatrix}
```
の時の基底$Σ'$に関する成分を求める。

```math
\vec{a} =
\begin{pmatrix}
a'_1 & a'_2 & a'_3
\end{pmatrix}
= 
\begin{pmatrix}
a_1 & a_2 & a_3
\end{pmatrix}
A^{-1}
```

NumPyでは
1. Aの逆行列を計算
2. `.dot()`で計算
の順で行います。

```python
A_inv = np.linalg.inv(A) #逆行列の計算

a = np.array([2,1,-4])
a_dash = a.dot(A_inv)
print(a_dash)

# 出力
# [-2. -1.  2.]
```
初めてのJavaScript③


今日の学習内容です。

-------
**配列**
[値1, 値2, 値3]のようにつくる。
配列に入っているそれぞれの値のことを**要素**と呼ぶ。
配列を代入する定数名は、慣習上複数形にすることが多い。（fruits など）

「console.log(定数名)」とすると、配列がコンソールに出力される。

配列の要素にはそれぞれインデックス番号という番号がついている。
インデックス番号は、0から始まる。

要素に値を代入することでその要素を上書きすることができる。

＜例文＞
繰り返し処理をする場合
const fruits=["apple","banana""orange"];

for(let i=0; i<3; i++){
console.log(fruits[i]);
}
iが0~2の間ループする
変数iを用いて要素を取得





**length（レンクス）**
console.log(animals.length);
配列.lengthとすることで、配列の要素数を取得できる。
＜例文＞
for(let i=0; 1<fruits.length; i++){
console.log(fruits[i]);
}

-----
・躓いた点
**for(変数の定義、条件式、変数の更新）**を忘れており
for(let i=0; i<3; i++){
console.log(fruits[i]);
}
の例文を見たときに混乱してしまった。

・感じた点
いきなり難しくなった。

-----------

次はオブジェクトからです。
sqlite3へのデータINSERT　by python

作成した喫茶店リストをDBに追加する


データカラムは
(id,title,住所、作成日、作成者、カテゴリー)の6要素
なので

```
ids=[]
for i,(name,address,date,author,category) in enumerate(zip(titles,adresses,dates,authors,categorys),1):
    id=(i,name,address,date,date,author,category)
    ids.append(id)
```
6つの引数を持つリストを作成(あらかじめdates,authors,categoryのタプルは作成済み)

ここからDB操作

テーブル名がわからないので

```
import sqlite3

sqlite_path = ""
connection = sqlite3.connect(sqlite_path)
cursor = connection.cursor()

cursor.execute("SELECT*FROM sqlite_master where type='table'")
for x in cursor.fetchall():
    print(x)
```
上記のコードでテーブル名を取得
得たテーブル名で改めてデータを挿入する


```
sqlite_path = ""
connection = sqlite3.connect(sqlite_path)
cursor = connection.cursor()

try:
    cursor.executemany("INSERT INTO talbe_name VALUES(?,?,?,?,?,?)",ids)
    connection.commit()


except sqlite3.Error as e:
    print('sqlite3.Error occurred:', e.args[0])
    
cursor.execute('SELECT*FROM table_name')
res=cursor.fetchall()
print(res)



connection.close()
```

ポイント
・try exceptでエラーをキャッチできるようにする
・VALUES()でカラム数を定義する
・複数なのでexecute()ではなくexecutemany()を用いる。
・commitし、DBへ保存
・DBへアクセスし、データを確認



おまけメモ
SELECT id, name FROM table
⇒id nameが返される
Laradockで２つのアプリケーション開発ができる環境を構築した

ローカルで複数サイトの開発環境を動かしたいということはよくあると思います。

今回はLaradockを使って2つLaravelアプリケーションの動作環境をつくります。
こんな感じでアクセスできればOK

```
http://project1.com
http://project2.com
```

フォルダ構成は以下のように複数プロジェクトがLaradockを参照する構成にする

```
laradock
   L project1
   L project2
```

# Laravelプロジェクト作成

コンテナ起動し、worksoaceに入る

```
docker-compose up -d nginx mysql workspace
docker-compose exec workspace bash
```

2つのプロジェクトを作成

```
cd /var/www
composer create-project laravel/laravel --prefer-dist project1
composer create-project laravel/laravel --prefer-dist project2
exit
```

# nginxの設定更新

デフォルトの設定ファイルを念のため無効にし、
各プロジェクトごとのnginx設定ファイルを作成する

```
mv laradock/nginx/sites/default.conf default.conf.bk
cp nginx/sites/app.conf.example nginx/sites/project1.conf
cp nginx/sites/app.conf.example nginx/sites/project2.conf

# project1.confの変更
server_name project1.com;
root /var/www/project1/public;

# project2.confの変更 
server_name project2.com;
root /var/www/project2/public;
```

# 設定ファイル

docker-compose.ymlのvolumesでコンテナのディレクトリとローカルディレクトリの紐付けが行われる。

```
cd laradock
vi docker-compose.yml

      volumes:
        - ${APP_CODE_PATH_HOST}:${APP_CODE_PATH_CONTAINER}

vi .env
APP_CODE_PATH_HOST=../ # ローカル
APP_CODE_PATH_CONTAINER=/var/www:cached # コンテナ
```

# 設定反映

```
docker-compose stop
docker-compose up -d mysql nginx workspace
```

# /etc/hostsを修正

```
127.0.0.1       project1.com
127.0.0.1       project2.com
```

# ブラウザで確認

http://project1.com
http://project2.com

どちらもLaravelのデフォルトのサイトが表示されればOK
![スクリーンショット 2019-01-28 23.55.35.png](https://qiita-image-store.s3.amazonaws.com/0/272635/b900eaf6-08ef-ae2c-b6f5-dcd9fd369c06.png)
Windows 10 Pro x64 + Python3 + pyodbc で SQLite3 にアクセスしてみる

#目的
SQLite3をインストールしたので、Python3 + pyodbc からのアクセスを試してみる
ODBCを使用してアクセスする
##環境変数の追加
Windows版のVsCodeでPythonを使う場合、出力ターミナルで日本語の文字化けが発生する
これを回避する手段はいくつかあるようだけど、自分は環境変数に以下を追加して回避している
　変数:PYTHONIOENCODING
　値：UTF-8
##pyodbcのインストール
$ sudo pip3 install pyodbc
##サンプルコード
```python:pytest003.py
import pyodbc
# Windows Add env PYTHONIOENCODING = UTF-8 & restart vscode
odbcdrv  = 'SQLITE3DEMO64'
database = r'C:\DEV\DB\sqlite3\demo.sqlite3'
username = '' 
password = '' 
# constr = 'DSN=' + odbcdrv + ';UID=' + username + ';PWD=' + password 
constr = 'DRIVER={SQLite3 ODBC Driver};DATABASE=' + database + ';UID=' + username + ';PWD=' + password

cnxn = pyodbc.connect(constr)
# Create a cursor from the connection
cursor = cnxn.cursor()

cursor.execute("SELECT * FROM TEST_TABLE")
row = cursor.fetchone()
if row:
    print(row)

cnxn.close()
```
##参考にしたのは以下のサイト
対象テーブルは以下で作成したもの
[Windows 10 Pro x64 で SQLite3を試してみる](https://qiita.com/tabizou/items/af8687201961e4d6b8a4)
【C#】「〇曜日の日付」を取得する方法

「今日の曜日」「月末日の曜日」など日付から曜日を取得するのは比較的簡単ですが、逆に「〇曜日の日付が知りたい」という場合は少々手間がかかります。
例えば「定休日が水曜日の時、休みとなる水曜日の日付を全て取得する」といった時には、以下のコードが役に立つかもしれません。

# コード

```c#:DateUtil.cs
public class DateUtils
{
    /// <summary>
    /// 対象年の指定された曜日に該当する日付を全て取得する
    /// </summary>
    /// <param name="targetYear">対象年</param>
    /// <param name="wantDayOfWeek">対象となる曜日。この曜日に合致する日付を取得する。</param>
    /// <returns>対象年における、指定した曜日の日付のリスト。</returns>
    public static List<DateTime> FindWantDayOfWeek(int targetYear, DayOfWeek wantDayOfWeek)
    {
        // 対象年の1月1日(元旦)の曜日を取得する。
        DateTime gantan = new DateTime(targetYear, 1, 1);

        // 対象年の1月において、引数で指定した曜日に該当する最初の日付を取得する
        DateTime date;

        if (gantan.DayOfWeek == wantDayOfWeek)
        {
            date = gantan;
        }
        else
        {
            int additionalDay = ((int)(DayOfWeek.Saturday - gantan.DayOfWeek + wantDayOfWeek) % 7) + 1;
            date = gantan.AddDays(additionalDay);
        }

        // 7日ずつ日付をずらして、対象年における指定した曜日の日付を全て取得する。
        List<DateTime> days = new List<DateTime>();
        while (date.Year == targetYear)
        {
            days.Add(date);
            date = date.AddDays(7);
        }

        return days;
    }
}
```

# コードの実行

## テストコード

```c#:UnitTestDateUtils.cs
[TestClass]
public class UnitTestDateUtils
{
    [TestMethod]
    public void TestFindWantDayOfWeek()
    {
        // 2019年の日曜日の日付を取得する。
        var days = DateUtils.FindWantDayOfWeek(2019, DayOfWeek.Sunday);
        var sunday2019 = string.Join(",", days.Select(day => day.ToString("yyyy/MM/dd")));
        System.Console.WriteLine(sunday2019);
    }

}
```

## テストコードの実行結果

```
2019/01/06,2019/01/13,2019/01/20,2019/01/27,2019/02/03,2019/02/10,2019/02/17,2019/02/24,2019/03/03,2019/03/10,2019/03/17,2019/03/24,2019/03/31,2019/04/07,2019/04/14,2019/04/21,2019/04/28,2019/05/05,2019/05/12,2019/05/19,2019/05/26,2019/06/02,2019/06/09,2019/06/16,2019/06/23,2019/06/30,2019/07/07,2019/07/14,2019/07/21,2019/07/28,2019/08/04,2019/08/11,2019/08/18,2019/08/25,2019/09/01,2019/09/08,2019/09/15,2019/09/22,2019/09/29,2019/10/06,2019/10/13,2019/10/20,2019/10/27,2019/11/03,2019/11/10,2019/11/17,2019/11/24,2019/12/01,2019/12/08,2019/12/15,2019/12/22,2019/12/29
```
JSON構造を可視化するツール：jsoneditoronline

![image.png](https://qiita-image-store.s3.amazonaws.com/0/133516/17430fd3-e512-0e3a-a119-4b4c3aca8276.png)

ここで見つけた：https://stackoverflow.com/questions/39355149/how-to-read-json-with-schema-in-spark-dataframes-spark-sql

ツール：
https://jsoneditoronline.org/
Smarty3で少し変化したforeach、iteration等の記述

勤務先でももうすっかりなにかのMVCモデル + Smarty3の形が定着。
のはずが、とある新人さんのソースを見てみるとSmarty2系の記法になってる。どうして。

そんな疑問を抱きつつ「smarty foreach」なんかで検索すると以下の通り。
![検索結果](https://qiita-image-store.s3.amazonaws.com/0/142724/490bc370-42cf-18c3-c93b-93feb8ebbb21.png)

なんとSmarty3系のforeach記事が1ページに出てこない。ページを切り替えても全然出てこない。
これは悲しい。今の記述方法も知って頂きたいので、以下どう違うのかを出してみました。

---

**[今の書き方(Smarty3)](https://www.smarty.net/docs/ja/language.function.foreach.tpl)**

```html:Smarty3
{* PHP の構文を使ってキーにアクセスすることもできます *}
{foreach $contact as $key => $value}
  <p>{$value@index}|{$value@iteration}</p>
{/foreach}
```

そうですPHPの記述そのまんまです。もちろんそのまま`{$key}`、`{$value}`として使えます。
iterationやらindexを取りたければ値の変数名($value)に`@index`やらをつけるだけでOK。
その他のオプションは以下の通り。

- `@index`
- `@iteration`
- `@first` 
- `@last`
- `@show`
- `@total`

その他、`as キー名($key)`としなくても、`変数名@キー名($value@key)`で取れるらしい。
PHPの記述に合わせるなら使い所はないと思いますが。

---

**[古い書き方(Smarty2)](https://www.smarty.net/docsv2/ja/language.function.foreach.tpl)**

```html:Smarty2
{* この出力は 0|1, 1|2, 2|3, ... のようになります *}
{foreach from=$myArray key=k item=i name=foo}
  <p>{$smarty.foreach.foo.index}|{$smarty.foreach.foo.iteration}</p>
{/foreach}
```

古い記述方法だと、foreachに名前をつけた上でiterationやindexを取る必要があり、文字数も増えがち。
あとitemとnameで勘違いしがち。
`Smarty 2.x 形式の {foreach from=$myarray key="mykey" item="myitem"} もまだ対応しています。`
との事なので将来的に消えるリスクもあります。

---

好みの問題といえばそうだし、html_optionsの記述やら基本的な書き方とは異なりはしますが、
やはりぱっと見でわかり易いのは3かなと思います。
新しいマニュアルが検索上位に来て広まりますように。

あと`{section}`があまり使われませんように。:rolling_eyes:
CentOS7にOAuth.ioのオープンソースをサーバ公開する

# 1.必要条件
- ドメイン付きの公的に利用可能なSSL HTTPサーバ（例えばNGINXを通して） ssl.example.com
- /oauthSSL下で他のWebアプリを使用できるようにするために、HTTPコンテキストルートからプロキシへのHTTPサーバーを使用する
- oauthdから何も外部から入手できないことを確認してください（すなわちoauthdはループバックからのみアクセス可能です）。
- 最も簡単な設定

# 2.NginxをCentOS 7にインストール
👉[Nginx を CentOS 7 にインストールする手順](https://weblabo.oscasierra.net/nginx-centos7-install/)

# 3.Let's EncryptでNginxにSSLを設定
👉[Let's EncryptでNginxにSSLを設定する](https://qiita.com/HeRo/items/f9eb8d8a08d4d5b63ee9)

# 4.oauthdをNginxに連携させる
👉[Server install under NGINX](https://github.com/oauth-io/oauthd/wiki/Server-install-under-NGINX)

リンク先の通りにNginxとoauthdを連携させようとしてもうまくいかない。
以下のようにやると設定できた。

## oauthdの設定ファイル

### `config.local.js`

**Note**: 最初の設定はSSL設定を使用していません。別途対応をしていきます。

        {
        // ...
            host_url: 'https://ssl.example.com',
            base:     "/",
            base_api: "/api",
            port:     6284,
            bind:     '127.0.0.1'
        // ...
        }

### Under NGINX
    server {
        listen 80;
        server_name example.com;
        return 301 https://$host$request_uri;
    }

    server {
        listen       443 ssl;
        server_name  ssl.example.com;

        ssl                  on;
        ssl_certificate      /etc/ssl/mycert.pem;
        ssl_certificate_key  /etc/ssl/mycert.key;

        location /{
          proxy_pass  http://127.0.0.1:6284;
        }
    }

# 5.起動シェルを作る
OAuthの起動シェルを作成する。

Nginxは、自動起動で起動時に立ち上がりますが、OAuthは起動しないので、シェルを作って対応する。

```startup.sh
#!/bin/sh

cd /opt/oauthd
nohup oauthd start &

exit 0
```

一旦これで運用してみる。
FlexMessageSimulatorで作成したJSONをPHPに取り込む時に苦戦した

#　はじめに
LINEのBOTの機能の一つである**Flex Message**を使ってみようと思い、**FlexMessageSimulator**を使ったときのことです。
**FlexMessageSimulator**で作成した**Flex Message**は、**JSON**形式または**YAML**形式でクリップボードに保存することができます。
今回は、JSON形式について記述します。

#苦戦したところ
たとえば、次のようなFlex MessageをJSON形式でPHPに取り込もうとしたとき、

```json:flexmessage.json
{
  "type": "bubble",
  "styles": {
    "footer": {
      "separator": true
    }
  },
  "body": {
    "type": "box",
    "layout": "vertical",
    "contents": [
      {
        "type": "text",
        "text": "hogehoge,hugahuga",
        "size": "xl",
        "color": "#555555",
        "wrap": true
      }
        ]
      }
}
```
最初、私はfile_get_contents()でそのままJSONを取得できるものだと思っていたが、知っての通りできなかった。

```php:json_yomikomu.php

$json = file_get_contents('flexmessage.json');
LINE BOTの処理が続く
.
.
.
//web_log:ERROR!!メッセージが長すぎます。
```
このコードだとJSONはただの文字列となっており、LINEの遅れるメッセージ数の上限でエラーをはいていることが分かった。

#調べずにもがいてしまった
私は思ってしまった、あれ？このJSONの文字列の「"」、「{}」、「:」をPHPが配列として認識できるように変換すればいいのでは？

##もがいたらできてしまった
間違えないように作成したflexmessageはtxt形式で保存するようにした。
PHPでis_array()関数を用いて調べると配列ではなかった。しかし、実際のLINEのAPIでは動いた（なぜかわからない）。

```PHP:henkan.php
$json = file_get_contents('flexmessage.txt');

$json = str_replace('{','[',$json);
$json = str_replace('}',']',$json);
$json = str_replace('"',"'",$json);
$json = str_replace("':","' =>",$json);
//$jsonは配列として認識されない

$message = [
    'type' => 'flex',
    'altText' => 'flexmessage',
    'contents' => [
                    $json
                  ]
           ];

//$messageはflex messageの形式でLINEに出力された。
```

#答えはjson_decode()だった

```PHP:henkan.php
$json = file_get_contents('flexmessage.json');

$json = json_decode($json,true);
//$jsonは配列として認識される

$message = [
    'type' => 'flex',
    'altText' => 'flexmessage',
    'contents' => [
                    $json
                  ]
           ];
//$messageはflex messageの形式でLINEに出力された。
```

#おわりに
json_decodeは公式マニュアルを見たらすぐわかったので、公式マニュアルはちゃんと読もう。（戒め）