OmniAICreator/Qiita-1.07M huggingface dataset:
【Javascript】「？」から始まるURLのクエリパラメータを設定・取得する方法

URLディレクトリの後ろに「?id=12345」のようなパラメータがあります。
このパラメータをサイト側で取得し、フォームのinputタグに渡し送信する方法を調べました。

# URLパラメータとは?
URLの後ろについている`?`と変数と値です。

```
http://hogehoge.com?id=1234567
```
この`?id=1234567`を取得を目的とします。

# なぜこのパラメータが必要なのか？
ではなぜこのパラメータをわざわざ付ける必要があるのでしょうか？
主に広告やマーケティングなどで計測の目的で使用されます。
広告側でパラメーターを付与し、サイト訪問時に取得し、申込み時にそのパラメータを渡せばどの経路で流入したかがわかるといったところでしょうか。

# JavascriptでURLを取得する
Javascriptでは`location.href`でURLを取得することができます。

```html
<div class="text-area">このページのURLは「<span id="urlparam"></span>」です。</div>
```
```js
var url = location.href;
document.getElementById("urlparam").innerHTML = url;
```

# パラメーターのみを取得する
先程のやり方だとURLすべてを取得します。ほしいのは後ろのパラメータだけですので
`location.search`でパラメータのみを取得します。

`location.href`を`location.search`に変更するだけです。

```js
var url = location.search;
document.getElementById("urlparam").innerHTML = url;
```

# 取得したパラメーターをinputタグに渡す
さてこちらの目的はフォームに埋め込み送信時に受け取ることです。
以下ではフォームのinputタグに埋め込む方法になります。

```index.html
<form action="php/form.php" method="post" id="test" name="test">
  <div>
    <label>お名前</label>
    <input name="お名前" type="text">
  </div>

  <div>
    <label>メールアドレス [必須]</label>
    <input name="メールアドレス" type="text">
  </div>

  <div>
    <label>お問い合わせ [必須]</label>
  </div>

  <div>
    <input type="hidden" name="param" id="inputparam">
  </div>

  <button type="submit">送信</button>
</form>

```

```form.js
var param = location.search;
document.getElementById("inputparam").value = param;
```

`location.search;`でパラメータのみを取得し
`DOM`の`id`の`inputparam`の`value`プロパティに変数`param`を代入し、`value`プロパティにパラメータを渡すことができます。

ユーザーには値は見えなくていいので`input`は`hidden`にしておきます。
そうすると下記のような形でパラメータがinputのvalueに入ります。

```html
<input type="hidden" name="param" id="inputparam" value="?id=1234">
```

#### 追記
ページ遷移したときもパラメーターの引き継ぎがほしい
http://times-diary.hatenablog.com/entry/2018/03/14/230000
Adafruit Trinket M0でTinyGo(シリアル通信編)

#はじめに
[初回](https://qiita.com/quadnine/items/cfe161e126d4391a8753)に続き、今回はTinyGoとMacとの間でシリアル通信してみる
#事前確認
###MacでTTYデバイスを確認
```
$ ls /dev/tty.usb*                                                                                                       [/Users/takaaki]
crw-rw-rw-  1 root  wheel   18,  40  3  8 15:55 /dev/tty.usbmodem14101
```
Adafruitが繋がっているTTYデバイス名を確認しておく
#実行コード
```go:main.go
package main

import (
	"time"
)

func main() {
	i := 0
	for {
		time.Sleep(time.Millisecond * 1000)
		println("Counter: ", i)
		i++
	}
}
```
#ビルド&書き込み
###パターン1. Macでビルド&書き込み
MacにインストールしたTinyGoを使ってビルドから書き込みまで一気に実行

```
$ tinygo flash -target trinket-m0 ./main.go
```

###パターン2. Dockerでビルド&Macから書き込み
Mac上でDockerを使ってビルドして、書き込みはMacから実行
Trinket M0はUSBマスストレージとして扱えるので、ビルドで生成されたUF2ファイルをドラッグ&ドロップで書き込み

```
$ docker run --rm -v $(pwd):/src -w /src tinygo/tinygo:0.12.0 \
tinygo build -o /src/flash.uf2 -size=short -target trinket-m0 ./main.go
```
#TinyGoとシリアル接続
```
$ screen /dev/tty.usbmodem14101
```
確認しておいたTTYデバイスに対してscreenコマンドで接続

#実行結果
```
Counter:  0
Counter:  1
Counter:  2
Counter:  3
Counter:  4
Counter:  5
```
接続を解除するにはCtrl+aを押した後にkを押し`Really kill this window [y/n]`というメッセージが表示されたらyを押す
KiCad でフットプリントライブラリが読めないトラブル

# 環境

- MS-Windows10 64bit
- KiCad 5.1.5-3

# フットプリントライブラリが出てこない

割り当てをしようとしたら左側ペインのフットプリントライブラリーが出てこない。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/3aaab5d4-cdc5-fdd6-aed6-d2211ed7cb37.png)

フットプリントライブラリーの管理を見るとプロジェクトに保存したライブラリーしか登録されていない。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/232ae33e-19d3-b8bf-f06e-78dbf32b80c8.png)

# エラーの起こった経緯

新規にKiCadをインストール
ほかのマシンからKiCadのプロジェクトをコピーして開く
Eeschema で回路図を編集、フットプリントの割り当て画面を開く


フットプリントライブラリテーブルを作る旨のダイアログが出た後、
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/6423a78f-131e-6192-9687-90bb01f71185.png)

ライブラリをロード。ここでプログレスが進行せずに止まってしまった。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/ee2a6ec2-0b32-2118-dbdf-9b6279a40ef6.png)

キャンセルを押すと冒頭のようなエラーが発生。

# 修正方法

今回は、以下の手順を取りました。

- 一旦設定ファイルを消す
- KiCad再インストール
- フットプリントライブラリテーブルを作成


## 設定ファイルの削除

KiCadを終了して、設定ファイルを削除。

Windowsの場合は例えば、

```

C:\Users\ユーザー名\AppData\Roaming\kicad
```

にある。

Windowsキー＋R で%AppData%と入力して「OK」でRoamingフォルダを開き、kicad フォルダを削除する。



![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/6224893a-46a6-7a0b-533a-cf8a22568e67.png)

KiCadを再インストール

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/3d7f9d15-308e-4184-1835-81be1ae53532.png)

適当にプロジェクトを開き、フットプリントの割り当て画面を出す。
フットプリントライブラリテーブルを作る旨のダイアログが出た後、
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/6423a78f-131e-6192-9687-90bb01f71185.png)

ライブラリをロード。前回はここでプログレスが進行せずに止まってしまったが今回は無事進んで
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/ee2a6ec2-0b32-2118-dbdf-9b6279a40ef6.png)

正常に画面が出ました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/e43a4ebc-984b-a4b8-af22-dcf0ed9bd21a.png)
strftimeの日本語対応が少し面倒なので代替関数を作った

曜日とか年号とか、strftimeで結果を日本語で表示したい場合、環境によって結果が異なる。ロケールの設定が必要とか、そもそも該当する設定ファイルがOSに同梱されてないことがあるとか、Cのライブラリが対応してないことがあるとかです。

strftimeとパラメータ互換で使える代替関数を作りました。同じようなものを作っている人がたくさんいるのは知ってますが、これくらいならコピペで済ませず自作したい。

```php
function datetime_format($format, $timestamp='0000-00-00 00:00', $default='') {
    if(!$timestamp || strpos($timestamp, '0000-00-00')===0) {
        // 値がない場合は空文字列を返す
        return $default;
    }
    if(!preg_match('@^[0-9]+$@', $timestamp)) {
        // 文字列の場合はUNIXタイムスタンプ形式に変換
        $timestamp = strtotime($timestamp);
    }
    if(strpos($format,'%')===false) {
        // strftime関数の変換指定子がない場合はdate関数で処理して返す
        return date($format, $timestamp);
    }
    if(strpos($format, '%曜')!==false) {
        // 日本語の曜日処理はここで
        $week = ['日', '月', '火', '水', '木', '金', '土'];
        $format = str_replace('%曜', $week[date('w', $timestamp)], $format);
    }
    if(strpos($format, '%E')!==false) {
        // 和暦処理
        $E = function($timestamp) {
            $ymd = date('Ymd', $timestamp);
            $Y = date('Y', $timestamp);
            if (20190501 <= $ymd) {
                return array('令和', ($Y - 2018));
            }
            if (19890108 <= $ymd) {
                return array('平成', ($Y - 1988));
            }
            if (19261225 <= $ymd) {
                return array('昭和', ($Y - 1925));
            }
            if (19120730 <= $ymd) {
                return array('大正', ($Y - 1911));
            }
            return array('明治', $Y-1868);
        };
        $format = str_replace(
            array('%EC', '%Ey'), $E($timestamp), $format
        );
    }
    return strftime($format, $timestamp);
}
```

