OmniAICreator/Qiita-1.07M huggingface dataset:
MATLAB の Live Editor でインタラクティブな処理してみた。

# はじめに
そういえば、MATLAB の [Live Editor](https://jp.mathworks.com/help/matlab/matlab_prog/create-live-scripts.html) って使っていますか？コードの記述やグラフ表示なんかを一つの環境でできちゃうってアレですよね。[Jupyter Notebook](https://jupyter.org/) みたいな。よくよく見てみると、対話型のコントロールもついてるみたい。インタラクティブな処理ってできるのかなと試してみました。あまり使用方法の詳細が載っていない、**ボタン** や **チェックボックス** に焦点をあててみました。
# 実行環境
MATLAB (R2019a) のみ！
# 結論から
先にポイントとなるところだけ書いておきますね。1点だけですが。

- **コードは非表示で**

# コントロールの外観
Live Editor を開いたら、**[挿入] → [コントロール]** でコントロールを選びます。
![control.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/482843/28b08ac9-6cf0-2f4a-8c6c-427b19a47d0c.jpeg)

こんな感じで。**ボタン** はこのセクションを実行するだけの機能です。
![edit.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/482843/99ee6b9e-5843-fb67-b0bf-09a1423468f9.jpeg)

それぞれの設定はこんな感じ。
![properties.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/482843/9e266292-2ba7-dc4d-6c1f-1c123e63673b.jpeg)

# コントロール以外のコード
コントロール以外のコードは以下のようにしました。
変数 **TF** はライトを照らすかどうか、**h** はライトをどちら側から照らすかになります。

```MATLAB:testLight.mlx
close all
% 数式の描画
r = @(u,v) 2 + sin(7.*u + 5.*v);
funx = @(u,v) r(u,v).*cos(u).*sin(v);
funy = @(u,v) r(u,v).*sin(u).*sin(v);
funz = @(u,v) r(u,v).*cos(v);
fsurf(funx,funy,funz,[0 2*pi 0 pi]) 

% LightのON/OFF
if(TF)
    camlight(h)
end
```
# さあ実行してみよう
ポイントは、**[表示] → [コードを非表示]** でコードを非表示にしておくことですかね。
![aaa.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/482843/0ebb6e7f-c6b8-f780-3bbb-9757139f6eee.gif)
#結果
こんな感じになりました:blush:
![2019-08-23_10-25-25.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/482843/8a6868a5-03ee-8bbf-e9e1-00cf59067aec.gif)
Gitlab on Dockerのバージョンアップ

### やりたいこと
・Gitlab のバージョンが古いのでなんとかしたい
・運用しているGitlab をバージョンアップする前に検証用GitLabを作成する
・検証機で動作確認が取れたら運用しているコンテナ上のGitLabをバージョンアップする
・この記事では検証機を作ってバージョンアップを実施する過程を記しています

### 前提
OS Linux Ubuntu　インストール済
Docker 19.03.1　インストール済
Gitlab （前）11.11.2　（後）当時の最新

### Dockerを使ってGitLabを導入する
1.バージョンを指定してGitLabをDockerコンテナで立ち上げる（今回は11.11.2を導入）

```
sudo docker run --detach \
  --hostname gitlab_host \
  --publish 443:443 --publish 80:80 --publish 22:22 \
  --name gitlab \
  --restart always \
  --volume /opt/docker/gitlab/etc:/etc/gitlab \
  --volume /opt/docker/gitlab/var/log:/var/log/gitlab\
  --volume /opt/docker/gitlab/var/opt:/var/opt/gitlab gitlab/gitlab-ce:11.11.2-ce.0
```

2.サーバーのIPにアクセスして検証用GitLabが立ち上がったことを確認する

### バックアップファイルを配置する

運用しているGitLabからバックアップファイル「～_gitlab_backup.tar」を取得し、
検証用GitLabのVolumeに指定したディレクトリ内であればどこでもよいので配置する
（/opt/docker/gitlab/varとか）

以下のコマンドでコンテナ内に入り、バックアップファイルを移動する

   ```
   #コンテナの中に入る（すでに入っている場合は省略）
   docker exec -it gitlab /bin/bash
   mv [バックアップファイル] /var/opt/gitlab/backups
   ```

### リストアを実施する
**

```
#コンテナの中に入る（すでに入っている場合は省略）
docker exec -it gitlab /bin/bash

#「/var/opt/gitlab/backups」配下に「_gitlab_backup.tar」を移動する

# 一部停止
gitlab-ctl restart
gitlab-ctl stop unicorn
gitlab-ctl stop sidekiq

# 停止を確認
gitlab-ctl status |grep down

# リストアを実行
# バックアップファイルが複数ある場合は「BACKUP=」でバージョンを指定すること
gitlab-rake gitlab:backup:restore 

# リストアを確認
gitlab-ctl restart
gitlab-rake gitlab:check SANITIZE=true
```


検証用GitLabにアクセスし、データのリストアを確認する


### バージョンをアップする

上記で作成したDockerコンテナのプロセス、イメージを削除する
アップしたいバージョンを指定して、sudo docker run ～を実行する

※注意
メジャーバージョンを上げるときは、マイナーバージョンの最新に上げてからが推奨されている
HTML: URL表示が改行してくれない

#HTML: URL表示が改行してくれない

レシポンジブ対応させるためにスマフォ画面では長いURLは自動改行してほしいものだが、あるCSS表記をしないと長いURLがそのまま1行になって表示されてしまう :point_right: スマフォ画面幅をはみ出してしまう。


###解決方法
以下の通り

```html
<!--例-->

<span style="word-break: break-all;">http://www.riversongplasticsurgery.com/pdfs/nerve_injury_nerve_reconstruction_recovery.pdf</span>
```

設定するHTMLタグはspanだけでなくpでもdivでもなんでも。
<br>

参照：[URLが自動改行してくれない問題](https://qiita.com/gonshi_com/items/b38780d1f3e31d1c0a84)
Googleフォームの投稿内容をHangouts Chatへ送信したい

Googleフォームにはフォーム投稿内容を自動でスプレッドシートへ出力する機能があるのですが、毎回スプレッドシートを確認するのも手間ですので、Google Apps Script(GAS)を使って投稿内容をHangouts Chatへ送信する仕組みを作ってみました。

## 実現したいこととやること
### 実現したいこと
- Googleフォームの投稿内容をHangouts Chatへ自動送信したい

### やること
- Googleフォームの作成
- Hangouts Chatでbot作成とWebhook URLの取得
- GASソース準備
- トリガーの設定

#### Googleフォームの作成
Googleフォームの書式自体は特に指定はありません。
好きな形式で作成すればよいかと思われます。

#### Hangouts Chatでbot作成とWebhook URLの取得
ここで解説するよりも、以下のリンク先を読んだほうがわかりやすいです。
[GASからhangout chatにPostする - Qiita](https://qiita.com/mistolteen/items/a67b131b31d5c5246a6c)

#### GASソースの準備(サンプルソース)
作成したGoogleフォームの編集画面からスクリプトエディタを開き、以下サンプルを入力します。今回はソース内でフォームIDとスクリプトを紐づけていないため、フォーム編集画面から直接スクリプトエディタを起動する必要があります。

```js
function SubmitForm(e){
  //Googleフォームの投稿内容をitemResponsesへ入れる
  var itemResponses = e.response.getItemResponses();

  //Googleフォームの質問項目名と回答を順番に変数textへ入れる
  var text = "Googleフォームの投稿内容です";
  for(var i=0; i<itemResponses.length; i++){
    var itemResponse = itemResponses[i];
    var question = itemResponse.getItem().getTitle();
    var answer = itemResponse.getResponse();
    text += "\n" + question + "\n" + answer;
  }

  //Hangouts ChatのチャットルームWebhook URL。前項で取得したURLをコピペすればOKです
  var post_url = "https://chat.googleapis.com/v1/spaces/xxxxxxxxxxxxxxxxxxxx";

  //チャットルームに投稿する本文(JSON形式) → 変数textの中身を入れているだけ
  var payload = {
    "text": text
  }

  //投稿する際のおまじない(JSON形式)
  var options = {
    "method":"POST",
    "headers":{"Content-Type":"application/json; charset=UTF-8"},
    "payload": JSON.stringify(payload),
    "muteHttpExceptions":true
  }

  //指定したチャットルームのURLへ投稿する
  var result = UrlFetchApp.fetch(post_url, options);
}
```
#### トリガーの設定
トリガー設定画面から、以下の条件でトリガーを追加します。

- 実行する関数を選択 - SubmitForm
- イベントのソースを選択 - フォームから
- イベントの種類を選択 - フォーム送信時

これにより、Googleフォームを送信したタイミングでSubmitFormが起動し、投稿内容が指定のHangouts Chatのチャットルームへ投稿されます。

## 何がおいしいの？
Googleフォームは外出先からスマートフォンでちょっとした報告をするのにとても便利・有用なツールです。今回はその投稿内容をHangouts Chatへ送信しましたが、ほとんど同じ仕組みでスプレッドシート(簡易DB)やスライド(報告書)の作成・更新、その他APIを叩くようなサービス(Slackなど)も利用できるので、積極的に使っていきたいですね。

## 参考にしたもの
[[超簡単]Hangouts Chat の incoming webhooks を使ってAPIから簡単にメッセージを投稿する](https://qiita.com/iitenkida7/items/3c8f9f8f6ee1e809558d)
[GASからhangout chatにPostする](https://qiita.com/mistolteen/items/a67b131b31d5c5246a6c)
Minitestのassert_differenceメソッドについて

## Minitestのassert_differenceメソッド
まずassert_differenceメソッドはMinitestそのもののメソッドではなく、Railsがminitestフレームワークを拡張するという形で独自のカスタムアサーションを追加しています。他にはassert_changesやassert_response、assert_redirected_toといったメソッドもRailsが提供するカスタムアサーションになります。assert_differenceの具体的な使用例としては以下のようになります。

```ruby
assert_difference 'User.count', -1 do
  delete user_path(@non_admin)
end
```
assert_differenceメソッドの第1引数に渡したメソッドの値が、ブロック内で変更されることを検証します。第2引数に変更される期待値を渡します。省略した場合は"+1"が期待値になります。つまりassert_differenceとはブロック内の処理をして指定した数字の分だけ変化したことを確認するメソッドになります。テストの用途としてはユーザーなどの数をテストしたり、画面遷移をした後のリンクの数を確認したり出来ます。


## assert_no_differenceについて
ちなみにassert_differenceに似たメソッドとしてassert_no_differenceというメソッドも存在します。式を評価した結果の数値は、ブロックで渡されたものを呼び出す前と呼び出した後で違いがないと主張する。使い方もassert_differenceと同じで以下のようになります。

```ruby
assert_no_difference 'User.count' do
  delete user_path(@user)
end
```
apt-getを使うためにfinkをインストールする（多分）最も簡単な方法（mac）

#finkをインストールしたい、がめんどくさい。
[http://www.finkproject.org/doc/users-guide/install.php?phpLang=ja](http://www.finkproject.org/doc/users-guide/install.php?phpLang=ja)
ここにインストールの方法が書いてある。
```./bootstrap```
を使う方法も載っているが、正直めんどくさい。

##そこで、
[http://www.finkproject.org/download/srcdist.php?phpLang=ja](http://www.finkproject.org/download/srcdist.php?phpLang=ja)
ここからヘルパースクリプトをインストールする

そうするとgithubに飛ばされる。
githubの画面から
**InstallFink.tgz**
をダウンロードする。

ダウンロードできたら、解凍してダブルクリックで起動。
finkを自動でインストールしてくれる。

途中でjavaやX11をインストールする必要が出てくるが、
Javaはbrewで
```brew cask install java```
インストール。

X11はヘルパーにしたがってインストールすれば良い。

ちなみにインストールするのに1時間ぐらいかかった。
長すぎる。
Gitチートシート（覚書）

※Gitのよく使うコマンドや便利コマンド，有用だと思ったコマンドを書き留める
※時たま更新する予定

# 基本

## そもそもGitとは

- Gitは分散型プロジェクト管理ツール．ソースコードなどの変更履歴を記録，追跡出来る．
- GitサービスとしてはGitHubやBitbucketなどがある（自分が知っている範囲での代表格）．
- 仕組みも含め，もっと詳しい説明を近々書いてみる予定．

## 基本コマンド

- git config user.name [name]
    - このコマンドでcommitに記録されるユーザ名を指定．

- git config user.email [email]
    - このコマンドでcommitに記録されるメールアドレスを指定．

- git config --list
    - 現在のconfig設定一覧を確認可能．

- git clone [repository url] [name(option)]
    - リポジトリをCloneする．nameを指定すると，その名前でローカルにディレクトリが作成される．

- git init
    - カレントディレクトリ以下のディレクトリをGit管理する．

- git remote add [repository name] [repository url]
    - リモートリポジトリの設定を行う．
    - [repository url]を[repository name]という名前で登録する．
    - [repository name]を省略すると，デフォルトのoriginになる．

- git remote set-url [repository name] [repository url]
    - 設定済みのリモートリポジトリを変更したい場合に利用する．

- git remote rename [old repository name] [new repository name]
    - 設定済みのリモートリポジトリの名前を変更する．

- git remote rm [reposotry name]
    - 設定済みのリモートリポジトリを削除する．

- git add [file/directory]
    - commitするファイルを指定する．ディレクトリを指定することで，そのディレクトリ以下のファイルをすべて指定．

- git commit
    - addしたファイルをcommitする．オプション無しの場合はコミットメッセージを記載するための表示になる．-mオプションでコミットメッセージをコマンドに付与できる．

~~~~
git commit -m "commit message"
~~~

- git push [repository name] [local branch]:[remote branch]
    - [repository name]で設定したリモートリポジトリの[remote branch]に対して[local branch]をpushする．
    - -f のオプションを付けると，強制pushになる．
    - リモートブランチが存在しない場合は作成される．
    - [local branch]を空文字にした場合，空のものをリモートブランチにpushすることになり，リモートブランチを削除出来る．

- git push [repository name] [branch]
    - 上記コマンドの[local branch]と[remote branch]が一致する場合は1つにまとめられる．

- git push
    - リポジトリの指定とブランチの指定を省略した形．
    - 意味合いは上記の[local branch]と[remote branch]を一致させた場合と同じで，リポジトリはoriginが自動的に指定され，ブランチはHEADになっているものが指定される．

- git branch
    - 現在のローカルブランチ一覧を表示．
    - -a オプションを指定すると，リモートブランチも表示される．

- git branch [branch]
    - [branch]の名前で，カレントブランチを複製する．

- git branch [branch] [repository name]/[branch]
    - [branch]の名前で，指定したリモートリポジトリのブランチを複製する．

- git checkout [branch]
    - カレントブランチから指定したブランチに移動する．

- git checkout -b [branch]
    - [branch]の名前でカレントブランチを複製するとともに，そのブランチに移動する．

- git checkout b [branch] [repository name]/[branch]
    - [branch]の名前で，指定したリモートリポジトリのブランチを複製するとともに，そのブランチに移動する．

- git diff -b
    - スペースの増減を無視する（新たに追加されたスペースは差分として表示）

# 便利なコマンド設定

- git tree
    - 以下のコマンドでエイリアスを設定しておくと，git treeと叩くことで，logをtree表示できる．

~~~
git config --global alias.tree 'log --graph --all --format="%x09%C(cyan bold)%an%Creset%x09%C(yellow)%h%Creset %C(magenta reverse)%d%Creset %s"'
~~~

※参考: [git log を見やすくする](https://qiita.com/takasianpride/items/842a785af610025a2030)
CSS命名で迷わない サイトで使う英語一覧

CSSのクラス名を決めるときに使う単語リストを
自分のチーム用にドキュメント化してみます🙌
設計のご参考になれば幸いです。

#CSS命名の考え方

##略さない
揺れる原因となるためbtn、bnrなど略した英単語を使わない。

##中学校の教科書程度の平易な英単語を使う
カタカナ英語でも一般的に使われている英単語を使うようにする。
プログラマ目線でなく一般的に使われる英単語を採用する。

##日本語ローマ字表記を使わない
mokujiなど日本語のローマ字の表示を使わない。

## 他要素の英単語を命名規則でも使う

- ディレクトリやURLの英単語
- デザインに英語表記がある場合
- 多言語で英語サイトがある場合

このような場合はCSS命名規則でも同じ単語を使用する。

次からclass命名の英単語一覧になります。

#サイト全体で使うclass命名

- main - メイン
- sub - サブ
- common - 共通
- local - カテゴリ以下

#カテゴリ／個別ページのclass命名

- index - トップページ（次候補：top）
- about - 会社概要（次候補：company）
- works - 仕事、実績
- product - 製品
- service - サービス
- news - お知らせ（次候補：info）
- event - イベント
- history - 沿革
- archive - 記事一覧（次候補：archives,bucknumber）
- contact - 問い合わせ（次候補：inquiry）
- access - アクセス
- shop - 店舗
- related - 関連記事
- privacy - プライバシーポリシー（次候補：privacypolicy）
- faq - よくあるご質問（次候補：qa）
- contact01 - フォームの入力（次候補：contact_input）
- contact02- フォームの確認（次候補：contact_）
- contact03 - フォームの完了（次候補：contact_fix）
- search - 検索結果
- cart - 購入カート
- law - 特定商取引
- career 中途採用
- recruit 新卒採用
- delivery 配送、送料
- message、greeting 代表挨拶、メッセージ
- officer - 役員紹介
- staff,member - 社員紹介
- jobs 職種
- welfare 福利厚生
- culture 社内制度
- terms 規約

#BEM_Block

- card - カードレイアウト
- section - セクション
- post - 記事（次候補：entry、article）
- wrap - 大枠（次候補：container）
- group - グループ
- module - 部品（次候補：parts、unit）
- area - 箇所
- note - 注釈
- description - 概要
- intro - 前置き・導入
- info - お知らせ
- detail - 詳細
- meta メタ情報
- noResults 検索結果なし

#BEM_Element

- inner - 内側の
- body - 主要部分（次候補：contents）
- head - 上部
- foot - 下部
- heading - 見出し
- lead - 見出しの補足・記事の要約
- list - 一覧・表。
- item - ul、olのli
- column - 縦列
- row - 横列
- text - 本文
- caption - 画像・図表の補足文
- thumb - サムネイル画像、画像の枠
- tel - 電話番号
- address - 住所
- date - 日時（次候補：time）
- category - カテゴリ
- tag - タグ
- separator - 境界線
- arrow 矢印
- lead リード文

#BEM_Modifier

- success - 成功
- alert - 注意
- error - 失敗
- small - 小
- large - 大
- push - 押す
- pull - 引く
- left- 左
- center - 中央
- right - 右
- top - 縦上部
- middle - 縦中央
- bottom - 縦下部
- prev 前 
- next 次 
- back もどる 
- more もっと

#UI／ナビゲーション

- globalNav グローバルナビゲーション
- localNav ローカルナビゲーション
- siteNav サイト全体のナビゲーション

#UI／インターフェイス

- humberger ハンバーガーメニュー
- mainVisual メインビジュアル
- carousel カルーセル
- tab タブ
- icon アイコン
- button ボタン

#State／状態変化

- show - 見せる（次候補：view）
- hidden - 隠す
- open - 開く
- close - 閉じる
- current - 現在地
- active - 有効
- disabled - 無効

#参考URL

CSSのクラス名を決めるときに使うリストをつくりました
https://qiita.com/manabuyasuda/items/dbb76ed36970bec95470
こちらの記事を大変参考にいたしました。
Salesforce Dataloader でAddress型を含むデータのエクスポートができないときの回避策

##実行環境

Salesforce Dataloader v46


##概要

Salesforce Dataloaderを使ってSalesforceのデータをエクスポートしたら下記のエラーが発生。

```
"org/apache/commons/beanutils/BeanIntrospector" error
```

いくつかエクスポートできているのに、特定のテーブルだけエクスポートできず。


##原因

Address型 という住所系のフィールドをエクスポートすることができなくなってしまったようです。

参考
https://success.salesforce.com/issues_view?id=a1p3A000001YmNXQA0&title=data-loader-v46-exporting-address-fields-generates-org-apache-commons-beanutils-beanintrospector-error


##回避策

Address型のフィールドをエクスポート対象から除外するか、Dataloader v45 を使えとのこと。
実際、v45で試したところ問題なく実行できました。

直す気があるのかわからないので、とりあえずバージョンを落としても問題ないのでv45を使うことにしました。
jQueryでUA判定して適宜スタイルシートを呼び出す

# 解決案
```html:likethis.html
<script>
  $(function () {
    var ua = navigator.userAgent;
    if (ua.indexOf('Android') > 0 && ua.indexOf('Mobile') > 0) {
      $('link').html('<link rel="stylesheet" href="styles/android.min.css" />');
    }
  })
</script>
```

# 補足
## navigator.userAgent
- Navigatorオブジェクトの「userAgentプロパティ」
- JavaScriptを実行しているブラウザのUserAgent（種類やバージョンなど）の情報を取得できる

参考　http://www.htmq.com/js/navigator_userAgent.shtml

## OS判断文字列
```html:likethis.html
if (ua.indexOf('ここに入れるやつ') > 0
```
| OS | 文字列 |
|:--|:--:|
| Windows | 「Windows」 |
| Mac | 「Mac + OS」 |
| iOS | 「Mac + OS + iPhone」「Mac + OS + iPad」「Mac + OS + iPod」 |
| Android | 「Android」 |
- Windows Phoneは「Windows + Phone」
- 「Android」には「Linux」も含まれている

参考　https://htaccess.cman.jp/useragent/os/

## どういう状況で使うねん
- AndroidとiOSでデザインが異なるアプリのLPの時に使うことができる
M3 と Thanos と Cortex

メトリクスをそれなりの規模でうまく運用するにはどうしたものかと今あるもので比較してみました。

## M3

[M3](https://m3db.io/) monorepo - Distributed TSDB, Aggregator and Query Engine, Prometheus Sidecar, Graphite Compatible, Metrics Platform

[M3 Documentation](https://m3db.github.io/m3/)

Key Features

- A distributed time series database
- A sidecar process
- A distributed query engine
- An aggregation tier

Components

- M3 Coordinator
- M3DB
- M3 Query (Engine)
- M3 Aggregator

アーキテクチャ 兼 資料 は、以下の通りです。
[![thumbnail](https://image.slidesharecdn.com/fosdemm3andanewageofmetricsandmonitoringinanincreasinglycomplexworld-190206195711/95/fosdem-2019-m3-prometheus-and-graphite-with-metrics-and-monitoring-in-an-increasingly-complex-world-38-638.jpg)](https://www.slideshare.net/RobSkillington/fosdem-2019-m3-prometheus-and-graphite-with-metrics-and-monitoring-in-an-increasingly-complex-world)

[CNCF to Host OpenMetrics in the Sandbox - Cloud Native Computing Foundation](https://www.cncf.io/blog/2018/08/10/cncf-to-host-openmetrics-in-the-sandbox/)
> We are excited to be a part of OpenMetrics and will natively support the standard in our open source distributed time series database M3DB, which we use to store petabytes of metrics with, alongside supporting long-term storage of metrics for Prometheus

## Thanos

[thanos-io/thanos: Highly available Prometheus setup with long term storage capabilities.](https://github.com/thanos-io/thanos)

Thanos is a set of components that can be composed into a highly available metric system with unlimited storage capacity, which can be added seamlessly on top of existing Prometheus deployments.

![arch](https://raw.githubusercontent.com/thanos-io/thanos/master/docs/img/arch.jpg)

[Thanos - 無制限ストレージを備えたスケーラブルなPrometheus](https://www.infoq.com/jp/news/2018/07/thanos-scalable-prometheus/)

## How does M3 compare to Thanos

[Uberが独自の大規模メトリクスプラットフォームM3をオープンソースとして公開](https://www.infoq.com/jp/news/2018/09/uber-metrics-m3/)

> ローカルに置かれていないメトリクスのレイテンシが大きいこと

## Cortex

[Cortex](https://github.com/cortexproject/cortex): horizontally scalable, highly available, multi-tenant, long term storage for Prometheus.

![arch](https://thinkit.co.jp/sites/default/files/styles/main_image_730x/public/main_images/15350_main.jpg?itok=kSs2wf7p)

## 感想

M3が一番シンプルな作りをしている気がします。

次は実際に動かしてみたいと思います。

## 出典

- [FOSDEM 2019: M3, Prometheus and Graphite with metrics and monitoring in an increasingly complex world](https://www.slideshare.net/RobSkillington/fosdem-2019-m3-prometheus-and-graphite-with-metrics-and-monitoring-in-an-increasingly-complex-world)
- [KubeConにKelsey Hightower氏登壇、コンテナからサーバーレスへ移行するデモを実演 | Think IT（シンクイット）](https://thinkit.co.jp/article/15723)
- [CNCF、Prometheus as a ServiceのCortexをサンドボックスプロジェクトとして採用 | Think IT（シンクイット）](https://thinkit.co.jp/article/15350)
【JavaScript】Array.prototype.map()とemptyな配列

JavaScriptの`Array.prototype.map()`はとても便利なメソッドです。
これのお陰で`for`文の出番はかなり減り、コードもスタイリッシュになりました。
なので皆さんも是非活用して欲しいと思っています。

そこで今回は、僕がうっかりミスした`array.map()`の落とし穴をご紹介したいと思います。

# やりたかった事
```js:NG
const ary = new Array(3).map(() => "hogehoge");
```
一見すると

1. 要素数3の配列を生成
2. 生成された配列を元に`map`で各要素に`"hogehoge"`を格納
3. `map`で生成された配列を`ary`に代入

というスタイリッシュな流れが思い浮かびます。

しかし、実際にはこれは上手く行きません。

```js:Result-NG
console.log(ary); // [(empty), (empty), (empty)]
```

# MDNを読んだら当たり前だった
- [Array.prototype.map() - MDN](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array/map)

> map() メソッドは、与えられた関数を配列のすべての要素に対して呼び出し、その結果からなる新しい配列を生成します。
(MDNから引用)


# つまりどういう事だってばよ
`new Array(n)`で生成された配列は、中身が`(empty)`つまり空なのです。
MDNの説明で __"すべての要素に対して呼び出し"__ と書いてある通り、要素が無いとそもそも呼び出されないのです。
配列リテラル`[,,,]`で生成された配列も同じく、各要素は空となります。

```js
const ary1 = new Array(3); // [(empty), (empty), (empty)]
const ary2 = [,,,]; // [(empty), (empty), (empty)]
```
この2つはどちらも同じく`map`しても呼び出されません。

# どうすればいいの
要素に何らかの値が入っていれば呼び出されます。

```js:OK
const ary1 = [null, null, null].map(() => "hogehoge"); // ["hogehoge", "hogehoge", "hogehoge"]
const ary2 = [undefined, undefined, undefined].map(() => "hogehoge"); // ["hogehoge", "hogehoge", "hogehoge"]
const ary3 = ["", "", ""].map(() => "hogehoge"); // ["hogehoge", "hogehoge", "hogehoge"]
```
JavaScriptにおいて`null`や`undefined`はプリミティブです。
なので「`null`や`undefined`という**"値"**が入っている」といった意味になります。
つまり`map`で呼び出される対象となる訳です。


# おわりに
`Array.prototype.map()`を活用してより良いJavaScriptライフを！
CloudFront+S3(OAI)設定時に外部アカウントからPutObjectしたファイルを開こうとすると403になる

# これはなんですか

- 別アカウントからS3バケットにオブジェクトを投入し、CloudFrontで読む設定をした時に失敗したのでメモとして残しておきます。
- クロスアカウントアクセスの際にはAssumeRoleを使いましょう、という話です。
- 失敗の内容と解決策を書きます。

# ざっくり構成

- アカウントAとアカウントBがあり、アカウントA側でCloudFront + S3(OAI)を設定する。
    - CloudFrontの署名つきURLを発行してバケット内のオブジェクトを読み込むアプリケーションを作成していた。
- アプリケーションの要件で、アカウントBからS3バケットにオブジェクトをおく必要があり、次の設定を行った
    - アカウントB側でS3バケットへのPutObjectを許可するポリシーを書き、ロールに当てる
    - アカウントAのS3バケットポリシーに上記ロールからのPutObjectを許可する設定を書く

# おきたことと解決策

## 事象1. アカウントAがオブジェクトを操作できない

上記設定でアカウントBからアカウントAにオブジェクトを配置したところ、アカウントAのユーザー、ロールからオブジェクトの操作ができなくなっていた。CloudFront経由でアクセスしても403 (AccessDenied) が返ってくる。

### 原因

オブジェクトのACLを確認したところ、アカウントBがオーナーとなっており、アカウントAへのアクセス権限が設定されていなかった。

### 解決策

原因は、アカウントBがオブジェクトへのアクセス権をアカウントAに付与しなかったこと。以下リンク (AWSのKnowledge Center) がまさにこの件を扱っている。

https://aws.amazon.com/jp/premiumsupport/knowledge-center/s3-bucket-owner-access/

ざっくり言うと、「PutObjectの際にACL設定に `bucket-owner-full-control` を指定すればOK」と言う内容。

## 事象2. CloudFrontで403エラー(AccessDenied)が返ってくる

上記問題を解決したものの、依然としてCloudFront経由のアクセスでは403となる。

### 原因

オブジェクトのオーナーについて調べたところ、以下の記事を見つけた。

https://qiita.com/h-imaoka/items/f1cfa242fd7c953bef5f

曰く、
> オブジェクトのオーナーがバケットのオーナーと異なる場合、そのオブジェクトにはバケットポリシーによるアクセス制御が効かない

とのこと。CloudfrontのOAI設定は以下のようなS3のバケットポリシーで行うため、今の構成ではCloudFront経由のアクセスは実現できない。

``` json
{
    "Version": "2012-10-17",
    "Id": "PolicyForCloudFrontPrivateContent",
    "Statement": [
        {
            "Sid": "1",
            "Effect": "Allow",
            "Principal": {
                "AWS": "arn:aws:iam::cloudfront:user/CloudFront Origin Access Identity Exxxxxxxxxxxxxxxx"
            },
            "Action": "s3:GetObject",
            "Resource": "arn:aws:s3:::my-bucket/*"
        },
        ... 略 ...
    ]
}
```

### 解決策

クロスアカウントアクセスの方法を変えることで解決した。

- アカウントAにIAMロールを作成し、アカウントBとの信頼関係を設定する
- 作成したIAMロールにS3バケットへのPutObject権限を付与する
- アカウントBはアカウントAのロールに対して `sts:AssumeRole` を許可するポリシーをロールに当て、アプリ側で AssumeRole を行いS3バケットにオブジェクトを配置する

こうすることでアカウントBはアカウントAの権限を委任されることになり、オブジェクトのオーナーがアカウントAとなる。この設定により無事にCloudFront経由のアクセスができるようになった。 (そもそも初めからこうしておけば事象1も発生しなかった)

# まとめ

- CloudFront + S3 構成で別アカウントからS3バケットにオブジェクトを投入しようとして失敗しまくった
- 素直にAssumeRole設定を書くことで解決した

# 感想

- すごく勉強になった。
- 横着はよくない。
備忘録）CSSで背景画像のみを暗くする

#今回のやりたいこと
背景画像が明るくて文字が読みにくいので、背景画像を暗くする

##コード
```html:index.html
<div class="bg">
  <div class="box">
    <h1>HEADDING</h1>
    <p>Lorem ipsum</p>
  </div>
</div>
```

```css:style.css
html,body{
  height: 100%;
  margin: 0;
}
.bg{
	background: url()
	background-size: cover;
	position: relative;
	height:100%;
}
.bg::before{
	/* 透過した黒を重ねる */
	background-color: rgba(0,0,0,0.5);
	/* どの範囲に重ねるかを指定 */
	position: absolute;
	top: 0;
	right: 0;
	bottom: 0;
	left: 0;
	content: ' ';
}
.box{
  position: absolute;
  width: 100%;
  text-align: center;
}
h1,p{
  color: #fff;
}
```
文字は暗くする必要がないので、`.box`を浮かせる(`position: absolute`)ことで解決しています。注意として`.box`を浮かせると`.bg::before``.bg::before`の大きさがなくなってしまうので`content:'';`を指定。

[参考サイト](https://glatchdesign.com/blog/web/css/532)
平日の売上を表示

以前実装して同僚に聞かれたので残しておきます、、、

# やりたいこと 営業日ベースの前日の売上が知りたい
具体的には月曜日には金、土、日曜の合算値が前日の売上として知りたい
業界によっては売上速報の実績Dashbord等の場合、こういうニーズが多いようです。
*さすがに月曜日には売上が出ない日曜日の売上ではなく金曜日できれば合算値が知りたいとのことらしいです。

# やり方 条件フィルターで関数を利用

Tableau Serverがグローバルにある場合Now()の部分を時差を踏まえて計算する必要があります。

```Tableau
CASE DATEPART("weekday", NOW())
  WHEN 1 //日曜日
    THEN DATEPART('day',[Date]) >= DATEADD('day', -2,NOW())
  WHEN 2 //月曜日
    THEN DATEPART('day',[Date]) >= DATEADD('day', -3,NOW())
  ELSE  //その他の曜日
    DATEPART('day',[Date]) >= DATEADD('day', -1,NOW())
```

こっちのがTableauっぽいやり方かもしれません。
https://community.tableau.com/thread/196966
初心者がPythonを学び作ってみた

こんにちは！！
Pythonを学んで、何が作れるかな〜？
って考えた時に、一昨年くらいに流行った「仮想通貨」
ビットコイン（BTC）のファンダメンタルズ分析ができないかな？
と、思いつらつらとやっていきます！

#BTCとは
BTCを語る前に、仮想通貨とは何か？に触れたいと思います。
仮想通貨とは
**実体をもたない通過**です。

その中でBTCは一番流通量が多く、
**仮想通貨 = BTC**
と考えてる方も多いくらい有名なコインです。

2017年のピークの時期には、１億円以上の利益を出し**億り人**という人を多く排出しました。
それから下火になり、現在ではピークの約30%くらいの金額で推移していますが
値動きが大きく、**値動きが読めれば、まだまだ稼げる**ものになっています。

##BTCでの有名人の発言との相関があるのでは？
どうすれば値動きが読めるだろう？

・・・・。


「BTCでの有名人のTwitterの呟き」と「BTCの値動き」
これに相関関係がないかを調べてみよう！！

ということで、今回は、ニシノカズさん @nishinokazu のツイートで検証していきます！

##まずはBTCの情報を取得しよう！！
~~ここは楽をしています。~~
BTCの情報をコインチェックから取得していきたいと思います。
https://blockrabbit.io/mercury-retrograde/
を参考に・・・。~~（全部持ってきました）~~
ありがとうございます！！


```python:main.py
import requests
import datetime
import pandas as pd
import csv
 
def daily_price_historical(symbol, comparison_symbol, limit=1, aggregate=1, exchange='Coincheck', allData='true'):
    url = 'https://min-api.cryptocompare.com/data/histoday?fsym={}&tsym={}&limit={}&aggregate={}&allData={}'.format(symbol.upper(), comparison_symbol.upper(), limit, aggregate, allData)
    if exchange:
        url += '&e={}'.format(exchange)
    page = requests.get(url)
    data = page.json()['Data']
    df = pd.DataFrame(data)
    df['timestamp'] = [datetime.datetime.fromtimestamp(d) for d in df.time]
    return df
 
df = daily_price_historical('BTC','JPY')
df.to_csv('./data/coincheck.csv')
```

いつもお世話になっております！！！！~~再度~~
これでBTCの情報は取得できました。


##Twitter情報を取得しよう！

これはどこにでも取得方法が転がっていると思います。
今回は、Aidemyで使った方法で取得していきたいと思います。

tweepyを使ってAPIにアクセスして取得していく方法です。

```python:main.py
import tweepy
import csv

screen_name = "@nishinokazu"

consumer_key = ""
consumer_secret = ""
access_key = ""
access_secret = ""

auth = tweepy.OAuthHandler(consumer_key, consumer_secret)
auth.set_access_token(access_key, access_secret)
api = tweepy.API(auth)

# ツイート取得
tweet_data = []

for tweet in tweepy.Cursor(api.user_timeline,screen_name = screen_name,exclude_replies = True).items():
    tweet_data.append([tweet.id,tweet.created_at,tweet.text.replace('\n','')])

# csv出力
with open('./data/tweets_fav1.csv', 'w',newline='',encoding='utf-8') as f:
    writer = csv.writer(f, lineterminator='\n')
    writer.writerow(["id","text","created_at"])
    writer.writerows(tweet_data)
```

Twitterの情報も取得できました。

##終わりに

はい。ということで今日は情報取得のところを書かせていただきました。
次から検証、解析をしていきたいと思います。

読んでいただきありがとうございました！！
忘れていた(新しく知った)Gitコマンド集

別の仕事をした後にGitを操作するとよくコマンドを忘れるんですよね。
随時更新していきます(更新がないのが一番良いですが:sweat_smile:)

追記: 新しく知ったコマンドも追加しました。

## 忘れていたコマンド

### git merge --abort

マージでコンフリクトを起こした時とかに一度マージ前に戻したい時に使う

### git reflog

gitの操作履歴を表示

### git commit --amend

以前のコミットに現在の変更を取り込ませる
何もステージに挙げていない場合は以前のコミットのコメントを編集することができるから便利

### git remote add

`git remote add origin [リモートリポジトリのURLのcopy]`

ローカルリポジトリとリモートリポジトリを紐付ける

[Gitでローカルリポジトリを作成して、後にリモートリポジトリへ反映する](https://qiita.com/taigamikami/items/26c29cb0fcdb0c05d396)

### git push --set-upstream

`git push --set-upstream origin master`

プッシュ先を指定する

## 新しく知ったコマンド

### git remote set-url origin <URL>

remoteのURLを変更する

### [git count-objects](https://git-scm.com/docs/git-count-objects) -vH

オブジェクトファイルの数とそれらが消費するディスク容量を数える
-v: 詳細に教えてくれる
-H:ファイルサイズに単位を付けてくれる(KiB等)

### git checkout [ファイル名]

ローカルの変更を破棄する
すべて破棄するときは以下コマンド
git checkout .
AWS LambdaからLambdaを非同期で呼び出す(Python)

Python3.6でやります。

# 呼ばれるLambda
まずは呼ばれるLambdaの関数。yobareru関数にしました。

```python:yobareru
import json

def lambda_handler(event, context):
    print("呼ばれています")
    return event
```
非常にシンプルな形です。
これが呼び出される時にeventにはjsonの形で入れますが、そのeventをそのままreturnしています。

# 呼ぶLambda
関数をテキトーに作っていただき、まずはロールの設定から。

### - ロールの設定
画面下部、実行ロールに割り当てられているロールがあると思いますが  
それのポリシーのアクセス権限を編集します。

```
        {
            "Effect": "Allow",
            "Action": [
                "lambda:InvokeFunction"
            ],
            "Resource": "*"
        }
```
これが入っていないので、いれてください。


### - 関数の編集
では関数を編集しましょう。
呼び出すには`invoke`というのを使います。

```python
response = boto3.client('lambda').invoke(
    FunctionName='yobareru',
    InvocationType='RequestResponse', # Event or RequestResponse
    Payload=Payload
)
```

これをかきます。
client('lambda')は変更しないでください。
変更するところは、FunctionNameです。作った関数名を入れてください。
InvocationTypeは
`Event` なら非同期
`RequestResponse` なら同期です。
色々なページでyobareruのデータをダンプするような記述がありますが、yobareruで指定したものをyobuのコンソールでみたい時は、RequestResponseの同期処理にしなければなりません。
Payloadはyobareruに渡すものです。yobareruのeventに入ります。

試しに同期処理のコードを書いてみましょう。

#### - 同期処理 RequestResponse

```python:yobu(同期ver)
import boto3
import json
 
def lambda_handler(event, context):
     
    # 引数
    input_event = {
        "param1": 1,
        "param2": 2,
        "param3": 3
    }
    
    Payload = json.dumps(input_event) # jsonシリアライズ
    print("---01: Payload:", Payload)
    
     
    # 呼び出し
    response = boto3.client('lambda').invoke(
        FunctionName='test0820',
        InvocationType='RequestResponse',
        Payload=Payload
    )
    print("---02: response:", response)
    
     
    # レスポンス読出し
    body = json.loads(response['Payload'].read()) #どうやらHTTPヘッダーは特殊な形をしているようで、普通にjson.
    print("---03: body:", body)

    return body
```

これでyobuの実行をすると、コンソールには

```
Response:
{
  "param1": 1,
  "param2": 2,
  "param3": 3
}
```
とでるのでいい感じです。
では非同期処理をしましょう。


#### - 非同期処理 Event
InvocationTypeをEventにして、レスポンス読出しをコメントアウトします。

```python:yobu(非同期ver)
import boto3
import json

def lambda_handler(event, context):
     
    # 引数
    input_event = {
        "param1": 1,
        "param2": 2,
        "param3": 3
    }
    
    Payload = json.dumps(input_event) # jsonシリアライズ
    print("---01: Payload:", Payload)
    
     
    # 呼び出し
    response = boto3.client('lambda').invoke(
        FunctionName='test0820',
        InvocationType='Event',
        Payload=Payload
    )
    print("---02: response:", response)
    
     
    # レスポンス読出し
    # body = json.loads(response['Payload'].read())
    # print("---03: body:", body)

    # return body
```
これで実行すると、Responseはnullになりますが、
yobareru側のCloudWatchをみてみましょう。
<img width="717" alt="スクリーンショット 2019-08-23 11.31.46.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/192887/f6787866-57db-107b-8829-13f9c9abdf43.png">

yobareru関数のprint文がでています！すごい~
非同期処理も完了です。


### 覚書注意点
- HTTP ヘッダーは 特殊な形のjson
- 同期処理にしないとreturnは帰ってこない
- 202の文字を見たら、それは成功している証拠。　[ステータスコード](https://developer.mozilla.org/ja/docs/Web/HTTP/Status)
VSCodeでファイルがタブで開かなくなった

設定を変更した記憶はないんですけど、今日VSCodeでファイルを開いたら、タブで開かなくなったので、タブで開くようにする設定方法を説明します。

# 環境

macOS Mojave 10.14.5
Visual Studio Code 1.37.1

# 設定方法

設定を開きます。

![スクリーンショット 2019-08-23 11.16.39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/75063/0d9674d5-37ab-0257-6f15-0944d101de44.png)

`show tabs` で検索し、「開いているエディターをタブで表示するかどうかを制御します」にチェックをつけます。

![スクリーンショット 2019-08-23 11.16.55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/75063/ac0b5ba7-c3e9-7674-4199-cc08ac91895d.png)

以上です。

なんで勝手に設定が変わったのかは謎のままです。。。
GitHub でエラーが出た時（Not a git repository)

先日GitHubを使ってgit cloneで cloneした後、git pushしようとしたらとあるエラーが出ました。

以下のようなエラーです。
```fatal: Not a git repository (or any of the parent directories): .git```


```push declined due to email privacy restrictions```


その時の解決法を書いていきたいと思います😁↓↓

## 1.Githubのページに行ってください。

初めに【Settings】→ 【Emails】に行って、

<img width="1086" alt="スクリーンショット 2019-08-23 10.49.51.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/407730/a508707a-98d2-326c-c851-98c4a6700989.png">

ここの所にチェックがついているか否かを見てください。
もし青いチェックがついているのであれば、画像のように外してください。

##2.ターミナルを開いてください。

次に、上記で出たエラーコードの下に


```$ git config --global user.email "email@example.com"```

と書いてください。

（この時に入れるメールアドレスは、【Settings】→ 【Emails】→ 【Primary email address】
に登録しているメールアドレスです）

上記のコードを書いた後、正しく書けてるかを確認するために

```$ git config --global user.email```

と書いてみてください。

もし
```$ git config --global user.email
email@example.com```

このように上で書いたメールアドレスが二行目で表示されたならば、成功です！！😆

##2.最後に、、

エラーが解消されたかどうかを確認するために、
```$ git push```

してみてください。
エラーが解消されたならば、きちんとpush成功しているはずです、、👍
webarenaでubuntu その25

#概要

webarenaでubuntu18.04やってみた。
php7.2やってみた。
生postが、見たかった。

#サンプルコード

```
<?php
	$stdin = fopen("php://input", "r");
	if (!$stdin)
	{
		print("ng!!");
	}
	while (!feof($stdin))
	{
		$buffer .= fgets($stdin, 10000);
	}
	fclose($stdin);
	print($buffer);
	print_r($_FILES);
	print("<br >");
	print_r($_POST);
	print("<br >");
?>
```

```
<FORM enctype="multipart/form-data" action="dump.php" method="post">
	m<br>
	<TEXTAREA name="m" wrap="off" cols="70" rows="1">0</TEXTAREA><BR>
	a<br>
	<TEXTAREA name="a" wrap="off" cols="70" rows="1">2</TEXTAREA><BR>
	<INPUT type="submit" value="send">
</FORM>
```


#結果

仕様で、見れない。

```
Array ( ) 
Array ( [m] => 0 [a] => 2 ) 
```

以上。
IEでコピーツールを作る

# はじめに

メモ帳やエクセルに書いてあるデータをコピペしまくる事、よくあります。でもちょっと使いにくい部分も…

- メモ帳の場合、範囲選択がめんどくさい※ダブルクリックしても思うような範囲選択にならないことも…
- エクセルだとテキストをコピーしたいのにセルがコピーされちゃってややこしいことになったり…
- そもそも`Ctrl + c`を押したくない…

クリックするだけでコピーできるツールがあると作業がはかどりそう！と思って作ってみました。

# IEで実装してみる

```html:index.html
<!DOCTYPE html>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>コピーテスト</title>

<style>
    table {
        border-collapse: collapse;
    }

    td {
        border: 1px solid #aaa;
        padding: 1rem;
        cursor: pointer;
    }
</style>

<table>
    <tr>
        <td>あいうえお</td>
        <td>かきくけこ</td>
    </tr>
    <tr>
        <td>さしすせそ</td>
        <td>たちつてと</td>
    </tr>
</table>

<script>
    (function () {
        var i,
            td = document.getElementsByTagName("td"),
            color1 = "black",
            color2 = "red";

        for (i = 0; i < td.length; i++) {
            td[i].style.color = color1;

            td[i].addEventListener('click', function () {
                window.clipboardData.setData("text", this.innerHTML);

                if (this.style.color == color1) {
                    this.style.color = color2;
                } else {
                    this.style.color = color1;
                }

            }, false);

        }

    }());
</script>
```
コピーしたい文字をクリックすると文字色が反転し、コピーされます。我ながら結構使いやすいです。文字を動的に変化させると色々なコピペツールが作れそうです。IE以外のブラウザでは動かないのが残念なので、後日エクセルVBAやElectronでの実装も行ってみます(^^)
Accept-Language HTTPヘッダー

##Accept-Language
Railsのことを調べていてAccept-Languageという用語を見かけて、聞きなれない用語だったため調べてまとめることにしました。これはRailsの国際化、言語設定を行う際に使われるもののようです。言語の切り替えを行う方法にはいくつか方法がありますが、今回はその切り替えを行う方法の１つです。HTTPヘッダーのAccept-Languageから言語を選択して、言語を設定します。

##HTTPヘッダーとは
WebブラウザからWebサーバーへ送信するHTTPリクエストに含まれる情報のことです。その中でブラウザがどの言語を理解できるか、またはどの種類のロケールかを表している部分がAccept-Languageリクエストヘッダーになります。以下がHTTPヘッダーの例になります。

```HTTP
GET / HTTP/1.1
Accept: image/gif, image/jpeg, */*
Accept-Language: ja
Accept-Encoding: gzip, deflate
User-Agent: Mozilla/4.0 (Compatible; MSIE 6.0; Windows NT 5.1;)
Host: www.xxx.zzz
Connection: Keep-Alive
```

HTTPのAccept-Languageリクエストヘッダーは、クライアントがどの言語を理解できるか、どの種類のロケールが推奨されるかを示します。コンテンツネゴシエーションを使用して、サーバーは提案されたものから一つを選択して使用し、Content-Languageレスポンスヘッダーを使用してクライアントに選択結果を知らせます。ブラウザはユーザーインターフェイスの言語に従って、このヘッダーに適切な値を設定し、ユーザーはこれを変更することができます。

このヘッダーはヒントであり、サーバーが言語を判別するための方法として、明示的なユーザーの選択によって制御する特定の URL など、他のものがない場合に使用されます。サーバーは明示的な決定を上書きしないことを推奨します。 Accept-Languageの中身はユーザーが制御できないことがよくあります（旅行中で外国のインターネットカフェを使用している場合など）。
同一端末で複数のgithubアカウントを使う

同一端末ので複数のgithubアカウントを使いたい。そんな時の設定です。

# 目次
1. メインGithubアカウント作成
2. メインssh設定
3. サブGithubアカウント作成
4. サブssh設定


# 1. メインGithubアカウント作成
アカウントを作成してください。

# 2. メインssh設定

###2-1. 公開鍵・秘密鍵の作成
公開鍵はGithubに送信し、秘密鍵は自分のPCの中に入れておきます。
※こちらの記事を参考にしました。
　[GitHubでssh接続する手順~公開鍵・秘密鍵の生成から~](https://qiita.com/shizuma/items/2b2f873a0034839e47ce)

```
$cd ~/.ssh
```
初めて作るときは何もないはず。

```
$ssh-keygen -t rsa
```
メインの方は、スタンダードに　id_rsaとid_rsa.pubの2つの鍵が生成されます。

###2-2. 公開鍵をGitHubにアップする
これも記事を参照してください。
titleには、わかりやすい名前、例えばMacBook-1などを入れておくと良いでしょう。

###2-3. 接続テスト
接続できているか確認と、試しにpushまでをお願いします。


# 3. サブGitHubアカウント作成
アカウントを作成してください。

# 4. サブssh設定

###4-1. 公開鍵・秘密鍵の作成
※こちらの記事を参考にしました。
　[1台のPCで複数のGitHubアカウントを使う(SSHとhttps)
](https://dackdive.hateblo.jp/entry/2015/10/12/210547)

```
$cd ~/.ssh
```

```
$ssh-keygen -t rsa -f id_rsa_sub
```
サブの方は、　id_rsa_subとid_rsa_sub.pubの2つの鍵が生成されます。

###4-2. 公開鍵をGitHubにアップする
2-2と同様です。

###4-3. ssh/configの修正
このコンフィグファイルを修正することで、ホストごとに秘密鍵を使い分けれられるようにできます。

```
# 仕事用
Host github
  User git
  Port 22
  HostName github.com
  IdentityFile ~/.ssh/id_rsa   # メイン秘密鍵のパス設定
  TCPKeepAlive yes
  IdentitiesOnly yes
# プライベート
Host github-sub  #github.com以外で自分がわかりやすい名前のHost
  User git
  HostName github.com
  IdentityFile ~/.ssh/id_rsa_sub  # サブ秘密鍵のパス設定
  TCPKeepAlive yes
  IdentitiesOnly yes
```

#5. リポジトリごとに分ける方法
サブアカウントに変えたいリポジトリで以下の設定をおこないます。

```
$ cd hogehoge
$ git config user.name [サブアカウントのユーザー名]
$ git config user.email [サブアカウントのメールアドレス]
```
すると、hohoge/.git/configが自動生成されます。
本来ならば~/.git/configの設定が適用されるところが、リポジトリに設定された.git/configが適用されるのです。
VBA キャメルケース スネークケース ケバブケース　変換

# VBA キャメルケース スネークケース ケバブケース　変換

## 概要
キャメルケースとスネークケースを変換するメソッド

### コード

```VB
' キャメルケースに変換
Private Function toCamel(ByVal val As String, delimiter As String, Optional ByVal isFirstUpper As Boolean = False) As String
     
        Dim ret As String
        Dim i   As Long
        
        Dim snakeSplit As Variant
        snakeSplit = Split(val, delimiter)
        
        For i = LBound(snakeSplit) To UBound(snakeSplit)
            ret = ret & UCase(Mid(snakeSplit(i), 1, 1)) & _
                        LCase(Mid(snakeSplit(i), 2, Len(snakeSplit(i))) _
                              )
        Next
     
        If isFirstUpper Then
            toCamel = ret
        Else
            toCamel = LCase(Mid(ret, 1, 1)) & Mid(ret, 2, Len(ret))
        End If
     
End Function

'スネークケースをキャメルケースに変換
Public Function snakeToCamel(ByVal val As String, Optional ByVal isFirstUpper As Boolean = False) As String
    snakeToCamel = toCamel(val, "_", isFirstUpper)
End Function

'ケバブケースをキャメルケースに変換
Public Function kababuToCamel(ByVal val As String, Optional ByVal isFirstUpper As Boolean = False) As String
    kababuToCamel = toCamel(val, "-", isFirstUpper)
End Function




'キャメルケースをスネークケースに変換

' Public Function camelToSnake(ByVal val As String, delimiter As String, Optional ByVal isUpper As Boolean = False) As String
 
 'キャメルケースから変換
 Private Function fromCamel(ByVal val As String, delimiter As String, Optional ByVal isUpper As Boolean = False) As String
     
        Dim ret As String
        Dim i      As Long
        Dim length As Long

       
        length = Len(val)
        
        For i = 1 To length
            If UCase(Mid(val, i, 1)) = Mid(val, i, 1) Then
                ' 大文字
                If i = 1 Then
                    ' 最初の文字なら、区切り文字は付与しない
                    ret = ret & Mid(val, i, 1)
                
                ElseIf i > 1 And UCase(Mid(val, i - 1, 1)) = Mid(val, i - 1, 1) Then
                    ' 前の文字が大文字なら、区切り文字は付与しない
                    ret = ret & Mid(val, i, 1)
                Else
                    ' 小文字なので区切り文字を付与
                    ret = ret & delimiter & Mid(val, i, 1)
                End If
            Else
                ' 小文字
                ret = ret & Mid(val, i, 1)
            End If
        Next
     
        If isUpper Then
            fromCamel = UCase(ret)
        Else
            fromCamel = LCase(ret)
        End If
        
End Function


'キャメルケースをスネークケースに変換
Public Function camelToSnake(ByVal val As String, Optional ByVal isUpper As Boolean = False) As String
    camelToSnake = fromCamel(val, "_", isUpper)
End Function


'キャメルケースをケバブケースに変換
Public Function camelToKababu(ByVal val As String, Optional ByVal isUpper As Boolean = False) As String
    camelToKababu = fromCamel(val, "-", isUpper)
End Function

```
Flutter for Desktopでエラーが出たときの自己流トラブルシューティング

# はじめに
Flutter for Desktopは開発中ということもあり、不安定で、`flutter run`などする際に良くエラーが発生します。そんなときにとりあえずやってみるといいと思うトラブルシューティングを紹介します。

※自己流であること、この方法を使ったことによって問題が発生した際の責任は負わないことを了承した上でお試しください。

#とりあえず
- `flutter clean`
- `flutter run`

これで大抵の場合は動きます。
buildファイルや諸々のデータを掃除します。

#それでも動かなかったら

割と最終手段ですが、バージョンを上げる上げない(`flutter upgrade`する/しない)はあなたにおまかせします。

- `flutter upgrade`する
- [google/flutter-desktop-embedding](https://github.com/google/flutter-desktop-embedding/)から最新のファイルを取ってくる
- `/flutter-desktop-embedding/example`内からlib,pubspec等必要なもの以外のフォルダを該当のプロジェクトファイルに置換する

これで先程の手段で動かなかった方も大抵の方は動くようになったと思います。

#それでもダメだったら
- Flutterのコミュニティは[たくさんある](https://flutter.dev/community)のでそちらで聞いてみるといいかもしれません。
CentOS6のLXCコンテナを仮想マシンに移す (lxc->kvm)

* [物理サーバをコンテナ化 (OpenVzの例) - Qiita](https://qiita.com/tukiyo3/items/a7ea4d21e6b2da3e200f) の逆
* CentOS6 64bit のLXCコンテナをどうにかしたかった。
* Proxmox6だとProxmox5のlxcコンテナのbackupをrestoreすると [mknodで失敗する](https://qiita.com/tukiyo3/items/370b24b3fe9a1553b8f4#lxc%E3%81%AE%E3%83%AA%E3%82%B9%E3%83%88%E3%82%A2%E3%81%AB%E5%A4%B1%E6%95%97%E3%81%99%E3%82%8B%E5%A0%B4%E5%90%88)。
    * 上記例はpostfixだけで済んだが、今回は/dev/以下の大量のものが該当だったため仮想マシンで動かすこととした。

## 1. CentOS6のインストールCDから普通にOSインストール

* 仮でCentOS6を入れておく。ブート出来るようにするのが目的のため設定は適当でよい。

## 2. lxcコンテナのファイルを全部tar.gzで固める

* proxmoxの場合、rawイメージで格納されている。

```sh:lxcのファイルをtar.gzに固める
mkdir a
mount -o ro,loop 〜.raw a
cd a

tar czf ~/lxc.tar.gz *.tar.gz *auto
```

## 3. CentOS6をインストールした仮想マシンに 2 のtar.gzをコピー

## 4. CentOS6のインストールCDからレスキューモードで起動

* ファイルシステムのマウントを求められた場合、`skip`にしないと以下のように青画面で再起動になる。

![スクリーンショット_2019-08-23_08-55-59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/25728/279c7f63-824c-8533-c8ce-978f487b52b8.png)

## 5. 仮想マシンの/内のものを LXCのtar.gzに差し替える

```go
# レスキューモード環境
cd /mnt
mkdir a
## / をマウント
mount /dev/vda3 a
cd a

mkdir kvm
## 仮想マシンのファイルを全てkvmフォルダに移す
mv * .auto kvm
## lxcの中身を展開
tar xzf lxc.tar.gz
```

![スクリーンショット_2019-08-23_08-58-00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/25728/1a46d7c8-0bbc-822b-e4c7-7935a6825fbd.png)

```go
## lxcの etc/mtab は/proc/mounts にシンボリックリンクが貼られているため修正。
rm etc/mtab
cp kvm/etc/mtab etc/mtab
```

```go
## カーネルモジュールを移植
mv kvm/lib/modules/* lib/modules/
```

## 6. 再度 レスキューCDで起動

* 今度はファイルシステムを自動検出でマウントしてもらい、Continue押下し以下。

```
cd /mnt/sysimage
chroot .

grub-install /dev/vda
exit

reboot
```

## 7. CDを抜いて、仮想マシンで普通に起動できることを確認。

* 完了
iOS <-> ROS via ESP32’s BLE

# log
2019/08/30 esp32_ble_cont プログラム修正

# 目的
展示会場等でのWiFiが使えない環境でもロボットのROSとiPhoneで通信を行いたい。
BLEを使えばいいじゃん!

# 構成
<img width="1028" alt="スクリーンショット 2019-08-23 9.44.29.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/124209/ed59ebc2-03ec-bedb-91a8-09079228f1bb.png">

## iPhone
![screen.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/124209/df621b52-ae0e-69b5-b4ad-1d2658cfef40.png)
- 開発環境：Xcode
- 使用言語：Swift
- GitHub：[BleROSCont](https://github.com/koki-ogura/BleROSCont)

## ESP32
![esp32.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/124209/4f269072-f476-a163-d7e2-10af26f1953d.jpeg)
- 開発環境：Arduino on mac
- 使用言語：C++
- GitHub：[esp32_ble_cont](https://github.com/koki-ogura/esp32_ble_cont)
- 購入先1：[左：秋月](http://akizukidenshi.com/catalog/g/gM-13628/)
- 購入先2：[右：Amazon](https://www.amazon.co.jp/dp/B0718T232Z)

## ROS Package
<img width="1048" alt="スクリーンショット 2019-08-23 10.03.48.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/124209/f7ed1998-aeb5-edb3-75f4-97b3120138fa.png">
- 開発環境：ROS melodic on ubuntu 18.04
- 使用言語：Python2
- GitHub：[esp32_ble_server](https://github.com/koki-ogura/esp32_ble_server)

# 技術情報
- ESP32はBLEペリフェラルとして動作
- アンテナ形状の違いから秋月のESP32の方が電波が良く飛ぶ
- BLE通信はwrite without responseとnotifyを使用
- 詳しくはそれぞれGitHubのREADMEを参照してください
rubyリファレンスマニュアルのobjectクラスを読んだので、気になった部分をまとめる

# ruby リファレンスマニュアル
rubyの仕組みや構造、機能を知りたいと思いrubyリファレンスマニュアルを読み始めました。
ざっくりと気になった部分をまとめます。

Ruby リファレンスマニュアル（公式）
https://docs.ruby-lang.org/ja/latest/doc/index.html

# Objectクラスとは

すべてのクラスのスーパークラス（他の下位クラスの派生元となる上位クラス。親クラス、基底クラスとも。）
Kernelモジュールをインクルードしていて、すべてのオブジェクトでKernelモジュールメソッドhttps://docs.ruby-lang.org/ja/2.6.0/class/Kernel.html  が使用可能で、Objectクラスのメソッドは実際にはこのモジュールで定義されています。

rubyのオブジェクトは一部をのぞいて固有のIDを持っており、
```object_id``` で呼び出せます

```
> a = "hoge"
> a.object_id
 => 2115678909
```

## 以下気になったもの

## 特異メソッド
### new

Objectクラスのインスタンスを生成して返します。
```
a = Object.new
=> #<Object:0x00007fe6127c9fe8>
```

## インスタンスメソッド
### 比較
#### self !~ other -> bool
selfがotherにマッチしていなければtrue,していればfalseを返します。
```
obj = 'regexp'
p (obj !~ /re/) # => false

obj = nil
p (obj !~ /re/) # => true
```

#### eql?(other) -> bool
```obj.eql?(other_obj)```
objとother_objが等しければtrue、違うならfalseを返します。

```
p("foo".eql?("bar")) #=> false
p("foo".eql?("foo")) #=> true
```

また、似たようなものとして、
### equal?(other) -> bool
```obj.equal?(other_obj)```
objとother_objが同一のものならtrue、同一でないならfalseを使用します。
冒頭の```object_id``` で同一のオブジェクトかどうか判断します。

### 変換

#### to_s -> String
オブジェクトを文字列に変換します。

``` 1.to_s --> "1"```
VBA UTF-8 取り扱いクラス

# 概要
excelでUTF-8の書き出し、読み込みを行う自作クラス



## コード

- クラスモジュール
clsStream

``` VB
Option Explicit

'UTF-8読みだし用クラス

Public stream As ADODB.stream
Public buf As String

    
Private Sub Class_Initialize()
    Set stream = New ADODB.stream
    stream.Charset = "UTF-8"
End Sub

' ストリームを開く
Public Sub begin()
    stream.Open
End Sub

Public Sub p(message)
    Debug.Print message
    buf = buf & message & vbCrLf
    stream.WriteText message & vbCrLf
End Sub

Public Sub finish()
    stream.Close
End Sub

Public Sub save(path As String)
    Dim fso As FileSystemObject
    Set fso = New FileSystemObject
    
    If fso.FileExists(path) Then
        fso.DeleteFile path
    End If
    
    stream.Position = 0 'ストリームの位置を0にする
    stream.Type = adTypeBinary 'データの種類をバイナリデータに変更
    stream.Position = 3 'ストリームの位置を3にする
 
    Dim byteData() As Byte '一時格納用
    byteData = stream.read 'ストリームの内容を一時格納用変数に保存
    stream.Close '一旦ストリームを閉じる（リセット）
 
    stream.Open 'ストリームを開く
    stream.Write byteData 'ストリームに一時格納したデータを流し込む
    
    stream.SaveToFile path
End Sub

' 一括でテキストファイル読み込み
Public Function readAll(path As String) As String
    If path = "" Then
        readAll = ""
        Exit Function
    End If

    With stream
        .Open
        .LoadFromFile path
        readAll = .ReadText
        .Close
    End With
End Function

```
## 使い方

### 参照設定
* VBAのIDE画面(Excelで alt + F11 で開く、VBA開発画面のこと)を開く

* 上段のメニューの　「(ツール)」-「参照設定」で以下のライブラリファイルにチェックを追加する

   * Microsoft ActiveX Data Object Library <--- なぜか、ここにUTF-8の読み書きの機能が入っている

### ファイル読み込み例

```VB
Sub readSample
    Dim s as clsStream
    Set s = new clsStream

    Dim path as String
    path = "C:\hoge\fuga.txt"

    Dim buf as String 
     
    s.begin
    buf = s.readAll
    s.finish

End Sub
```

### ファイルの書き込み例


```VB
Sub writeSample
    Dim s as clsStream
    Set s = new clsStream


    Dim buf as String 
     
    s.begin
    s.p "書き込みたい文字"

    Dim path as String
    path = "C:\hoge\fuga.txt"
    s.save path

    s.finish

End Sub
```
HTTPメッセージについて

webサイトにおいてHTTPプロトコルは欠かせない技術である。
# Webページが表示される流れ
１、　クライアントがWebサーバーに対してリクエストを送る。
２、　静的コンテンツならWebサーバーからクライアントにコンテンツがレスポンスとして返される。
　　　動的コンテンツの場合はWebサーバーがAPサーバーに対しリクエストが出され、サーバーサイド・スクリプトが起動し、コンテンツが生成され、レスポンスとして返される。
３、返ってきたコンテンツをクライアント側で処理し、ページが表示される。

# HTTPメッセージ(リクエスト編)
リクエスト、レスポンスの際に利用されるデータの形式のこと。といってもイマイチピンとこないので、HTTPメッセージの中身を実際に見ていくこととする。
リクエストの際にWebサーバーに送られるHTTPメッセージは主に３層に分かれている。
１、リクエスト行
２、メッセージヘッダー
３、メッセージボディー

## リクエスト行
以下の内容が記述されている。
・メソッド
・リクエストURL
・プロトコルバージョン
## メッセージヘッダー
リクエストメッセージのメタデータ
Date、Cache-Control、Connectionなど
## メッセージボディー
補足のメモ書きが入る。
Getだと何も入らず、POSTだと受け渡されるパラメーター。

## 知っておくべきリクエストヘッダーとは
・User-Agent：ブラウザの種類やOSの情報。
・Referer(リファラ)：どのページから発生したリクエストなのか
・if-Modified-Since/if-None-Match：ブラウザは１度表示したデータを「ローカルキャッシュ」として保存している。その時に、ローカルキャッシュのデータが更新されていないかをチェックするために、ファイルの変更日付や管理情報をリクエストに含めている。
・Cookie：ブラウザに保存されているクッキーデータは毎回サーバーに送られている。
・Accept、Accept-Language、Accept-Encoding、Accept-Charset：どんなデータを受け取りたいか、画像の種類や、言語、文字コードなどを伝える。

## HTTPメッセージ(レスポンス編)
レスポンスの際にブラウザに送るデータも３層に分かれている
１、　レスポンスの状態
２、　メッセージヘッダー
３、　メッセージボディー

## レスポンスの状態
・HTTPステータスコード

## HTTPヘッダー
各種の状態を示す情報が入れられている部分。

## メッセージボディー
ブラウザに表示されるWebサイト、HTMLソースコードや画像などのデータ。

## 知っておくべきレスポンスヘッダーとは
・Content-Type：データがHTMLなのか画像なのか、文字コードなのかの情報
・Expires：キャッシュの制限に使われる
・Last-ModifiedやETag：HTMLや画像がいつ更新されたかの情報や、サーバー上のファイルの場所ID、ファイルのサイズ、更新チェック情報
・Cache-ControlやPragma：グラウざや通信を橋渡しするプロ棋士が、データのキャッシュをどう扱うかの情報。
・Connection：keep-alive(接続を持続するか)、close(毎回接続を切断するか)
・Location：リクエストと違う場所からデータを取得するように示す指示。リダイレクト先を示す情報。

## rubyでリクエストを送る方法
net/httpライブラリを活用する。net/httpを活用すると、HTTPを簡単に扱うことができる。
open-uriライブラリを活用する。より簡単にHTTPにアクセスできるライブラリ。

```sample.rb
ruby -ropen-uri -e 'open("http://www.ruby-lang.org/ja/").read.display'
```

・１ページを取得する場合だけであればopen-uriはとても便利だが、繰り返しアクセスするような場合にはnet/httpを使ったほうがいい。

実際にnet/httpでGETリクエストを送る方法

```sample.rb
require 'net/http'

Net::HTTP.start('www.ruby-lang.org', 80) {|http|
  response = http.get('/ja/')
  puts response.body
}
```

net/httpでPOSTリクエストを送る方法

```sample.rb
require 'net/http'

Net::HTTP.version_1_2

Net::HTTP.start('search.hatena.ne.jp', 80) {|http|
  response = http.post('/search',"word=ruby")
  puts response.body
}
```
WordPress カスタム投稿タイプ 検索機能

## 目標

カスタム投稿タイプの一覧画面に検索機能を追加する
投稿タイプを `news` とした場合のサンプル

## アーカイブページに検索フォームを設置する

```php
<form name="search" method="get">
    <input type="text" name="text" value="<?= esc_attr(get_query_var('text')) ?>" >
</form>
```

## 独自のクエリーストリングを許可する

この設定をすることで、 `$wp->query_string` に含まれたり、 `get_query_var('text')` で取得できる。
※ WordPressがデフォルトで用意してあるものがあるので、重複しないように注意。
　https://wpdocs.osdn.jp/WordPress_Query_Vars

```php
function my_query_vars($vars)
{
	$vars[] = 'text';

	return $vars;
}

add_filter('query_vars', 'my_query_vars');
```

## メインクエリをフックする

https://wpdocs.osdn.jp/%E3%83%97%E3%83%A9%E3%82%B0%E3%82%A4%E3%83%B3_API/%E3%82%A2%E3%82%AF%E3%82%B7%E3%83%A7%E3%83%B3%E3%83%95%E3%83%83%E3%82%AF%E4%B8%80%E8%A6%A7/pre_get_posts

```php
function my_pre_get_posts($query)
{
	if (is_admin() || ! $query->is_main_query()) {
		return;
	}
	if ($query->is_post_type_archive('news')) {
		/** @var WP $wp */
		global $wp;

		$params = [];
		parse_str($wp->query_string, $params);

		if (isset($params['text'])) {
			$query->set('s', $params['text']);
		}

		// 以下は本題とは違うが、1ページあたりの件数と、表示順もここで設定できるので
		// 一覧画面で表示件数を動的に変更したり、並び順を動的に変更することが可能
		$query->set('posts_per_page', 12);
		$query->set('orderby', ['post_date' => 'DESC']);
	}
}

add_action('pre_get_posts', 'my_pre_get_posts');
```
CloudFirestoreで降順データをクエリの開始点と終了点で絞り込む時の注意点

## やりたいこと
Firestoreに登録しているデータを日付の期間指定で絞り込みをしたい。
RDBでお馴染みの標準SQLで言うところの下記。

```sql
select ...
from ...
where CREATE_AT between date1 and date2
order by CREATE_AT desc
```

## 結果
１. まずは普通に期間指定　...できました。

```javascript
orderBy("CREATE_AT").startAt(date1).endAt(date2)
```

２. 続いて降順　...検索結果が０件になってしまいました。

```javascript
orderBy("CREATE_AT", "desc").startAt(date1).endAt(date2)
                      ^^^^^
```

## 正解
```javascript
orderBy("CREATE_AT", "desc").startAt(date2).endAt(date1)
                                     ^^^^^        ^^^^^
```
上記のように、範囲指定を大きい日付から小さい日付に入れ替えることで抽出することができました。
まず降順にソートされてから範囲指定するため、大きい日付を先に設定しないといけないのですね。

原因が分かってから改めてコードを見れば、先にソートがかかるので当たり前なのですが、SQLの構文に慣れていると無意識に「範囲指定→ソート」と考えてしまい、地味にハマりました。

## 参考
* [クエリカーソルを使用したデータのページ設定  |  Firebase](https://firebase.google.com/docs/firestore/query-data/query-cursors?hl=ja)