OmniAICreator/Qiita-1.07M huggingface dataset:
Rails6.0 + Docker上のPostgreSQLでの開発環境を作成する。

## はじめに
Qiita初投稿.
Rails歴は今夏のインターンで始めて３週間くらいです.
この記事はインターンで教えてもらったことのアウトプット兼, 自分の備忘録のために書きました.
不足している要素などあればコメントなどでご教授お願いします.

## 概要
ローカル環境のRailsとDocker環境上のPostgreSQLで開発環境を作成する.

##この開発環境を作成する理由
- 個人開発をするときに使われることの多いHerokuはPostgreSQLが使われている.
- データベースをDocker上で作成することで, デザイナーなど非エンジニアが環境構築をする際の手間が軽減される.
- Railsをローカルで作成する理由は, bundlerなどバージョン管理ツールが用意されている, またDocker上ではデバッグがしづらくなるため.

## 環境
rbenv 1.1.2

Bundler 2.0.2

node.js v12.10.0

yarn 1.17.3

postgresql 11.5

Docker 19.03.2

Rails 6.0.0

## 前提
以下のコマンドがコマンドラインで実行できる.
`$ rbenv -v`

`$ node -v`

`$ yarn -v`

`$ psql --version`

`$ bundle -v`

` $ docker -v` 

` $ docker-compose -v`

## 手順
#### Bundlerを初期化してRails newするところまで

```text:作業ディレクトリの作成
$ mkdir [project-name]
$ cd [project-name]
```

```text:Bundlerの初期化
$ bundle init
```
生成されたGemfileのコメントアウトを外す.

```text:Gemfile
# frozen_string_literal: true

source "https://rubygems.org"

git_source(:github) {|repo_name| "https://github.com/#{repo_name}" }

# gem "rails"    ←この行のコメントを外す
```
bundle installする.

```
$ bundle exec rails -v
$ bundle --path vendor/bundle -j4
$ bundle exec rails new . -d postgresql
```
最後のコマンドを実行した際に「conflict Gemfile」みたいなのが出て聞かれたら「Y」を選択する.
`rails new`する時のオプション, bundleのコマンドについては下記のQiita記事が参考になりました.