実用上の問題がなければいいと思って、明治よりも前の判定は作ってません。これ以上を求めるならCarbonを使うのがいいと思います。

```php
echo datetime_format('%EC%Ey年%m月%d日(%曜)', '2020-03-09'); // 令和2年3月9日(月)
```

元号や日本語の曜日が不要な場合は、`$format` はstrftime方式・date方式どちらでもokです。 `%` 文字を含むかどうかで判定します。`$timestamp` はunixタイムスタンプ・日付文字列どちらでもokです。
空の値を与えた場合はstrftime関数もdate関数も1970-01-01のような値を返しますが、当関数では空文字を返します。
GitHub Actions でapkファイルを検査する

アプリを開発していると、導入したライブラリの影響等で知らぬ間に意図しないpermission要求が含まれていたり、バイナリのサイズが大きくなってしまうことはよくあります。

> 例えば `com.android.installreferrer:installreferrer:1.1` の追加には、意図しないパーミッション要求が追加されてしまう現象がありました。

master ブランチへのマージを契機に、これらをチェックする GitHub Actions のアクションを書いてみました。Android SDK ツールに含まれる [apkanalyzer](https://developer.android.com/studio/command-line/apkanalyzer?hl=ja) を利用しています。
（ビルド時間が気にならないなら、マージされてしまってからチェックするのではなく、プルリクエスト作成時にチェックした方がよいと思います。）

```yaml
name: Inspect apk

on:
  push:
    branches:
      - master

env:
  # apkanalyzer で出力される順に定義しておく
  KNOWN_PERMISSIONS: "android.permission.INTERNET, android.permission.ACCESS_NETWORK_STATE, android.permission.ACCESS_WIFI_STATE"
  ALLOWED_DOWNLOAD_SIZE: 10485760 # 10M

jobs:
  inspect:
    name: Inspect apk
    runs-on: macos-10.15 # Ubuntuだとapkanalyzerが含まれないので
    steps:
      - name: Check out
        uses: actions/checkout@v1
      - name: Set up JDK
        uses: actions/setup-java@v1
        with:
          java-version: 1.8
      - name: Build with Gradle
        run: ./gradlew assembleRelease
      - name: Inspect apk
        run: |
          has_error=false

          known_permissions=$(echo $KNOWN_PERMISSIONS | tr -d ' ') # スペースを削除
          apk_permissions=$($ANDROID_HOME/tools/bin/apkanalyzer manifest permissions app/build/outputs/apk/release/app-release.apk)
          apk_permissions=$(echo $apk_permissions | tr ' ' ',') # 出力を1行にしスペースをカンマへ置換
          if [[ $known_permissions != $apk_permissions ]]; then
            echo "::error::Incorrect permissions"
            has_error=true
          fi

          allowed_download_size=$ALLOWED_DOWNLOAD_SIZE
          apk_download_size=$($ANDROID_HOME/tools/bin/apkanalyzer apk download-size app/build/outputs/apk/release/app-release.apk)
          if let "allowed_download_size < $apk_download_size"; then
            echo "::error::Download size too large"
            has_error=true
          fi

          if "$has_error"; then
            exit 1
          fi
```

job を失敗させているので、リポジトリの watch をしていれば GitHub の通知(Notificaton)で失敗を検知できそうですが、[ステータスバッジ](https://help.github.com/ja/actions/configuring-and-managing-workflows/configuring-a-workflow#adding-a-workflow-status-badge-to-your-repository) をリポジトリの README.md へ貼っておいたり、次のように失敗時に何かしらの通知するstepを追加してもよいでしょう。

```yaml
steps:
  - name: Inspect apk

  ...

  - name: Notify failure
    if: failure()

    ...

```

もし Slack へ通知する場合はこちらを参考にしてください ⇒ [GitHub Actions で Slack に通知をお手軽に送る](https://qiita.com/hkusu/items/3dbf09f7fa83ba6d457c)
赤ちゃんのために部屋の状況をNature Remoで監視する

#はじめに
赤ちゃんを育てる環境としては20～25℃、湿度50～60%あたりが適するようです。
いつの間にか寒くなっていたり、乾燥していたりすると困るので、
Nature Remoに入っているセンサー情報を使って気づけるようにします。

温度/湿度計を見ればいい話ですが、せっかくNature Remoがあるので活用してみよう！という感じです。

#処理フロー
1. Nature RemoのAPIを使い、温度・湿度・照度・人感センサーの情報を取得します。
2. 経過も確認しておきたいので、スプレッドシートに記録していきます。
3. 関数は15分おきにGASのトリガーを使い発火させます。
4. 温度や湿度が一定範囲外であることを判断したら、LINEのAPIを使い、家族LINEにPOSTします。

```Java:MyHome.gs
//室温取得
function tempNatureRemo() {
  //nature remo 温度データGET用変数
  var remourl = "https://api.nature.global/1/devices";
  var remotoken = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX";
  var remooptions = {
    "method" : "GET",
    "headers" : {"Authorization" : "Bearer "+ remotoken},
    "contentType": "application/json",
  };
  //nature remoのセンサーデータをGETする  
  var Postdata = UrlFetchApp.fetch(remourl, remooptions);
  
  //JSONパースして必要なデータのみを抜き取る
  var Jsonp = JSON.parse(Postdata.getContentText());
  var tempdata    = Jsonp[0]["newest_events"]["te"]["val"];  //温度
  var humidity    = Jsonp[0]["newest_events"]["hu"]["val"];  //湿度
  var illmination = Jsonp[0]["newest_events"]["il"]["val"];  //照度
  var motion      = Jsonp[0]["newest_events"]["mo"]["val"];  //人感センサー  0 or 1
  
  var tempdata2 = Math.floor(tempdata); 
  var tempdatatxt = "現在の室温は" + tempdata2 + "℃です。" + "\n";

  //スプレッドシート変数
  var spreadsheetId = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX";
  var sheetName = "XXXXXXXXXX";
  var spreadsheet = SpreadsheetApp.openById(spreadsheetId);
  var sheet = spreadsheet.getSheetByName(sheetName);

  //今日の日時
  var year  = Utilities.formatDate(new Date(), 'JST', 'yyyy');
  var month = Utilities.formatDate(new Date(), 'JST', 'MM');
  var day   = Utilities.formatDate(new Date(), 'JST', 'dd');
  var time  = Utilities.formatDate(new Date(), 'JST', 'HH:mm:ss');

  //スプレッドシートに日時と温度を追記
  sheet.appendRow([year, month, day, time, tempdata, humidity, illmination, motion]); 
  
  //温度が適温以外ならLINEに通知
  checktempdata(tempdata);
  
  //湿度が適温以外ならLINEに通知
  checkhumidity(humidity);
  
  return tempdatatxt;
}


//一定の湿度以下ならLINEに通知する
function checkhumidity(humidity){

  var ret; //戻り値
  var upperlimit = 70; //換気の目安
  var lowerlimit = 30; //加湿の目安
  
  //25℃以上は熱すぎる
  if(humidity >= upperlimit){
    push("湿度が" + upperlimit + "％を超えました。\n" + "現在の湿度：" + humidity + "％\n" + "換気しましょう。");
  }
  //20℃以下は寒すぎる
  else if(humidity <= lowerlimit){
    push("湿度が" + lowerlimit + "％以下になりました。\n" + "現在の湿度：" + humidity + "％\n" + "加湿器をつけましょう。");
  }
  //適温なので何もしない
  else{
    ret = "";
  }

  return ret;

}

//一定の温度以外ならLINEに通知する
function checktempdata(tempdata){

  var warmlimit = 25; //暑さの目安
  var coldlimit = 20; //寒さの目安
  
  //25℃以上は熱すぎる
  if(tempdata >= warmlimit){
    push("室温が" + warmlimit + "℃を超えました。\n" + "現在の室温：" + tempdata + "℃\n" + "換気しましょう。");
  }
  //20℃以下は寒すぎる
  else if(tempdata <= coldlimit){
    push("室温が" + coldlimit + "℃以下になりました。\n" + "現在の室温：" + tempdata + "℃\n" + "暖房をつけましょう。");
  }
  //適温なので何もしない
  else{
  }
  
  return;

}
```

#結果
こんな感じでLINEに通知される。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/545683/4e27935c-48d3-dc37-50e3-4cfc13bc85a5.png)
※デバッグのため閾値をいじっています。

#その他
IFTTTやGAS経由で本情報をトリガに自動制御できるっちゃできるが、今回はやめておきます。
そもそもNature Remoにそういう機能あるし。
【Rails】SimpleCovを使ってCircleCIでカバレッジを見れるようにするまで

# SimpleCov とは

Ruby用のコードカバレッジ解析ツールです。

# 環境

- Rails 5.2.3
- [SimpleCov](https://github.com/colszowka/simplecov) v0.18.5
- RSpec 3.8.2

# インストール

```ruby:Gemfile
group :test do
  gem 'simplecov'
end
```

# RSpec実行時に、SimpleCovの結果が出力されるようにする

`spec/spec_helper.rb`の一番初めに、以下のような設定を記述します。

```ruby:spec/spec_helper.rb
require 'simplecov'

# minimum_coverage、minimum_coverage_by_file はオプショナルです。
# - カバレッジが90%未満の場合、non-zero exit する（CircleCI上の場合、ジョブが失敗する）。
SimpleCov.minimum_coverage 90
# or
# - カバレッジが80%未満のファイルがあった場合、non-zero exit する（同上）。
SimpleCov.minimum_coverage_by_file 80

SimpleCov.start do                                     # 最低限、この行のみ必要。ブロックの中はオプション。
  add_filter '/spec/'                                  # /spec/ が含まれるファイルは除外する。
  add_filter do |source_file|
    source_file.lines.count < 5                        # 行数が 5行未満のファイルは除外する。
  end

  enable_coverage :branch                              # https://github.com/colszowka/simplecov#branch-coverage-ruby--25

  add_group 'Models', 'app/models'                     # 以降の設定で、グルーピングして結果を出力することが出来るようになります。
  add_group 'Services', 'app/services'                 # この設定をした場合も、All Files も含まれます。
  add_group 'Controllers (api)', 'app/controllers/api' # ここに含まれないものは Ungrouped として別タブで表示されます。
  add_group 'Controllers', 'app/controllers'
  add_group 'Helpers', 'app/helpers'
end
```

# 出力ファイル

`rspec`実行時に、`coverage/index.html`にファイルが出力されます。
`open coverage/index.html`などでブラウザで確認してください。

# 注意（SimpleCovのレポートに、特定のクラスが含まれていない場合）

例えば、`app/models/foo.rb`というファイルがあった時に、このファイルに含まれるコードに対応するテストがまったくないと、そもそも`SimpleCov`のチェック対象とならず、`coverage/index.html`にも含まれないということがありました。
この場合、以下のような空ファイルを作成すると、結果に含まれるようになりました。

```ruby
# frozen_string_literal: true

require 'rails_helper'

describe Foo, type: :model do
  # NOTE: This `it` is added to prevent the following warning by rubocop, Empty example group detected.
  it do
    # do nothing
  end
end
```

# .gitignoreでcoverage以下を無視する

```
echo "coverage" >> .gitignore
```


# CircleCIでSimpleCovの結果を確認する

[このCircleCIの設定](https://qiita.com/luigiii/items/8addbc04982dcd40c076#%E8%A8%AD%E5%AE%9A%E4%BE%8B)で以下の箇所を参照してください。
この設定により、rspecのジョブ完了時に、CircleCI上の該当ジョブの`ARTIFACTS`タブで、`coverage/index.html`が確認できるようになります。

```
      - store_artifacts:
          path: coverage
```

# その他
## SimpleCovの対象にしたくない行

以下のように、`:nocov:`で囲います。

```ruby
# :nocov:
def skip_this_method
  never_reached
end
# :nocov:
```
ref: https://github.com/colszowka/simplecov#ignoringskipping-code

## 特定の条件（カバレッジが低い等）で、non-zero exitさせる

ref: https://github.com/colszowka/simplecov#customizing-exit-behaviour

## 特定条件下でのみSimpleCovを実行したい場合

十分速いので基本的に必要となることはほぼない想定ですが、以下に書かれている通り、環境変数で制御することになります。

ref: https://github.com/colszowka/simplecov#running-coverage-only-on-demand
Pythia Instllation


# はじめに
Facebook AI Researchが公開しているマルチモーダルな深層学習モデルのフレームワークPythiaを自分がインストールしたときの方法を残します。
いろいろとひっかかり友人に聞いたりして結果的に動かせた流れなので、適切ではないのかもしれません。

Introduce how to install Pythia which is Framework of Multimodal AI models from Facebook AI Research.

<!--more-->

# コンテナ準備 Create Docker Contena

まず、下記のDockerfileをビルドしてコンテナを作成します。

First, creating Docker contena using following Dockerfile.

https://github.com/facebookresearch/maskrcnn-benchmark/blob/master/docker/Dockerfile


そのコンテナ内で[Pythia's Documentation](https://learnpythia.readthedocs.io/en/latest/?badge=latest)のQuickstartにあるColoabのデモコードを参考にインストール作業をしていきます。

Let's install Pythia according to the Documentation. Follow the code of Quickstart Colab file.

# Installation

terminalで以下のコードを順に実行していきます。

Run following codes on terminal.

```
cd
mkdir content

# Install dependencies
pip install ninja yacs cython matplotlib demjson
pip install git+https://github.com/cocodataset/cocoapi.git#subdirectory=PythonAPI
```

```
cd ~/content/
rm -rf fastText
git clone https://github.com/facebookresearch/fastText.git fastText
cd /content/fastText
pip install -e .
```

```
cd ~/content/
rm -rf pythia
git clone https://github.com/facebookresearch/pythia.git pythia
cd /content/pythia

# Don't modify torch version
sed -i '/torch/d' requirements.txt
pip install -e .
```


以下を.bashrcに追加

Add the next PATH to bashrc.

```
PATH="$PATH":~/content/pythia
```

```
# Install maskrcnn-benchmark to extract detectron features
cd /content
git clone https://gitlab.com/meetshah1995/vqa-maskrcnn-benchmark.git
cd /content/vqa-maskrcnn-benchmark
# Compile custom layers and build mask-rcnn backbone
python setup.py build
python setup.py develop
```


以下を.bashrcに追加
Add the next PATH to bashrc.

```
PATH="$PATH":~/content/vqa-maskrcnn-benchmark
```

また、自分は保険でpythia dirで以下を実行

```
python setup.py develop
```

これをすると次のようなエラーが返ってきます
If run the above code, following error may return.

```
error: tqdm 4.19.9 is installed but tqdm>=4.27 is required by {'transformers'}
```


しかしPythiaはインストールできているようなので手作業でtransformersを入れます。
Transformers lib requires tqdm>=4.27 , so you should update tqdm and install transformers manually using pip.

```
pip install -U tqdm
pip install transformers
```

これでtransformersは使えるようになりました。
Then you can use (it means import) transformers.

以上でInstallionは完了です。以降は使ってみた様子を残していこうと思います。
Instllation of Pythia is finished.
From now on, I'll record how I used it.
Terminalで日本語を表示・入力するための環境変数LANGの設定方法

# ターゲット
Terminalで日本語を表示したり、入力したりしようとすると、文字化けしたり、日本語の入力自体ができないのを、解決したい人

# 事象
Terminalで日本語を表示しようとすると、以下のように「?????」と文字が正常に表示されない。
<img width="986" alt="Screen Shot 2020-03-08 at 15.46.30.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/292215/7c5f07fd-7940-c1e8-41a0-840c63ad87b7.png">


# 設定方法
環境変数を設定するファイル `.bash_profile` に、 `export LANG=ja_JP.UTF-8` を追記する。
追記したら、Terminalを再起動する。
<img width="824" alt="Screen Shot 2020-03-08 at 16.02.34.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/292215/e5525807-adc6-0aa6-b9c1-9edf549cd56b.png">

# 設定後
Terminalで日本語を表示したり、入力したりできるようになる。
<img width="878" alt="Screen Shot 2020-03-08 at 16.04.43.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/292215/15ca828b-d40b-8cc7-6803-7fefa5a69258.png">
IAMユーザに「請求情報とコスト管理ダッシュボード」へのアクセスを許可する

#公式
https://docs.aws.amazon.com/ja_jp/IAM/latest/UserGuide/tutorial_billing.html

#事象
AWSアカウントのデフォルト設定のままだと、IAMユーザで「請求情報とコスト管理ダッシュボード」が表示されません。
![請求ダッシュボードエラー.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/599093/370e3417-6e82-6a92-b1ee-debb349d3798.png)


#対応手順
1. AWSアカウントでログインし、「マイアカウント」を選択
![マイアカウント.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/599093/9c44770c-5be5-b13c-50b5-f4108100474b.png)

2. 「IAMアクセスのアクティブ化」をチェックして更新
![IAMアクセスのアクティブ化.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/599093/3109f794-544d-e0e2-b4d5-99500d43e467.png)


#結果確認
IAMユーザでBillingにアクセスすると、「請求情報とコスト管理ダッシュボード」が表示されるようになりました。（IAMユーザーにAdministratorAccessポリシーが割り当たっている前提です）
![請求ダッシュボード.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/599093/a28328f1-c9db-01df-452d-8f6bd899f380.png)
kubectlのデフォルトnamespaceをコマンドで変更

## 概要

kubectlでコマンドを実行するとき、 `--namespace` で任意のnamespaceを指定できる。

```
$ kubectl get pods --namespace=hoge
```

特に指定しない場合はデフォルトのnamespaceが利用される。

またコマンドでどのnamespaceがデフォトで呼び出されるかわかる。

```
#設定されているnamespaceがわかる
$ kubectl config veiew | grep namespace

#現在存在するnamespaceが一覧できる
$ kubectl get ns
```

便利である一方、基本的に操作されるnamespaceが同じなのに毎回指定するのは面倒だしヒューマンエラーも起きる。

その場合はデフォルトnamespaceを登録してやる。

## やってみる

手動でファイル更新は悪手なので、コマンドで操作していく。
やることはシンプルで「どのcontextが」「どのnamespaceに紐づくか」を設定してやるだけ。

```
$ kubectl config set-context $(kubectl config current-context) --namespace=[ns名]
```

ちなみに上記はcurrent-contextをset-contextに渡している。
current-contextはこのコマンドで見れる。


```
$ kubectl config current-context
```

current-context以外を渡したい時は、$()を変えてやればいい。


以下のコマンドのような結果ならOK。

```
$ kubectl config view | grep namespace
    namespace [ns名]
```


## 小ネタ

`--namespace` で任意のnamespaceを指定できる、と言ったが以下の4パターンとも有効。同じ結果が返ってくる。

```
$ kubectl get pods --namespace=hoge
$ kubectl get pods -n=hoge
$ kubectl get pods --namespace hoge
$ kubectl get pods -n hoge
```
Laravelでモデルのファクトリーを作成

#はじめに
備忘録になります。
Laravel5.5系で実施。

#仕様
LaravelでUserモデルのファクトリーを作成したい
・name：ランダムな名前
・email：重複しないメールアドレス
・password：複数レコードを作成する際は同じパスワードを使用。
・remember_token：10桁のランダム値

#コマンド
`php artisan make factory UserFactory --model=User`
今回は、Seederでfactoryを呼び出すためSeederも追加。
`php artisan make:seeder UsersTableSeeder`

#factoryソースコード

```UserFactory.php
<?php

use Faker\Generator as Faker;

$factory->define(App\User::class, function (Faker $faker) {
    static $password;

    return [
        'name' => $faker->name,
        'email' => $faker->unique()->safeEmail,
        'password' => $password ?: $password = bcrypt('test1234'),
        'remember_token' => str_random(10),
    ];
});
```

fakerを作る際はこちらが参考になりました。
[[Laravel5.1]Fakerチートシート](https://qiita.com/tosite0345/items/1d47961947a6770053af)

#Seederソースコード

```UsersTableSeeder.php
<?php

use Illuminate\Database\Seeder;

class UsersTableSeeder extends Seeder
{
    /**
     * Run the database seeds.
     *
     * @return void
     */
    public function run()
    {
        factory(App\User::class, 50)->create();
    }
}

```
Linuxコマンドchmodでファイルのパーミッション（権限）を調整

# はじめに
## パーミッションの確認
`ls`コマンドでファイルのパーミッションを確認します。

```shell
$ ls -l
```

## パーミッションの意味
`drwxr-xr-x`みたいなやつが権限設定を表します。

| アルファベット | 意味 |
| --- | --- |
| d | ディレクトリ |
| r | 読み込み |
| w | 書み込み |
| x | 実行 |
| - | 不許可 |

先頭の`d`はディレクトリであることを表しています。
あとは、所有者と、グループユーザーと、その他のユーザーの3パターンの権限を表します。
`drwxr-xr-x`は以下の状態になります。

|  | 所有者（u） | グループユーザー（g） | その他のユーザー（o） |
| --- | --- | --- | --- |
| d | rwx | r-x | r-x |
| ディレクトリである | 読み出し、書き込み、実行の許可 | 読み出し、実行の許可、書き込みの不許可 | 読み出し、実行の許可、書き込みの不許可 |

## パーミッションの数字
`rwx`を8進数の数字で表す場合は以下のようになります。
0は権限なし、1は権限ありとなります。

| rwx | 8進数 |
| --- | --- |
| 000 | 0 |
| 001 | 1 |
| 010 | 2 |
| 011 | 3 |
| 100 | 4 |
| 101 | 5 |
| 110 | 6 |
| 111 | 7 |

所有者だけに操作を許可する場合は、
`rwx------`で`111000000`で`700`になります。

# 使い方
## プラスとマイナスで操作する
指定したファイルに所有者の書き込み権限を付ける

```shell
$ chmod u+w test.txt
```

指定したファイルの所有者の実行権限を外す

```shell
$ chmod u-x test.txt
```

## 数字でまとめて指定する
または8進数の数字でまとめて指定する

```shell
$ chmod 700 test.txt
```
覚えておきたいLinuxコマンド

覚えておきたいlinuxコマンドをまとめました。

# pwd
カレントディレクトリパスを確認する

```shell
$ pwd
```

# cat
指定したファイルの中身を表示する

```shell
$ cat test.txt
```

# less
指定したファイルの中身を表示する

```shell
$ less test.txt
```

| 操作 | キー |
| --- | --- |
| 次のページに進む | space |
| 前のページに戻る | b |
| 元のコマンド画面に戻る | q |

# grep
指定した条件に当てはまるファイルの文字列を検索する

```shell
$ grep "test" *.txt
```

# find
指定したディレクトリで、指定した条件に当てはまるファイル、ディレクトリを検索する

```shell
$ find . -name "*.js"
```

# ifconfig
現在のネットワークインタフェースの設定を表示する

```shell
$ ifconfig
```

# ping
指定アドレスとのネットワーク疎通確認をする

```shell
$ ping www.google.com
```

# nslookup
指定したアドレスのIPやドメインのネットワークデータを取得する

```shell
$ nslookup www.google.com
```

# netstat
現在の通信の接続状況を確認する

```shell
$ netstat
```

# ps
実行中のプロセスを表示する

```shell
$ ps aux
```

# kill
指定したプロセスIDのプロセスを強制終了する

```shell
$ kill -9 5859
```

# その他
コマンドの実行結果を別コマンドに渡して処理する

```shell
$ ls | less
```

コマンドの実行結果を別ファイルに出力する

```shell
$ ls > test.txt
```

カレントディレクトリ以下のファイルリストを出力する

```shell
$ ls -d $(find `pwd`)
```
Python csvの文字列の長さを変える

#import csv
極値テストの際にcsvの文字列の長さを変更する必要がありました。
EXCELでサクッとやればよかったんですが興味本位でPythonで文字列の長さを変更しました。以下、コード

#コード
```length.py
import csv
import random

# 出力用リスト
exp_list = []
max_len = 256
# csv読み込み
with open(r'sample.csv', 'r',encoding='utf-8') as f:
    reader = csv.reader(f)
    for r in reader:
        buff = ''
        r_len = len(r[0])
        while len(r) < max_len - r_len:
            ran = random.randrange(10)
            r += str(ran)
        for x in r:
            buff += x
        exp_list.append(buff)
# csv書き込み
with open(r'output.csv', 'w',encoding='utf-8') as f:
    writer = csv.writer(f, lineterminator='\n')
    writer.writerow(exp_list)

```

##実行結果

```実行コマンド.txt
python length.py
```

###入力
```sample.csv
data1
data2
data3
```

###出力
```sample.csv
data198745...
data265644...
data354351...
```
Amazon SQS ロングポーリングを理解する

# 概要
Amazon SQSのFAQを見れば理解出来ますが、ちょっと分かりづらいところもあるので、自分用にまとめ直します。

（参考）よくある質問 - Amazon SQS | AWS
https://aws.amazon.com/jp/sqs/faqs/

# 結論
ロングポーリングを使う（ショートポーリングは使わない）。ロングポーリングタイムアウトは20秒（最大値）を設定する。

# 個人的に思った疑問と回答
## ＊メッセージがキューに入った後、取り出せるのは最大20秒後になる？
No.
下記の通り、メッセージがキューに入った後すぐ取り出せる。（レイテンシはあるが）
> ロングポーリングリクエストを使用すると、メッセージがキューに達した時点ですぐに、キューの消費コンポーネントがそのメッセージを受信でき、また ReceiveMessageResponses インスタンスが空で返される回数が減ります。

複数メッセージが短時間にキューに入ったケースも検証しましたが、問題なくすぐ取り出せていました。

## ＊キューが空の場合のReceiveMessageの挙動は?
### ショートポーリングの場合
すぐに空のメッセージが返される
### ロングポーリングの場合
ロングポーリングタイムアウト秒（最大20秒）ウエイトした後、空のメッセージが返される

SQSはリクエスト課金なので、出来るだけリクエスト数を少なくした方が良い。つまり、ロングポーリングタイムアウト秒を最大に設定することで、リクエスト回数を減らし、コストを抑えることが出来る。

## ＊ショートポーリングの使いどころは？
> ほとんどのユースケースで、Amazon SQS ロングポーリングはパフォーマンスの向上とコスト削減につながります。ただし、アプリケーションが ReceiveMessage 呼び出しから直ちに応答を受け取る必要がある場合は、アプリケーションに多少の変更を加えないとロングポーリングのメリットを活用できない可能性があります。
> 
> たとえば、複数のキューを単一スレッドでポーリングするアプリケーションの場合は、ショートポーリングからロングポーリングへの切り替えが機能しない可能性があります。単一スレッドは、すべての空のキューでロングポーリングタイムアウトを待機し、メッセージが含まれる可能性のあるキューの処理が遅れるためです。
> 
> このようなアプリケーションで複数のキューを処理する場合は、単一スレッドを使用しないようにすることができます。これにより、そのアプリケーションで Amazon SQS ロングポーリングのメリットを活用できるようになります。

2つのキュー（キューAとキューB）からメッセージを順番に取り出してシングルスレッドで処理するようなアプリケーションを想定します。
t=0[sec]でキューAに対してロングポーリングした場合、キューAが空の場合に最大で20秒待つことになるので、その間にt=10[sec]でキューBにメッセージが入っていても処理できません（t=20[sec]でキューAから取り出されます）。このような遅れを防ぐため、ショートポーリングは使われるのではないかと思います。
ただ、そもそもアプリケーションの作りが悪いですよね。もし、2つのキューのメッセージがお互いに依存しないで処理できるなら、アプリケーションを２つのスレッド（またはプロセス）に分ければロングポーリングにすることが可能です。

# 参考（SQSにアクセスするLambda関数）
動かす場合は、SQSへアクセスするポリシーを付与するのを忘れずに。

## 送信側
```
import json
import boto3

def lambda_handler(event, context):
    # TODO implement
    sqs = boto3.client('sqs')
    queue_url = sqs.get_queue_url(QueueName='testqueue.fifo')
    response = sqs.send_message(QueueUrl=queue_url["QueueUrl"], MessageBody='world3', MessageGroupId='group')
    
    return {
        'statusCode': 200,
        'body': json.dumps('Hello from Lambda!'),
        'queue_url': queue_url["QueueUrl"],
        'response': response
    }
```

## 受信側
WaitTimeSecondsを0にするとショートポーリング、1以上20以下にするとロングポーリング。

```
import json
import boto3

def lambda_handler(event, context):
    # TODO implement
    sqs = boto3.client('sqs')
    queue_url = sqs.get_queue_url(QueueName='testqueue.fifo')
    message = sqs.receive_message(QueueUrl=queue_url["QueueUrl"], WaitTimeSeconds=20)
    isMessageExists = message.get("Messages")
    if isMessageExists:
        response = sqs.delete_message(QueueUrl=queue_url["QueueUrl"], ReceiptHandle=message["Messages"][0]["ReceiptHandle"])
    else:
        response = ""
        
    return {
        'statusCode': 200,
        'body': json.dumps('Hello from Lambda!'),
        'message': message,
        'response': response
    }
```

## 追記
receive_messageのパラメータとしてWaitTimeSecondsを設定する方法の他に、キュー属性のReceiveMessageWaitTimeSecondsを設定する方法もあります。
https://docs.aws.amazon.com/ja_jp/AWSSimpleQueueService/latest/SQSDeveloperGuide/sqs-short-and-long-polling.html
アイコンきれいにだすやーつ

```scss


Icon {
  position: relative;
  overflow: hidden;
  width: 28px;
  height: 28px;
  border-radius: 50%;
  margin-right: 12px;
  border: 1px solid #ced4da;
  img {
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    height: 100%;
    width: 100%;
    object-fit: cover;
  }
}

```
あたまのなかの整理メモ(Java - 配列編)


## My Java環境

* java11

## 配列

* 同じ型や互換性のある型しか扱えない
* 要素数はインスタンス生成時、あとから変更不可

## 配列の宣言

* 配列の要素数は`int`型であること。
* 1次元目の要素数は省略不可。
* 多次元配列の場合は大括弧`[]`をまとめて記述する必要はない。
* 多次元配列では2次元目以降の配列の要素数を合わせる必要はない。

### 宣言の例

```java

int arr[];
int[] arr1;
int[][] arr2;
int arr3[][];
int[] arr4[];
int[][] arr5[];

arr = new int[2];
arr1 = new int[2];
arr2 = new int[2][1];
arr3 = new int[1][2];
arr4 = new int[2][];
arr5 = new int[2][][];
```


### 配列インスタンスの生成

#### プリミティブ型の場合

```java

int arr[] = new int[2];
```

上記だと、`arr[0]`は`0`になる。
`int`の初期値は`0`であるため。

##### 要素数`0`の配列

```java
int array[] = new int[0];
```

* 要素数`0`でもコンパイルは通るが、`array[0]`は存在しない。アクセスしようとすると例外が発生する。
* `main`メソッドの引数なし実行した場合、要素数`0`の配列が`args`に設定されている。

##### 配列の初期化

配列インスタンスの生成と同時に初期化を行う場合は`{...}`を使用する。
`{...}`は変数宣言と同時にしか使えない。

```java

int arr[] = {1, 2, 3};
```

初期化している場合は、要素数の指定はNG。

```java

int arr[] = new int[]{1, 2}; // OK
int arr[] = new int[2]{1, 2}; // NG
```

多次元配列の場合は、変数の次元数と参照先の次元数が同じであること。

```java

int arr[][] = new int[][]{}; // OK
int arr[][] = new int[]{}; // NG
```

以下もOK。

```java

int arr1[][] = {};
```

#### 参照型の場合
```java

TestBean testArr[] = new TestBean[2];
```

上記だと、`testArr[0]`は`null`になる。
配列の宣言をしただけでは、配列インスタンスの生成をするだけで、配列の各要素を生成しているわけではない。
以下のように、初期化する必要がある。

```java

testArr[0] = new TestBean();
```
【CSS】上の要素に食い込ませたい、かぶせたい

#問題
 模写コーディングをしていると、要素が”その上の要素のmarginの下部”に食い込んで、重なっている箇所があったが具体的な方法がわからなかった。

#対策
　要素に、```margin-top： -50px;```と設定することで食い込ませることができた。そういったマイナス方向に設定するマージンのことを『ネガティブマージン』という。

# 参考文献

この記事は以下の情報を参考にして執筆しました。

- [[CSS]ネガティブマージンの理解を深め、活用するテクニック集](https://coliss.com/articles/build-websites/operation/css/css-using-negative-margins.html)
DVWAでjavaScript

## 前提
- kali linux環境がある
- DVWAのセットアップ済み（https://qiita.com/KPenguin/items/7e4f1c428c3dadf8591c ）

## 目標
- token制御のformを突破する（今回の場合はsuccessを入力してもsubmitを成功させる）

## 手順概要
- 挙動確認
- phraseを変更し、submitを成功させる

## 内容
### 前準備
- DVWAにログインする
    - 以下コードをkali上で実行しDVWAを立ち上げる。
    - http://localhost/DVWA-master/index.php
    - admin/passwordでログイン
- セキュリティレベルを下げる。
    - メニュー下にあるDVWA securityへアクセス
    - デフォルトがimpossibleなので、このままではハッキングできない。なのでlowに変更する

```shell:
# ファイルへのアクセス許可する
root@kali:~# service apache2 start
# DB_createできるようにする
root@kali:~# service mysql start 

```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/584889/bb95d520-1602-b7b8-afa3-85da3ffb651e.png)

- javaScriptにアクセスする（左メニューにある）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/584889/65c2db91-1380-c24e-a344-599c79bf86a2.png)

### javaScript

- 挙動を確認する
    - 何も変更せず、submitする。
        - phraseが違うらしい。
    - 指示通り「success」を入力しsubmitする。
        - invalid tokenらしい。 
    - htmlを確認１
        - tokenとphraseを送信している
    - htmlを確認２
        - tokenはここで生成しているっぽい
        
 ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/584889/09d82bf0-32fb-be6c-b870-cfcae660947c.png)

        
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/584889/9a3149fd-1ac0-95cc-9c39-885df3e1b863.png)

        
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/584889/e2625601-c46e-a323-1015-580c89338042.png)

```js:
function rot13(inp) {
		return inp.replace(/[a-zA-Z]/g,function(c){return String.fromCharCode((c<="Z"?90:122)>=(c=c.charCodeAt(0)+13)?c:c-26);});
	}

	function generate_token() {
		var phrase = document.getElementById("phrase").value;
		document.getElementById("token").value = md5(rot13(phrase));
	}

	generate_token();
```
- 挙動からの考察
    - phraseから生成したtokenとphraseが一致した場合、成功する
    - 初期設定ではchangeMeで成功するので、phraseを変更するとinvalid-tokenになっている可能性がある。
    - tokenはgenerate_token()で生成できる。
    - generete_token()はphraseにある値を読み取ってtokenを生成する。
- phrase:successで成功させる
    - phraseに「success」を入力
    - conosoleでgenerate_token()を実行する
    - submit!で成功

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/584889/4d47119e-2ca5-0dfe-2046-184f9479078e.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/584889/d9bbb071-6cdd-83a5-7fe9-ebea25484303.png)

- 最後に
    - これが簡易的なログイン画面だとすると、どれだけ高度な暗号化技術をつかったとしても、フィルターを突破できることになる。
おわり
Elastic Load Balancing (ELB)について　

#ELB（Elastic Load Balancing）
マネージド型のロードバランシングサービスで、EC2インスタンスの処理を分散する際に標準的に利用する
ELBで実現できるシステム

***特徴***
＊ インスタンス間の負荷を分散する
＊ 異常なインスタンスを認識して対応する(ヘルスチェック)
＊ パブリック／プライベートどちらでも使用可能
＊ ELB自体も負荷に応じてキャパシティを自動増減するスケーリグを実施
＊ 従量課金で利用可能
＊ マネージドサービスなので管理が不要
＊ Auto Scaling, Route 53, Cloud Formationなどと連携

##<font color="green">スケーラブル
<img width="1030" alt="スクリーンショット 2020-03-08 15.03.43.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/522222/aa7089bf-ac1a-91c7-c1f4-0c9501181351.png">
＊＊ポイント＊＊
 複数の**<font color="red">EC2インスタンス/ECSコンテナ..etc（ターゲット）**に負荷分散

##<font color="green">高い可用性 
<img width="1065" alt="スクリーンショット 2020-03-08 15.11.34.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/522222/4d808e4e-eb42-a7dc-6ef8-24252552691c.png">

複数の**<font color="red">アベイラビリティゾーンにある複数のターゲット**の中から正常なターゲットにのみ振り分け
**高可用性とは**
システムなどにおいて、サービス提供が出来なくなる事態の発生頻度が少ないことを指す

###クロスゾーン負荷分散
ロードバランサーのノードは、クライアントからのリクエストを登録済みターゲットに分散させます。クロスゾーン負荷分散が有効な場合、各ロードバランサーノードは、有効なすべてのアベイラビリティーゾーンの登録済みターゲットにトラフィックを分散します
<img width="460" alt="スクリーンショット 2020-03-08 15.16.22.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/522222/946a796f-0a91-0a9f-761d-c41edaad57b2.png">


#ELBの種類
<img width="908" alt="スクリーンショット 2020-03-08 15.38.57.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/522222/044ffe68-e86e-b033-7f48-8f6073ceecfa.png">

<img width="1061" alt="スクリーンショット 2020-03-08 15.04.37.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/522222/908d184c-b27f-f6fe-5843-48fd062f61e4.png">

##CLB（Classic Load Balancer ）
初期に提供されたELBであり、標準的なL4／L７におけるロー
ドバランシングが可能だが複雑な設定はできない

##ALB（Application Load Balancer ）
レイヤー7の対応が強化された単一ロードバランサーで、異な
るアプリケーションへリクエストをルーティングが可能

###CLBとの違い
ALBは**<font color="red">パスルーティング**によりCLBより容易にバランシング構成が可能!!
<img width="1005" alt="スクリーンショット 2020-03-08 15.25.16.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/522222/1dc59288-98b6-df6b-a74f-2a6acbe0882f.png">

##NLB（Network Load Balancer）
NLBは超低遅延で高スループットを維持しながら秒間何百万リクエストを捌く様に設計された新しいロードバランサ―
**ポイント**
1. 高可用性、高スループット、低レイテンシ
2. Source IP/Portがターゲットまで保持される
3. 固定IP

##最後に
参考
AWS　Elastic Load Balancing (ELB)
https://aws.amazon.com/jp/aws-jp-introduction/aws-jp-webinar-service-cut/
66円のドアセンサを試してみる

## 最初に
66円のドアセンサを入手したのでArduinoで動かしてみました。

## 用意するもの
**Arduino UNO互換機**
<img width="300" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/89227/3692b5e4-3800-7380-bcfe-8c5b2e530b58.png">
https://www.amazon.co.jp/gp/product/B013QV28CW/ref=ppx_yo_dt_b_asin_title_o08_s00?ie=UTF8&psc=1

**ドアセンサ**
`66円`のドアセンサです。
<img width="300" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/89227/3b612e30-cf3e-3a05-9fa8-71d414f6455b.png">

AliExpress
https://ja.aliexpress.com/item/4000138461602.html?spm=a2g0s.9042311.0.0.27424c4daU7DDx


**配線**
<img width="300" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/89227/44065abb-1124-eade-f09e-4e47e6a13bd7.png">
https://www.amazon.co.jp/gp/product/B00P9BVKOK/ref=ppx_yo_dt_b_asin_title_o02_s00?ie=UTF8&psc=1

**ブレッドボード**
<img width="300" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/89227/b5dd96d1-94e3-adf5-c66e-1f1851d67dd2.png">

https://www.amazon.co.jp/gp/product/B010SHL6RK/ref=ppx_yo_dt_b_search_asin_title?ie=UTF8&psc=1

**抵抗**
10kオームです
<img width="300" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/89227/654c288b-be0c-941e-1c57-0bc16427ef81.png">


# 手順
## 1.動作確認
基本的に片方に磁気センサが入っており、時期が近づくとONになる機構です。
ですので、一度テスタなどで確認するとわかりやすいと思います。
<img width="300" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/89227/8f8f8fae-2d14-30ec-c86c-7e2abea7e5d9.png">


## 2.スケッチ例を選択
スケッチは、単純なデジタル読み込みのスケッチですので標準で入っています。
「ファイル」＞「スケッチ例」＞「01.BASIC」＞「DigitalReadSerial」を選択します
<img width="300" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/89227/b127ecbe-2608-fa5d-0102-282adb80be70.png">
この中で、利用するIOポートとシリアル通信の通信速度が規定されています。
今回は初期値で実施するのでIOは`2番`でシリアル通信の通信速度は`9600bps`になります。
<img width="300" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/89227/b441894d-4460-3f8d-5946-f84f4500fc38.png">

## 3.配線図確認
配線はこんな感じです。
<img width="300" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/89227/c695f4e1-2abf-ac80-13c8-1eaa0ae1dfef.png">

ソースコード上でIO2番になっているので、入力は2番です。
ドアセンサーは極性がないため、どちらに挿しても動きます。

## 4.書き込み And 動作確認
この状態で書き込めば、シリアルコンソールで動きを確認する事ができます。
![download.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/89227/2c657ee3-a314-fb7c-088e-cd4a2e66506d.gif)


# 備考
今回の記事も動画にしてあります。
もし、ご興味がある方はご確認を。

[![IMAGE ALT TEXT HERE](http://img.youtube.com/vi/Ha8N8pNTEsc/0.jpg)](http://www.youtube.com/watch?v=Ha8N8pNTEsc)
bashで行列データベースの特定行を読み出し一度に複数の変数を定義する方法

# 1. 目的
n行m列のテキストデータベースがあったとします。それから指定の行の要素を読み出して、複数の変数に格納します。面倒なので配列は使いたくありません。

# 2. 環境
1. CentOS 7.
2. bash 4.2

# 3. 考え方
指定行を`sed`で読み出してそれを`read`渡して変数に設定する。

# 4. テスト用のデータベース
- 第1列は重なりのない1刻みの数字だとします。データの列の並びは`NUM MAKER MODEL TYPE`とします。例えば、

```{bash}
$ cat data.txt
1 apple iPhone AAA
2 google Android BBB
3 sony Walkman CCC
```

# 5. コード
```{bash}
$ cat test.bash
#!/usr/bin/bash 
read NUM MAKER MODEL TYPE <<< $(sed -n "${1}p"  $2)
echo "$MAKER" "$TYPE" "$NUM" "$MODEL"
```
- 説明：
    - `read`は変数を複数設定できます。その`read`に文字列を渡します。
    - 実行したコマンド結果を`<<< $()`で文字列として取り出します
    - `sed`は`-n`で非表示にして、`数字p`で指定行だけ表示します。
    - `sed`に表示行数とファイルを`$1`と`$2`で渡します。
    - 最後の`echo`で変数がグローバル変数であることを確認しています。順番も変えて確かめています。 

# 6.結果
```bash
$ ./test.bash 1 data.txt
apple AAA 1 iPhone
$ ./test.bash 2 data.txt
google BBB 2 Android
$ ./test.bash 3 data.txt
sony CCC 3 Walkman
$ 
```

- 大丈夫なようです。普通に考えると
    - `MAKER=$(awk '$1 == 1{print $2}' data.txt)`
みたいなコード書きがちですが、変数が多いと長くなりがちです。
- データベースとして情報を行列にして、レコードをユニークなシリアル数字で管理するという基本形を採用すると`bash`でもシンプルにコードが書けます。アルゴリズムよりデータ構造が大切ですね。データベースの登録時に重なりがないことのチェックとか、情報の削除はレコードは残しフィールドだけ`void`にするとか、それなりに気を使う必要がありますが、読み出すのは楽です。
- こんな短いコードでデータベースを扱えるので`bash`好きです。ちょっとしたアイディアですが、どなたかのお役に立てると嬉しいです。
django-admin startprojectで「コマンドが見つかりません」の対処法

#初めに
Django-admin startprojectで表題のエラーで苦戦したため、その備忘録を残しておきます。経験はまだまだ浅いため、間違っていたらごめんなさい。

#環境
- MacOS 10.15
- python3.7
- Django3.0

#対処法
```
$ python3 -m Django-admin startproject mysite
```
パスを通してないとできないかもです。
「python3」、自分の環境に合わせて「python」とかに変えてください。
特に何もしてないと、python→Python2系、python3→Python3系だと思います。
たぶん公式のコマンドのままだとPython2系を使ってるのかな？
以下に問題解決の時に参考にしたページを載せています。

Django公式トラブルシューティング：
[https://docs.djangoproject.com/ja/3.0/faq/troubleshooting/](https://docs.djangoproject.com/ja/3.0/faq/troubleshooting/)

Macを最近使い始めたので、個人的にはPython3のインストールディレクトリを探していろいろするのが辛かったです。
皆さんも頑張ってください！
CakePHP環境で「certbot renew」実行時のエラーが出たときの対処法

## 環境について

- Linux CentOS7
- apache
- PHP(CakePHP2)
- Let's Encrypt
 

# SSL証明書の更新でエラー
某WebサイトでLet's Encryptを使っています。
Let's Encryptは3か月ごとに更新をしなければならなく、証明書の期限が1か月前から更新することができます。

それを毎回手動でやるのは結構面倒なので、cronでバッチ処理をして自動でSSLの更新をかけていることにして、実行した場合はその結果をメールで返す仕組みにしています。


## 更新失敗のメールが届く

ある時メールに更新失敗の件名が…

**Faild renew letsencript SSL cert**

現状Webサイトは問題なかったのですが、これが更新期間を過ぎると、

**信頼されていないサイトです**

的な表示が出てしまうのですぐに対処します。


## CentOSの中へ


とりあえず手動で実行してみます。

```sh
certbot renew --dry-run
```

以下の結果が…

```
Cahllenge failed for domain *****.jp
Challenge failed for domain www.*****.jp
```

```
Attempting to renew cert (www.*****.jp) from /etc/letsencrypt/renewal/www.*****.jp produced an unexpected error: Some challenges have failed.. Skipping.
All renewal attempts failed. The following certs could not be renewed:
```
※一部伏字

こんな感じでとにかく、失敗したよ的なことがずらずらと書かれているわけです。

注目すべきはさらにその下。

```
Domain: ******.jp
Type:   unauthorized
Detail: Invalid response from
https://******.jp/.well-known/acme-challenge/xZtOg19utX8Mch7n3hgYJNeNk4GM2PBw6LVqFgzs9pI
[153.***.***.***]: "<!DOCTYPE html>\n<html lang=\"ja\"
ng-app=\"NetCommonsApp\">\n<head>\n\t<meta
charset=\"utf-8\">\n\t<meta http-equiv=\"X-UA-Compatible\" conte"
```


**ここにアクセスしたらうまくいかなかったよ～**みたいなことが書かれています。

```
https://******.jp/.well-known/acme-challenge/xZtOg19utX8Mch7n3hgYJNeNk4GM2PBw6LVqFgzs9pI
```

↑自分のドメイン＋「.well-known/acme-challenge」みたいなURLです。

どうやらここにSSL証明書が配置されているみたいですが、アクセスできないから失敗したとのことです。


## 正しくそのURLの先を導いてあげる

今回はapache＋CakePHP2でWebサイトを構築しています。
ルートディレクトリは以下の感じです。
apache側も以下のパスを参照するように設定されています。

```
/var/www/html/cakephp
```

いったんルートディレクトリへ

```
cd /var/www/html/cakephp
```

ルートディレクトリなので、ここにアクセスするのが普通なのですが、
CakePHPではさらにここからリダイレクトしているわけですね。

それをやっているファイルが

**.htaccess**

になります。

中身はこんな感じです。

```apache
<IfModule mod_rewrite.c>
   RewriteEngine on
   RewriteRule    ^$ app/webroot/    [L]
   RewriteRule    (.*) app/webroot/$1 [L]
</IfModule>
```

CakePHPの中の**app/webroot**にさらにリダイレクトしてあげています。

ただ、webrootの中にwell-knownというディレクトリは存在しないので、
「https://*****.jp/well-known」というURLにアクセスがあった場合は、リダイレクトさせないようにします。

以下の文を追加

```apache
RewriteRule ^\.well-known(.*)$ .well-known$1 [L]
```

↓

```apache
<IfModule mod_rewrite.c>
   RewriteEngine on
   RewriteRule ^\.well-known(.*)$ .well-known$1 [L]
   RewriteRule    ^$ app/webroot/    [L]
   RewriteRule    (.*) app/webroot/$1 [L]
</IfModule>
```

これでwell-knownにアクセスした場合はリダイレクトされなくなります！

## 再度実行！


以下のコマンドを実行

```sh
certbot renew --dry-run
```

成功時のログを取っておくのを忘れてしまいました。。


**failed**という文字が出ていないこと、
**succeed**という文字が出ていること、

を確認できたら大丈夫だと思います。


成功したら「--dry-run」を外して再実行。

```sh
certbot renew 
```

無事、証明書が更新されました。

終わり。
GitHub ActionsでAnsible PlaybookのCIを実行する

この記事ではGitHub ActionsでAnsible PlaybookのCIを実行するサンプルを紹介します。

GitHub Actionsで提供されているVM（Ubuntu)上にDockerコンテナを起動しconnection pluginにDockerを利用します。

説明を簡単にするために必要最低限の実装になっています。必要に応じてlint処理、playbook実行後の設定の確認処理等を追加してください。


## ディレクトリ構成

```
├── .github/workflows/playbook.yml
├── install.yml
└── roles
    ├── centos7
    │   └── tasks
    │       └── main.yml
    └── requirements.yml
```

## それぞれのファイルの中身

```YAML:.github/workflows/playbook.yml
name: Ansible Playbook
on: push

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
        uses: actions/checkout@v2

      - name: Docker run Centos7
        env:
          DOCKER_REGISTRY_URL: https://hub.docker.com/
        run: sudo docker run -d -t --name=mycontainer centos:7

      - name: Install Ansible galaxy roles 
        run: ansible-galaxy install -r roles/requirements.yml

      - name: ansible
        run: ansible-playbook -i 'mycontainer,' -c docker -u root install.yml
```

```YAML:install.yml
- hosts: all
  roles:
    - role: geerlingguy.repo-epel

  tasks:
    - name: Install cowsay with yum
      include_role:
        name: centos7
      when: ansible_distribution == "CentOS"
```

```YAML:roles/centos7/tasks/main.yml
- name: Install cowsay with yum
  yum:
    name: cowsay
    state: present
```

```YAML:roles/requirements.yml
---
- geerlingguy.repo-epel
```

## 解説

「.github/workflows/playbook.yml」がGitHub Actionsの設定ファイルになります。

このファイルの設定だとリポジトリにpushがあるとActionが実行されます。

Ansible Playbookは起動したコンテナに対して実行されます。

Dockerコンテナを起動する時は環境変数からDocker HubのURLを指定します。他のコンテナレジストリサービスを利用する場合はDOCKER_PASSWORD、DOCKER_REGISTRY_URL、DOCKER_USERNAMEをそれぞれ指定します。

## その他注意点

AnsibleはGitHub Actionsが提供するVMに既にインストールさています。ただしインストールされている **Ansibleのバージョンがリリースとともに上がっていく** ため、Ansibleのバージョンを指定して利用したい場合は工夫が必要になります。

またAnsible PlaybookをUbuntuへ実行する場合、Docker Hub上のUbuntuのイメージにはPythonがインストールされていないため事前にPythonをインストールしたUbuntuのイメージを用意する必要があります。

イメージはAction内でdocker buildコマンド等でビルドすることも可能です。

## 参考サイト

* [ansible-joke-programs/asciiquarium | GitHub](https://github.com/ansible-joke-programs/asciiquarium)
* [ansible-joke-programs/cowsay | GitHub](https://github.com/ansible-joke-programs/cowsay)
tmuxのコピーモードをviで操作

tmuxのコピーモードに惹かれて使ってみたのですが、すごく便利。
vimキーバインドでのコピーモードの使い方をまとめておこうと思います。

.tmux.confの設定についてはこちらの記事を参考にさせてもらいました。

[tmuxを必要最低限で入門して使う
](https://qiita.com/nl0_blu/items/9d207a70ccc8467f7bab)

```.tmux.conf
# prefixキーをC-qに変更
set -g prefix C-q

# C-bのキーバインドを解除
unbind C-b

# vimのキーバインドでペインを移動する
bind h select-pane -L
bind j select-pane -D
bind k select-pane -U
bind l select-pane -R

# コピーモードを設定する
# コピーモードでvimキーバインドを使う
setw -g mode-keys vi

# 'v' で選択を始める
bind -T copy-mode-vi v send -X begin-selection

# | でペインを縦分割する
bind | split-window -h

# - でペインを縦分割する
bind - split-window -v
```

`prefix`は`Ctrl + q`で設定しているので、それに準じて記述します。

### コピーモード

コピーモードの開始コマンドの`prefix + [`, `prefix + ]`の役割が相対している訳ではないので、
理解するのに少し時間がかかりました。

|  コマンド | 説明 |
|:---:|:---|
| prefix + [ | コピーモード開始 |
| prefix + ] | コピーされた内容を貼り付ける(コピーモードを終了後) |

#### コピーモード中の操作

| 操作 | 説明 |
|:---:|:---|
| space | コピー位置開始 |
| Enter | ハイライトされた部分をコピーし、コピーモードを終了 |
| q | コピーモードを終了 |
| ESC または ctrl + { | ハイライトをキャンセル |
| Ctrl + u | 上方に移動 |
| Ctrl + d | 下方に移動 |

＊ 先に`.tmux.conf`に書いたものは説明を省いています

その他、コピーモード中に使えるvi操作

```
e, b, w, 0, gg, G, $, ^, /, ?
```
などなど

検索はターミナルに出力された全範囲が行われるので`?`の方が便利でした。
`y`をヤンクに設定して使ってみましたが、`Enter`のままで使う方が入力キーを減らせて良さそう。
マリオカートツアーを毎日自動的に起動してログインボーナスをもらう

#用意するもの
1. Android実機(エミュレータでもいいが動かないかも)
2. adbがインストールされた端末

#準備
1. Android実機にマリオカートツアーをインストールして起動→初期設定まで済ませる
2. Android実機を開発者モードにする
3. adbコマンドで実機に接続しておく(初回に接続を許可するか聞かれるため)

#起動～終了
```shell
adb connect 192.168.0.xx
adb shell am start -n com.nintendo.zaka/com.nintendo.android.PermissionActivity
sleep 300
adb shell am force-stop com.nintendo.zaka
```

#懸念事項
1. 起動途中に最新データのダウンロードが入った場合はどうすべきか検討中(Appium使えばいけるか？)
Accessでリンクテーブルの接続先を一括変更するには

Microsoft Access のお問い合わせで圧倒的に多いのは、**PCやファイルサーバをリプレースしたら動かなくなった！**というもの。
PCなら4年、サーバなら5年。これが税制上定められている減価償却期間（法定耐用年数）なので、この周期で必ずやってくるのだ。

そして今回は、『**パス 'フルパス文字列' は正しくありません。パス名に間違いがないことと、ファイルが置かれたサーバーに接続していることを確認してください。**』というエラーメッセージで停止している。
Windowsのコンピュータ名（ホスト名）が変更されたことに因る影響だ。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/236222/a23d9b80-847a-2f23-4d62-1ba15aa44aad.png)
VBAに明るいユーザーならここでVBEを起動し、エラーの原因となったフルパス文字列の全検索を試みるのだが、それでも見つからないので、一体どこで定義しているの！？と途方に暮れることになる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/236222/04539f33-e6bd-7068-cdca-e8231aa8186a.png)
このエラーメッセージで先ず疑うのはリンクテーブルの接続先。
次の操作で、データソースが古いパス名を指していないかチェックしてみよう。

---
1. [外部データ] :arrow_forward: [リンクテーブルマネージャー] の順にクリック。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/236222/d4229314-c060-48ac-f262-86642349a87a.png)

2. リンクテーブルマネージャーで、該当するデータソースを選択し、[編集] をクリック。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/236222/b02919bc-e7ad-79b5-dc8d-3d37ced34e2a.png)

3. データソースのパスを書き替えて [保存] をクリック。すべて修正したら最後に [更新] を実行。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/236222/ce890fa3-49dd-1ec9-d61f-7ff810cac071.png)

---
リンクテーブルを多用している場合、いちいち手で直してられないので、マクロで一括変換してしまおう。

```vb
Sub データソースパス一括変更()
    Dim td As DAO.TableDef
    Dim sBefore As String, sAfter As String
    Dim sFrom As String, sTo As String
    
    sFrom = "uksrv01w"  '検索する文字列
    sTo = "uksrv02w"    '置換する文字列
    
    For Each td In CurrentDb.TableDefs   'すべてのテーブルで
        If td.Attributes And dbAttachedTable Then   'リンクテーブルなら
            sBefore = td.Connect   '接続文字列を取得
            sAfter = Replace(sBefore, sFrom, sTo)
            If sBefore <> sAfter Then   '置換されていたら
                td.Connect = sAfter
                td.RefreshLink   'リンクを更新
                Debug.Print sBefore & " ==> " & sAfter
            End If
        End If
    Next
End Sub
```

言うまでもないが、実行前に必ずバックアップを取っておくこと。
複雑な置換には正規表現で対処しても良いだろう。