OmniAICreator/Qiita-1.07M huggingface dataset:
RS 232テスト。シリアルポートをテストするには？

![spm.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/447311/2a98052d-4666-503e-1cc3-8ce7e445ecbb.png)

シリアルデバイスがマシンのCOMポートに接続されています。マシンにはデータ収集ソフトウェアがインストールされていますが、デバイスを接続した後でもデータは表示されません。問題は深刻であり、問​​題がRS232通信に関連していると考えるようになる可能性があります。この問題を解決するには、シリアルポートのテストを行うことにしますが、それを進める前に、シリアルポートのテスト方法を理解する必要がありますか？
簡単です。RS232テストソフトウェアを備えた[Serial Port Tested](https://www.serial-port-monitor.org/rs232-sniffer/)アプリケーションをダウンロードするだけです。シリアル通信に関する情報を提供し、問題の特定と解決に役立ちます。

COMポートを使用してデータを取得する際に問題に直面している場合

COMポートの詳細を設定します
マシンに接続されるシリアルデバイスに関するすべての情報が必要です。この情報は、実行する前にシリアルポートテスターソフトウェアに入力する必要があります。次の情報を収集してソフトウェアに入力する必要があります。マシンに接続されているシリアルポートの総数、パリティ、ボーレート、およびデータビットのバイト数。
ストップビットに関する情報がない場合は、2に設定するだけです。これは、メッセージを少し遅くすることを除いて、決して害を及ぼすことはありません。
各設定に関する詳細については、シリアルポート経由で測定を行うためのドキュメントを参照してください。ソフトウェアのCOMポートステータスウィンドウを使用して、コンピューターに接続されているコンピューターからの回線のステータスを照会できます。
シリアル通信の問題を特定して修正するのが難しい場合があります。ただし、RS232テストソフトウェアはシリアル通信の問題を修正するのに役立つツールであるため、さまざまなオプションを検討できます。
最適なソリューションは、Eltimaソフトウェアのシリアルポートテスターです。このツールの最大の利点は、柔軟性と汎用性であり、高度な機能をユーザーに提供します。シリアルデバイステスターを頻繁に使用する場合は、このソフトウェアがソフトウェアツールボックスに含まれている必要があります。
Elixirのノード、プロセス間通信

# はじめに
プログラミングElixirの「15.2　プロセスの名前付け」を理解するための備忘録です。
概要：とあるコールバックプロセスのPIDを登録し、そのPIDに対して2秒間隔でメッセージを送信するプログラム
異なるノードからコールバックプロセスを登録できるようにする。


# 参考
プログラミングElixir「15.2　プロセスの名前付け」

# 環境
- IEx 1.9.1 (compiled with Erlang/OTP 22)

# 目次
- ソース
- ノード１で実行
- ノード２で実行
- まとめ

# ソース

```Elixir:ticker.ex
defmodule Ticker do
  @interval 2000 # 2 seconds
  @name :ticker
  def start do
    # 関数generatorのプロセスを開始
    pid = spawn(__MODULE__, :generator,[[]])
    # 開始した関数generatorを名前「ticker」として登録
    :global.register_name(@name, pid)
  end

  def register(client_pid) do
    # ticker（関数generator）に{ :register, client_pid }を送信
    send :global.whereis_name(@name), { :register, client_pid }
  end

  def generator(clients) do
    receive do
      # 関数registerから呼ばれた場合に実行
      {:register, pid} ->
        # code
        IO.puts "registering #{inspect pid}"
        generator([pid|clients])
      after
        # 2秒間隔で実行
        @interval ->
          IO.puts "tick"
          Enum.each clients, fn client ->
            # モジュールClientの関数receiverへメッセージ「:tick」を送信
            send client, { :tick }
          end
          # 再帰
          generator(clients)
    end
  end
end

defmodule Client do
  def start do
    # 関数receiverのプロセスを開始
    pid = spawn(__MODULE__, :receiver,[])
    # 関数registerを実行（pid=receiver）
    Ticker.register(pid)
  end
  def receiver do
    receive do
      # 関数generatorからのメッセージ受信
      {:tick} ->
        # code
        IO.puts "tock in client"
        # 再帰
        receiver
    end
  end
end
```

#ノード１で実行

```Elixir:
% iex --sname one
iex(one@kochiex)1> c("ticker.ex")
[Client, Ticker]
iex(one@kochiex)2> Node.connect :"two@kochiex"
true         
iex(one@kochiex)3> Node.list
[:"two@kochiex"]
iex(one@kochiex)4> Ticker.start
:yes
tick
tick
tick
iex(one@kochiex)5> Client.start
registering #PID<0.128.0>
{:register, #PID<0.128.0>}
tick
tock in client
tick
tock in client
tick
tock in client
tick
tock in client
# Node twoでClient.startを実行
registering #PID<15299.123.0> 
tick
tock in client
tick
tock in client

```

#ノード２で実行

```Elixir:
%  iex --sname two
iex(two@kochiex)1> c("ticker.ex")
[Client, Ticker]
iex(two@kochiex)2> Node.list
[:"one@kochiex"]
iex(two@kochiex)3> Client.start    
{:register, #PID<0.123.0>}
tock in client
tock in client
```
#まとめ
次回はGenServer　の　つもり。
S3にCSVファイルがアップロードされるとLambdaがDynamoDBへデータを挿入します

#概要
S3へjsonファイルがアップロードされるとLambdaがそのファイルの中身を解析して、DynamoDBへデータを挿入します。

#jsonファイルの構成
`data`キーに配列があり、配列の要素はオブジェクトとなっています。

```json
{
    "data": [
        {
            "item1": "sample data1",
            "item2": 123,
            "item3": "test data1"
        },
        {
            "item1": "sample data2",
            "item2": 1234,
            "item3": "test data2"
        },
    ]
}
```

#主な流れ

1. S3へファイルがアップロードされるとLambdaが起動
2. アップロードされたファイルの中身を取得
3. `data`キーから配列を取得
4. 配列を`forEach`で各要素をDynamoDBへPUTするためのパラメーター化
5. さらにパラメーター化したオブジェクトを配列に格納
6. その配列を`batchWrite`するためにパラメーター化
7. `batchWrite`メソッドで一気にDynamoDBへ書き込み

#Lambdaのコード

```javascript:indes.js
const S3 = require('aws-sdk/clients/s3');
const s3 = new S3({ apiVersion: '2006-03-01', region: 'ap-northeast-1' });
const s3Params = {};
const dynamodb = require('aws-sdk/clients/dynamodb');
const docClient = new dynamodb.DocumentClient({"convertEmptyValues":true}); //convertEmptyValuesをtrueにすると空の値がtrueになる。（多分他の値にしたほうが良い）
const TABLE_NAME = process.env.DYNAMO_TABLE_NAME; // 環境変数から取得する

exports.handler = async (event) => {
    console.log('Received event:', JSON.stringify(event, null, 2));
    const key = event.Records[0].s3.object.key;
    const bucket = event.Records[0].s3.bucket.name;
    console.log(bucket, key);
    s3Params.Bucket = bucket;
    s3Params.Key = key;
    try {
        const data = await s3.getObject(s3Params).promise();
        const jsonBody = data.Body.toString(); // toString()しないとBuffer形式になる
        const orders = JSON.parse(jsonBody).data;
        const requestArry = [];
        orders.forEach( order => {
            const requestObj = {
                PutRequest: {
                    Item: order
                }
            };
            requestArry.push(requestObj);
        });
        const dynamoBatchPrams = {
            RequestItems: {
                [TABLE_NAME]: requestArry
            }
        };
        await docClient.batchWrite(dynamoBatchPrams).promise();
        console.log('Success DynamoDB PutRequest!');
    } catch (error) {
        console.log(error);
    }
};
```

#Lambdaの設定
##環境変数
DynamoDBのテーブルを作成したらLambdaの環境変数へテーブル名を入力してください。
##Lambdaの実行ロール
デフォルトの設定で作成後、IAMコンソールで`DynamoDB FullAccess`のポリシーを追加してください。
##トリガーの追加
S3を選択して、バケットとイベントタイプを選択して、トリガーを追加してください。

#DynamoDBのテーブル
DynamoDBのテーブルは名前とプライマリーキーを設定して作成してください。

#最後に
複数のレコードを書き込む際はPUTではなく、`batchWrite`メソッドが良いと思われます。
正規表現のパターン一覧

今日学習した正規表現のパターン一覧を残しておく。

| パターン           |     意味                                      |
|:-----------------|---------------------------------------------:|
| [a - z]          | 各カッコで囲まれた文字のいずれか１個にマッチ            | 
| \d               | 　　　　　　　　　　　　　　 数字にマッチ            |
| {n, m}           | 直前の文字が少なくとも n 回、多くても m 回出現するものにマッチ |
| .                | どの１文字にもマッチ                               |
| +             | 直前の文字の１回以上の繰り返しにマッチ                   |


役に立つ日はくるのだろうか。。。
勉強議事録：２回目

こんにちは〜UNIZONです！
前回は「１日目」って書いたけど、毎日投稿出来ないもんね。サボり症だもんね。
けど、２日に一回くらいはPC開いてたよ！←

この１週間？２週間はずっとpaizaやっておりました。
提出数：31問提出／全323問（提出率9％）
D問題余裕で出来るぜ天才だぜってC問題やったら挫折した。。。。
平均24分くらいの所、40分かかったぜ。。。。。
あれ？考え方が下手くそなのかな？

これは、数こなしていけば早くなるものなのか。。。。？
考え方が根本的に間違っている気が。。。。
頑張って１日１問C問題にチャレンジしていこう

早くプログラム書けるコツがあれば教えてください。
めんどくさがりの私は毎日40分も時間かけると死んじゃう。やる気削げちゃう。

詰まったところのコード書いてレビューとかしたいけど、面倒臭い。。。。
基本めんどくさい。。。。。
もう少し慣れてきたらそういう感じの投稿する←

以上！
Vagrantfileを作る

# Vagrantfile を作ってみよう
Vagrant と VirtualBox を使うときに作るのが Vagrantfile
これがあると簡単にVM環境を生成/破棄したり出来る

- 作り方
  - Vagrantfileをしまっておくフォルダを作る
     - フォルダに1つだけ必要
     - 何度も使われる
     - 書き換えたら更新できる（当たり前だけど）

1. フォルダを作る
  - mkdir する
  - ここでは仮に mkdir myapp にしておく
2. フォルダに移動
  - vagrant init bento/ubuntu-18.04 を実行する
     - boxの内容は他のでもいいけど、ココで解説するのは bento/ubuntu-18.04 だけだよ
     - Vagrantfile が myapp フォルダの中に出来る
  - VM環境のディスク容量を指定したい場合
     - vagrant plugin install vagrant-disksize を実行する
     - 参考サイトは、[ココ](https://qiita.com/yut_h1979/items/c84c490053877beee5c1)
  - クリップボードとかを双方向で使いたい場合
     - vagrant plugin install vagrant-vbguest を実行する
     - 参考サイトは、[ココ](https://you84815.blogspot.com/2018/02/virtualboxvim.html)
4. テキストエディタで開いて Vagrantfile の中身を確認する

中身には色々書いてます。
VM環境で使うメモリのサイズとか、IPとか、GUIを使うかどうかとか。

Vagrantfileの詳細は公式で確認してね

- Box は bento/ubuntu-18.04 を使う
- 他は以下みたいな形で書けば、とりあえずは良いかもしれない

```text:Vagrantfile
#Vagrantfile
Vagrant.configure("2") do |config|
  config.vm.box = "bento/ubuntu-18.04"
  config.vm.box_version = "201912.14.0"
  #config.disksize.size = '40GB' # 指定する場合はpluginをインストールしてね
  config.vm.box_check_update = false
  config.vm.network "private_network", ip: "192.168.123.222"
  config.vm.provider :virtualbox do |vb|
    vb.memory = 4096
    vb.cpus = 2
    vb.gui = true
    vb.customize [
      "modifyvm", :id,
      "--vram", "256",
      "--clipboard-mode", "bidirectional", # VirtualBox6.0だと"--clipboard"なので注意。idは同じ
      "--draganddrop", "bidirectional",
      "--accelerate3d", "off",
      "--hwvirtex", "on",
      "--nestedpaging", "on",
      "--largepages", "on",
      "--ioapic", "on",
      "--pae", "on",
      "--paravirtprovider", "kvm",
    ]
end

  config.vm.provision :shell, :inline => <<-EOS
    wget -q https://www.ubuntulinux.jp/ubuntu-ja-archive-keyring.gpg -O- | sudo apt-key add -
    wget -q https://www.ubuntulinux.jp/ubuntu-jp-ppa-keyring.gpg -O- | sudo apt-key add -
    sudo wget https://www.ubuntulinux.jp/sources.list.d/bionic.list -O /etc/apt/sources.list.d/ubuntu-ja.list
    sudo apt-get update
    sudo apt-get upgrade -y
    sudo apt-get full-upgrade -y
    sudo apt-get autoremove -y
    sudo apt-get autoclean
    sudo apt-get clean
    sudo apt-get install -y ubuntu-desktop ubuntu-defaults-ja aptitude curl dnsutils lsof zip unzip lsb-release tree man
    sudo timedatectl set-timezone Asia/Tokyo
    sudo update-alternatives --set editor $(update-alternatives --list editor | grep 'vim.basic')
    #sudo apt-get install build-essential #gccを使うなら有効にしてね
    EOS
end
```


# 参考
- Vagrant + VirtualBox 構築の時の話
  - https://qiita.com/w2-yamaguchi/items/191830191f8af05ac4dd
  - https://qiita.com/koji9004/items/d436ffb939b6192e0d09
  - https://qiita.com/Esfahan/items/46da3ce1893a67789b58
- VMのディスクサイズの話
  - https://qiita.com/yut_h1979/items/c84c490053877beee5c1
- VMのクリップボードの話
  - https://you84815.blogspot.com/2018/02/virtualboxvim.html
- Vagrantfileの説明
  - https://qiita.com/watahani/items/1fa7bbc981534a4e907a
- Vagrant公式 
  - https://www.vagrantup.com/docs/
【統計学】チェビシェフの不等式を理解する

#はじめに
統計学を勉強していると出てくる「チェビシェフの不等式」ですが、その式だけを見ても中々理解が難しかったため、丁寧にその導出過程の式展開を追ってみました。

##参考
ポアソン分布の理解とその分布の描画を行うに当たって下記を参考にさせていただきました。

- [【大学数学】チェビシェフの不等式【確率統計】](https://youtu.be/d-ugoDdXWrU)
- [統計学入門 (基礎統計学Ⅰ)](https://www.amazon.co.jp/dp/4130420658/ref=cm_sw_r_tw_dp_U_x_r56nEb3G5Y13F)
- [チェビシェフの不等式(wikipedia)](https://ja.wikipedia.org/wiki/%E3%83%81%E3%82%A7%E3%83%93%E3%82%B7%E3%82%A7%E3%83%95%E3%81%AE%E4%B8%8D%E7%AD%89%E5%BC%8F)

#チェビシェフの不等式
##チェビシェフの不等式とは何か

```math
P(|X-μ|\geq kσ) < \frac{1}{k^2}

```
任意の実数$k>0$かつ$μ=E(X)$、$σ^2=V(X)$である時どんな**確率変数$X$に対しても上記不等式が成り立ちます。**これを**チェビシェフの不等式**と呼びます。どんな確率変数$X$に対しても、というところが味噌でこの不等式は**どんな確率分布に対しても成り立つ絶対的なもの**になっています。

具体的に数字を当てはめてチェビシェフの不等式を見てみます。
$k = 3$を上記不等式に代入するとこのような感じになります。

```math
P(|X-μ|\geq 3σ) < \frac{1}{9} \fallingdotseq 0.11　
```
上記の式の意味は、**どんな確率分布であってもあるデータが3σ範囲外である確率は11%未満**であるということです。確率分布が正規分布である時は3σ範囲から外れる確率は0.3%程度であることが知られていますが、正規分布ではないデータに対してもこういった確率が導き出せることが非常に重要なポイントです。


##チェビシェフの不等式の導出
###マルコフの不等式
チェビシェフの不等式の証明に用いられるマルコフの不等式を先に見ていきます。

**マルコフの不等式**
$X$を非負の値をとる確率変数とした時、任意の定数$c > 0$に対して下記不等式が成り立つ。

```math
P(X \geq c) \leq \frac{E(X)}{c}　
```

こちらをチェビシェフの不等式の導出に用いるのですが、まずこのマルコフの不等式を導出する過程を見ていきます。


```math

{\begin{eqnarray*}E(X)&=&\int^\infty_0 xf(x)dx\\ 
&=&\int^c_0 xf(x)dx + \int^\infty_c xf(x)dx\\ 
&\geq&\int^\infty_c xf(x)dx\\
&\geq&c\int^\infty_c f(x)dx\\ 
&=&cP(X>c)
\end{eqnarray*}
}
```

2行目から3行目への展開は、$c>0$のため$\int^c_0 xf(x)dx$が必ず正となることから可能です。
また3行目から4行目の展開も積分の中身の$x$には必ず$c$以上の値が代入されるため可能です。
上記式を整理するとこのようなマルコフの不等式が導出可能です。

```math
P(X \geq c) \leq \frac{E(X)}{c}　
```


###チェビシェフの不等式の導出
それでは、先ほどのマルコフの不等式を用いてチェビシェフの不等式を導出します。
マルコフの不等式において$X = (X-μ)^2$、$c = k^2σ^2$とおきます。

```math

{\begin{eqnarray*}
P((X-μ)^2 \geq k^2σ^2) &\leq& \frac{E((X-μ)^2)}{k^2σ^2}\\
P(|X-μ| \geq kσ) &\leq& \frac{σ^2}{k^2σ^2}\\
P(|X-μ| \geq kσ) &\leq& \frac{1}{k^2}

\end{eqnarray*}}


```
するとこんな感じで簡単にチェビシェフの不等式を導出することができました。

##大数弱の法則
大数の法則は大雑把に言うと、**大量のサンプルを集めればそのサンプルの平均は真の平均に近づく**という法則です。実は今までのマルコフの不等式とチェビシェフの不等式で大数弱の法則を導き出すことが可能です。大数の法則には、大数弱の法則と大数強の法則の2つがありますが、今回導き出すのは大数弱の法則の方です。

**大数弱の法則**
互いに独立な確率変数 $X_{1},X_{2},⋯,X_{n}$ が母平均 $μ$ 母分散 $σ^2$ の同一の確率分布に従うとき、 その標本平均 $\overline{X}=X_{1}+X_{2}+⋯+X_{n}$と任意の正の定数 $\epsilon$ について下記が成り立つ。


```math
\displaystyle\lim_{n \to \infty}P(|\overline{X}-μ|< \epsilon)=1
```

$n$を限りなく大きくすれば「$\overline{X}$が限りなく$μ$に限りなく近く確率」が限りなく100%に近くなるということです。

###大数弱の法則の導出
まず、マルコフの不等式において$X = (X-μ)^2$、$c = k^2$とおきます。
すると下記式を導き出すことができます。

```math

P(|X-μ|\geq σ) \leq \frac{σ^2}{k^2}

```
ここで確率変数を標本平均$\overline{X}=X_{1}+X_{2}+⋯+X_{n}$とするとその期待値と分散はそれぞれ$E(\overline{X})=μ$・$V(\overline{X})=\frac{σ^2}{n}$となります。こちらを上記不等式に当てはめます。

```math
{\begin{eqnarray*}

P(|X-μ|\geq σ) &\leq& \frac{σ^2}{nk^2}\\

\end{eqnarray*}}

```
ここで$n$を限りなく無限大に近づけると$\frac{σ^2}{nk^2}$は$0$になります。
すると数式的には下記のように表されます。

```math

\lim_{n \to \infty}P(|\overline{X}-μ|\geq σ) \leq 0

```
また$P(|\overline{X}-μ|\geq σ)$は負の値を取らないので下記のように変形できます。

```math
{\begin{eqnarray*}

\lim_{n \to \infty}P(|\overline{X}-μ|\geq σ) &=& 0 \\
\lim_{n \to \infty}P(|\overline{X}-μ|< σ) &=& 1

\end{eqnarray*}}


```

これで大数弱の法則を導出することができました。

#Next
今後も統計関連で学んだことを色々まとめていきます。
CircleCIでAPIリクエスト起動


CircleCiでAPIリクエスト起動の詳細ドキュメントが少なく、既存Doc通りではいかなかったので書いてみます。

### 環境

Circleci config version: 2.0
APP: Ruby on Rails 5.1で構築
テスト: rspec

## Workflows

- jobs
    - build_and_test(構築してRspecを実行)
    - deploy(Capistranoでデプロイ)

#### やりたかったこと

- ワークフロー全体の起動

- Job単体での起動

## CircleCI API URL

今回使ったAPIは2本。

- POST: ワークフローの実行

[build]を実行（そもそもJOBがbuildしかない場合など)

```bash
curl -X POST -H  \
              -d "{}" \
              https://circleci.com/api/v1/project/$USER/$PROJECT/tree/$BRANCH?circle-token=$API_TOKEN
```

JOB指定

```bash
curl -X POST -H "Accept: application/json" -H "Content-type: application/json" \
              -d "{\"build_parameters\":{\"CIRCLE_JOB\":\"build_and_test\"}}" \
              https://circleci.com/api/v1/project/$USER/$PROJECT/tree/$BRANCH?circle-token=$API_TOKEN
```

- GET: ビルド番号指定して情報取得

```bash
curl https://circleci.com/api/v1.1/project/github/branu-ws/$PROJECT/$current?circle-token=$API_TOKEN
```


### 補足
-d の書き方がいろんなサイトみたけど、うまく動かないことが多かった
$API_TOKEN: プロジェクトのAPI_PERMISSIONで取得。権限はallにしないといけない。
Android 小ネタ帳

Androidの開発を行っていると、「そんな機能があるの？」という機能を時々見つけます。
業務上、スマートフォンの機能を全て押さえておきたいため、知らなかった機能を見つけたら随時追加します。

## Android 9

### 画面の手動による回転機能

普段は表示されていませんが、画面を回転させると回転ボタンが表示され、ボタンを押すと回転されます。

![20190219-y0102.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/56144/1f706308-5df8-d5a8-2545-5f97eca49bc8.png)

https://dekiru.net/article/17811/

## Android 10

## 画面録画機能

「電源ボタン」の長押してから、「画面の保存」の長押しすることで「画面の録画」ができるようになります。ただし、その前に adb 経由で設定を有効化している必要があります。

```
adb shell settings put global settings_screenrecord_long_press true
```

https://android.benigumo.com/20200117/settings_screenrecord_long_press/
package-lock.jsonってなんぞ

Angularにでてくる。package-lock.jsomってなんだって思ったのでメモを少しまとめてみた。

## package-lock.json

package-lock.json：dependencyのバージョンをlockするためのファイル。npm install の実行時に自動的に作成される。  

一般にnpm パッケージは他のチームの開発マシン、テスト環境、本番環境など複数の環境で実行されるため、  
すべての環境で全く同じバージョンのdependencyをインストールしたいと思うのは自然である。  
(バージョンが同じでなければ「ある環境ではうまく実行でき、あるか環境ではエラーが出る」といったことが起こりうる)

実際のところ、package.jsonだけではこれは実現できない。キャレット _^_ ,チルダ _~_ を使わなければ大丈夫というわけではない。  
常にバージョンの変化が起こっているので、そのたびにnpm install をしていると最新バージョンでinstallされてしまう → dependencyのバージョンが異なる環境ができる  。

これを解決するためにnpm v5以降でpackage-lock.jsonが導入された。  
このファイルに、dependency、dependencyのdependency…と間接的なものも含めてすべてのdependencyのバージョン(とそのintegrity)が記録される。  

npm v6.9.0時点では _npm install_ の具体的な挙動は次のようになっている。  

- package-lock.jsonが存在しない
  - package.jsonに基づいてdependencyがインストールされ、実際にンストールされたバージョンがpackage-lock.jsonに書かれる。  
- package-lock.jsonが存在するとき  
  - package-lock.jsonに基づいてインストールされるが、package.json指定されたバージョンとの矛盾があれば、  
    package.jsonが優先され、実際にインストールされたバージョンがpackage-lock.jsonに書かれる。  

**package-lock.jsonを優先したい場合はnpm ci を実行すればよい**。  
このコマンドはpackage-lock.jsonに基づいてdependencyをインストールし、  
もしpackage.jsonとの矛盾があればエラーを出力する。  
また、インストール前にnode_modulesを削除するので、クリーンインストールしたいときにも使える。
AndroidStudioのtextで文字列を打ち込むとWarningが出る件

#AndroidStudioでアプリ作成を解説通りやっているときに。。。
##textに解説通り文字列を打ち込むとこんなWarning
```
Hardcoded string "文字列", should use @string resource
```

##解決法
どうやら、文字列をtextに直接打ち込むより@stringを使ったほうがおすすめということらしい
>https://detail.chiebukuro.yahoo.co.jp/qa/question_detail/q1294171037
>>たとえば、
android:text="テキスト"
とするより、

>>string,xmlに
<string name="text1">テキスト</string>
と定義し、

>>android:text=@string/text1
とするほうが、コーディングの仕方としておすすめですよ、ということです。

同じ文字列を何度も使うならこの方法は便利かもしれない。
プロパティー・アクセス制限

```py:
class Car(object):
    def __init__(self, model=None):
        self.model = model
    
    def run(self):
        print('run')

class TeslaCar(Car):
    def __init__(self, model='Model A',
                 enable_auto_run=False,
                 password='123'):
        super().__init__(model)
        self._enable_auto_run = enable_auto_run
        self.password = password
    
    @property
    def enable_auto_run(self):
        return self._enable_auto_run
    
    @enable_auto_run.setter
    def enable_auto_run(self, is_able):
        if self.password == '456':
            self._enable_auto_run = is_able
        else:
            raise ValueError
    
    def run(self):
        print('run very fast')
    
    def auto_run(self):
        print('auto run')

tesla_car = TeslaCar(password='456')
tesla_car.enable_auto_run = True
print(tesla_car.enable_auto_run)
```

```:実行結果
True
```

```py
@property
def enable_auto_run(self):
    return self._enable_auto_run
```
で
_enable_auto_runを外部から操作できない様にする。
が、

```py
@enable_auto_run.setter
def enable_auto_run(self, is_able):
    if self.password == '456':
        self._enable_auto_run = is_able
    else:
        raise ValueError
```
で
passwordが'456'の場合、
enable_auto_runを外部から操作でき、
それ以外の場合は、
ValueErrorを起こす。

なので、最後の三行を

```py:
tesla_car = TeslaCar(password='123')
tesla_car.enable_auto_run = True
print(tesla_car.enable_auto_run)
```
にして、
passwordを'123'にすると、
ValueErrorが発生する。
GAE/GoからSpreadsheetをサービスアカウントに共有せず操作する話

## GAE/GoからSpreadsheetを弄る事になった
仕事でGAE/GoからSpreadsheetを操作することになったので色々調べた
一旦はサンプル通り作り、JWTを使ってクライアントを作成し、サービスアカウントから操作ができた
しかし、テスト段階ではサービスアカウントのアドレスを共有して操作していたのが、
お客様の環境ではそれはアカンとのことだった
じゃあどうすんのってことで、GSuite側のセキュリティ設定を弄ることで、
サービスアカウントがあたかもGSuiteに所属するユーザとして操作をする方法があった
そこら辺の設定まわりに苦戦したので一通り備忘録としてまとめておく
やったことは以下2点

- サービスアカウントの許可設定（ここがGsuiteの設定）
- クライアント作成時にSubjectを設定

## サービスアカウントの許可設定（GSuite）
GSuite側で設定する必要がある
GSuiteに管理者権限アカウントを使用してログイン
セキュリティから詳細設定を開き、「APIクライアントアクセスを管理する」を押す

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/63896/23085656-9018-0473-8d00-77592192bd78.png)

「クライアント名」には使用するサービスアカウントの詳細画面にある「一意のID」（21桁の数字）を、
「1つ以上のAPIスコープ」には後述するクライアントで使用するAPIスコープを入力する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/63896/f8751231-8517-a296-9b64-8a374be590d3.png)

## クライアント作成時にSubjectを設定
クライアント作成部分でスコープと`Subject`を設定する
スコープは前述したGSuiteの設定と同様にする
Subjectは成り済ますユーザのメールアドレスを文字列で入れる。
サービスアカウントが設定したアドレスのユーザに成り済ます形でSpreadsheetを操作する
（当たり前だが、成り済ますユーザが権限を持っていないSpreadsheetは操作できない）

```golang:client.go
package app

import (
	"context"
	"io/ioutil"
	"net/http"

	"golang.org/x/oauth2/google"
	"google.golang.org/api/drive/v3"
	"google.golang.org/api/sheets/v4"
)

func NewClient(ctx context.Context) (*http.Client, error) {
	jsonData, err := ioutil.ReadFile("サービスアカウント作成後にダウンロードしたJSONキーファイル名.json")
	if err != nil {
		return nil, err
	}

	// スコープの設定。何が必要になるかはAPIのリファレンスに書いてある。
	conf, err := google.JWTConfigFromJSON(jsonData, sheets.SpreadsheetsScope, drive.DriveScope)
	if err != nil {
		return nil, err
	}

	// test@gmail.com の部分には成り済ますユーザのアドレスを入れる
	conf.Subject = "test@gmail.com"

	// クライアントを返す
	return conf.Client(ctx), nil
}
```

## まとめ
以上の設定でGAE/GoからSpreadsheetをサービスアカウントを共有設定せず、SheetsAPIで操作できる
実際にやってからしばらく経ってるので何か書き忘れとかあるかもしれない


Spreadsheetの操作については以下の記事を参考にしました
[Google Sheets APIでセルの値を書き込む方法](https://qiita.com/howdy39/items/c28c0328038d9c43f389)
[Go言語からGoogle Sheets API v4でスプレッドシートを新規作成する方法](https://qiita.com/katsumic/items/a7984afca2d4522f60ac)
EC2インスタンスをAnsibleで操作するための事前準備


## 目的

本投稿では、AWSインスタンス（EC2）に対して、Ansibleでリモート操作するための事前準備について解説します。



## 構成

Ansible Client (Cloud9) -> Ansible Target(EC2 インスタンス)

- Ansibleインストール対象となるインスタンスとして、Cloud9を今回は利用しましたが、通常のEC2インスタンスでも構いません。
- Ansible ClientとAnsible Targetは、ネットワーク疎通が取れる状態にする必要があります。


## 設定手順

### STEP1. Ansibleのインストール

以下コマンドでcloud9インスタンスに対して、ansibleのインストールを行います。

```
sudo su -
yum install ansible -y
cd /etc/ansible/
```

最新バージョンである2.6.20がインストールされていることを確認します。

```
ansible --version
ansible 2.6.20
  config file = /etc/ansible/ansible.cfg
  configured module search path = [u'/root/.ansible/plugins/modules', u'/usr/share/ansible/plugins/modules']
  ansible python module location = /usr/lib/python2.6/site-packages/ansible
  executable location = /usr/bin/ansible
  python version = 2.6.9 (unknown, Nov  2 2017, 19:21:21) [GCC 4.8.5 20150623 (Red Hat 4.8.5-11)]
```


### STEP2. 秘密鍵（pemファイル）の格納

Ansible Clinetは、Ansible Target(EC2インスタンス)に対して、pemファイルを用いたssh認証を行います。
したがって、Ansible Targetと紐づく秘密鍵（pemファイル）を任意のディレクトリに格納します。
今回のケースでは、```/etc/ansible/pemfile```に```tokyo01.pem```を格納しました。


### STEP3. hostsファイルの設定


```/etc/ansible/hosts```にAnsible Targetの接続情報を記載します。

```/etc/ansible/hosts
# targethost: Elastic Stackをインストール対象となるホストのIPアドレス情報一覧
[targethost]
172.16.1.109

# targethost_vars: Ansible実行時に利用する変数一覧
[targethost:vars]
ansible_ssh_port=22
ansible_ssh_user=ec2-user
ansible_ssh_private_key_file=/etc/ansible/pemfile/tokyo01.pem
ansible_become=yes
host_key_checking=False

```

## 確認手順

pingモジュールを用いて、Ansible Targetに対して接続できていることを確認します。
以下のようにSUCCESSと表示されれば問題なく接続することが確認されます。

```
ansible targethost -m ping
172.16.1.109 | SUCCESS => {
    "changed": false, 
    "ping": "pong"
}

```
Pycharmで「Package requirements not satisfied」と表示されたら

まずは迷わずにこれをやりましょう

![スクリーンショット_2020-02-03_17_16_47-1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/101357/58b4d04a-6632-05bc-9ba3-b8d684e3bfab.png)

画面ショットを取り忘れましたが、mojimoji 0.0.9とかで同様のエラーが出ると他の問題だと思って結構慌てます。

このあたりとか
https://qiita.com/sabaku20XX/items/968e830fa9fdaf6df8de
Vagrantの共有ディレクトリでのnpmインストールエラー回避

# 最初に
vagrantでLaravelの環境を作ることがよくあります。
Laravelプロジェクトを共有ディレクトリに配置し、ローカルで開発。
よくある話かと思います。
※まぁ、Homesteadとかで。

# npmインストールエラー

んで、vueを使いたい時もあるわけです。
ですが、vagrantログイン後、Laravelプロジェクト下でnpm installをするとエラーが出ます。

```vim
# Vagrantfileの設定
config.vm.synced_folder "./data", "/home/vagrant/project"
```

```php
# (vagrantログイン後)Laravelプロジェクト直下にて
$ pwd
/home/vagrant/project/SampleProject
$ npm install
npm ERR! code ENOENT
npm ERR! syscall open
npm ERR! path /home/vagrant/project/SampleProject/node_modules/yargs/node_modules/require-main-filename/package.json.2754704624
npm ERR! errno -2
npm ERR! enoent ENOENT: no such file or directory, open '/home/vagrant/project/SampleProject/node_modules/yargs/node_modules/require-main-filename/package.json.2754704624'
npm ERR! enoent This is related to npm not being able to find a file.
npm ERR! enoent 

npm ERR! A complete log of this run can be found in:
npm ERR!     /home/vagrant/.npm/_logs/2020-02-03T07_39_18_468Z-debug.log
```

上記回避策として、ローカルにて、Laravelプロジェクト下で、npm installを実行、があるようです。他にもあるかと思いますが…

# マウントにてエラー回避
ローカルにnodeを入れない（入れたくない！）場合、node_modulesを共有ディレクトリ以外のディレクトリにマウントしてあげるとエラーが回避できるようです。
※正しい回避策かは不明ですが…

```
$ mkdir /home/vagrant/vagrant_node_modules
$ sudo mount --bind /home/vagrant/vagrant_node_modules /home/vagrant/project/SampleProject/node_modules
```


参考ページ：[Isolating node_modules in Vagrant](https://medium.com/@dtinth/isolating-node-modules-in-vagrant-9e646067b36)
[Android] 静的解析ツールPMD

##導入
「ファイル」→「設定」→「プラグイン」でPMD Pluginと出てくるので、それをインストールする。
![スクリーンショット (7).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/506451/db3c9d3f-0818-5e5e-bf87-4ee8883a2b58.png)

その後再起動する。

##使い方
右クリックで「Run PMD」と出てくるので、その中の選択肢を選んで解析できる。

![スクリーンショット (8).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/506451/4cca077d-aba3-7e16-8e2e-0202b90a5a5e.png)

##結果
以下のような結果が出てきた。
![スクリーンショット (9).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/506451/b0d1b939-8b12-a5d1-915c-d1a56dcdb1ec.png)

##感想
導入は特に問題なくできた。静的解析ツールは、ほかにもCheckStyleなどたくさんあるのでぜひ使ってみたい。
WordPressで使うプラグインまとめ

# はじめに
毎回、どのWordPressでどのプラグインを入れていたか思い出すのが大変になってきたのでまとめます。

# よく使う
## UpdraftPlus WordPress Backup Plugin
[公式サイト](https://ja.wordpress.org/plugins/updraftplus/)
Googleアカウントなどで簡単にバックアップが取れるので、安心。
私はDBだけ毎日取ったりしています。

## WP-Optimize
[公式サイト](https://ja.wordpress.org/plugins/wp-optimize/)
私は入れているだけだったりしますが...
余分なデータを消したり、キャッシュしたりする機能があるそうです。

## SiteGuard WP Plugin
[公式サイト](https://ja.wordpress.org/plugins/siteguard/)
- ログイン時に、ひらがなの入力も追加
- ログイン画面のURLを`wp-admin`から変更
- ログイン時に通知メールを飛ばす
など

ちなみにPCの苦手なお客さんのときは、ログインが煩雑になるので入れません。
自分のサイトで入れることが多いです。

## Advanced Custom Fields
[公式サイト](https://ja.wordpress.org/plugins/advanced-custom-fields/)
WordPressのカスタムフィールドを簡単に画面から設定できるプラグインです。
むしろ知らない人はいないのでは？くらいの知名度

[使い方](https://www.advancedcustomfields.com/resources/)

# 便利
## All-in-One WP Migration
[公式サイト](https://ja.wordpress.org/plugins/all-in-one-wp-migration/)
すでにサーバー上にあるWordPressの環境をローカルで作ったり、ローカルで作成したものをサーバーにアップするのは、手作業でやると手間だし、間違えます。
そんなときは、こちらのプラグインがおすすめ！
使い方は[こちら](https://qiita.com/shima0218/items/66cbd8d311124a60717e)

## Contact Form 7
[公式サイト](https://ja.wordpress.org/plugins/contact-form-7/)
WordPressでお問い合わせフォームを作るときといえば、こちらのプラグインですね。
ただ、毎回、送信完了メッセージの日本語を直したり、完了メッセージのスタイルを変えたりしている自分がいる。

## MW WP Form
[公式サイト](https://ja.wordpress.org/plugins/mw-wp-form/)
こちらも問い合わせフォームのプラグインです。
確認画面が必要な場合や、問い合わせ内容をDBに保存してほしいという要望がある場合は、こちらがおすすめです。

## SEO SIMPLE PACK
[公式サイト](https://ja.wordpress.org/plugins/seo-simple-pack/)
他のSEO系のプラグインは、機能が多すぎる気がしますが、これはちょうどいいような感じがします。

## Smash Balloon Social Photo Feed
[公式サイト](https://ja.wordpress.org/plugins/instagram-feed/)
Instagramの埋め込みは、トークンの取得が大変ですが、このプラグインを使うと簡単にできます。

## Intuitive Custom Post Order
[公式サイト](https://ja.wordpress.org/plugins/intuitive-custom-post-order/)
投稿をソートしたり、カテゴリーをソートしたりするときに使用します。
ドラッグ＆ドロップで並び替えて表示できるので、説明も楽ちんです。

## WooCommerce
[公式サイト](https://ja.wordpress.org/plugins/woocommerce/)
オンラインショップ、ECサイトをつくるならこのプラグインですね！
本当に無料でいいのか？というクオリティ。

特にこだわりがなければ、デフォルトのデザインでもサイト運営可能です。

日本対応が必要なので、以下のプラグインもセットで入れてくださいね↓
[Japanized For WooCommerce](https://ja.wordpress.org/plugins/woocommerce-for-japan/)
基本情報16週目(2/3)

##目標と結果##

##目標##
•参考書を理解しつつ、独習ゼミでの基礎テストを完璧にして自分の理解度を深めます。自分の間違いやすいところ、理解度が低い問題に取り組む。

•午後試験までの徹底表を組み立てる。組み立てながら、今後の勉強方法などを見直しつつ改善していく。

##振り返り##
春の試験までの大まかな予定表は組み立てることができた。午前対策事件に関しては、今月末、または３月上旬までに仕上げる。午後試験に関しては、３月中旬から参考書を中心に確実にこなします。
__Keep__
１日1時間勉強。
__Try__
勉強時間数を増やすこと。
__Problem__
1時間確保できるのはいいものの、それ以上時間数を伸ばすことが出来ていない。
##次週 and more...##
[1/27](https://qiita.com/Comitakato0515/items/e06aadf6d470a7de6239)
２月全体計画

##目標と結果##

##目標##
•午前試験でのマネジメント系、ストラテジ系の分野の2項目の理解度を深め、改めて問題を回答し、間違えた所の理解度を深めていく。

•独習ゼミのテストを活用しつつ、ポイントを押さえていくこと。

•勉強時間最低でも週の内10時間は確保すること。常に空いている時間、隙間時間で独習ゼミ又は過去問道場をやりこむこと。無駄な１日を過ごさないようにする。

##結果##

##月次報告##
[１月全体](https://qiita.com/Comitakato0515/private/4ae8c631dcd3a42aa826)
middlemanで新サービスをスピーディにスモールスタートした話



初めまして、プレイライフ株式会社で昨年５月に入社したばかりで
唯一の正社員プロダクト開発エンジニアの[合原](https://qiita.com/kieaiaarh)ですw

当社では、現在「ホテコ」という新しいサービスを立ち上げ、サービスの検証を日々繰り返しています。
本サービスでは現在、`middleman`を用いて、静的ページで、サイト開発・運用をしています。

Qiita初投稿となる本記事では、エンジニアとして、「ホテコ」のサービスローンチに当たって技術選定等どういう思考で、`middleman`を採用したのか、主にその点について順にまとめます。

[<img width="677" alt="スクリーンショット 2020-02-03 17.08.52.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/578823/be80f140-0d72-79ef-d926-c8cfa5e93725.png">](https://middlemanapp.com/jp/)


# 前提
例に漏れず、[当社](https://play-life.jp/)では、これまでのスピード感のある開発に伴い、いわゆる技術的負債も多分が蓄積しています。
そんな中、さらなる事業展開するため「ホテコ」という新サービス立ち上げることとなりました。

# 当社エンジニアとしての大前提
そんな中、弊社のようなスタートアップでは、いかに速くサービス展開、マネタイズするかのかが非常に重要になってきます。これは「汚いコードでもいいから速く作ればいい」、ということでは、決してありません。むしろ、そういったコードは許されません。
上記の`前提`からして、当社でのスピーディな開発のためには、以下の点が肝要になります。

* 1秒でも速く実現できること
* お金にならないコードは無駄
* 技術的負債を産まない

### リーン開発とは
> リーン開発は、トヨタ生産方式をソフトウェアの開発工程に応用させた、
> プロセスから無駄を取り除くことを目的とした開発手法。
> 特にスクラムのようなプロジェクトマネジメントフレームワークではなく、
> 実践手段を提供するための手助けの役割を担う。

> 具体的には、ビジネスアイデア（多くの場合それは思い込み）をまずは仮説と捉えるという事。
> そして最小限のコストで実装しスピーディーにリリースしてユーザーの反応を見る（計測する）。
> 得られたデータを精査し、反響があればさらに一歩進めて実装をしていく。
> これを繰り返す事で開発コストを抑えながら仮説を実証していく方法。

# 前提となる必要要件
* [既存サービス](https://play-life.jp/)への影響はZEROにしたい
* 速くスタートできること
* 速く試し改善できるようにしたい
* サービススタート時必要なページは２ページのみ
* 将来的には、契約に応じて掲載ホテル（ページ）数が増やしたい
* 流入経路は、（ほぼ）リスティング広告のみ

上記を踏まえると、
自ずと、リーンな開発手法が想像できます。なぜなら、ビジネスアイデア自体まだ仮説であり、極論、それ自体が間違っているケースさえありえます。

そういう場合、webサーバ用意して、DB用意して、、、と作り込んでから、成果出ませんでしたでは、話になりません。
そこで、まず

# [既存サービス](https://play-life.jp/)への影響はZERO
この点についは、ドメインを分け、別環境で行うこととしました。
※ビジネス観点での考慮含む

# 速く改善できるようにする
上記の要件からしても、動的処理は必要ない＆webサーバすら必要ない

また、
* ページ数が少ない
* デザイン・UI・UXを手軽に変更できるようにする

ということからも、静的ページでの運用が最適と考えました。
掲載ホテル（ページ）数の増減については、営業次第で、月に何百件もあるといったことではないので、
最初から動的に量産できる状態にする必要もありません。

また、目的とするCV（コンバージョン）に最適なUI・UXも未確定な状態では、多ページに渡り共通化されたCSS等を利用するよりも、ページ毎に改変しやすい静的ページを利用する方が最適だと考えられます。

# 速くスタート（ローンチ）するために
上記を踏まえ
* 実装コスト低

私自身、普段Railsでの開発が主、つまりrubyに慣れていることからも、
手軽にできる方法として、middlemanを採用しました。
実際デザインカンプ上がってから、１w強で、サービスのスタートができました。

# 技術スタック
* middleman
* S3
* ACM
* cloudfront
* EC2（DNSレコード追加のみ）

`middleman`で、主にページ作成(html,js,css等)を行い、circleciで、`middleman`でbuildされたファイル`S3`への配置しています。

また、`AWS Certificate Manager`を設定したオリジン（`cloudfront`）経由とすることでhttps化された静的サイトを構築しています。
結果的に、ローコストでスピーディに本サービスのスモールスタートができました。


# まとめ
現状は、新サービスの検証フェーズですが、特に大きなトラブルも起きていません。約1週間単位で、現状はデザインテストを繰り返しコンバージョン率のもっとも良いデザイン、UI・UXの検証を続けています。今後、リダイレクトする、量産化に向け、本運用するとなった場合などは、`nuxtjs`の利用や、当社のメインサービスサイト[play-life.js](https://play-life.jp/)と同様の`Rails`環境下への移行なども検討しています。

手前味噌ですが、このように当社では、やりたいと思ったことができるのはもちろん、時間や労力といった観点でのコストなど、そういった点も含め自身で技術選定ができるので非常にやりがいがあります。今後も技術視点であったり、ビジネス視点であったり、当社の多岐に渡るエンジニアリングについて情報共有していくので、ぜひよろしくお願いいたします。
【Nuxt.js】AWS ECR/FargateにデプロイするためのDockerイメージ作成方法

# TL;DR.
- AWS上でNext.js(SSR)アプリを動かすために、NuxtアプリをビルドするためのDockerイメージが必要
- ローカル環境で`docker build`した後、ECRにDockerイメージをpushして、それをFargateにデプロイする

## 前提
- Node.jsのパッケージは管理は`yarn`を利用
- ローカル環境でNuxt.jsアプリが立ち上がる（yarn build / yarn startが実行できる)であること

# ローカル環境での作業

#### 1. ルート直下に以下のファイルを作成

```Dockerfile:Dockerfile
FROM node:12-alpine

ENV HOST 0.0.0.0

RUN mkdir -p /app
COPY . /app
WORKDIR /app

ARG ENV
ENV ENV $ENV

RUN yarn && yarn build

EXPOSE 3000

CMD ["yarn", "start"]
```

```text:.dockerignore
node_modules/
.nuxt/
```

#### 2. Dockerイメージの作成

```bash
$ docker build -t docker-image-name:0.0.1 .
```

#### 3. 動作確認
以下コマンド実行後、ブラウザで`http://localhost:3000`にアクセス

```
$ docker container run -d -p 3000:3000 --name docker-image-name docker-image-name:0.0.1
--- container id が表示されている ---
```

#### 4. dockerコンテナの停止＋削除

```
$ docker stop xxxxx
$ docker rm xxxxx
```
※ `xxxxx`の部分は、上記で「docker container run」を実行した際にに出力されたコンテナIDを入力
（わからなければ、`docker ps`等で調べる）


# 作成したDockerイメージをECRにpush
#### 1. Dockerイメージのタグ付け

```
$ docker tag docker-image-name:0.0.1 xxxxx.dkr.ecr.ap-northeast-1.amazonaws.com/docker-image-name:0.0.1

$ docker tag xxxxx.dkr.ecr.ap-northeast-1.amazonaws.com/docker-image-name:0.0.1 xxxxx.dkr.ecr.ap-northeast-1.amazonaws.com/docker-image-name:latest
```

#### 2. Dockerイメージのpush

```
$ docker push xxxxx.dkr.ecr.ap-northeast-1.amazonaws.com/docker-image-name:latest
```

# Fargateへのデプロイ

> 新しいdocker imageをlatestタグ付けしてECRにアップ後、Amazon ECS>クラスター>対象クラスタ>サービス名リンククリック>更新ボタンから、 新しいデプロイの強制にチェック入れて他そのままで更新すると、勝手にlatestでデプロイしてくれる(数分かかる)

ref: [nuxtプロジェクトを独自ドメインでSSR（CloudFront -&gt; ALB -&gt; Fargate） - Qiita](https://qiita.com/geerpm/items/a97f0605177b3a18bb5b)

---

AWS超初心者なので、何か誤った情報や誤解を招く表現があればご指摘ください

## 参考
- [Nuxt.jsでアプリ作成→Dockerfileを使ってイメージ作成→fargateでデプロイ→ドメイン設定・SSL化まで - Qiita](https://qiita.com/yujiro0102/items/0a4672d7f8ea64fe1d6d)
- [Vueで書かれた自社サイトをNuxt対応した時にAWSインフラでハマったポイントとその解決策｜小林佑樹（ARおじさん）｜note](https://note.com/ar_ojisan/n/n02334166cf57)
参照関係のあるSOQLの書き方

カスタムオブジェクト
どっちが親でどっちが子かというと、参照関係の項目を作った方が子 です。
Child-to-parent：子(ChildObj__c)から親(ParentObj__c)を参照![キャプチャ.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/578884/e7515cd1-b053-3706-9bac-e8b03e28711a.png)

ParentObj__c で取れるのは Id のみ。Id 以外の項目を取る時は __c でなく __r にする。
Parent-to-child：親(ParentObj__c)から子(ChildObj__c)を参照
![キャプチャ.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/578884/91038319-791e-35b5-d54c-c565a08eed14.png)

workbench rest api の書き方
/services/data/vXX.0/query/?q=SELECT+JID__c+,+Name+,+LastModifiedById+,+(select+Name+,+ListAndFlow__c+,+activeTime__c+from+conditions__r)+FROM+ListAndFlow__c


原本：
＜https://dackdive.hateblo.jp/entry/2014/06/10/112629＞
Brew で PHP7.3 の PHP IMAP Extension をインストールする方法 (MacOS)


参考記事: macos - OSXでPHP 72にIMAPを追加する
https://tutorialmore.com/questions-1754536.htm

ありがとうございます！

kabel/php-ext とは、stable ではない、Core PHP Extension の Homebrew Package マネージャーレポジトリ。

PHP Imap Extension PHP7.2 に加えて、 7.3 も追加されてて助かった

## インストール方法

```
brew install kabel/php-ext/php@7.3-imap
```

ただし、公式にサポートされていないので、気をつけるように！
備忘録：NASに繋がらなくなった時の対処法。

開発環境が、NASに繋がらなくなった時に真っ先に疑うのは、
私の環境だと Windows10 Pro なので、SMB v1.0 から疑う。
まだ NAS で SMB v1.0 運用のものがあるので……。

- SMB 有効化/無効化
  - [MSのサイト](https://docs.microsoft.com/ja-jp/windows-server/storage/file- 
  server/troubleshoot/detect-enable-and-disable-smbv1-v2-v3)のものがあるので、そちらで対応
- それでもダメなら？
  - もしかしたら、[ゲストログオン無効](https://www.iodata.jp/support/qanda/answer/s30200.htm)関係の話かも

手元の開発環境は、ゲストログオンを有効にすることで、
どうにかNASに繋がるようになった。よかったよかった。
ノートパソコンのサスペンドを防止する

大量のパソコンを集めて GNU/Linux をインストール、並列プログラミングを実施するというのは昔からよくある[高性能計算](https://ja.wikipedia.org/wiki/%E9%AB%98%E6%80%A7%E8%83%BD%E8%A8%88%E7%AE%97)の手法です。

最近は Windows 7 が EOL を迎えたこともあり、廃棄のパソコンが大量に出たので、それらを収集して HPC のための環境を構築するといったこともあるでしょう。

このとき GNU/Linux を起動して放置していても、勝手にパソコンがサスペンドしないように設定しておく必要があります。特にノートパソコンをサーバー利用している場合、デフォルトでは一定時間で勝手にサスペンドするので注意が必要です。

そこで、設定する場所を記します。

ディストリビューションは Debian 10 または Ubuntu 18.04 LTS とします。

## GUI 無しの場合

普通は並列計算用途であれば CUI でインストールすると思いますが、最近のバージョンではデフォルトでもサスペンドします。これは systemd の設定にて回避できます。

/etc/systemd/logind.conf

```bash
HandleLidSwitch=ignore
```

上記を記述後 systemd を再起動。

```bash
systemctl restart systemd-logind.service
```

これで OK です。

## GUI 有りの場合

[リモートデスクトップで GNU/Linux に接続する](https://qiita.com/ynakayama/items/8c14707db919ca2439ce)といった用途でマスターノードや運用監視ノードにデスクトップ環境を導入するケースが考えられます。

/etc/gdm3/greeter.dconf-defaults

```bash
sleep-inactive-ac-timeout=0
sleep-inactive-battery-timeout=0
```

設定ファイルの最後の方に Automatic suspend という項目があるので、上記のように設定しておきます。これでログイン画面のまま放置しても勝手にサスペンドしなくなります。

なおこのファイルは /usr/share/gdm/dconf/ の下のファイルからのシンボリックリンクとなっているはずなので、そちらも確認しておくと良いです。

以上です。
LOGICOOL OPTION logicool optionをmacのPCに導入する

# 目的

- macのPCにlogicool optionをインストールし使えるようにする

# 作業概要

1. ダウンロード
1. インストールして設定

# 作業詳細

1. ダウンロード
    1. 下記のリンク先にアクセするする。
        - [https://www.logicool.co.jp/ja-jp/product/options](https://www.logicool.co.jp/ja-jp/product/options)
    1. 「ダウンロード(macOS用)」をクリックする。

    ![スクリーンショット 2020-01-29 12.20.12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306417/c0a73b7b-f745-1bb8-2a94-419834db4163.png)

    1. ダウンロードが開始される。

    ![スクリーンショット 2020-01-29 12.21.39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306417/fb2b3e8b-1f20-3833-de13-fc4c440eb8a5.png)
  
1. インストールして設定
    1. zipで取得したインストーラーを解凍する。
    1. 下記のウインドウが出たら「開く」をクリックする。

    ![スクリーンショット 2020-01-29 12.24.35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306417/1ca8d458-881f-0bfe-e82a-7919cbe26f53.png)

    1. パスワードの入力を求められたらパスワードを入力する。

    ![スクリーンショット 2020-01-29 12.25.56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306417/0043be41-873a-f2e6-0a3e-21947ccd5960.png)

    1. 「LOGICOOL OPTIONのインストール」をクリックする。

    ![スクリーンショット 2020-01-29 12.26.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306417/fa04f127-2742-63eb-de18-a104623edd76.png)

    1. 製品強化にご協力くださいの画面で「いいえ、共有しません」をクリックする。

    ![スクリーンショット 2020-01-29 12.28.42.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306417/bed10c25-6c32-374c-a838-737904b4517c.png)

    1. 下記の画面が出るので待つ。

    ![スクリーンショット 2020-01-29 12.30.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306417/48beb967-fccc-b92e-175c-46931e956f9f.png)

    1. 待っていると下記画面出るのでログインはお好みで実施する。ログインしなくても十分に使用できるがデバイスの設定を引き継げるらしいのでログインした方が良いかもしれない。

    ![スクリーンショット 2020-01-29 12.32.11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306417/de05dfe9-6893-8f2d-d8fb-029af5048af2.png)

    1. すでにデバイスを接続している場合はデバイスの説明が始まる。

    ![スクリーンショット 2020-01-29 12.33.21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306417/3b26bd8d-1c1c-7972-cee6-144976616586.png)

    1. まだデバイスが登録されていない時はデバイスの登録が画面の案内に沿って実施される。

# logicool option起動後にウインドウが黒画面になり一向に進む気配がない時

- Windows用のトラブルシューティングであるが下記を参考にしていただきたい
    - [LOGICOOLオプション logicool optionが起動しない デバイスが見れないときの解決法　通常ダウンロード方法](https://qiita.com/miriwo/items/151e7f5c35318e853ec6)

# 余談

- logicoolのキーボードである「craft」を自分のmacbook proに接続して設定したところmacの設定からJISにしてたがUS配列として認識されていた。
- logicool optionを導入し接続したところJIS配列として入力できるようになった。
- 家にある全てのデバイスを登録してみたらデバイス選択画面が充実してニヤニヤが止まらない。

![スクリーンショット 2020-01-29 12.46.36.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306417/9b8cc951-8a61-7162-13e4-439b7dc366c2.png)
PHP/MySQLを使った掲示板をherokuでデプロイする流れ


ローカルで作った掲示板をheorkuに移行する際、めちゃくちゃ苦戦したのでまとめておきます。

#手順

##1. herokuに登録する
ここで、登録はクレジットカードの登録もしなければなりません。
クレジットカード登録ができなければMySQLを使うことができませんでした。
デビットカードでもできると思いますが、三井住友銀行のデビットでは無理でした。
楽天のデビットで登録しました。

##2. heroku CLIをインストールする
https://devcenter.heroku.com/articles/heroku-cli
正直これは僕もよくわからなかったので、このサイトの手順通りにやっていったら大丈夫だと思います（）
これでherokuのコマンドが使えるようになるはずです？

##3. アプリを作成

```
$ heroku login
```

ここでアプリのファイルがまとまっているルートディレクトリに移動してください。git管理するイメージです。

```
$ heroku create アプリ名
```

アプリ名の指定がなければ自動で割り当てられます。
また、アプリ名は、小文字の英字と数字とハイフンのみで作成してください。それ以外を使った場合エラーが出るはずです。

##4. composer

```
$ touch composer.json
```

```composer.json
{
    "require": {
      "php": "~7.0",
      "ext-mbstring": "*"
    }
 }
```

```
$ curl -sS https://getcomposer.org/installer | php
$ mv composer.phar /usr/local/bin/composer
$ composer -v
$ composer install
```

この手順通りやればいいはず？？
https://qiita.com/nanshi99/items/baad35db1d1cde1fdba2
この記事を参考にしています。

##5. ClearDBの設定

```
$ heroku addons:add cleardb:ignite --app 3で作ったアプリ名
$ heroku config --app 3で作ったアプリ名
```

```
mysql://ユーザー名:パスワード@ホストネーム/データベース名?reconnect=true
```

configコマンドで出てきた

 - ユーザー名
 - パスワード
 - ホストネーム
 - データベース名

にコードを書き換える
また、これらを使って下記コマンドを打つことで、DB内に入ることができる。

```
$ mysql -u[USERNAME] -p[PASSWORD] -h[HOSTNAME] -D [DATABASE]
```

次にDBのテーブル設計を行う。

```
mysql> create table テーブル名(id int, view_name varchar(100));
```

idにプライマリーを追加

```
mysql> ALTER TABLE table_name ADD PRIMARY KEY(id);
```

idにオウトインクリメントを追加

```
mysql> ALTER TABLE table_name CHANGE id id int(11) AUTO_INCREMENT;
```

これにてDB設計終わり！





##6. gitの準備

GitHubで新しいリポジトリを作成してください。

```
$ git init
$ git remote add origin URL(リモートリポジトリ)
$ git add .
$ git commit -m "first commit"
$ git push origin master
```

##7. GitHubとherokuを連携させる
 - herokuにアクセスする
 - Dashboardをクリックして3で作成したアプリを開く
 - Deployをクリックし、Deployment methodの欄をGitHubに変更する
 - Connect to GitHubをクリックする
 - Authorize herokuをクリックする
 - repo-nameに6で作成したリポジトリ名を入力してSearchをクリックする
 - Connectをクリックする
 - Automatic deploysとManual deployの欄があれば完成です
 - Manual deploy欄のDeploy Branchをクリックする
 - Viewをクリックする

この流れで自分が作ったサービスが全世界に発信できました。

https://qiita.com/sho7650/items/ebd87c5dc2c4c7abb8f0
この記事を参考にしました。

##参考記事
https://qiita.com/nanshi99/items/baad35db1d1cde1fdba2
https://qiita.com/yutaono/items/34bdc9383ce5870e7b8b
https://qiita.com/tsuzuki557/items/7244b23d86364ace06bd
https://qiita.com/sho7650/items/ebd87c5dc2c4c7abb8f0
http://www.ownway.info/Ruby/heroku/how/management/database/cleardb
https://tutorialmore.com/questions-61774.htm

#まとめ
サーバーサイド難しい！！！
クレジットカードの登録から詰まったのでめちゃくちゃ苦戦しましたが、なんとか一人で掲示板を作成してからサーバーにあげるまで一通りできたのですごい達成感です。
流れとしては、この記事の通りやってもらったらできるはずです。
何か間違い等あればご指摘お願いします。
DockerでMySQLを使う流れ

DockerでMySQLを初めて使った時、かなり手こずったのでまとめておきます。

Dockerfielや.ymlファイルが既にある前提で進めます。

#手順

コンテナを立ち上げます。

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

docker-compose.ymlでのnetwork-modeに書いてあるnetwork_nameを作成します。

```
$ docker network create network_name
```

コンテナIDを確認します。

```
$ docker ps
```

mysqlのコンテナ内に入ります。

```
$ docker exec -it コンテナID bash
```

mysqlを起動します。

```
$ mysql -u root -p
```

DBを作成します。

```
mysql> create database db_name;
```

DBを指定します。

```
mysql> use db_name;
```

テーブルを作成します。

```
mysql> create table table_name(id int, view_name varchar(100));
```

idにプライマリーを追加します。

```
mysql> ALTER TABLE table_name ADD PRIMARY KEY(id);
```

idにオウトインクリメントを追加します。

```
mysql> ALTER TABLE table_name CHANGE id id int(11) AUTO_INCREMENT;
```

mysql内で文字化けが起こった時に解消します。

```
mysql> set names utf8;
```

DB設計は一通りこんな感じです！

#sql内になかなか入れない時

```
$ sudo mysql.server start	
$ mysql -u root
```

これを試すことで入れるかもしれません。

#その他のコマンド

今あるDBの一覧を表示

```
mysql> SHOW DATABASES;
```

DB削除

```
mysql> DROP DATABASE db_name;
```

今あるテーブルの一覧を表示

```
mysql> SHOW TABLES;
```

テーブル構造を確認

```
mysql> DESC table_name;
```

テーブルを削除

```
mysql> DROP TABLE table_name;
```

データ検索

```
SELECT * FROM table_name;
```

#まとめ
初めてやることはやっぱり躓きまくりますね。
流れをつかめたので大きな進歩だと思います。

https://kitsune.blog/mysql-command
参考記事です。これは有能
AndroidでTextViewのテキストの一部にリンクをつけたいときのKotlinExtension

サインインが必要なアプリで、「サービスに登録することで利用規約とプライバシーポリシーに同意したとみなします。」系のテキストの「利用規約」と「プライバリーポリシー」にClickListenerを付与したい場合のKotlinExtensionを書きました。

```kotlin
fun TextView.addLinkedSpannable(highlight: String, listener: (view: View) -> Unit) {
    val original = when {
        (text != null && text is SpannableString) -> text
        else -> SpannableString(text)
    }

    val startPos = original.indexOf(highlight)

    movementMethod = LinkMovementMethod.getInstance()
    text = SpannableStringBuilder(original).also {
        it.setSpan(object : ClickableSpan() {
            override fun onClick(view: View) {
                listener(view)
            }

            override fun updateDrawState(ds: TextPaint) {
                super.updateDrawState(ds)
                ds.color = ContextCompat.getColor(context, R.color.black)
            }
        }, startPos, startPos + highlight.length, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE)
    }
}
```
[TextViewExt.kt - Add linked spannable to TextView for Kotlin Android.](https://gist.github.com/dforest/e3c82cb7cbda1d19b39e4d5c1151d2c5)

表示したいテキストをTextViewのtextに入れて、そのTextViewの`addLikedSpannable()`を実行すれば下線がついて、タップするとlistenerが実行されます。ひとつのtextに複数付与できます。

以下使用例です。
※ 文字列はstrings.xmlを使いましょう。

```kotlin
binding.textView.also {
  it.text = "サービスに登録することで利用規約とプライバシーポリシーに同意したとみなします。"
  it.addLinkedSpannable("利用規約") { 
    //Do something
  }
  it.addLinkedSpannable("プライバシーポリシー") {
    //Do something
  }
}

```

### 参考
[TextViewの一部にリンクをつける - Qiita](https://qiita.com/sudo5in5k/items/c0479968a25bf3bd78df)
Node.jsでYYYYMMDDの文字列を出力する

#概要
Node.jsを使って現在日時からYYYYMMDDの文字列を出力します。
2020/2/3なら`20200203`となります。
少し工夫しないと`202023`とかになってしまいます。
#実際のコード
```javascript
const createYYYYMMDD = () => {
    const today = new Date();
    const monthMM = ('0' + (today.getMonth() + 1)).slice(-2);
    const dayDD = ('0' + today.getDate()).slice(-2);
    return today.getFullYear().string() + monthMM + dayDD;
};

console.log(createYYYYMMDD);  // 20200203
```

##ポイント
`getMonth()`で得られる値は、現在の月（日）から1引いた値となります。
そのため1を足して`(today.getMonth() + 1)`います。
さらに`'0' +`として、先頭に0を付けた文字列に変換して、`.slice(-2)`で必ず2文字になるようにします。
Firebase Functions x TypeScript デバッグをHotReload

- 2020/06/30
    - よりスマートな方法を記述しました。
    - 以前記述していた tsc --watch を併用する方法では、tscのプロセスが不正に残り続けてしまうことがありました。

## 更新版
`npm i -D tsc-watch`

```json:package.json{
{
  "scripts": {
    "emulators": "tsc-watch --onFirstSuccess 'firebase emulators:start --only firestore,functions'",
    "shell": "tsc-watch --onFirstSuccess 'firebase functions:shell'",
  }
}
```

`npm run shell`
`npm run emulators`

## 非推奨な方法

```json:package.json
{
  "scripts": {
    "watch": "tsc --watch",
    "shell": "npm run watch & firebase functions:shell",
    "start": "npm run shell"
  }
}
```

`npm start`
GoModules時代のホットリロード

# 概要
Goでホットリロードを実現する場合、[oxequa/realize](https://github.com/oxequa/realize)がお勧めとしてよく出てきます。
ですが、そのままではGo Modulesに対応していない問題があり、監視対象に`go.mod`が含まれているとエラーが出て正常に動いてくれません。

結論として、`.realize.yml`に設定を追加した上で`realize start`する必要があります。
古い記事にある`realize start --run`や`realize start --run --no-config`では動かないので注意。
なお、設定については[こちらの記事](https://qiita.com/h-sakano/items/b2c38e13387705f34dec)の通り。

## .realize.yamlの設定
`commands`の下位項目として`install`を追加し、監視対象に変更が入ったら`app.out`としてビルドして吐き出します。
`run`として吐き出した`app.out`を実行します。

```.yml
schema:
  # 略
  commands:
    install:
      status: true
      method: go build -o app.out /your/src/path
    run:
      status: true
      method: ./app.out
  # 略
```

# まとめ
[Go1.11互換性に関するissue](https://github.com/oxequa/realize/pull/218)を遡ると、2019年1月時点で、oxequa/realizeは開発放棄されてるんじゃない？みたいな旨もあります。
Docker環境で使う際に発生する[gopkg.in/urface/cli.v2のバージョン違いによるビルドエラー](https://github.com/oxequa/realize/issues/253)の対策も対症療法的で、プルリクが随分前から無視されているようです。
今後はforkされたrealizeを使うか、別のホットリロードツールを利用するのが良いのかもしれないですね。
Vagrant  共有フォルダー   vagrant-vbguest version up時のエラー

vagrant 2.2.6から2.2.7にversion upすると
共有フォルダーが動かなくなりました.

``` 前提
>vagrant version
Installed Version: 2.2.7
Latest Version: 2.2.7
 
You're running an up-to-date version of Vagrant!
```

こんなエラーです.

````
>vagrant vbguest --status
[default] A Virtualbox Guest Additions installation was found but no tools to rebuild or start them.
```

# 原因
vagrant-vbguest (0.22.0) のバグでした
vagrant-vbguest (0.22.1)で解消されています


参考 https://github.com/dotless-de/vagrant-vbguest/issues/362

#  対処法
versionを指定してupgrade

```
vagrant plugin uninstall vagrant-vbguest
vagrant plugin install vagrant-vbguest --plugin-version 0.21.1
```

日本語だと記事が見つからなかったので書きました.
macOS CatalinaでROOT CERNが動かなくなった

#macOS Catalinaにアップデートすると、ROOT CERNが起動しなくなった

備忘録として書いておく。手持ちのiMacのmacOSのCatalina(カタリナ)にアップデートしたら、rootが動かなくなった。スクリプトが動かないだけでなく、ただ

```
root
```
とだけコマンドプロンプトで打っても

```
ERROR in cling::CIfactory::createCI(): cannot extract standard library include paths!
```
などと表記される。

```
echo $ROOTSYS
```


```
echo $PATH
```
と打ち込んでも、正しく表示される。(例えばここで```$PATH```が```$ROOTSYS/bin```を指し示していない場合にはまず環境変数周りがおかしいことがわかる)

そうではないのでしばらく時間を食ったが、どうやら単純な問題で、xcode周りであることが判明した。

```
xcode-select --install
```
とやってxcodeをアップデートすると問題が解決した。
QuickCameraを使用してスクリーンキャプチャ動画(Xcodeプログラミング手順ビデオ)収録

Quick CameraにてYouTube等へのアップ動画を解説者動画付属で作成する手順のメモ。
下記のサイトよりQuick Cameraダウンロード、インストールして起動![スクリーンショット 2020-02-03 15.44.14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/101462/40c2ec7b-4273-fa07-9c27-fc4017ef5ad3.png)
デスクトップの任意の場所に置く、この際Cameraの設定をBorderlessすると常に前面に表示される。
![スクリーンショット 2020-02-03 15.46.34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/101462/31a50fd6-339b-33a2-3220-06df252de710.png)
次にQuickTimePlayerを起動し、新規画面収録を設定。
![スクリーンショット 2020-02-03 15.49.21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/101462/31d92221-3caf-f0c3-1715-561117eb9def.png)
更に画面収録のダイアログの中央の録画ボタンにて録画開始下記のメッセージに従い処理。
![スクリーンショット 2020-02-03 15.49.50.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/101462/f8124347-a317-1366-8fae-fb760ee03b57.png)
![スクリーンショット 2020-02-03 15.53.29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/101462/708c026f-322f-fca5-07b5-22060ee2288f.png)
ストップはMac画面右上のストップボタンにて終了。其の後確認動画が表示されます。
![スクリーンショット 2020-02-03 15.57.01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/101462/2c5652af-b96b-834c-e45c-03ae217b7237.png)
こうやってYouTubeの解説動画作っているのですね！！利用させて頂きありがとうです！！
Docker  docker-compose up時、You must use Bundler 2 or greater with this lockfile.　という地獄のエラー

#背景・エラー発生状況
1. Dockerfileとdocker-compose.ymlの作成
2. Dockerfileの記載
3. docker-compose.ymlの記載
4. database.ymlの変更

この流れを行った後に、 
###docker-compose up
行ったところ、

```
You must use Bundler 2 or greater with this lockfile.
```

なんだこれは、、、

bundlerが悪さしていることに間違いない！！
bundlerのversionを調べて見ると！

###2.0.1

#いろいろ調べた結果、、、
##Bundlerのバージョン2.0.1が悪さをしている模様。
以下の手順で以前のバージョンを入れる
1. gemfile.lockの中身全削除
2. $ gem install bundler -v バージョン
　　古いバージョンのBundlerのGem取得
3. $ bundler バージョン install　
　　Bundlerをインストール
4. docker-compose build
  　ビルドし直す
5. $ docker-compose run web rake db:create
    再度modelを作成する
#参考記事
Docker × Ruby on Rails × MySQLの環境構築
https://qiita.com/tatsuo-iriyama/items/0bf3b08de03280314c91

本当に助かりました！