[薄いRailsプロジェクトを rails new する](https://qiita.com/shinkuFencer/items/e6b4e24a92f7b34e9f24)
[bundler、bundle execについて　※自分用メモ](https://qiita.com/dawn_628/items/1821d4eef22b9f45eea8)

#### Dockerの設定ファイルを記入し, Dockerイメージを作成する
[project-name]/docker-compose.ymlを作成し, 以下のように記入.

```yaml:docker-compose.yml
version: '3.7'
services:
  postgres:
    image: postgres
    restart: always
    environment:
      POSTGRES_USER: root
      POSTGRES_PASSWORD: root
    hostname: postgres
    ports:
      - 5432:5432
    volumes:
      - ./data/postgres:/var/lib/postgresql/data
```
先ほど記入した設定ファイルからDockerイメージをビルドする.

```
$ docker-compose build
```
PostgreSQLを起動する.

```
$docker-compose up -d
```

終了するとき.

```
$ docker-compose down
```

#### Docker上のPostgreSQLにRailsから接続するための設定をする.

```yaml:config/database.yml
development:
  <<: *default
  host: localhost    ←追加
  database: [proj_name]_development
  username: root    ←追加
  password: root    ←追加
　・
　・
　・
test:
  <<: *default
  host: localhost    ←追加
  database: [proj_name]_test
  username: root    ←追加
  password: root    ←追加
```
データベースを作成する.

```
$ bin/rails db:create
```
Railsのローカルサーバーを立ち上げる.

```
$ bin/rails db:migrate
```
#### 完成！！
うごいたーー :raised_hands::raised_hands::raised_hands:
<img width="1680" alt="screenshot01.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/318449/4d5a98f6-814f-c760-3ce9-bdd588d9e3b6.png">


## 終わりに
Dockerの設定ファイルの部分など自分のなかでおまじない状態になっている部分があるので, それらの説明ができるように勉強していきたいと思います.オススメの本や記事などあれば教えてください.
embulk bundle installで「If this error persists you could try removing the cache directory '/home/user/embulk/bundle/jruby/x.x.x/cache/bundler/git/xxx'fatal: Refusing to fetch into current branch refs/heads/master of non-bare repository」が出た場合

#結論
bundle配下のjrubyフォルダをgit管理して残していたため。
jrubyフォルダを削除後再試行したら解決した

##実行環境
1. docker run -it [toru2220/embulk-handbrake-ffmpeg](https://hub.docker.com/r/toru2220/embulk-handbrake-ffmpeg) /bin/bash
2. git clone https://fuhajin@bitbucket.org/fuhajin/embulk.git
3. cd embulk/bundle
4. embulk bundle install
【Unity】ローカル通知/PUSH　 Mobile Notifications

体力ゲージが満タンになったとか、デイリーミッションが復活したよとかをスマホに通知してユーザをアプリへ誘導する機能について。
相変わらずメモ書き程度の記述。そのうち本にでもしたいなぁ。

「Mobile Notifications」使います。

理由は無料なのとUnityの付属機能だから今後Androidのバージョンが変わってもサポートを期待できるため。

■インストール
Window > Package Managerを選択。Packagesから「Mobile Notifications」を選択してインストール。Projectに「Mobile Notifications」があればインストール成功。


■設定
Project Settingsでアイコン画像を設定できたりする。

APIのレベルが足りなくなった場合はPlayer Settings > Othersからminsdkを変更。

■実装
マニュアルはここ。
https://docs.unity3d.com/Packages/com.unity.mobile.notifications@1.0/manual/index.html

マニュアルいきなり読んでもよくわからないので、実施したことをメモメモ。

```NotificationManager.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

using Unity.Notifications.Android;
using System;

public class NotificationsManager : MonoBehaviour
{
    private string m_channelId = "ここm_channelId";
    private void Awake()
    {
        // 通知用のチャンネルを作成
        //チャンネル情報は通知に表示されない。
        var c = new AndroidNotificationChannel
        {
            Id = m_channelId,
            Name = "ここName",
            Importance = Importance.High,
            Description = "ここDescription",

        };
        AndroidNotificationCenter.RegisterNotificationChannel(c);
    }

    //通知の関数　関数名は自由につける
    public void DoNotification()
    {
        // 通知を送信する
        var n = new AndroidNotification
        {
            Title = "ここTitle",
            Text = "ここText",
            //アイコンはなくても動く
            //SmallIcon = "icon_0",
            //LargeIcon = "icon_1",
            //FireTime = DateTime.Now.AddSeconds(10), // 10 秒後に通知
            FireTime = DateTime.Now.AddSeconds(30), // 10 秒後に通知

        };      
        AndroidNotificationCenter.SendNotification(n, m_channelId);
        
    }
}

```



■呼び出しタイミング
遊んでいる最中に通知送ってもしょうがないので、遊んでいないときに通知を送る方法を模索します。

OnApplicationPauseで呼び出すと、ホーム画面や他のアプリに移っても通知が実施される（なぜかたまに通知来ないけど）。


■通知のキャンセル
通知のキャンセルをしないと、フォアグラウンドに復帰したのに通知が来るハメになります。

通知のキャンセルは
CancelAllScheduledNotifications()
を使う。

仕様はこちら
https://docs.unity3d.com/Packages/com.unity.mobile.notifications@1.0/api/Unity.Notifications.Android.AndroidNotificationCenter.html

通知予定をキャンセルしてくれるので、通知が来なくなります。


ちなみに通知済みをキャンセル（削除）してくれるのがこちら。
CancelAllDisplayedNotifications()

これを走らせると、アプリ復帰時に通知済みを削除するので、通知がすっきりします。

なのでこんな感じに。

    private void OnApplicationPause(bool pause)
    {
        //一時停止(ホームボタンを押す)
        if (pause)
        {
            DoNotification();
        }
        //再開時
        else
        {
            AndroidNotificationCenter.CancelAllDisplayedNotifications();
            AndroidNotificationCenter.CancelAllScheduledNotifications();
        }
    }


■課題
この機能はunityの機能を使っているっぽいので、unity（アプリ）が落ちると通知が来なくなる。アプリが落ちてる時こそ通知で再来訪してほしいんだけど。。。

この辺は今後のUnityのアップデートに期待かな。
探索的テストを勉強しました。

#探索的テスト

##テストケースベースのテスト

探索的テストを話す前に、
ストケースベースのテストについて、話します。

テストケースベースのテストは、
要件の機能を確認するために、入力値、実行条件、期待される結果を用意して、テストをする

簡略的な流れは、
【ソフトウェアの理解】→【テストケース作成】→【テストケース試行】

これは、悪い方法はないですが、こんな考え方をする方がいらしゃるとかもしれないです。

- テストケース作成は、時間がかかる。
- テストケースを用意するより、実際色んなことを確認してテストしたい。
- テストを何回繰り返すのは、意味がない

##探索的テスト

テストケースの作成の時間を最小限に抑えながら、
テストエンジニアの発見的な知的能力を最大限に活用して、テストを実行すること

###探索的テストの構成要素

![wefasf.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/421654/5144e052-b9aa-46d6-a08f-bb3ed4541dae.jpeg)

テストチャーター（Test Charter）
時間制限（Time-boxing）
セッションシート（Session Sheet）
回顧（Debriefing）

#### テストチャーター（Test Charter）

対象、目的、範囲などを明示をします。
各セッションについて明確な任務を設定
チャーターを計る前各セッションごとに時間（Time-boxing）設定が必要です。

#### 時間制限（Time-boxing）

実行される各セッションごとに時間を決める

#### セッションシート（Session Sheet）

テスト結果を記録します。
また、テスト中に得られた新しいテストのアイデア、
プロダクトのための提案など必要な最低限の内容の記録。

#### 回顧（Debriefing）

テストの経験の共有を通じたチーム学習と進化
docker関連の用語が多くて混乱したのでまとめてみた

# まとめた事

以下の疑問点についてまとめました。

- docker toolbox と docker for windowsの違いは?
- 同じ事をするのに複数コマンドが存在する?
- docker-machine とは? Dockerエンジンとの違いは?

# 用語について

| 用語 | 説明 |
|:-----------|:------------------|
|Dockerエンジン|仮想環境を提供するための３つの主なコンポーネントを持つクライアント・サーバ型アプリケーション|
|Dockerホスト|Dockerエンジンが動くホスト|
|DockerToolbox|Windowsアプリケーション。仮想環境としてVirtualBoxを利用|
|Docker for Windows|Windowsアプリケーション。仮想環境としてHyper-Vを利用|
|docker-machine|ホストPCにDockerの実行環境を構築するツール|

DockerはLinuxのみ動作可能。Windowsでは仮想環境のLinux VMからDockerを利用する。Dockerを利用するためのアプリケーションとして、DockerToolbox と Docker for Windows の2つが利用できる。

- DockerToolbox
    - メリット:  
    Windows10 Pro以外からも利用できる。Virtualboxと共存可能。
    - デメリット:  
    Visual Studio CodeのDocker拡張機能が利用不可。  
- Docker for Windows
    - メリット:  
    Visual Studio CodeのDocker拡張機能が利用可。DockerホストをWindowsコマンドから操作できる
    - デメリット:  
    Windows10 Proのみ。Virtualboxと共存不可。

参考: 
- http://docs.docker.jp/v1.12/engine/understanding-docker.html
- http://docs.docker.jp/

# 全体像

新コマンドをベースに以下の3つのグループに分類して全体の流れを書いています。

- docker-machine
- docker image
- docker container

![docker-overview-msgothic.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/494172/1e6a55d6-f2af-8db6-4571-d14a00b773a5.png)

## 新コマンドとは

Docker v1.13以降(2017年1月18日にリリース)、 docker コマンドラインの命令体系が再編成されたため現在新旧のコマンドが混在している。

### 例

| 旧コマンド     | 新コマンド           | 説明              |
|:--------------|:--------------------|:------------------|
| docker ps     | docker container ls | コンテナ一覧の表示 |
| docker images | docker image ls     | イメージ一覧表示   |

参考: [docker container / image コマンド新旧比較](https://qiita.com/zembutsu/items/6e1ad18f0d548ce6c266)

# まとめ

- docker toolbox と docker for windowsの違いは?  
Dockerの実行環境を作成する目的は同じだが、それぞれメリットとデメリットがある。特に理由がなければDocker for Windowsが良さそう。
- 同じ事をするのに複数コマンドが存在する?  
コマンドラインの体系が再編成されたので新旧が混在している。
- docker-machine とは? Dockerエンジンとの違いは?  
Dockerエンジンは仮想環境を提供するためのアプリケーション。docker-machineはDockerエンジンが動作する環境を作成するためのコマンド。
ドメイン名にちょうどマッチする正規表現を作る

# 要旨
[ドメイン名のしくみ - JPNIC](https://www.nic.ad.jp/ja/dom/system.html) を読む機会がありまして、ドメイン名の正規表現を書いてみたくなって書いてしまいました。この記事では、作った正規表現の解説をメインに説明します。 `PHP` の `PCRE` 正規表現で書きます。

書いた正規表現の答え合わせをしようと思って、「ドメイン 正規表現」でググったのですが、上位に出てきた10件のページはみんな間違っていました。

もしかしたらもっと下の方には正しい正規表現を説明したページがあるのかもしれません。しかし、間違ったページが上に来るのはよろしくないですね。この記事が正しいと思った方は、この記事が「ドメイン 正規表現」のトップになるように協力してくださいmm

# 要件
上記のページにはこのような記載があります。この記事ではこの記載をもとに要件を定義します。
> ピリオド(.)で区切られた部分は「ラベル」と呼ばれます。 一つのラベルの長さは63文字以下、ドメイン名全体の長さは、 ピリオドを含めて253文字以下でなければなりません。※1 ラベルには、英字(A～Z)、数字(0～9)、 ハイフン( - )が使用できます(ラベルの先頭と末尾の文字をハイフンとするのは不可)。 ラベル中では大文字・小文字の区別はなく、 同じ文字とみなされます。

以下を要件とします ↓

1. ラベルとは、ハイフン(-)、数字(0-9)、アルファベット大文字(A-Z)、アルファベット小文字(a-z)のみからなる文字列である ※1
1. ラベルの長さは1文字以上、63文字以下である ※2
1. ラベルの先頭と末尾の文字はハイフンではない
1. ドメイン名とは、1つ以上のラベルの列をピリオド(.)で繋げた文字列である
1. ドメイン名の長さには制限がないものとする ※3

- ※1: 大文字・小文字の区別はない、と書かれているので、アルファベット大文字(A-Z)に加えてアルファベット小文字(a-z)を含めています。
- ※2: 最低文字数に言及されていないので、勝手に1文字以上にしておきました。本質的ではないと考えているので適当です。
- ※3: ドメイン名の長さは253文字以下、と書かれていますが、そんなのはあとで `strlen()` でもすればいいので本質的ではないと考えて無視しました。

# 解答

```PHP
$regexp = '/^(?!\-)[\-0-9A-Za-z]{1,63}(?<!\-)(?:\.(?!\-)[\-0-9A-Za-z]{1,63}(?<!\-))*$/';
```

# 解説

[PHP: PCRE 正規表現構文 - Manual ](https://www.php.net/manual/ja/reference.pcre.pattern.syntax.php) はとても充実しています。なので、わざわざまとめ直すことはせず、長部の解説を読むのに必要なドキュメントのリンクを貼るようにします。

## ラベルの正規表現

### Step 1: 

> 1\. ラベルとは、ハイフン(-)、数字(0-9)、アルファベット大文字(A-Z)、アルファベット小文字(a-z)のみからなる文字列である ※1

を実装すると

```PHP
$regexp = '/[\-0-9A-Za-z]*/';
```

#### 参考文献

- [PHP: 文字クラス - Manual ](https://www.php.net/manual/ja/regexp.reference.character-classes.php)
- [PHP: エスケープシーケンス - Manual ](https://www.php.net/manual/ja/regexp.reference.escape.php)
- [PHP: 繰り返し - Manual ](https://www.php.net/manual/ja/regexp.reference.repetition.php)

### Step 2:

> 2\. ラベルの長さは1文字以上、63文字以下である ※2

を加えて実装すると

```PHP
$regexp = '/[\-0-9A-Za-z]{1,63}/';
```

#### 参考文献

- [PHP: 繰り返し - Manual ](https://www.php.net/manual/ja/regexp.reference.repetition.php)

### Step 3:

> 3\. ラベルの先頭と末尾の文字はハイフンではない

をさらに加えて実装すると

```PHP
$regexp = '/(?!\-)[\-0-9A-Za-z]{1,63}(?<!\-)/';
```

#### 参考文献

- [PHP: 言明 - Manual ](https://www.php.net/manual/ja/regexp.reference.assertions.php)

## ドメイン名の正規表現

見やすさのため、一旦 `LABEL = (?!\-)[\-0-9A-Za-z]{1,63}(?<!\-)` と置くことにします。これは、 `LABEL` が出てきたら `(?!\-)[\-0-9A-Za-z]{1,63}(?<!\-)` で置換する、ということを意味すると約束します。マクロの感覚で導入しました。

> 4\. ドメイン名とは、1つ以上のラベルの列をピリオド(.)で繋げた文字列である

を実装すると

```PHP
// PCRE ではマクロは使えないので、そのままでは動きません
// キャプチャしても使わないものはキャプチャしない主義なので (?:) を使っています
$regexp = '/LABEL(?:\.LABEL)*/';
```

マクロを展開し、始まりと終わりの言明もつけると

```PHP
$regexp = '/^(?!\-)[\-0-9A-Za-z]{1,63}(?<!\-)(?:\.(?!\-)[\-0-9A-Za-z]{1,63}(?<!\-))*$/';
```

#### 参考文献

- [PHP: サブパターン - Manual ](https://www.php.net/manual/ja/regexp.reference.subpatterns.php)
- [PHP: メタ文字 - Manual ](https://www.php.net/manual/ja/regexp.reference.meta.php)

# おわりに

他のページが間違っているんだ！と言ってこの記事を書きましたが、そもそもこの記事も間違っているかもしれません。もしくは、間違っていないにしても、本質的なところを本質的でないと言って切り捨てているかもしれません。変なところに気づいた方は、コメント欄にてボコボコにして頂けると幸いです。
ubuntuのエラー対処[Could NOT find Atlas]

# はじめに
結構前のことなので何かは忘れてしまいましたが、実行時にタイトルにあるエラーが発生しました。

その時にメモしておいた解決方法を記載します。

# エラー内容
タイトル通りですが一応。

```sh:error
Could NOT find Atlas
```

# 解消するためのコマンド
 `Atlas`が無いとのことで以下のコマンドを実行することでエラーが解消されました。

```sh:solution
$ sudo apt install libatlas-base-dev
```
ubuntuのエラー対処[Could NOT find PROTOBUF Compiler]

# はじめに
結構前のことなので何かは忘れてしまいましたが、実行時にタイトルにあるエラーが発生しました。

その時にメモしておいた解決方法を記載します。

# エラー内容
タイトル通りですが一応。

```sh:error
Could NOT find PROTOBUF Compiler
```

# 解消するためのコマンド
 `PROTOBUF Compiler`が無いとのことで以下のコマンドを実行することでエラーが解消されました。

```sh:solution
​$ sudo apt install protobuf-compiler
```
IBM Cloud Kubernetes Service上のKanikoからIBM Cloud Container RegistryにイメージをpushするためのSecretの設定方法


# 目的

Kanikoはコンテナイメージを作成するためのコンテナです。最近はCI/CDのパイプラインそのものをコンテナで実装するケースが増えてきていますが、その中でイメージを生成してレジストリに登録する際によく使われるツールです。

> https://github.com/GoogleContainerTools/kaniko

さて、IBM Cloud Kubernetes Service（以下、IKS）でKanikoを使用してIBM Cloud Container Registry（以下、ICR）にイメージをプッシュする際に、レジストリのトークンをうまくKanikoに渡す必要がありますので、その方法を紹介します。

# 方法

## Secretの確認

最近プロビジョンしたIKSであれば、下記のトークンがSecretとして登録されているはずです。

```
$ kubectl get secret -n default | grep icr
default-au-icr-io     kubernetes.io/dockerconfigjson        1      20d
default-de-icr-io     kubernetes.io/dockerconfigjson        1      20d
default-icr-io        kubernetes.io/dockerconfigjson        1      20d
default-jp-icr-io     kubernetes.io/dockerconfigjson        1      20d
default-uk-icr-io     kubernetes.io/dockerconfigjson        1      20d
default-us-icr-io     kubernetes.io/dockerconfigjson        1      20d
```

これを利用します。

## その1. ServiceAccountのSecretを追加する

defaultのServiceAccountを使用しているとします。kubectl patchまたはeditでsecretsにイメージをプッシュしたいリージョンのsecretを追加します。

```
$ kubectl edit sa default

# Please edit the object below. Lines beginning with a '#' will be ignored,
# and an empty file will abort the edit. If an error occurs while saving this file will be
# reopened with the relevant failures.
#
apiVersion: v1
imagePullSecrets:
- name: default-icr-io
- name: default-us-icr-io
- name: default-uk-icr-io
- name: default-de-icr-io
- name: default-au-icr-io
- name: default-jp-icr-io
kind: ServiceAccount
metadata:
  creationTimestamp: "2019-09-02T02:18:45Z"
  name: default
  namespace: default
  resourceVersion: "2648750"
  selfLink: /api/v1/namespaces/default/serviceaccounts/default
  uid: fd8c5622-cd27-11e9-aad6-82ec3bdf12d1
secrets:
- name: default-token-2h2lz
- name: default-jp-icr-io # <- 追加（jp.icr.ioの場合）
```

## その2. SecretをVolumeMountして渡す

方法1はServiceAccountの設定変更をすることになるので、嫌な人は、Kaniko実行時にSecretをファイルとしてマウントして見せる方法もあります。

```text:Pod,TektonのTask定義等
      env:
        - name: "DOCKER_CONFIG"
          value: "/builder/home/.docker/"
      volumeMounts:
        - name: kaniko-secret
          mountPath: /builder/home/.docker/config.json
          subpath: .dockerconfigjson
  volumes:
    - name: kaniko-secret
      secret:
        secretName: default-jp-icr-io
```

以上です。
DSPラジオ用　水晶発振回路　32.768kHz 74HCU04

#はじめに
* DSPラジオの場合、クロックの供給が必要だが、多くのICでは発振回路を内蔵しており、水晶（クリスタル）を外付けで接続すればOKなケースも多い。
* 外部からのクロック供給が必要なICもあるので、水晶発振に挑戦してみた。ブレッドボード上に組んでみましたが、上手くいきました。

#使用したもの
* 水晶（32.768Khz）円筒形のやつです。
* セラミックコンデンサー 22PF * 2
* 抵抗　10MΩ、470KΩ
* ロジックIC 74HCU04
* AN299　Silicon Labsの参考資料。32.768kHzの発振回路についての資料。
* [この記事](https://blog.goo.ne.jp/mappimk2/e/0c6b46fd923f3cda09cc8008727138ac)を参照させていただきました。

#回路、配線
* 上記の記事を参照に回路をミニブレッドボードに組んでみました。インバータ回路は１と６を使いました。未使用の回路の入力ピンはグラウンドに落としています（開放のままでも動作しました）。
* 電源はArduinoの3.3V出力を使いました。ここではArduinoは単に電源として使っています。
![crystal32768BB.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/482773/af698ea1-124f-ebe1-c1b8-651404833104.jpeg)
![CRYSTAL_32768_BB.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/482773/eb63f921-de38-ba92-a425-be9c03170d60.jpeg)

#出力波形
* クロック出力を手元の簡易オシロで計測してみました。一応、32.768kHz近辺で発振しているようです。波形の良し悪しなどはよくわからないのですが。
![crystal23768_wave.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/482773/459ed7bb-1dc8-c7e2-d731-f7fc094bcac8.jpeg)

#おまけ
* AN299を読むと、回路のレイアウトに注意を払わないといけないようですが、あまり気にせず回路を組んでみました。基板上に組むときは考慮する必要あるのかも。
* ワンチップの水晶発振器（オシレータ/クロックジェネレータ）は多数あるのですが、32.768kHzの発振器はあまり見つかりません。
* Silicon Labs の Si5351A も試してみたのですが、本用途に使うにはもったいない感じがしました。
線形計画問題を Python + Google OR-Tools で解いて潜在価格を調べる

線形計画問題(Linear Programming: LP)を勉強すると必ずついてくる「潜在価格」の話がありますが，Google OR-Toolsの線形計画ソルバー(Glop)ではこれをさくっと取り出すことができます。
潜在価格は，双対価格とかShadow Priceとか言われることもあります。

たとえば，制約式のオブジェクトconstraint1に対して

```python
pi1 = constraint1.DualValue()
```

とすると潜在価格が取得できます。

[OR-Tools公式のサンプル](https://developers.google.com/optimization/lp/glop?hl=ja)をほぼそのまま写して，そのうしろに，3つある制約式それぞれの潜在価格を書き出してみます。潜在価格の変数にはよく$\pi$を使うのでそんな雰囲気でprintしてみます。

```python
from ortools.linear_solver import pywraplp

def main():
    """線形計画問題のサンプル"""
    # ソルバーのインスタンスを生成
    solver = pywraplp.Solver('LP1', pywraplp.Solver.GLOP_LINEAR_PROGRAMMING)

    # LPの変数を宣言
    x = solver.NumVar(0, solver.infinity(), 'x')  # コピペ元と違うけど
    y = solver.NumVar(0, solver.infinity(), 'y')  # なんとなく非負制約を付けたくなる…

    # 制約 0: x + 2y <= 14.
    constraint0 = solver.Constraint(-solver.infinity(), 14)
    constraint0.SetCoefficient(x, 1)
    constraint0.SetCoefficient(y, 2)

    # 制約 1: 3x - y >= 0.
    constraint1 = solver.Constraint(0, solver.infinity())
    constraint1.SetCoefficient(x, 3)
    constraint1.SetCoefficient(y, -1)

    # 制約 2: x - y <= 2.
    constraint2 = solver.Constraint(-solver.infinity(), 2)
    constraint2.SetCoefficient(x, 1)
    constraint2.SetCoefficient(y, -1)

    # 目的関数: maximize 3x + 4y.
    objective = solver.Objective()
    objective.SetCoefficient(x, 3)
    objective.SetCoefficient(y, 4)
    objective.SetMaximization()

    # 求解開始
    solver.Solve()

    print('変数の個数 =', solver.NumVariables())
    print('制約の個数 =', solver.NumConstraints())

    # 最適解を取得
    print('最適解:')
    print('目的関数値 =', solver.Objective().Value()) # 目的関数値はこれでも取れる
    print('x = ', x.solution_value())
    print('y = ', y.solution_value())

    # 各制約式の潜在価格を取得
    print('潜在価格:')
    print('Pi_0 =', constraint0.DualValue())
    print('Pi_1 =', constraint1.DualValue())
    print('Pi_2 =', constraint2.DualValue())


if __name__ == "__main__":
    main()
```

実行結果です。

```
変数の個数 = 2
制約の個数 = 3
最適解:
目的関数値 = 33.99999999999999
x =  5.999999999999998
y =  3.9999999999999996
潜在価格
Pi_0 2.333333333333333
Pi_1 -0.0
Pi_2 0.6666666666666661
```
AnsibleでWindowsのDNSの逆引きレコードを追加したときの話

#概要
WindowsのDNS逆引きレコードを追加しようとしたら、変なレコードが出来上がった話です。

#環境
Ansible環境:CentOS7.6+Ansible2.8.5
ターゲット:Windows2016
ネットワーク:192.168.0.0/16

#背景
ドメインコントローラで、Windows2016 ServerCoreを利用していたので、Ansibleでレコード登録をやろうと思いました。
AnsibleのDocumentを探していたら、「win_dns_record」なるものを発見。
逆引き登録がOKそうなので、試してみることにしました。

#何が起きた？
正引きは、特に問題なくAレコードを作成できたので、今回は割愛します。

問題は逆引きです。
まず、レコード登録するZoneは存在している必要があります。
(無ければ事前に作成が必要です。今回は設定情報を明確にするため、サブネットは/16にしています。)

次に下記のようなPlaybookを作成しました。

```yml:dns_record.yml
name: Create PTR Record
win_dns_record:
  name: "192.168.1.100"
  state: present
  type: "PTR"
  value: "foo.hoge.com"
  zone: "168.192.in-addr.arpa"
```

登録されたレコードは下記の通りでした。

```text
192.168.1.100.1.168.192 Pointer (PTR) foo.hoge.com
```

？？？
Bugだ！と思ってGitHubみたら、すでにCloseされていました･･･
[win_dns_record incorrectly creates PTR records](https://github.com/ansible/ansible/issues/60068)
Playbookは、下記のように修正すれば、正しく登録されました。

```diff:dns_record.yml
name: Create PTR Record
win_dns_record:
- name: "192.168.1.100"
+ name: "100.1"          #"1.100"ではないです
  state: present
  type: "PTR"
  value: "foo.hoge.com"
  zone: "168.192.in-addr.arpa"
```

```text
192.168.1.100 Pointer (PTR) foo.hoge.com
```

公式サイトに凡例を追記するっぽいですね。
IPアドレスをひっくり返すのがポイントかと思います。
C#でコードコントラクトを書いてみた（使ったとは言ってない）

# 概要

[．ＮＥＴのエンタープライズアプリケーションアーキテクチャ　第２版 (マイクロソフト公式解説書)](https://www.amazon.co.jp/dp/4822298485)を読んでいて、コードコントラクトというのを知りました。

というわけで実験しようと思ったのですが、`Code Contracts for .NET` が Visual Studio 2017で使えないため、試すことができませんでした。

## 試したこと

[コードコントラクト](https://docs.microsoft.com/ja-jp/dotnet/framework/debug-trace-profile/code-contracts)をみると、`CONTRACTS_FULL` が定義されている必要があるみたい。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/7886/7142abac-6b45-3b58-a3c0-5bcff67d5b04.png)

で、いい感じに `Contract.Requires` を追加してみる。

```c#
        /// <summary>
        /// 割り算
        /// </summary>
        /// <param name="divisor">割られる数</param>
        /// <param name="dividend">割る数</param>
        /// <returns></returns>
        private double div(double divisor, double dividend)
        {
            Contract.Requires(dividend != 0);
            return divisor / dividend;
        }
```

が、エラー。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/7886/6a87880e-35c9-9d7e-ffc3-71f79f651e3a.png)

## Extentionsを入れる

[Code Contracts for .NET](https://visualstudiogallery.msdn.microsoft.com/1ec7db13-3363-46c9-851f-1ce455f66970) をダウンロード＆インストール。

`[Code Contracts]ペイン` どこ？？
> Works with
> Visual Studio 2010, 2012, 2013, 2015

えー・・。

## 先人のソースコード

GitHubで使い方を検索してみた。
`Requires` も、`if-then-throw`も書かれてる。
`Contract` はあくまでデバッグ用だったのかな？？
今はもう使われないのかな？？

[housnberg/inf3project/game/game/client/Connector.cs](https://github.com/housnberg/inf3project/blob/24fba4f19fd4a0ec9d1c31b19ab8fcc5a6ad4fd0/game/game/client/Connector.cs#L58-L95)

```c#
        public void connect(String ip, UInt16 port)
        {
            Contract.Requires(ip != null);
            Contract.Requires(ip.Length > 6);
            Contract.Requires(ip.Length < 16);
            Contract.Requires(port >= 0);
            Contract.Requires(port <= 65535);
            
                try
                {
                    if (ip == null || ip.Length > 16 || ip.Length < 7)
                    {
                        throw new ArgumentException("parameter cannot be null and parameter length must be bigger 7 and smaller 16");
                    }
                    else
                    {
                        if (client == null || !client.Connected)
                        {
                            client = new TcpClient(ip, port);
                            buffer.clear();
                        }
                        else
                        {
                            throw new SystemException("the client is already connected!");
                        }
                        Console.WriteLine("client connected");
                    }
                }
                catch (Exception exeption)
                {
                    Console.WriteLine(exeption.Message);
                }
            
            
            Contract.Ensures(client != null);
            Contract.Ensures(client.Connected);
            Contract.Ensures(receiverThread.IsAlive);
        }
```

## 参考文献

- [．ＮＥＴのエンタープライズアプリケーションアーキテクチャ　第２版 (マイクロソフト公式解説書)](https://www.amazon.co.jp/dp/4822298485)

以上。
【超級初心者のための】詳細タブの内容【Unreal Engine 4】

![無題.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/501431/015bca62-b490-d741-4ec4-7c58aea37335.png)
※表示されていない場合、メニュー「ウィンドウ→詳細→詳細1」をクリックで表示される

# トランスフォーム
- 位置：座標
- 回転：角度
- 拡大・縮小：サイズ
- 可動性：？？？

# Static Mesh
- Static Mesh：？？？

# Materials
- エレメント0：？？？

# Phisics
- Simulate Physics：物理演算を行うかどうか
- Masking：？？？
- Liner Damping：？？？
- Angular Damping：？？？
- Enable Gravity：？？？
- コンストレイント：？？？
- Ignore Radial Impulse：？？？
- Ignore Radial Force：？？？
- Apply Impulse on Damage：？？？

# Collision
- ？？？

# Lighting
- ？？？

# Rendering
- ？？？

# Tags
- ？？？

# Cooking
- ？？？

# Actor
- ？？？

# HLOD
- ？？？

# Mobile
- ？？？

# Asset User Data
- ？？？

# Navigation
- ？？？
Node-REDのhttp requestノードで自己証明書を利用する

# 目的

Node-REDの`[http request]ノード`で自己証明書を利用できるように設定する。

# 事象

Node-REDの`[http request]ノード`で自己証明書を使用しているサーバにアクセスしようとした場合、次のエラーが発生することがある。

```
Error: self signed certificate in certificate chain
```
```
SELF_SIGNED_CERT_IN_CHAIN
```

# 解決方法

Node-REDに`CA証明書`を登録し、`[http request]ノード`から参照できるようにする。

1. `[http request]ノード`の`[プロパティ]`を開く。
1. `[SSL/TLS接続を有効化]`チェックボックスにチェックを付ける。
1. `[TLS設定]`プルダウンが表示されるので、右にある`[鉛筆アイコン]`ボタンをクリックする。
1. `[ローカルファイルの秘密鍵と証明書を使用]`チェックボックスのチェックを外す。
1. `[CA証明書]`の右にある`[ファイル]`ボタンをクリックする。
1. ローカルPCに保管されている`[CA証明書]`ファイル(cacert_yyyymmdd.crtなど)を指定する。
1. `[サーバ証明書を確認]`チェックボックスのチェックを外す。
1. `[追加]`ボタンをクリックする。
1. `[TLS設定]`プルダウンに`[TLS設定]`が1つあり、選択されていることを確認する。
1. `[完了]`ボタンをクリックする。
1. `[デプロイ]`ボタンをクリックする。
SQL クエリの学習（基礎)

# SQL クエリの基礎から学習
+ SELECT文

```.sample.sql

SELECT name  # SELECTの後にnameというカラムをこの場合は指定している。
```
+ FROM

purchasesテーブルからnameカラムのデータを取得するには下記のようになる。

```.sample.sql
SELECT name     # ②どのカラムのデータを？
FROM purchases; # ①どのテーブルの？
```

+ 複数のカラムを取得する場合

```.sample.sql
SELECT name, price  # nameとpriceカラムのデータを取得する
FROM purchases;
```

+ 全てのカラムからデータを取得する場合

```.sample.sql
# SELECT id, name, price, user_name, category, purchased_at としても取得はできるが

SELECT *    # これで全てのカラムのデータが取得できる。
FROM purchases;
```
# 特定のデータの取得
+ WHERE 「どこのレコード(横の列)を取得するか」

```.sample.sql
WHERE category = ○○   # categoryカラムが○○であるレコードを取得
```

# データ型の種類
参考テーブル

|カラム|データ型|保存されているデータ|
|-----|------|---------------|
|id|数値|1|
|name|テキスト|"お弁当"|
|price|数値|1000|
|user_name|テキスト|"太郎"|
|category|テキスト|"食費"|
|purchased_at|日付|"2019-09-22"|

「category」カラムの中の「食費」であるデータを取得する。
「食費」というデータ型はテキストなのでクォテーションで囲む必要がある。

```.sample.sql
SELECT *
FROM purchases
WHERE category = "食費";  #テキストデータはクォーテーションで囲むことに注意。
```

+ 数値データを取得する場合

クォーテーションで囲まない

```.sample.sql
SELECT *
FROM purchases
WHERE price = 1000;  #クオーテーションで囲まない。
```

+ 日付データを取得する場合

クォーテーションで囲む

```.sample.sql
SELECT *
FROM purchases
WHERE purchased_at = "2019-09-22"  #クォーテーションで囲むことに注意。
```

以上、今日の復習アウトプットでした。
【書いて覚えるTypeScript 】変数・定数宣言、関数編

# 動作環境
[TypeScript Playground](https://www.typescriptlang.org/play/index.html)

# 参考
[TypeScript Handbook](https://www.typescriptlang.org/docs/handbook/basic-types.html#toc-handbook)

# 変数・定数宣言

```typescript
let 変数名: 型 = 初期値;
var 変数名: 型 = 初期値;
const 変数名: 型 = 初期値; 
```

## 基本的な例
object型、enum型、tuple型など他にも色々ありますが、書き方の問題なので、必要になった際に[公式Handbook](https://www.typescriptlang.org/docs/handbook/basic-types.html#toc-handbook)を見たほうが頭に残りやすいでしょう。

※ オブジェクトについては、後述するInterfaceを活用することが多いと思うので割愛。

```typescript
// boolean
let isDone: boolean = true;
// number
let decimal: number = 6;
// string
let firstName: string = 'Taro';
let lastName: string = 'Yamada';
let fullName: string = `${firstName} ${lastName}`;

// array
let numArray: number[] = [1, 2, 3]; // 要素がnumber型のarray
let strArray: string[] = ['Japan', 'China', 'Korea']; // 要素がstring型のarray
// any 何でも入れれる
// 異なる型を代入してもエラーにならない。
let anyVar: any = 1;
anyVar = 'hoge';
anyVar = [1, 2, 3];

// null, undefined
let u: undefined = undefined;
let n: null = null;
```

## 複数の型を指定したい場合

`null`と`number`を許容したいというケースがあると思います。（例えば、`id`とか）
そういった場合は、`|`で複数指定します。

```typescript
let userId: number | null = 1;
userId = null; // エラーにならない
userId = '2'; // => Type '"2"' is not assignable to type 'number | null'.
```

## 型推論
letやvarではデータ型を省略して、初期値を与えた場合、型推論が働きます。

```typescript
let status = 'close';
status = 'open';
status = 10; // エラー。Type '10' is not assignable to type 'string'.
```

初期値として、String型のデータを代入しているので、その後に異なる型の値を代入しようとするとエラーになります。

また、初期値も省略してしまうと、Any型になるので、どんなデータ型でも代入することができます。

```typescript
let antData;
antData = 1;
antData = 'close';
antData = { type: 'close', message: 'close status' };
```

# 関数定義

```
function 関数名(引数1: 型, 引数2: 型): 戻り値の型 {
    ...
}
```

関数の場合も基本的な例を書いていきましょう。

## 基本的な例

- 数値同士の足し算をする関数add

```typescript
function add (num1: number, num2: number): number {
    return num1 + num2;
}
add(1, 2); // => 3
// 引数の型が違うのでエラー
add('1', '2'); // => Argument of type '"1"' is not assignable to parameter of type 'number'
```

- アロー関数

```typescript
const calcArea = (width: number, height: number): number => {
    return width * height;
}

calcArea(10, 20);
```


## 値を返さない関数の場合
値を返さない場合は`void`型を使います。

```typescript
function putsError(message: string): void {
    console.error(message);
}

putsError('log error');
```


## オプショナルな引数の場合

オプショナルな引数には、引数名の後ろに`?`をつけます。

```typescript
function buildName(firstName: string, lastName?: string): string {
    if (lastName) {
        return firstName + " " + lastName;
    } else {
        return firstName;
    }
}

buildName("Taro");
```

## デフォルト値のある引数の場合

```typescript
function displayTime(date: Date = new Date()): string {
    return date.toLocaleTimeString();
}
displayTime();
```

次回は、[インターフェース(interface)編](https://qiita.com/nomuyoshi/items/781a84c278f163f7907b)です。
kintone モバイルにタブ表示

kintone 新モバイルUIは、アプリを探しやすくなったり、一覧が見やすくなったりと改善されましたが、肝心のレコード詳細画面や編集画面が相変わらず。
見たい項目が見つからない...、縦にスクロール・スクロール・スクロール・・・。
そう縦に長すぎるのだ。そんなモバイルにタブ表示を。


# タブ表示プラグインがモバイル対応

[rex0220 タブ表示プラグイン](https://qiita.com/rex0220/items/1af3527d60fbaecbfceb)が、2019年10月にリリース予定の Ver.9 で、モバイル対応します。

<img width="715" alt="2019-09-22_15h11_45.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100572/85e1831b-9a90-09ff-1c93-fff1be0ed28f.png">

# タブ表示プラグイン操作例

縦にスクロールすると、タブが上部に残りますので、切り替えが簡単ですね。

![2019-09-22_22h55_09.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100572/801d91bd-4646-e5db-b51b-14f8e9a32e8f.gif)


# タブ表示プラグインの設定

これまでと同様です。モバイル対応で新たに設定する箇所はありません。

<img width="1128" alt="2019-09-22_23h24_10.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100572/8dbb709d-cd51-53a6-1d9f-0b0ce1fdd853.png">


# 関連

[rex0220 タブ表示プラグイン](https://qiita.com/rex0220/items/1af3527d60fbaecbfceb)
[kintone 従業員名簿アプリのタブ表示例](https://qiita.com/rex0220/items/d4d0f2fd86875ac11f91)

# あとがき

今後 kintone でのモバイル利用が進んでいくと、仕事がスマホだけでこなせるかも。
ローマ字入力を平仮名に変換する

改良中。。。
覚書としてのこします。


```main.cpp
#include <iostream>
#include <string>
#include <map>
#include <vector>
#include <algorithm>
#include <stdio.h>
#include <cstdlib>

const std::vector<std::uint8_t> sDictionary1 = {
	' ','k','s','t','n','h','m','y','r','w','g','z','d','b','p','f'
};

const std::vector<std::uint8_t> sDictionary2 = {
	'a','i','u','e','o' 
};

const std::vector<std::string> sDictionary3 = {
	"あ", "い", "う", "え", "お",
	"か", "き", "く", "け", "こ",
	"さ", "し", "す", "せ", "そ",
	"た", "ち", "つ", "て", "と",
	"な", "に", "ぬ", "ね", "の",
	"は", "ひ", "ふ", "へ", "ほ",
	"ま", "み", "む", "め", "も",
	"や", "  ", "ゆ", "  ", "よ",
	"ら", "り", "る", "れ", "ろ",
	"わ", "  ", "を", "  ", "ん",
	"が", "ぎ", "ぐ", "げ", "ご",
	"ざ", "じ", "ず", "ぜ", "ぞ",
	"だ", "ぢ", "づ", "で", "ど",
	"ば", "び", "ぶ", "べ", "ぼ",
	"ぱ", "ぴ", "ぷ", "ぺ", "ぽ",
	"ふぁ", "ふぃ", "ふ", "ふぇ", "ふぉ", 
};

const std::vector<std::string> sDictionary4 = {
	"あ", "い", "う", "え", "お",
	"きゃ", "きぃ", "きゅ", "きぇ", "きょ",
	"しゃ", "しぃ", "しゅ", "しぇ", "しょ",
	"ちゃ", "ちぃ", "ちゅ", "ちぇ", "ちょ",
	"にゃ", "にぃ", "にゅ", "にぇ", "にょ",
	"ひゃ", "ひぃ", "ひゅ", "ひぇ", "ひょ",
	"みゃ", "みぃ", "みゅ", "みぇ", "みょ",
	"や", "  ", "ゆ", "  ", "よ",
	"りゃ", "りぃ", "りゅ", "りぇ", "りょ",
	"わ", "うぃ", "うぅ", "うぇ ", "を",
	"ぎゃ", "ぎぃ", "ぎゅ", "ぎぇ", "ぎょ",
	"じゃ", "じぃ", "じゅ", "じぇ", "じょ",
	"ぢゃ", "ぢぃ", "ぢゅ", "ぢぇ", "ぢょ",
	"びゃ", "びぃ", "びゅ", "びぇ", "びょ",
	"ぴゃ", "ぴぃ", "ぴゅ", "ぴぇ", "ぴょ",
	"ふぁ", "ふぃ", "ふ", "ふぇ", "ふぉ",
};

int main()
{
	std::string aInput;
	std::cout << "アルファベットを入力する：" << std::endl;
	std::cin >> aInput;

	// 文字サイズ
	auto aSize = aInput.size();

	// アルファベット判定
	for (auto i = 0u; i < aSize; ++i) {
		if ((aInput[i] >= 0x41) && (aInput[i] <= 0x5A)) {
			aInput[i] += 0x20; // 大文字→小文字
		}
		else if ((aInput[i] >= 0x61) && (aInput[i] <= 0x7A)) {
			// Do Nothing;
		}
		else {
			std::cout << "Not Alphabet!!" << std::endl;
			std::exit(1);
		}
	}

	std::string aOutput;

	auto aPoss = aInput.begin();
	auto aEndPoss = aInput.end();

	do {
		auto aIndexItr = std::find(sDictionary1.begin(), sDictionary1.end(), *aPoss);
		auto aOyaIndex = 0u;
		if (aIndexItr != sDictionary1.end()) {
			aOyaIndex = aIndexItr - sDictionary1.begin(); // 1文字目が子音だった場合

			if (*aPoss == *(aPoss + 1)) {
				aOutput += "っ";
				++aPoss;
			}
			++aPoss;
		}

		auto aFlag = false;
		if (*aPoss == 'y') {
			aFlag = true;
			++aPoss;
		}

		// 1文字目が母音だった場合
		auto aTempIndexItr = std::find(sDictionary2.begin(), sDictionary2.end(), *aPoss);
		auto aKodomoIndex = 0u;
		if (aTempIndexItr != sDictionary2.end()) {
			aKodomoIndex = aTempIndexItr - sDictionary2.begin(); // 1文字目が子音だった場合
		}

		auto aTable = aFlag ? sDictionary4 : sDictionary3;
		aOutput += aTable.at(aOyaIndex * 5 + aKodomoIndex);
		++aPoss;
	}
	while (aPoss != aEndPoss);

	std::cout << aOutput << std::endl;

    return 0;
}
void foo(const char* iStr, std::weak_ptr<std::ostream> oPtr)
{
	// wpの監視対象であるspが、有効なリソースを保持している状態なら処理する。
	if (std::shared_ptr<std::ostream> r = oPtr.lock()) {
		*r << iStr << std::endl;
	}
}
```
Pythonの正規表現における、「\（バックスラッシュ）」で混乱したこと

Pythonの正規表現でバックスラッシュ`\`の扱いで混乱した際に、自分なりに整理した事項をまとめました。

今後、新たにPythonを学ぶ方の参考になれば幸い。

正規表現の解説や練習問題をやると出てくる以下のような表記、最初ちょっと混乱しました。

```python
pattern1 = r"\[.+\]"
```
このバックスラッシュってなんのためにあるのだ・・・？　と・・・
結論から言うと、このバックスラッシュ`\`は、
正規表現において特殊な意味を持つ文字を、意味のない文字列として認識させるための表記です。

**参考）分かりやすいpythonの正規表現の例**
https://qiita.com/luohao0404/items/7135b2b96f9b0b196bf3

Pythonにおける正規表現では、`[`や`]`は特殊な意味を持つメタ文字となります。
集合を表すために使われ、例えば、

`[a-c]`

という表記はraw文字列中であっても、`[a-b]`という文字列ではなく、
「aからcまでの集合」として扱われます。

では、`[` や`]`を文字列として扱いたい場合はどうすればいいでしょうか。

例えば、正規表現を用いて、ある文字列から`[]`に囲まれた文字を抽出したい、
といったような場合です。

その場合は、`[`などを純粋な文字列として認識させる必要があります。
それが直前に`\`をつける、という表記になります
以下にもありますが、

**re --- 正規表現操作**
https://docs.python.org/ja/3/howto/regex.html
>また、バックスラッシュはすべての特殊文字をエスケープするのにも利用されます、つまり、特殊文字をマッチさせることができます; 例えば、 [ または \ にマッチさせたい場合、それらをバックスラッシュに続けることで特殊な意味を除きます

ということなので、raw文字列表記の中でも、特殊文字を意味のない文字列として扱うには、
バックスラッシュ`\`をつける必要があります。

個人的には、raw文字列表記中は、バックスラッシュ`\`も文字列として認識される、
という説明を受けた後に、`r"\[.+\]"`のような表記を見えると、
「あれ、この`\`ってなんで必要なんだ・・・？」
と混乱してしまいましたが、上記の通り、正規表現における特殊文字を普通の文字列として扱うために必要な、おまじないみたいなもの、と調べて気づきました。
Wordpressのサーバーに、秘密鍵を使ってscpコマンドでファイルを送信する

すぐに忘れるので、メモに残しておきます。

##1. 秘密鍵を使ってscpコマンドでファイルを送信する

今回は、サーバー内に画像を送信してみます。

__[基本形]__

```
$ scp -i [秘密鍵] [送りたいファイル] ユーザー名@DNS名:[ファイルを送信したい場所]
```

__[実際の例]__

```
$ scp -i ~/XXX/test.pem test.png ubuntu@ec2-00-000-000-0.compute-1.amazonaws.com:~/apps/wordpress/htdocs/wp-content/themes/twentyseventeen/assets/images
test.png                                                                                                       100% 1850     5.9KB/s   00:00
```

`100% 1850     5.9KB/s   00:00`と表示されたので、無事に送信されたことがわかりました。

##2. 秘密鍵を使ってscpコマンドで複数のファイルを送信する
簡単です。どんどん追加していくだけです。

```
$ scp -i ~/XXX/test.pem test1.jpg test2.jpg test3.jpg test4.jpg test5.jpg test6.jpg test7.jpg test8.jpg test9.jpg ubuntu@ec2-00-000-000-00.compute-1.amazonaws.com:~/apps/wordpress/htdocs/wp-content/themes/twentyseventeen/assets/images
test1.jpg                                                                                                        100% 1919KB 955.3KB/s   00:02    
test2.jpg                                                                                                        100% 2644KB   4.0MB/s   00:00    
test3.jpg                                                                                                        100%  741KB   2.1MB/s   00:00    
test4.jpg                                                                                                        100% 1451KB   3.5MB/s   00:00    
test5.jpg                                                                                                           100% 1037     3.6KB/s   00:00    
test6.jpg                                                                                                        100% 1026     3.2KB/s   00:00    
test7.jpg                                                                                                        100%   36KB 152.3KB/s   00:00    
test8.jpg                                                                                                        100%   34KB 110.9KB/s   00:00    
test9.jpg                                                                                                        100% 9576    33.7KB/s   00:00    

```
まとめて送信できました。


##参考
* [scpコマンド チートシート](scp -i ~/Documents/MyPortfolio/img/)の、__鍵認証を使ってリモートにコピー__の部分を参考にさせていただきました。
Javascriptのclassのプロパティとメソッド

javascriptのclassの挙動でハマったので備忘録として残しておく。
エラーメッセージが分かりにくい。。

___

```js
class User {
  constructor(name) {
    this.name = name;
  }

  name() {
    return this.name;
  }
}

const user = new User('taro');
console.log(user.name());  // error
```

```
TypeError: user.name is not a function
```

`name` プロパティは呼んでないし `name()` メソッドを呼んだんですけど！
`taro` が返ってこればハッピーだったのですが...

ということでクラスのプロパティとメソッドの挙動を試行錯誤して実験してみた。

## まずはuserオブジェクトの確認

```js
class User {
  constructor(name) {
    this.name = name;
  }

  name() {
    return this.name;
  }
}

const user = new User('taro');
console.log(user);
```

userの中身は `User { name: 'taro' }` のようになっていた。
なんかもうこの時点でクラス感が無い。


## 試行錯誤

### 仮設

プロパティと同名のメソッドがあるとメソッドを呼べない

プロパティ `name` と、メソッド `name()` は同名っていう扱い？

### 実験

```js
class User {
  constructor(name) {
    this.name = name;
  }

  name() {
    return this.name;
  }

  getName() {
    return this.name;
  }
}

const user = new User('taro');
console.log(user.getName());  // taro
console.log(user.name);  // taro
console.log(user.name());  // TypeError: user.name is not a function
```

### 結果

`user.getName()` では設定した `name` の値が取得できた。
`user.name` では設定した `name` の値が取得できた。
`user.name()` では `TypeError: user.name is not a function` が発生した。

プロパティと同名のメソッドは共存はできるけど、あまりやらない方が良さそう。。

## Rubyだと...

```ruby
class User
  def initialize(name)
    @name = name
  end

  def name()
    @name
  end
end

user = User.new('hoge')
p user.name()  # hoge
```

`user.name()` で `name()` メソッドが呼ばれて `@name` の値が返される。
`name` は function じゃないよ！ とか言われない。


## あとがき

javascriptヨクワカラナイ...

やりたいこと

- bind について調べる
- this について調べる

## 参考

- https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Classes
【超簡単】Pythonをインストールする方法について解説

## 1.Pythonとは
- `Python` とは、 `プログラミング言語` の1つで、AIなどに代表する `機械学習用プログラム` として利用されることが多い。
- `Python` のメリットは、 `ライブラリ` が豊富なため、
少ないコードでも簡単にプログラムがかけることだ。

## 2.Pythonをダウンロードする方法
![01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/449867/56bee378-4f0c-ca50-b78c-1920b21f5a7a.png)
![02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/449867/5f90f798-480b-6738-dcef-c0d7f7797241.png)
![05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/449867/59c9e85a-19da-14c4-b49a-c00b976a17bc.png)

1. [Pythonの公式サイト](https://www.python.org/) へアクセスし、 `Downloads` にカーソルを合わせ、 `Windows` をクリック。
2. `Python Releases for Windows` の `Windows x86-64 executable installer` をクリック。
3. ダウンロードが完了したら、 `フォルダ` をチェック。
4. `python-3.7.4-amd64` がダウンロードされていれば成功。

## 3.Pythonをインストールする方法

![06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/449867/01f17aa9-1f68-d278-8627-7d59babd4864.png)
![07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/449867/1aa91794-7f14-5469-f0f1-d6fd8b566659.png)
![08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/449867/0ff62734-82a1-6d17-0a3b-6608baec5c36.png)
![09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/449867/28ca360c-e8e6-6cf1-41d1-618d061c0772.png)
![10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/449867/8251ae69-2f1b-8a2c-d53d-ede337e06edc.png)

1. ダウンロードした `python-3.7.4-amd64` を起動。
2. `Customize installation` をクリック。
3. 全ての項目にチェックをつけ、 `Next` をクリック。
4. 下の `2つの項目以外` にチェックをつけ、 インストールする `フォルダの場所` を指定し、 `Install` をクリック。
5. インストールが完了後、 `Close` をクリック。

## 4.インストールの確認
![11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/449867/4d885a42-7d2b-071d-93bf-edbd8208d212.png)
![12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/449867/9c59eba0-5d7e-6da0-4a3f-ed4c64c5f8e3.png)

```python:テストソースコード
ptint("Hello")
```

1. `コマンドプロンプト` を起動。
2. `Python` と入力。
3. `Python` の起動を確認し、上記のソースコードを入力。
4. 画像のように `Hello` と表示されれば成功。
Dockerのhello-worldが出来なかった時のメモ

#環境
MacbookPro: MacOS Mojave (version:10.14.6)
Docker:version 19.03.2

#前置き
技術書展で購入した[Dockerの漫画](https://techbookfest.org/event/tbf07/circle/5171055656173568)をみてDockerを触りたくなった。
[公式HP](https://www.docker.com/)を参考に
Get Started →　Download Desktop and... →　Docker Hubの登録する
を行いDockerをインストールして起動してみる
ターミナルを起動し以下を入力したところ...

```bash
$ docker run hello-world
```

#結果
```bash
Unable to find image 'hello-world:latest' locally
docker: Error response from daemon: Get https://registry-1.docker.io/v2/library/hello-world/manifests/latest: unexpected EOF.
See 'docker run --help'.
```
という返事が返ってきた、どうやらdaemon君がよしなにしてくれない感じ...

```bash
$ docker run --help
```
っと打ってもよく分からなかったので色々調べてみたところ、どうやらDockerにログインが必要なのかもしれないと考えた。

#対処法
<img width="426" alt="スクリーンショット 2019-09-22 22.39.01.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/407528/5334c3b3-9a08-86c5-6701-80bc76047631.png">
ここのSign in/Create Docker IDを選択し、Log inする。
ターミナルで以下を入力

```bash
$ docker login
```
こちらでもLog in する。
この違いは自分もよく分かっていないので[これ](https://qiita.com/tearoom6/items/b14913161250b2b30d0f)とかを参考にして分かった気になっておく。
Log inが成功した後に再度

```bash
$ docker run hello-world
```
を入力すれば上手くいきました
#参考引用文献
[docker](https://www.docker.com/)
[docker login での Sign in について](https://qiita.com/tearoom6/items/b14913161250b2b30d0f)
AWSのEC2を利用してWordPressを立ち上げ、sshで"Permission denied (publickey)."が返ってくる問題について

タイトルの通りですが、訳もわからず[こちらのチュートリアル](https://aws.amazon.com/jp/getting-started/tutorials/launch-a-wordpress-website/)に従いながらEC2インスタンスでWordPressを立ち上げ、sshログインする際に苦しんだので、メモに残します。


##1. 事象："Permission denied (publickey)."エラーで、sshログインできない

```
$ ssh -i test.pem ec2-user@ec2-0-00-000-000.compute-1.amazonaws.com
ec2-user@ec2-0-00-000-000.compute-1.amazonaws.com: Permission denied (publickey).
```
いくらsshコマンドを叩いても、`Permission denied (publickey).`しか返ってきません。


##2. 原因：インスタンスとキーペアが関連づけられていなかったから
[こちらのチュートリアル](https://aws.amazon.com/jp/getting-started/tutorials/launch-a-wordpress-website/)の、「ステップ 2: インスタンスを設定する」のf.にて、__[Proceed without a key pair]__で関連づけられたキーペアを作成していなかったため、そもそもインスタンスに関連した秘密鍵を作成していなかったことが原因でした。おい。

そのため、新しくインスタンスを作り直し、インスタンスに関連した秘密鍵もきちんと作成し、無事にsshログインに成功しました。

```
$ ssh -i test.pem ubuntu@ec2-00-000-000-00.compute-1.amazonaws.com
Welcome to Ubuntu 16.04.6 LTS (GNU/Linux 4.4.0-1092-aws x86_64)
*** System restart required ***
       ___ _ _                   _
      | _ |_) |_ _ _  __ _ _ __ (_)
      | _ \ |  _| ' \/ _` | '  \| |
      |___/_|\__|_|_|\__,_|_|_|_|_|

  *** Welcome to the Bitnami WordPress 5.2.3-0 ***
  *** Documentation:  https://docs.bitnami.com/aws/apps/wordpress/ ***
  ***                 https://docs.bitnami.com/aws/ ***
  *** Bitnami Forums: https://community.bitnami.com/ ***
bitnami@ip-000-00-00-00:~$
```

長かった〜。チュートリアルの流し読みは禁物ですね。
js setTimeout

#構文
 - var timeoutID = scope.setTimeout(function[, delay, param1, param2, ...]);

## 引数
- function
    - タイマーが満了した後に実行したい関数
- delay
    - ミリ秒単位でfunctionに待ち時間を作るための数値
- param1, ..., paramN
    - functionに渡す引数

## 例
```javascript
function greeting(name) {
  console.log('Hello,' + name);
}
  
setTimeout(greeting, 3000, 'World');
```
npmプロジェクトのためのnode_modulesフォルダに困らない開発用containerの作り方

mountハックはもういらない！

```markdown:フォルダ構成
- project
    - package.json
    - package-lock.json
    - index.js
    - Dockerfile
```

```dockerfile:Dockerfile
FROM node:slim
ENV PATH $PATH:/node_modules/.bin
COPY package.json package-lock.json ./
RUN npm install && npm cache clean --force
WORKDIR /usr/src/app
# Use -v ${HostOSWorkSpace}:/usr/src/app
CMD bash
```

## 説明
開発環境にcontainerを利用したい。
開発用containerは、普通のcontainerと違い、LocalWorkspaceディレクトリをマウントして使い、ソースコードの変更がHostOSにも反映されるようにしたい。
開発用containerは、npm runが動作できるようにしたい。

### 問題
node_modulesをdocker-build時にcontainerに含め、LocalWorkspaceに作らない運用をすると、docker-run時のmountで、containerのnode_modulesが隠れてしまう問題がある

### 従来の回避策A. node_modulesはcontaienrに含めない作戦
node_modulesをdocker-build時にcontainerに含めずに、docker-runでmountをしてから初めて作成し、HostOS上にnode_modulesを持ってくる。

#### だめな点
Windows上で動作しない。ファイルシステムやらパスやらの問題だと思われる。Windows上でマウントさせてはいけない。

### 従来の回避策B. mountハック
https://castaneai.hatenablog.com/entry/2019/01/29/151257

#### だめな点
- キモい
- docker-compose運用だと、upするたびに無限にvolumeが増えていく
    - 毎回確実に ```docker-compose down -v``` しないといけない
- HostOSに、空の node_modulesが作られる
    - キモい。何かの表紙に空のnode_modulesがマウントされてしまうこともしばしば

### 今回の回避策
- node_modulesはcontainerに含める
- mountハックはしない
- node_modulesをmount dir以外に対比する

#### 作戦
- そもそもこの仮想環境時代に、project-localなinstallなど不要(害悪)、global-installすればよいのでは
    - 無理だった。npmはそういうちゃんと考えられた設計をしていない。npmライブラリも然り。
        - package.jsonからglobal-installする機能がnpmに存在しない
        - 依存解決の方法がglobalとlocalで違い、ライブラリがある
            - localはflatでinstallされるが、globalはflatされない
            - localをglobal-styleにはできるがその逆はできない
- project-localなinstall先をカレントディレクトリ以外に変更すればよいのでは
    - できた
    - nodeはNODE_PATHというものがありmoduleが見つからない場合順次そちらを確認しに行く
    - mount dir以外の場所にnode_modulesをinstallしてNODE_PATHを通せばすべて解決では
    - npm でカレントディレクトリ以外にnode_modulesを作る方法はない
        - じゃあ作ってからmvする、もしくは、node_modulesを作りたいディレクトリにpackage.jsonを持ってくればよいのでは
    - binにかんしては、NODE_PATHは面倒見てくれない
        - PATHに追加すれば動いてくれるのでは？

```dockerfile:Dockerfile
FROM node:slim
# はじめから /node_modules はNODE_PATHに通っているのでENV設定不要
ENV PATH $PATH:/node_modules/.bin # そのくせPATHは通っていないのでENV設定必要

# カレントディレクトリは / の想定
COPY package.json package-lock.json /
RUN npm install && npm cache clean --force # /node_modules を生成
# ここまでで依存パッケージがインストール済のコンテは完成

WORKDIR /usr/src/app
# Use -v ${HostOSWorkSpace}:/usr/src/app
CMD bash
```
[Dart] 正規表現を使って文字列を分割して List にする

例えば、 `f5f6f7f8` みたいなのを `アルファベット一文字 と 数字一文字` をセットとした List にしたい時。
こう書く。 See: https://api.dartlang.org/stable/2.5.0/dart-core/RegExp-class.html

```dart
void main() {
  String str = "F5f6F7f8abcdefg";
  print(_splitMoves(str)); // => [F5, f6, F7, f8]
}

List<String> _splitMoves(String moves) {
  final exp = RegExp(r'([a-hA-H]{1}[1-8]{1})');
  return exp?.allMatches(moves).map((match) => match.group(0)).toList();
}
```
grepがどのパターンを検知したかを行頭に出したい

他人の書いたコードの解析等をやっていると検索のパターンを動的に生成する場合が
多く、そういった場合、100超のパターンを全部選言で突っ込むことがある。

そういう場合、こういうふうにwhile文を避けて書くと心理的な引っかかりが少ない。

```bash
#普通の書き方
パターン生成処理 | while read pattern; do
  echo '### '$pattern
  grep -rwn 開発ディレクトリ
done > result.txt

#whileを使わない書き方
パターン生成処理 | grep -rnwf - 開発ディレクトリ > result.txt
```

この方法にはひとつ欠点があってヒットした行がどのパターンに
引っかかったのか簡単にわからない。

この問題に対する最も簡単な解法は--color=alwaysを指定することだ。

```
$ パターン生成処理 | grep -rnwf --color=always - 開発ディレクトリ > result.txt
$ cat result.txt
※ヒットした文字列が色付きででる。
```

しかし、エディタで読みづらいし、この後も自動で解析結果を解析することを思うと、
行数の横に出ているくらいが嬉しい。

正直この問題は線形のパイプラインでできる範囲だとスマートな解法が思いつかない。
以下はawkで色付き文字を先頭に出してカラーコードを削除する(適当な)コードである。

```bash
filter_color() {
  awk -v RED_BOLD='\033\\[01;31m\033\\[K' \
      -v DEFAULT='\033\\[m\033\\[K' '{
    line=$0
    gsub(RED_BOLD"|"DEFAULT, "", line)
    while(match($0, RED_BOLD"[^\033]*"DEFAULT)) {
      print substr($0, RSTART, RLENGTH)":"line
      $0=substr($0, RSTART+RLENGTH)
    }                              
  }'
}
```

```
$ dd if=/dev/urandom | od | grep -E --color=always '123|456' | filter_color
456:0000340 154563 070206 026626 152453 026651 036307 074574 004500
123:0000540 144656 025632 044464 030031 121746 114156 123764 131157
123:0001060 007733 013551 036742 123017 115207 016440 067670 140456
456:0001060 007733 013551 036742 123017 115207 016440 067670 140456
456:0001100 054746 040723 116312 076244 132456 054674 176716 004234
123:0001120 027336 171251 123561 011752 056744 037504 017437 134132
...
```