OmniAICreator/Qiita-1.07M huggingface dataset:
各仮想化技術の違いをざっと理解していくぅ

# 補足

学んだ知識のほとんどは，Qiitaではなくこちらにバーッとまとめております．

https://hiroki-it.github.io/tech-notebook/virtualization/virtualization.html

## 01. 仮想化

###  仮想化とは

一つの物理サーバー上で仮想的なハードウェアを稼働させる技術のこと．仮想環境の構築方法にはいくつか種類がある．

### ホスト型仮想化

#### ・ホスト型仮想化とは

物理サーバーのホスト上で，仮想サーバー（仮想マシン）を構築する．

#### ・Provider例

VMware Workstation，Oracle VM VirtualBox，など

![ホスト型仮想化](https://user-images.githubusercontent.com/42175286/60386396-3afbd080-9acf-11e9-9094-f61aa839dc04.png)



### ハイパーバイザー型仮想化

#### ・ハイパーバイザー型仮想化とは

物理サーバーのBIOSから起動したハイパーバイザー上で，仮想サーバー（仮想マシン）を構築する（※ホストは用いない）．

#### ・Provider例

VMware vSphere Hypervisor，Xen，KVM，など

![ハイパーバイザー型仮想化](https://user-images.githubusercontent.com/42175286/60386395-3afbd080-9acf-11e9-9fbe-6287753cb43a.png)


### コンテナ型仮想化

#### ・コンテナ型仮想化とは

物理サーバーのホスト上で，仮想サーバーではなく，仮想サーバーとしての機能を持つコンテナを構築する．カーネルのリソースを分割できるNamespace（PID namespace，Network namespace，UID namespace）とControl Groupsを用いて，単一のOS上に独立したコンテナを構築する．

→ DockerToolboxがちょい違う

#### ・Provider例

Docker，LXC，OpenVZ，など

![コンテナ型仮想化](https://user-images.githubusercontent.com/42175286/60386394-3afbd080-9acf-11e9-96fd-321a88dbadc5.png)


## 01-02. 各仮想化のパフォーマンスの比較

### 起動速度の違い

ホスト型とハイパーバイザ型では，ハードウェア（CPU，メモリ，ハードディスク）とゲストOSを仮想化することが必要である．一方で，コンテナ型では，ハードウェアとゲストOSの仮想化は行わず，namespaceを用いてコンテナを構成するため，その分起動が速い．

![サーバー仮想化](https://user-images.githubusercontent.com/42175286/60386143-57e2d480-9acc-11e9-88b7-99a566346aba.png)


### 処理速度の違い

#### ・Overheadの小ささ

ゲストOS上のアプリを操作する場合，ホスト型とハイパーバイザ型では，ハードウェアやハイパーバイザーを経由する必要がある．この分だけ，時間（Overhead）を要する．一方で，コンテナ型では，各コンテナがホストとカーネルを共有するため，Overheadが小さい．

![仮想化](https://user-images.githubusercontent.com/42175286/60386143-57e2d480-9acc-11e9-88b7-99a566346aba.png)

#### ・Overheadの比較

sysbenchというベンチマークツールを用いて，CPU・メモリ・ファイルI/Oに着目し，物理サーバー・コンテナ型仮想化（Docker）・ホスト型仮想化（VirtualBox）のパフォーマンスを比較すると，コンテナ型であるDockerは最もOverheadが小さい．

![各仮想化の比較](https://user-images.githubusercontent.com/42175286/60386476-27049e80-9ad0-11e9-92d8-76eed8927392.png)
[Twilio/studio] 自動応答システムで発信者が終話キー押下時に呼が切断されない？現象

ずっと困ってた現象がようやく解決できたので、メモを残しておきます。
ググっても出てこなかったので（当たり前すぎるから？）。誰かのお役に立ちますよーに。

対象はTwilio初心者です。玄人の方は読み飛ばしてくださいまし。

## やりたいこと

Twilioの[studio](https://twilio.kddi-web.com/function/studio/)(ブロックで動作を作成する機能）にて電話の自動応答システム(IVR)機能を実現。

ケータイ電話/固定電話からTwilioシステムへ電話をかけて、プッシュボタンでやりたいことを数字入力して
その内容をhttpで他サーバー(heroku/node.js等)へ飛ばしてなんらか処理（詳細略）

## 困っていたこと

* 電話をかけて数字入力時にケータイ電話の終話キー押下で処理が強制終了（中断）され、初期化されることを期待していた。
しかし、再度該当電話番号へ電話発信すると通話中？なのかぷーぷーっと８秒程度で切れる。

* twilioコンソールを見ると、[stop Execution]ボタンが表示されており、これを押下すると、本[stop Execution]表示が消える
その後、再度該当電話番号へ電話発信すると正常動作する（作成したフローが動作する）
（通話料金は大きく減ってるわけでは無いので課金はされていなさそう。しばらくされており自動切断されている可能性有）

![twilio_発生現象1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/236033/bcb30e82-77ec-96c3-1583-1b06fb537cc6.jpeg)
![twilio_発生現象2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/236033/0e3ea2c4-46a5-43c3-2ec8-89a120a9e762.jpeg)

## 解決方法

フローの[Gather Input on Call]にて数字入力を待つが、
タイムアウトを設定しておき、[No input]フローに来たら、時間内に入力できなかった場合やダイヤル回線の場合の配慮などのためもう一度入れてね、という内容の発話をするようにしていた。

しかし、
発信者が終話をしたら、この[No input]フローに流れるようだ。
[No input]フローをどこにも繋がないようにすることで終話時に正常切断されるようになった。

＜修正前＞
![twilio_復帰before.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/236033/32b3c930-d466-f3e6-68ab-dfdb893bd12b.jpeg "修正前")

＜修正後＞
![twilio_復帰after.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/236033/6019b1b8-7179-22d1-a37b-5eea9fc1521b.jpeg "修正後")


## おわり

お役に立てると幸いです。
間違ってたら指摘お願いします（やさしくね:relaxed:）。
RubyMotionチュートリアル(Views)ができない

#はじめに
RubyMotionチュートリアルのViews項目をやっていて詰まった部分を、あくまで自分用に記録しています。
私はRubyMotion、さらにはネイティブなiOSアプリの開発は初めてなので間違いだらけだと思いますがご容赦ください。
もし、間違いがあればコメントにて教えていただけると嬉しいです。
## 開発環境
・macOS Mojave(10.14.6)
・RubyMotion6.4
・Atom
##本題
先日、RubyMotionをインストールしてViwesのチュートリアル(下記)をしていたところ、rakeできませんでした。

```app_delegate.rb
class AppDelegate
  def application(application, didFinishLaunchingWithOptions:launchOptions)
   @window = UIWindow.alloc.initWithFrame(UIScreen.mainScreen.bounds)
   @window.makeKeyAndVisible

   @blue_view = UIView.alloc.initWithFrame(CGRectMake(10, 10, 100, 100))
   @blue_view.backgroundColor = UIColor.blueColor
   @window.addSubview(@blue_view)

  true
  end
end
```
エラーの内容的には`.makeKeyAndVisible`に対してエラーをはいているようですが、`@window`に対してControllerを定義してあげないとうまく`rake`できないようです。(.makeKeyAndVisibleより前に。)

```app_delegate.rb
class AppDelegate
  def application(application, didFinishLaunchingWithOptions:launchOptions)
   @window = UIWindow.alloc.initWithFrame(UIScreen.mainScreen.bounds)
   #この行を追加する。
   @window.rootViewController = UIViewController.alloc.init
   @window.makeKeyAndVisible

   @blue_view = UIView.alloc.initWithFrame(CGRectMake(10, 10, 100, 100))
   @blue_view.backgroundColor = UIColor.blueColor
   @window.addSubview(@blue_view)

  true
  end
end
```
このように、コードを１行追加してみましょう。

# 結論
昔がどうだったのかわかりませんが、しっかりと`rootViewController`を定義しなければいけません。
もし、`rake`する際にエラーが起きたときは一度確認してみましょう。
vagrantで作成した仮想環境にAnsibleで接続出来ない時の対応

# 内容
vagrant initコマンドで用意したvagrantファイルから、作成した仮想環境にplaybookを実行したところ「unreachanle」のエラーが出たので、その時に取った対応を書きます。

## 工程

### 1.Vagrantfile内でIPアドレスを指定する。
指定しなくても作成時にIPアドレスは仮想環境に付与されていますが、このIPだとping通らなかったので必須。

```
[Vagrantfile]

config.vm.network :private_network, ip: "IPアドレス"
```

### 2.Vagrantfile内でユーザー名とパスワードを指定しておく
`vagrant ssh`だと無くても接続出来ますが、playbook実行には必要みたいです。
1と同じようにVagrantfaileに追記してください。

```
[Vagrantfile]

  config.ssh.username = 'vagrant'
  config.ssh.password = 'vagrant'
```

ユーザ名、パスワードは`vagrant`で無くても良いのでお好みで。


##3.公開鍵を作成した仮想環境に渡す
`vagrant up`で仮想環境を起動させたら、`ssh-copy-id`コマンドで仮想環境に公開鍵を渡します。

```
# ssh-copy-id "ユーザー名"@"IP"

<例>
# ssh-copy-id vagrant@192.168.11.10
```


##3.ユーザー名を指定してplaybook実行
インベントリファイルとplaybookを作成して実行します。

今回実験で作ったインベントリファイルとplaybookを下記に載せます。


```
[インベントリファイル]

[test]
"IPアドレス" ansible_ssh_user="ユーザー名"
```

`ansible_ssh_user`は記載しなくても、playbook実行時に「-u」オプションでユーザー名を指定すれば動きます。ただ、一々入れるのが面倒なのでインベントリファイルに記載しておきます。

```
[playbook.yml]

- hosts: test
  tasks:
    - shell: uptime
      register: result

    - debug:
        msg: "{{ result.stdout }}"
```

playbookの中身をざっくり説明すると、testグループに対して、`uptime`コマンドを実行、結果をdebugモジュールを使って出力すると言った感じです。

##終わりに
vagrantで作成した仮想環境にplaybookが実行出来ず、調べた情報だけだと上手く行かなかったので書きました。

もうちょっとスマートな方法もあるかも知れませんが、確認取れた方法をとりあえず備忘録で。
pythonでatcoder(ABC133 A)　

問題文はこちら
https://atcoder.jp/contests/abc133/tasks/abc133_a

標準入力で　N、A、Bを取得し
N＊AとBを比較、少ない方を表示する。

n,a,b = map(int,input().split())
標準入力を取得
c = n*a
if c >= b:
  print(b)
else:
  print(c)

最初、間違えて大きい方を出すように指定しまって、WA出してしまった。
凡ミス注意！
１日少しずつでも解いて、あとを残すこととしよう
Windowsのエクスプローラ回りの小技

# はじめに
Windowsのエクスプローラの使い勝手が好きなので、
よく使う小技を集めてみました。


# エクスプローラ起動系
## ショートカット
**Win + e** 
デフォルトで起動するフォルダが開く

## ショートカット(パスを指定する場合)
**Win + r** で「ファイル名を指定して実行」を起動し、以下のコマンドを実行

```
explorer C:\test
```

タブ補完もないので、あまり実用的ではないかも。

## コマンドプロンプト(PowerShell)から開く
```
explorer <パス>
```

もしくは

```
start <フォルダパス>
```

startの方はファイルを指定してしまうと、規定のプログラムで開いてしまうので注意が必要です。
GitBashからも開けるので、大体開くと思います。


## 同じパスのエクスプローラをもう一枚開く
**Ctrl + n**
エクスプローラが選択されている状態で押すと、同じパスで開かれる。

# エクスプローラ から 起動
## アプリケーションを開く
エクスプローラのアドレスバーで実行可能、
次の例はファイル直下のtext.txtをメモ帳で開きます。

![test.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/131499/d17842a5-3625-ddca-e893-bd65910e0fc5.png)

### コマンドプロンプト(PowerShell)を開く
基本的にパスが通ってれば色々なアプリで開きますが、よく使うため別記
そのまま**cmd**や**powershell**と入力すれば、プロンプトが開きます。
エクスプローラのパスのまま開くのでよく使います。
macでTypeScriptの環境を構築したのでメモ

macでTypeScriptの開発環境を構築したのでメモ。

# node.jsの用意

TypeScriptをインストールするにはnode.jsのnpmを使用するらしい。
[node.js](https://nodejs.org/ja/)とnpmがインストールされているかを確認。

```
$ node -v
v8.10.0
```

```
$ npm -v
5.6.0
```

インストールされていた。

### バージョンが古いのでアップデートしたい
nをインストール

```
$ sudo npm install -g n
```

node.jsを推奨版へアップデート

```
$ sudo n stable
```

npmのアップデート

```
$ sudo npm update -g npm
```

### アップデートされたバージョンの確認

```
$ node -v
v10.16.3

$ npm -v
6.11.2
```

# TypeScriptをインストール

1 適当な場所にディレクトリを作成

```
$ mkdir my-typescript-project
```
2 作成したディレクトリの中で `npm init`を実行
実行したときに色々聞かれる
`package name` と `version` 以外はそのままエンターでも良さそう。
https://techacademy.jp/magazine/16151

```
$ cd my-typescript-project
$ npm init
```

3 ローカルにTypeScriptをインストール

```
$ npm install --save-dev typescript
```

4 `tsconfig.json`を作成

```
$ node_modules/.bin/tsc --init
```

5 作業ディレクトリ（my-typescript-project）直下にtsファイルを作成

```ts:test.ts
export function test() {
    return 'hello wold';
}
```
6 `tsc` コマンドを実行

```
$ node_modules/.bin/tsc
```

7 `my-typescript-project` 内に `test.js` が生成される

```js:test.js
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
function test() {
    return 'hello wold';
}
exports.test = test;

```

# 参考

[TypeScript チュートリアル](https://qiita.com/EBIHARA_kenji/items/31b7c1c62426bdabd263)
[Node.jsとnpmをアップデートする方法](https://parashuto.com/rriver/tools/updating-node-js-and-npm)
atcoder_E-Knapsack2を解いてみた

# 概要
AtCoderの[DPまとめコンテストのE問題](https://atcoder.jp/contests/dp/tasks/dp_e)を解いてみました。
解説は[こちらの記事](https://qiita.com/drken/items/dc53c683d6de8aeacf5a#e-%E5%95%8F%E9%A1%8C---knapsack-2)が分かりやすいと思いますが、いざ自分で実装するとなると中々手が動かせない。。。
そこで、記事の解説を図（手書き(;'∀')）で書いてみました。

#解の方針
以下のように定義して、dpを順に更新していく。
詳しくは[こちらの記事](https://qiita.com/drken/items/dc53c683d6de8aeacf5a#e-%E5%95%8F%E9%A1%8C---knapsack-2)がやはり分かりやすいのでおススメです。

- dp[ i ][ sum_v ] := i-1 番目までの品物から価値が sum_v 以上を達成するように選んだときの、重さの総和の最小値

#イメージ図
さて、解の方針（概念）は分かってけど、いざ実装しようと思ったら手が止まる(;'∀')
そこで少しでも分かりやすくするため図に書いてみた。
![dpcontest_E.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/250830/e08e4a5c-9e01-be88-d283-bfc2efc09603.jpeg)


#コード
上の図を見ながらなんとか実装。。。

```python:E-Knapsack2.py
#E問題
#https://atcoder.jp/contests/dp/tasks/dp_e
import numpy as np
N,W = map(int,input().split())
wvlist = [list(map(int,input().split())) for _ in range(N)]
INF = 10**15
ans = INF

#初期条件
dp = np.full((N+1,N*1000+1),INF)
dp[0][0] = 0

for i in range(N):
    #ここを普通の配列で2重ループで処理するとTLEになる。numpyの機能を使ってすばやく処理。
    dp[i+1][:wvlist[i][1]] = dp[i][:wvlist[i][1]]
    dp[i+1][wvlist[i][1]:] = np.minimum(dp[i][wvlist[i][1]:],dp[i][:-wvlist[i][1]]+wvlist[i][0])
        
for i in range(N*1000+1):
    if W >= dp[N][i]:
        ans = i

print(ans)

```


ちなみに、機能は満たしてるけど性能的にout(TLEになる)のがこちら
2重ループしてるとこが遅い。

```python:E-Knapsack2(TLE).py
#あっているけど、実行時間超過
N,W = map(int,input().split())
#N,W = [3,8]
wvlist = [list(map(int,input().split())) for _ in range(N)]
INF = 10**15
ans = INF
#初期条件
dp = [[INF for _ in range(N*1000+1)] for i in range(N+1)]
#dp = np.full((N+1,N*1000+1),INF)
dp[0][0] = 0

for i in range(N):
    for v in range(N*1000+1):
        if v-wvlist[i][1]>=0:
            dp[i+1][v] = min(dp[i+1][v],dp[i][v-wvlist[i][1]]+wvlist[i][0])
        dp[i+1][v] = min(dp[i+1][v],dp[i][v])
        
for i in range(N*1000+1):
    if W >= dp[N][i]:
        ans = i
        
print(ans)
    
```

以上です。
DPの問題を解くときは、2次元配列の操作が難しくて図を描かないと解けません💦
いつか頭の中でできるようになりたいですねー(´･ω･｀)
[GCP] GCPサービスを勝手にまとめてみた(IoT編)

# GCPって
https://qiita.com/risa0320/items/5f34bc9102e575705274

# サービスの分類
おおまかにはこんな感じ。（一部省略してます）
※2019年8月末時点のもの。
※α版、β版を含む。
https://cloud.google.com/products/?hl=ja よりいろいろ引用してます。

| 分類       |  サービス例    |
|:-----------------|:------------------|
| AIと機械学習   | AutoML,Vision AI,Cloud TPU... |
| API管理 | Apigee Sense,Cloud Healthcare API... |
| コンピューティング | Compute Engine,App Engine,Cloud Functions... |
| データ分析 | BigQuery,Cloud Composer,Cloud Dataflow... |
| データベース | Cloud SQL,Cloud Bigtable,Cloud Spanner... |
| デベロッパーツール | Container Registry,Cloud Build... |
| ハイブリットとマルチクラウド | Anthos,GKE On-Prem... |
| IoT | Cloud IoT Core,Edge TPU |
| 管理ツール | Stackdriver,Monitoring,Private Catalog... |
| メデイアとゲーム | Zync Render,Anvato... |
| 移行 | Cloud Data Transfer,Transfer Application... |
| ネットワーキング | Virtual Private Cloud,Cloud DNS,Cloud NAT... |
| セキュリティ | Cloud Security Scanner,Cloud IAM,Cloud HSM... |
| ストレージ | Cloud Storage,Cloud Firestore... |

# サービスをもう少し深く見てみる
## IoT
### Cloud IoT Core
広範囲に分散したデバイスの接続、管理、データ取り込みを、セキュリティを維持しながら簡単に行うためのフルマネージド サービス
> Cloud IoT Core は、広範囲に分散した多数のデバイスの接続、管理、データ取り込みを、セキュリティを維持しながら簡単に行うことができるフルマネージド サービスです。Cloud IoT Core を Cloud IoT プラットフォーム上のその他のサービスと組み合わせると、IoT データの収集、処理、分析、可視化をリアルタイムで行うために必要なものがすべて揃い、業務の効率化に役立ちます

主要要素は、デバイス マネージャとプロトコル ブリッジの2つ。

<特徴>

* エンドツーエンドのセキュリティ
* フルマネージドでスケーラブル
* 単一のグローバル システム
* 役割レベルのアクセス制御
* すぐに利用できるデータ分析情報
* 大規模なデバイス導入

ML関連サービスと連携できて、すぐに分析できる環境はいい。

### Edge TPU(β版)
エッジで推論を行うために設計された Google の専用 ASIC。
> AI は今日、コンシューマ アプリケーションからエンタープライズ アプリケーションに至るまで広く使用されています。接続デバイスが急激に増加し、プライバシーや機密性保持、低レイテンシ、帯域幅の制約の需要とともに、クラウドでトレーニングした AI モデルをエッジで実行することがますます必要になっています。Edge TPU は AI をエッジで実行する目的に特化して Google が設計した専用 ASIC です。小さく低消費電力のフットプリントで高いパフォーマンスを実現し、高精度の AI をエッジにデプロイできます。

<特徴>

* 型
    * 推論アクセラレータ
* パフォーマンス例
    * Edge TPU では電力効率の良い方法を使い、高解像度の動画上でフレームごとに複数の最先端の AI モデルを 30 フレーム/秒で同時に実行できます。
* 数値
    * nt8、Int16
* IOインターフェース
    * PCIe、USB
[GCP] GCPサービスを勝手にまとめてみた(ハイブリットとマルチクラウド編)

# GCPって
https://qiita.com/risa0320/items/5f34bc9102e575705274

# サービスの分類
おおまかにはこんな感じ。（一部省略してます）
※2019年8月末時点のもの。
※α版、β版を含む。
https://cloud.google.com/products/?hl=ja よりいろいろ引用してます。

| 分類       |  サービス例    |
|:-----------------|:------------------|
| AIと機械学習   | AutoML,Vision AI,Cloud TPU... |
| API管理 | Apigee Sense,Cloud Healthcare API... |
| コンピューティング | Compute Engine,App Engine,Cloud Functions... |
| データ分析 | BigQuery,Cloud Composer,Cloud Dataflow... |
| データベース | Cloud SQL,Cloud Bigtable,Cloud Spanner... |
| デベロッパーツール | Container Registry,Cloud Build... |
| ハイブリットとマルチクラウド | Anthos,GKE On-Prem... |
| IoT | Cloud IoT Core,Edge TPU |
| 管理ツール | Stackdriver,Monitoring,Private Catalog... |
| メデイアとゲーム | Zync Render,Anvato... |
| 移行 | Cloud Data Transfer,Transfer Application... |
| ネットワーキング | Virtual Private Cloud,Cloud DNS,Cloud NAT... |
| セキュリティ | Cloud Security Scanner,Cloud IAM,Cloud HSM... |
| ストレージ | Cloud Storage,Cloud Firestore... |

# サービスをもう少し深く見てみる
## ハイブリットとマルチクラウド
### Anthos
最新のハイブリッド アプリケーションをさまざまな環境で構築、管理できます。
> Anthos を使用すると、既存のオンプレミスの資産やパブリック クラウド上で最新のハイブリッド アプリケーションをビルドし、管理できるようになります。Anthos は Google が開発したオープンソース テクノロジー（Kubernetes、Istio、Knative など）を利用して構築され、オンプレミス環境とクラウド環境の間の整合性を実現します。Anthos を利用することで、アプリケーションの開発を迅速化し、サービス メッシュ、コンテナ、マイクロサービスなどの変革的テクノロジーを必要とするビジネス運営を戦略的に実現できます。

<利点>

* モダナイゼーション
* 移行とモダナイゼーション
* ポリシーとセキュリティを大規模に自動化する
* 一貫性のある体験

オンプレであろうとクラウド上であろうと、アプリケーションを管理し、それらの環境の間を取り持ってくれる。

### Istio on GKE(β版)
Istio on GKE アドオンを使用して Kubernetes Engine に Istio をインストールします。
> 
フィードバックを送信
GCPのIstio
GKEのIstio


は、
ベータ版です。
これは、Istio on GKEのベータ版リリースです。このプロダクトは下位互換性のない方法で変更される可能性があり、とは、SLAまたは非推奨ポリシーの対象ではありません。

Istio on GKEは、GKEのアドオンであり、Istioサービスメッシュの作成と実行に必要なすべてのコンポーネントを含むクラスターを1ステップですばやく作成できます。インストールすると、Istioコントロールプレーンコンポーネントは自動的に最新の状態に保たれるため、新しいバージョンへのアップグレードについて心配する必要はありません。アドオンを使用して、既存のクラスターにIstioをインストールすることもできます。

### Anthos Config Management
ハイブリッドの Kubernetes Deployment でポリシー運用とセキュリティ対策を大規模に自動化できます。
> Anthos Config Management は Anthos の重要なコンポーネントです。迅速かつセキュアなアプリケーション開発は、ハイブリッドなコンテナ環境で業務を行う管理者にとって、容易なことではありません。Anthos Config Management を使用すれば、オンプレミスとクラウドの両方で Kubernetes クラスタに適用されるすべての管理ポリシーに共通する構成を作成できます。Anthos Config Management は、望ましい状態が常に反映されるよう、変更点を評価し、すべてのクラスタに展開します。

<特徴>

* 構成の定義
* 構成の適用
* 検証
* 共通の構成フォーマット
* ソース管理のように構成を管理
* 名前空間を認識
* アクティブなモニタリング

### Traffic Director(β版)
エンタープライズに対応したオープン サービス メッシュ用トラフィック管理。
> サービス メッシュは強力な抽象的概念で、マイクロサービスや最新アプリケーションの提供において普及しつつあります。サービス メッシュでは、サービス メッシュ データ プレーンおよびサービス プロキシ（Envoy など）がトラフィックを移動し、サービス メッシュ コントロール プレーンがポリシー、構成、情報をこれらのサービス プロキシに提供します。Traffic Director は、GCP で提供される、フルマネージドのサービス メッシュ用トラフィック コントロール プレーンです。Traffic Director を使用すると、複数のリージョンのさまざまなクラスタや VM インスタンスでのグローバルな負荷分散のデプロイ、サービス プロキシからのヘルスチェックのオフロード、高度なトラフィック制御ポリシーの構成を簡単に行うことができます。Traffic Director はオープン xDSv2 API を使用してデータプレーン内のサービス プロキシと通信するため、専用インターフェースに縛られません。

<特徴>

* オープン サービス プロキシのトラフィック管理
* VM とコンテナの操作
* グローバルな負荷分散
* 大規模なヘルスチェック
* リクエスト ルーティングとリッチ トラフィックのポリシーを適用したトラフィック コントロール(α版)
* サービスのインテリジェントかつ高速な自動スケーリング

このサービスのバックエンドではどんなシステムが動作して、実現されているのかを考えると面白そう。
[GCP] GCPサービスを勝手にまとめてみた(データベース編)

# GCPって
https://qiita.com/risa0320/items/5f34bc9102e575705274

# サービスの分類
おおまかにはこんな感じ。（一部省略してます）
※2019年8月末時点のもの。
※α版、β版を含む。
https://cloud.google.com/products/?hl=ja よりいろいろ引用してます。

| 分類       |  サービス例    |
|:-----------------|:------------------|
| AIと機械学習   | AutoML,Vision AI,Cloud TPU... |
| API管理 | Apigee Sense,Cloud Healthcare API... |
| コンピューティング | Compute Engine,App Engine,Cloud Functions... |
| データ分析 | BigQuery,Cloud Composer,Cloud Dataflow... |
| データベース | Cloud SQL,Cloud Bigtable,Cloud Spanner... |
| デベロッパーツール | Container Registry,Cloud Build... |
| ハイブリットとマルチクラウド | Anthos,GKE On-Prem... |
| IoT | Cloud IoT Core,Edge TPU |
| 管理ツール | Stackdriver,Monitoring,Private Catalog... |
| メデイアとゲーム | Zync Render,Anvato... |
| 移行 | Cloud Data Transfer,Transfer Application... |
| ネットワーキング | Virtual Private Cloud,Cloud DNS,Cloud NAT... |
| セキュリティ | Cloud Security Scanner,Cloud IAM,Cloud HSM... |
| ストレージ | Cloud Storage,Cloud Firestore... |

# サービスをもう少し深く見てみる
## データベース
### Cloud SQL
MySQL、PostgreSQL、SQL Server のデータベース サービス。
> Cloud SQL は、クラウド上の PostgreSQL、MySQL、SQL Server のリレーショナル データベースの設定、メンテナンス、運用、管理を簡単にできるようにするフルマネージド データベース サービスです。Cloud SQL は高パフォーマンス、スケーラビリティ、利便性を提供します。また、Google Cloud Platform 上にホストされるので、場所を問わずアプリケーションを実行できるデータベース インフラストラクチャの構築が可能です。

AWSでいうRDS。

<機能>

* スケーラビリティ
* 高パフォーマンス
* 統合
* 高可用性の確保
* フルマネージド
* 標準API
* セキュリティ
* パートナーシップと統合

### Cloud Spanner
水平スケーリング可能で高い整合性を備えた、初のリレーショナル データベース サービス
> Cloud Spanner は、エンタープライズ クラスで唯一、グローバルに分散され、強整合性を備えたデータベース サービスです。リレーショナル データベースの構造と非リレーショナル データベースの水平スケーラビリティを兼ね備え、クラウドに特化した設計となっています。2 種類のデータベースの特性を組み合わせることにより、業界最高水準となる 99.999% の可用性 SLA、計画的ダウンタイムの排除、エンタープライズ クラスのセキュリティに加え、高性能のトランザクションと、行、リージョン、大陸をまたぐ強整合性が実現します。Cloud Spanner によりデータベースの管理は大きく変わり、効率的なアプリケーション開発が可能になります。

<機能>

* グローバルなスケーラビリティ
* 多言語対応
* フルマネージド
* トランザクションの整合性
* リレーショナル セマンティクス
* エンタープライズ クラスのセキュリティ
* 高可用性

### Cloud Memorystore
フルマネージドの Redis 向けインメモリ データストア サービス
> Cloud Memorystore for Redis は、Google が管理する、スケーラブルで安全かつ可用性の高いインフラストラクチャ上に構築された、フルマネージドのインメモリ データストア サービスです。Cloud Memorystore を使用すると、ミリ秒以下のデータアクセスを実現するアプリケーション キャッシュをビルドできます。Cloud Memorystore は Redis プロトコルに対応しているため、コードを変更することなく簡単に移行できます。

いいなと思ったけどRedis向け。

### Cloud Firestore
モバイルアプリとウェブアプリのデータ向けの NoSQL ドキュメント データベース。
> Cloud Firestoreは、高速で完全に管理されたサーバーレスのクラウドネイティブNoSQLドキュメントデータベースであり、モバイル、Web、IoTアプリのデータをグローバル規模で保存、同期、クエリすることを簡素化します。クライアントライブラリはライブ同期とオフラインサポートを提供し、そのセキュリティ機能とFirebaseおよびGoogle Cloud Platform（GCP）との統合により、真のサーバーレスアプリの構築が加速されます。

<特徴>

* セキュリティ
* データストアモード
* 自動アップグレード
* ACIDトランザクション
* マルチリージョンレプリケーション
* 強力なクエリエンジン
* クラウドネイティブアプリケーション向けに構築
プログラミングスクールを3ヶ月通学しての感想

#初めに
この記事はプログラミングスクールに行くか迷っている人に向けての記事になります。

2019年5月からの8月の3ヶ月間、渋谷にある某プログラミングスクールにて学習しました。
そこで感じたことや、学習内容を簡単に残したいと思います。

ここでは、通ったプログラミングスクールをD社とします。

#D社のプログラミングスクールに決めた理由
私は２社のプログラミングスクールのどちらに行くか悩んでいました。（どちらも渋谷にあるスクールです）
##面談
スクールを受講するには事前に、面談する必要があったのでA社とB社それぞれ行きました。
**T社**・・・教室は大きく受講生も多い。しかし、メンターが不足している様に感じた。（たまたまいなかっただけかも...）
         教室に来ないといけない時間が決まっている。朝礼、夕礼がある。
         受講生同士でアウトプットを行い、理解度を深める時間がある。
         
**D社**・・・教室は広くはないが、受講生もT社ほどはいない。
         待機メンターが多く感じた。
         月ごとにスクールでの学習時間が決められている。
この様な違いがありました。

##金額
どちらとも安いとは言えない金額です。
D社は最近値上げをした様ですね。

どちらも、返金制度があります。
条件は違いますが、合わないと感じれば無傷でリタイアすることも可能です。

##選考
T社は選考があるという記事がちらほらありますが、現在は廃止されているそうです。(案内出来る就職先が増えた為）
D社は選考がありました。WEBで30問30分の問題を解かなければいけません（記憶は曖昧です）
結果は分かりませんが、そこまで気合いを入れる物でもないかと感じました。（全然できなかったから...）

##学習内容
基本的には同じです。
HTML、CSS、RubyOnRails、DB、AWS、github等です。
D社は、１ヶ月目に基礎学習、２ヶ月目にチーム開発、３ヶ月目に個人開発を行います。
T社は１ヶ月目に基礎学習、２ヶ月目に個人開発、３ヶ月目にチーム開発を行います。


##決めた理由
ほぼ同じ内容なので、どちらに行っても同じかとは思いましたが以下のことを考慮しD社にしました。
・金銭面（T社に比べて１０万円ほど安かった）
・メンターの多さ
・D社のネームバリュー


#1ヶ月目
##学習内容
javascript、AWS等も学習しますが、主にHTML、CSS、RubyOnRailsについて学習します。
1ヶ月の間で３つの課題があり、それ全てに合格しないと2ヶ月目には進めません。
###1つ目の課題
HTML、 CSSで作成されたviewをレスポンシブ対応させることが一つ目の課題です。
内容自体はそこまで難しくありません。
しかし、何をしろと明確に記載されていないので、何が課題なのか見極めなければなりません。笑
###2つ目の課題
RubyOnRailsを使用した本の投稿サイトを作ります。
この辺りからだんだん難しくなります。
また、スクールの教材にはないことを自分で調べてやらなくてはいけなくなります。
###3つ目の課題
2つ目の課題の進化版に作成します。本の投稿だけでは無く、ユーザの登録も行わなけばいけません。
私は、初めは全く理解できず非常に苦しみました。（課題提出もギリギリ...）
###1ヶ月目の感想
基本的には月生は２０人ほどと聞いていたのですが、私の月は30人以上いました。
なので、メンターに質問待ちの時間で発生することが度々ありました。

#2ヶ月目
##学習内容
チームメンバーは4人で1ヶ月間チーム開発をし月の最後に発表をします。
チーム開発は、最低限実装しないといけないことがお題としてあります。それにプラスαして機能を実装しても大丈夫です。
案件定義、アプリの設計（DB、フレームワーク等）、実装、発表準備まで全部チームでやります。
###2ヶ月目の感想
やる事なす事全部初めてです。なので、大変苦労します。
特にDB関係の設計にはとても苦労しました。
実装に関しても基本的にやった事ないことばかりなので、エラーの連続で心が折れそうになります。
しかし、実務に近い環境で学習出来るので非常にいい経験になります。

#3ヶ月目
自作のアプリケーションを作成し、デプロイまで行います。（就活時にポートフォリオとして使用）
スクール側から大まかな機能一覧とそれぞれの難易度が分かる資料が渡されます。
どの機能を実装するかは人それぞれです。
十人十色なので、メンターに質問しても望んでいる回答が帰ってくるかは完全に運です。笑
###3ヶ月目の感想
自作のアプリケーションなので、やっていて非常に楽しかったです。
私はリアルタイムでのチャット機能を持つアプリケーションを作成しました。
結果、非常に後悔するほど難しかったです。

スクールからのデプロイに関する資料に、リアルタイムでのチャット機能を実装した際のデプロイ記事が記載されていませんでした。
なので、非常に苦労することになりました。
ですが、メンターの中には外部メンター（フリーランス）がいるのでその方々に聞けばスムーズに進む場合があります。
しかし、外部メンターがいつ出勤されるか分からないので、運次第になるかもしれません。


#全体の感想
##良かった点
1.　質問できる相手がいることで、挫折することが無い。
2.　実務に近い経験が出来る。
3.　エラーを解決して貰えるだけでは無く、現象、解決方法を教えてもらえる。
4.　外部メンターから実務経験を聞ける
5.　息抜きにお菓子がある

##不満点
1.　メンターによって知識量が違うので、聞いても回答がもらえないことがある（６月に質問し、後で教えると言われたがまだ回答を貰えていない笑）
2.　日によってスクールにいる受講生が違うの、メンターに質問できないことが度々あった
3.　教材内容が分かりやすいとは言えない内容だった（自分で調べて自走力を養わせてるかもしれません）
4.　たまにwifiが使い物にならない位遅くなることがある

#最後に
決して安い値段ではありませんでしたが、悪い買い物だとは思いませんでした。
最近は各社とも金額が高騰する傾向にあるようです。
悩んでいる人がいるなら、ぜひ面談に行くことをお勧めします。（面談に行っても強制させるようは話し方は一切ありませんでした。)
『百聞は一見にしかず』

私は転職コースなので、現在就活中です。
就活が終了したらまた、就活に関する記事を投稿したいと思います。

長々とお付き合いありがとうございました。
RailsのテンプレートエンジンSlimにbootstrapのtableを適用させる

Slimにbootstrapのtableを使いたいときに、書き方がよく分からず、試行錯誤しました。
thのあとのscopeはそのまま書く感じでした。

```ruby:app/views/blogs/index.html.slim
table.table.table-borderless.table-dark
  thead
    tr
      th scope="col" id
      th scope="col" title
      th scope="col" article
    tbody
      - @blogs.each do |blog|
        tr
          td = blog.id
          td = blog.title
          td = blog.article
```

大変参考にさせていただきました。
[Slim入門をして書き方を練習をしました]
(https://qiita.com/pugiemonn/items/b64171952d958dc4d6be)

[Bootstrap
Bordered table]
(https://getbootstrap.com/docs/4.3/content/tables/#bordered-table)
【RubyonRails入門】Railsで作成したアプリケーションを、Herokuにデプロイする手順

##1.アプリケーションをはじめてデプロイするときにすること
忘備録です。

####1-0. Herokuを登録する
ここでは省略させていただきます。

####1-1. Herokuにログインする

```
$ heroku login --interactive
```
ここでメールアドレスとパスワードを入力します。

####1-2. Gemfileを編集、インストールする
#####1-2-1. なぜGemfileを編集するのか？
開発環境と本番環境で、使う必要があるパッケージが若干違うから。
現在開発環境で使用しているパッケージ(`gem 'sqlite3'`)を、本番間環境(ここではHeroku)用(`gem 'pg'`)に書き換える。

```ruby:Gemfile
# production(製品版の環境/本番環境)で、pgというパッケージを使用する。
group :production do
  gem 'pg'
end

# sqlite3は、development(開発環境)用に移動させる。
group :development do
　# ~~~~~(略)~~~~~
  gem 'sqlite3'
　# ~~~~~(略)~~~~~
end
# ~~~~~(略)~~~~~
```
【用語確認】
・Gem = Rubyのパッケージ
・Gemfile = Rubyのパッケージ一覧


```
$ bundle --without production
```
現在は開発環境で作業をしているので、production以外のパッケージをインストールします。

####1-3. Gitの初期化

```
$ git init
```
バージョン管理システムで、最新版をHerokuにアップロードしていきます。

####1-4. Heroku上にアプリケーションを作成する

```
$ heroku create test001
Creating ⬢ test001... done
https://test001.herokuapp.com/ | https://git.heroku.com/test001.git
```
test001(=URLにもなる) の部分は、他の人とかぶると作成できないので、アプリ名が被らないように、自分の好きな名前で作成します。


##2. 再デプロイの際に毎回すること
####2-1. Gitをステージング、コミットする

```
$ git add *
$ git commit -m "initial commit"
```

####2-2. Herokuにpushする

```
$ git push heroku master
```

####2-3. Heroku上でマイグレーションをする

```
$ heroku run rails db:migrate
```

####2-4. Heroku上でdb:seedをする

```
$ heroku run rails db:seed
```
seeds.rbファイルから、データをHeroku上で生成します。
 
####2-5. Herokuにアップされているかどうか確認する

```
$ heroku open
 ▸    Error opening web browser.
 ▸    Error: Exited with code 3
 ▸    
 ▸    Manually visit https://test001.herokuapp.com/
 ▸    in your browser.
```
表示されたURLアクセスすると、デプロイされたサイトを確認することができます。
JavaScript | 分割代入 (配列, オブジェクト)

分割代入ってなんじゃらほい

> 分割代入 (Destructuring assignment) 構文は、配列から値を取り出して、あるいはオブジェクトからプロパティを取り出して別個の変数に代入することを可能にする JavaScript の式です。

https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment

OK！！めっちゃ便利そうなコンセプトだから例を作りながらチェックしてゆく
まずはobjっていうオブジェクトを用意します

```js
const obj = { x: 1, y: 2 };
```
objのプロパティを取り出して別個の変数に代入する...
ぱっと思いつくのはこんなやつ

```js

let x_ = obj.x;
let y_ = obj.y;

console.log(x_);
console.log(y_):

// 期待する出力結果
// 1
// 2
```

もっとシンプルな書き方があるらしい

```js

let { x: x_, y: y_ } = obj;

console.log(x_);
console.log(y_);

// 期待する出力結果
// 1
// 2
```

もし代入したい変数の名前をオブジェクトのプロパティと同じにしたいなら、もっと簡単な書き方があるらしい

```js
let { x, y } = obj;

console.log(x)
console.log(y)

// 期待する出力結果
// 1
// 2
```
***
##### 配列の場合

```js
const arr = [1, 2];

let [x, y] = arr;

console.log(x)
console.log(y)

// 期待する出力結果
// 1
// 2
```

単純にxだけy無しで定義してみる
そうすると一番最初の値がきちんと取れる

```js
const arr = [1, 2];

let [x] = arr;

console.log(x)

// 期待する出力結果
// 1
```

## 参考にしたい記事

* [《JavaScript》ES6の分割代入のはじめかた。](
https://qiita.com/uto-usui/items/a9d17447fe81c17c41fa)
How to list and filter related column on Laravel-Admin


I'll try to get question table value from answer table this time.

# Code

```sql
CREATE TABLE `questions` (
  `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
  `content` varchar(191) COLLATE utf8mb4_unicode_ci NOT NULL,
  `created_at` timestamp NULL DEFAULT NULL,
  `updated_at` timestamp NULL DEFAULT NULL,
  PRIMARY KEY (`id`),
);

 CREATE TABLE `answers` (
  `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
  `question_id` int(11) NOT NULL,
  `answer` int(11) NOT NULL,
  `created_at` timestamp NULL DEFAULT NULL,
  `updated_at` timestamp NULL DEFAULT NULL,
  PRIMARY KEY (`id`),
);
```

```php:app/Models/Answer.php
    public function question(){
        return $this->belongsTo(Question::class);
    }
```

```php:app/Admin/Controllers/AnswerController.php
    protected function grid()                                                      
    {
        $grid = new Grid(new Answer); 
        $grid->column('id', __('Id'))->filter();
        $grid->column('question.content', __('question')); // Here is the point.
        $grid->column('created_at', __('Created at'));
                             
        $grid->filter(function($filter){
            $filter->equal('question.content');
        });

        return $grid;                                                              
    }                                                                              
         
```

# Reference
[One to one](https://laravel-admin.org/docs/#/en/model-grid?id=relation)
[Model grid filters](https://laravel-admin.org/docs/#/en/model-grid-filters)
【SQL ZOO 解答集】(1 SELECT name)

##本投稿の目的
- sql学習サイト[**sqlzoo**](https://sqlzoo.net/wiki/SQL_Tutorial)を用いたsqlの学習と理解
- 学習のアウトプット
- 学習メモとして、かつ公式の解答ページがなかったので作成した。

[0 SELECT basics](https://sqlzoo.net/wiki/SELECT_basics)
[1 SELECT name（このページ）](https://sqlzoo.net/wiki/SELECT_names)
[2 SELECT from World](https://sqlzoo.net/wiki/SELECT_from_WORLD_Tutorial)
[3 SELECT from Nobel](https://sqlzoo.net/wiki/SELECT_from_Nobel_Tutorial)
[4 SELECT within SELECT](https://sqlzoo.net/wiki/SELECT_within_SELECT_Tutorial)
[5 SUM and COUNT](https://sqlzoo.net/wiki/SUM_and_COUNT)
[6 JOIN](https://sqlzoo.net/wiki/The_JOIN_operation)
[7 More JOIN operations](https://sqlzoo.net/wiki/More_JOIN_operations)
[8 Using Null](https://sqlzoo.net/wiki/Using_Null)
[8+ Numeric Examples](https://sqlzoo.net/wiki/NSS_Tutorial)
[9 Self join](https://sqlzoo.net/wiki/Self_join)

####[1 SELECT name](https://sqlzoo.net/wiki/SELECT_names)
####問題1
#####Yで始まる国を探す
```sql
SELECT name 
FROM world
WHERE name 
LIKE 'Y%';
```

####問題2
#####yで終わる国を見つける
```sql
SELECT name 
FROM world
WHERE name 
LIKE '%y';
```

####問題3
#####文字xを含む国を見つける
```sql
SELECT name 
FROM world
WHERE name 
LIKE '%x%';
```

####問題4
#####Iceland, Switzerlandなど、最後がlandの国を見つける
```sql
SELECT name 
FROM world
WHERE name 
LIKE '%land';
```
####問題5
#####Cで始まりiaで終わる国を見つける
```sql
SELECT name 
FROM world
WHERE name 
LIKE 'C%ia';
```

####問題6
#####名前に2つoがある国を探す

```sql
SELECT name 
FROM world
WHERE name 
LIKE '%oo%';
```

####問題7
#####名前に3つ以上のaがある国を見つける

```sql
SELECT name 
FROM world
WHERE name 
LIKE '%a%a%a%';
```
####問題8
#####2番目の文字が「t」である国を検索する

```sql
SELECT name 
FROM world
WHERE name LIKE '_t%'
ORDER BY name;
```
####問題9
#####2つの「o」が区切られている国を検索する。

```sql
SELECT name 
FROM world
WHERE name LIKE '%o__o%'
ORDER BY name;
```
####問題10
#####4文字の国を見つける。

```sql
SELECT name 
FROM world
WHERE name 
LIKE '____';
```
####問題11
#####ルクセンブルクの首都はルクセンブルクである。首都が国の名前と同じすべての国を表示する
#####国名と首都が同じ国を探す。

```sql
SELECT name
FROM world
WHERE name = capital;
```

####問題12
#####首都名が「国＋City」の国を探す

```sql
SELECT name
FROM world
WHERE capital=concat(name,' City');
```
####問題13
#####

```sql
SELECT name 
FROM world
WHERE name LIKE '_t%'
ORDER BY name;
```

####問題14
#####首都と国名を探す。（首都名が国名を拡張している場合）
- 検索結果にはMexico よりも長くなったMexico Cityを含める。
- Luxembourg は首都と国名が同じなので含めない。


```sql
#解答1
SELECT capital,name
FROM world 
WHERE capital 
LIKE concat('%',name,'%') AND name<>capital;

#解答2
SELECT capital,name
FROM world
WHERE capital 
LIKE concat(name, '%') AND name<>capital;

```

####問題15
#####国名と首都の拡張部分を探す。例）Monaco-Ville の国名は Monaco で、拡張部分は -Ville
- SQL の関数 MIDとLENGTH を使う。


```sql
#解答1
SELECT name, REPLACE(capital, name, '') as ext
FROM world
WHERE capital 
LIKE CONCAT(name, '_%');

#解答2
SELECT name,RIGHT(capital,LENGTH(capital)-LENGTH(name)) as ext
FROM world 
WHERE capital 
LIKE concat(name,'%') AND name<>capital

#解答3
SELECT name,SUBSTRING(capital,LENGTH(name)+1) as ext
FROM world
WHERE capital LIKE concat(name, '%')
AND capital <> name

```
前回
[0 SELECT basics](https://qiita.com/m_masashi/items/b48bc05948bba27cc06e)
次回
[2 SELECT from World](https://qiita.com/m_masashi/items/140b130eef5c62f0e46f)
Webスクレイピング


HTMLから`table`タグの内容を取得する。
日経平均株価の一覧を取得してみる。
https://stocks.finance.yahoo.co.jp/stocks/history/?code=998407.O
`selector`のパラメータはChrome Developer Toolsを使用して取得。

# C\# 

[AngleSharp](https://anglesharp.github.io/)を使用。

```c#
public static void Main(string[] args)
{
    string url = "https://stocks.finance.yahoo.co.jp/stocks/history/?code=998407.O";
    HttpClient client = new HttpClient();
    var t = client.GetStringAsync(url);
    string source = t.Result;

    var parser = new HtmlParser();
    var doc = parser.ParseDocument(source);
    var table = doc.QuerySelector("#main > div.padT12.marB10.clearFix > table");
    var trs = table.GetElementsByTagName("tr");
    foreach (var tr in trs)
    {
        var tds = tr.GetElementsByTagName("td");
        if (tds.Count() == 0) continue;
        var ymd = DateTime.Parse(tds.ElementAt(0).TextContent).ToString("yyyy/MM/dd");
        Console.Write("{0}", ymd);
        for (int i = 1; i < tds.Count(); i++)
        {
            var num = double.Parse(tds.ElementAt(i).TextContent, NumberStyles.Any);
            Console.Write(",{0}", num);
        }
        Console.WriteLine();
    }
}
```

```
2019/08/23,20579.98,20719.31,20579.98,20710.91
2019/08/22,20706.07,20731.19,20584.29,20628.01
2019/08/21,20489.97,20626.05,20482.62,20618.57
2019/08/20,20605.35,20684.06,20582.01,20677.22
2019/08/19,20590.47,20633.9,20502.66,20563.16
2019/08/16,20323.97,20465.71,20300.35,20418.81
2019/08/15,20324.25,20419.88,20184.85,20405.65
2019/08/14,20669.99,20697.42,20581.17,20655.13
2019/08/13,20432.68,20503.38,20369.27,20455.44
2019/08/09,20758.15,20782.06,20676.92,20684.82
2019/08/08,20529.29,20682.24,20462.98,20593.35
2019/08/07,20548.07,20570.19,20406.52,20516.56
2019/08/06,20325.52,20607.83,20110.76,20585.31
2019/08/05,20909.98,20941.83,20514.19,20720.29
2019/08/02,21211.06,21211.06,20960.09,21087.16
2019/08/01,21361.58,21556.69,21288.9,21540.99
2019/07/31,21526.38,21589.11,21476.07,21521.53
2019/07/30,21681.82,21792.98,21665.86,21709.31
2019/07/29,21627.55,21652.95,21518.7,21616.8
2019/07/26,21700.2,21709.74,21590.66,21658.15
```


# Python

[BeautifulSoup](https://www.crummy.com/software/BeautifulSoup/bs4/doc/)を使用。

```python
import requests
from bs4 import BeautifulSoup
import datetime

url = "https://stocks.finance.yahoo.co.jp/stocks/history/?code=998407.O"
source = requests.get(url)
doc = BeautifulSoup(source.text, 'html.parser')
table = doc.select_one("#main > div.padT12.marB10.clearFix > table")
trs = table.findAll('tr')
for tr in trs:
    tds = tr.findAll('td')
    if len(tds) == 0:
        continue
    ymd = datetime.datetime.strptime(tds[0].get_text(), '%Y年%m月%d日').strftime('%Y/%m/%d')
    values = [ymd]
    for i in range(1, len(tds)):
        num = float(tds[i].get_text().replace(',',''))
        values.append(num)
    print(','.join(map(str,values)))
```

# 参考情報

- [【C#】AngleSharpの使い方メモ](https://qiita.com/NekozeDaisensei/items/c74f71e5d79d6de05841)
- [Beautiful Soup での スクレイピング基礎まとめ [初学者向け]](https://qiita.com/U-MA/items/896c49d46585e32ff7b1)
ReactNative(Expo)でFirebase Storageに画像をアップロードする方法

## はじめに
ExpoでFirebaseを使用する場合、Web版のFirebaseを使用することになると思います。ここで、FirebaseStorageに画像をアップロードする際にいくつもの罠があり、筆者は二日以上溶かしてしまいました。具体的には以下のような罠がありました。

1. reactnativeがatob関数に対応していないためstorageが使えない
2. storageにbase64エンコード画像をアップロードしたがうまく表示されない

以上の二点に関して、具体的に説明していきます。

## 1. ImageFormを作成する

~~~
class ImageForm extends React.Component {
    constructor(props) {
        super(props)
}

    componentDidMount() {
        this.getPermissionAsync();
      }

    getPermissionAsync = async () => {
        if (Constants.platform.ios) {
          const { status } = await Permissions.askAsync(Permissions.CAMERA_ROLL);
          if (status !== 'granted') {
            alert('Sorry, we need camera roll permissions to make this work!');
          }
        }
      }

      _pickImage = async () => {
        let result = await ImagePicker.launchImageLibraryAsync({
          mediaTypes: ImagePicker.MediaTypeOptions.All,
          allowsEditing: true,
          aspect: [4, 3],
          base64: true,
          quality: 0.5
        });
    
        console.log(result);
    
        if (!result.cancelled) {
            var uris = this.props.uris
            const uri = result.uri
            uris.push(uri)
　　　　　　　// 
        }
      };

    
      render() {
    
        return (
          <View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
          <Text >{this.props.title}</Text>
            <Button
              title="Pick an image from camera roll"
              onPress={this._pickImage}
            />
            
          </View>
        );
      }
    }
~~~

iphoneで使用できるようにするため、getPermissionAsyncをする必要があります。
Buttonを押すと画像をPickすることができ、そのURLをurlsに格納しています。
このurlsをprops等に保存しといてください。

## 2. firebase storage に画像をアップデート
筆者はredux-sagaとredux-saga-firebaseを使って非同期処理を行なっています。流れとしては、pickした際の画像uriから画像データをfetchしてblobデータを取得。それをアップロードします。

~~~
function fetchImage(fileData){
    return fetch(fileData)
    .then(results => {
        const blob = results._bodyBlob;
        return blob
    })
    .catch(error => {
        console.log("error" , error)
    })
}

export function* uploadImageToStorage({uris}){ 
    var filePath = "/image300"
    const uri = uris[0]
    const blob = yield call(fetchImage, uri)
    const metadata = {contentType: "image/jpeg"}
    yield call(storage.uploadFile, filePath, blob, metadata)
~~~

以上のソースコードをsaga内に置くことでできるようになります。
<img width="336" alt="スクリーンショット 2019-08-25 19.38.30.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/251551/ae52f56c-5372-8b26-9abc-66b25dbeb752.png">

## 発生する罠・エラー
### atob関数に対応していない
[base-64]ライブラリをインストールしてnode-moduleに直接書き込みます

~~~
npm install -s base-64
~~~

/node-modules/redux-saga-firebase/storage.js
~~~
const atob = require('base-64').decode;
window.atob = atob;
~~~

### putStringやuploadStringでbase64を直接アップロードしたが、base64とフォーマットが違う、もしくはプレビューが表示されない

ここでかなり時間をつかいました。一番の対応策はbase64を直接アップロードするのではなく、Blob型にしてアップロードすることだとおもいます。上のやり方でできるとおもうのでやってみてください。

#### 参考URL
http://sys1yagi.hatenablog.com/entry/2017/03/26/223143
MAC AWS-CLIのインストール

# インストールしたのに見つからないと言われる

この手順に沿って、インストールしたのに見つからないと言われる
https://docs.aws.amazon.com/ja_jp/cli/latest/userguide/cli-chap-install.html

## インストール
```console
$ pip3 install awscli --upgrade --user

中略

Installing collected packages: docutils, pyasn1, rsa, colorama, PyYAML, jmespath, six, python-dateutil, urllib3, botocore, s3transfer, awscli
  WARNING: The scripts pyrsa-decrypt, pyrsa-decrypt-bigfile, pyrsa-encrypt, pyrsa-encrypt-bigfile, pyrsa-keygen, pyrsa-priv2pub, pyrsa-sign and pyrsa-verify are installed in '/Users/kshimadutsu/Library/Python/3.7/bin' which is not on PATH.
  Consider adding this directory to PATH or, if you prefer to suppress this warning, use --no-warn-script-location.
Successfully installed PyYAML-5.1.2 awscli-1.16.225 botocore-1.12.215 colorama-0.3.9 docutils-0.15.2 jmespath-0.9.4 pyasn1-0.4.6 python-dateutil-2.8.0 rsa-3.4.2 s3transfer-0.2.1 six-1.12.0 urllib3-1.25.3
```

## 確認
```console
$ aws --version
-bash: aws: command not found
```

## PATHが通ってない模様
https://qiita.com/mokuo/items/0484feefbaddb70a9b06

> pip で --user をつけると .local 以下にインストールされる

と記載があるが、私の環境がpipのバージョンが違うため、 `~/.local/bin` が存在していない

## どこにインストールされているか確認

```console
$ pip3 show -f awscli
Name: awscli
Version: 1.16.225
Summary: Universal Command Line Environment for AWS.
Home-page: http://aws.amazon.com/cli/
Author: Amazon Web Services
Author-email: UNKNOWN
License: Apache License 2.0
Location: /Users/{username}/Library/Python/3.7/lib/python/site-packages
Requires: PyYAML, docutils, s3transfer, botocore, rsa, colorama
Required-by: 
Files:
  ../../../bin/aws
  ../../../bin/aws.cmd
  ../../../bin/aws_bash_completer
  ../../../bin/aws_completer
  ../../../bin/aws_zsh_completer.sh
  awscli-1.16.225.dist-info/DESCRIPTION.rst

中略

  awscli/topictags.py
  awscli/utils.py
```

pythonのパッケージは、 `/Users/{username}/Library/Python/3.7/lib/python/site-packages` で、実行ファイルがそのパッケージの場所から、 `../../../bin/aws` となっているから `~/Library/Python/3.7/bin/aws` 

# 結論
以下の追記する

```bash:~/.bash_profile
export PATH=~/Library/Python/3.7/bin:$PATH
```
Jupyter notebookでC/C++をインタプリタ的に使う方法

# Jupyter notebookでC/C++をインタプリタで使う方法

今回はタイトル通り普段コンパイルして使用するC/C++をインタプリタとして使用する方法を書きます。<br>
環境はMacで行なってます。また、Python3を使用してインストールしてます。



# はじめに
C/C++をインタプリタとして使うために、今回はスイスの加速器実験施設のCERNが開発している素粒子・原子核実験等でよく使われるROOTという解析ソフトを利用します。

このROOTを普段研究で使っていて、Jupyternotebookを使用して使えると教えてもらって今回は使う手順を書いてみます。

僕もつい3日前くらいに知ったのであまり詳しく知らないですが、どうもJupyROOTカーネルというのが付属で入っててそれを利用するらしい。
詳細:
[https://r9y9.github.io/blog/2017/12/21/jupyter-cxx/:embed:cite]



正直いうとROOTは高エネルギー物理関係以外の人には必要性はあまり感じないです。図を書いたり統計解析するのに便利なメソッド等はいっぱいあるけれど他の業界の人が使うかどうかというと微妙...(上記URLにROOT以外のカーネル等もある)

手順としては、ROOT6(>バージョン6.05)のインストールをするくらいです。
注意点として、デフォルトでPython2を使ってビルドするのをPython3を使って行うためにcmake オプションを少し設定するくらいです<br>

では始めます。

# ROOTのインストール
まずは以下の公式サイトでソースコードをダウンロードしましょう<br>
https://root.cern.ch/content/release-61800

ここでは最新版の6.18verを使います
ダウンロードした後に解凍しておきます。するとroot-6.18.00が出来ると思います。

では早速、よく分からなくなっても消せるようにホームディレクトリにcernというディレクトリを作ってその中にroot-6.18.00を移動させてインストールしましょう。(また簡単にするためにroot-6.18.00をrootという名前に変更します。)
ターミナルを開いて以下のコマンドを打ちます。

```
mkdir cern
cd cern
mv (各自のroot-6.18.00のパス) .
mv root-6.18.00 root   
cd root
```


さて作業ディレクトリ(path: ~/cern/root)は出来たのでインストールします。
それには次のようにします。<br>

```
mkdir obj
cd obj
cmake -Dpython3=On -DPYTHON_EXECUTABLE=/Library/Frameworks/Python.framework/Versions/3.6/bin/python3 ../
make -j 4 
make install
```

これで終わりです。cmakeの際にPython3の機能をオンにしたオプションをつけてあげます。<br>

他にもオプションはたくさんありますが各自調べてみてください。
[https://root.cern.ch/building-root:embed:cite]



```
-DPYTHON_EXECUTABLE=/Library/Frameworks/Python.framework/Versions/3.6/bin/python3 ../
```
については僕の場合のPython3.6の実行ファイルののパスを書きましたが各自変更してください。

which python3など打ってみると出るかも知れないです。

```
make -j 4
```
の4もコア数に合わせて変えてもいいです。(大体1時間くらいかかります。)

これでmakeが通らなかったらrequirementsで各OSで足りてないものを調べてみてください。
もしかしたらXquartz、Python3でnumpyやmatplotlibなどを入れてないとかもあるかも知れないです。

(詳細)
[https://root.cern.ch/build-prerequisites:embed:cite]

以上でインストールは終わりです。<br>
次にホームディレクトリ上の.bashrc, .zshrcなどに以下のコードを載せます

```
source ~/cern/root/obj/bin/thisroot.sh
```
これはrootを使う際に関するパスを色々設定してくれるシェルスクリプト

# jupyter notebook上でのC/C++
それでは早速使いましょう。

ターミナルで

```
root --notebook
```
と打つことで起動できます。

```
jupyter notebook
```
と打って使いたい場合は次のコマンドを打ちましょう。(root notebookのカーネル設定をjupyter notebookに引き継がせる。)

ぼくはこっちを使っています。

```
cp -r $ROOTSYS/etc/notebook/kernels/root /Users/$USER/Library/Jupyter/kernels/
jupyter notebook
```

詳細

[https://github.com/root-project/root/tree/master/bindings/pyroot/JupyROOT:embed:cite]


すると次のような画面が出てくると思います。
newにROOT C++が出ていたら成功です。
![スクリーンショット 2019-08-25 14.07.31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/252787/81c898c1-54c8-067a-bd58-4afd6830321e.png)


それをクリックしてあとはjupyter notebookでpythonを使うときのようにC++をインタプリタで使うことが出来ます。

Cのコマンドをインタプリタで使っている様子が以下です。![スクリーンショット 2019-08-25 14.11.10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/252787/c437e651-9c53-2a4b-33a0-60c931199a13.png)

使い方のサマリーはこちら
[https://root.cern.ch/notebooks/HowTos/HowTo_ROOT-Notebooks.html]

以上でインタプリタを用いて使う方法の説明は終了です。
RailsでTwitterAPIを使って簡単にツイートする方法

# はじめに
こんにちは^^
こちらの記事ではTwitterAPIを使って、ツイートをしてみたいと思います。
この記事は、コントローラーを読み込んでツイートするものになります。
Formを踏ませると手順が増えますので、使っておりません。Formからツイートする方法は別の記事で公開いたします。

# Gemfile
まずはGemfileに下記を記述します。
そして `bundle install` コマンドを打ってください。

```
source 'https://rubygems.org'
git_source(:github) { |repo| "https://github.com/#{repo}.git" }

ruby '2.4.2'
.
..
...
....(省略します)

gem 'twitter'

```

# Keyを記述し、ツイートを投稿する
ご自身で作成してあるいずれかのControllerに下記を記述してください。
TwitterAPIを使って、ツイートするためには、`update`メソッドを使用します。
`update`メソッドの第一引数にツイート内容を指定します。
ツイートの文字列を指定する際には、140字の制限がございますのでお気をつけください。
Topコントローラーのindexアクションを読み込むとクライアントに指定したアカウントでツイートされていると思います^^

```
class TopController < ApplicationController
  def index
    # Twitterのクライアントを作成する。
    client = Twitter::REST::Client.new do |config|
      config.consumer_key        = "**********"
      config.consumer_secret     = "**********"
      config.access_token        = "**********"
      config.access_token_secret = "**********"
    end

    # ツイートする
    @client.update("API使ってツイートしました！")
  end
end
```

# 画像付きツイートも
画像付きツイートをTwitterAPIから行う場合は、 `update_with_media` メソッドを使用します。
update_with_mediaメソッドでは、第一引数にツイート内容、第二引数に画像のパスを指定します。画像を指定する際には、Railsのopenメソッドを使用しています。このopenメソッドは、**seed.rbに画像のテストデータを作りたい**場合にも使用できますので試してみてください^^
`Rails.root`は現在使用しているRailsアプリケーションのパスを自動で読み込んでくれます。Macの場合はRails.rootを指定すると、`/Users/ユーザー名/Railsアプリケーション名`というパスが読み込まれると思います。

```
class TopController < ApplicationController
  def index
    # Twitterのクライアントを作成する。
    client = Twitter::REST::Client.new do |config|
      config.consumer_key        = "**********"
      config.consumer_secret     = "**********"
      config.access_token        = "**********"
      config.access_token_secret = "**********"
    end

    # 画像付きツイートをする
    @client.update_with_media(API使って画像付きツイートしました！, open("#{Rails.root}/app/assets/images/solect.png"))
  end
end
```

# ツイート機能のAPI制限
こちらのツイート機能には2019年8月25日時点で、3時間に300回までという制限がございます。(~時点と記述しているのは、こういったAPIは制限がちょくちょく変わるためです。数年前はもっと制限が緩かったです。。)

# 終わりに
以上がTwitterのAPIでツイートをする方法です。
初めて実装した時は、ツイートをするだけでも苦労したことを覚えています。。

プログラミングの勉強をしている方、独学で勉強している方など、少しでも助けになれればと思います^^
M5StackでSDカードからmp3を再生してみる

## 作ったもの
以前M5Stackを使って作った時刻表タイマーに終電通知機能を実装しました。
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">終電が近くなるとお知らせしてくれる機能を実装しました。 <a href="https://t.co/zR1s8UYbOI">pic.twitter.com/zR1s8UYbOI</a></p>&mdash; Keisuke KAWAHARA (@ktansai) <a href="https://twitter.com/ktansai/status/1160164492489052161?ref_src=twsrc%5Etfw">August 10, 2019</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
**注: 音量に注意してください↑↑** 


## 経緯
以前のものに関しては下記の記事を参照してください。
[[Qiita]次の電車があと何分で来るか分かるガジェットをM5stackで作ってみた](https://qiita.com/ktansai/items/35597438a232e2239c07)

数ヶ月職場の入り口近くの目立つ場所に置かせていただいて運用していたのですが、夜型の自分は遅くまで会社にいたときに、終電を過ぎてしまうということが何度かありました。
そこで、終電10分前に音でお知らせしてくれる機能を追加しました。


## 仕組み
SDカードにmp3ファイルを配置し、ファイルを読み込んで、再生するという簡単な仕組みです。
[ESP8266Audio](https://github.com/earlephilhower/ESP8266Audio)というライブラリを使いました。

自分のArduino-esp32と互換性が悪いのか、コンパイルエラーが起きたので、
以下のバージョンに戻して、ビルドしたところ、うまく動いたのでこれで様子を見ています。
- Arduino-ESP32 1.0.0
- [ESP8266Audio 1.1.2](https://github.com/earlephilhower/ESP8266Audio/tree/ff18640db71d9813def86148f1c9967b6b54dce6)

おそらく最新版同士で検証するのが良いと思うのですが、自分の環境では他のライブラリがarduino-esp32最新版との相性が悪いようで、
arduino-esp32をアップデートできずにいます。
なので、今回はarduino-esp32が1.0.0がリリースされた日時に近いESP8266Audioを試したところ動いたことを確認しました。

ライブラリ導入方法などは[ESP8266AudioのREADME](https://github.com/earlephilhower/ESP8266Audio) が詳しいので必要な方は参照してください。

## コード
以下、サンプルコードなどから色々抽出して、自分的に使いやすく整理したコードです。
M5StackのボタンA,B,Cを押すと、対応するsample.mp3が再生されます。
ESPAudioのサンプルを見ていたら、wavや他のファイル形式もサポートされているようです。自分は試してません。
電車の時刻表示のやつと一緒に実装してある版は[こちら](https://github.com/ktansai/TrainTimer/blob/master/TrainTimer.ino)から見れます。

```c++:playMP3fromSD.ino

#include <M5Stack.h>
#include <WiFi.h>
#include "AudioFileSourceSD.h"
#include "AudioFileSourceID3.h"
#include "AudioGeneratorMP3.h"
#include "AudioOutputI2S.h"


AudioGeneratorMP3 *mp3;
AudioFileSourceSD *file;
AudioOutputI2S *out;
AudioFileSourceID3 *id3;

void setup()
{
  M5.begin();
  WiFi.mode(WIFI_OFF); 
  delay(500);
  
  M5.Lcd.setTextFont(2);
  M5.Lcd.printf("Sample MP3 playback begins...\n");
  Serial.printf("Sample MP3 playback begins...\n");
}

void playMP3(char *filename){
  file = new AudioFileSourceSD(filename);
  id3 = new AudioFileSourceID3(file);
  out = new AudioOutputI2S(0, 1); // Output to builtInDAC
  out->SetOutputModeMono(true);
  out->SetGain(1.0);
  mp3 = new AudioGeneratorMP3();
  mp3->begin(id3, out);
  while(mp3->isRunning()) {
    if (!mp3->loop()) mp3->stop();
  }
}

void loop()
{
  M5.update();
  if(M5.BtnA.isPressed()){
    playMP3("/sound_A.mp3");
  }
  if(M5.BtnB.isPressed()){
    playMP3("/sound_B.mp3");
  }
  if(M5.BtnC.isPressed()){
    playMP3("/sound_C.mp3");
  }
  Serial.printf("MP3 done\n");
  delay(10);
  
}

```

## 備考
色々な方がM5Stackのスピーカーの音質の悪さを指摘されています。
- [M5Stackのスピーカーの音質が悪い原因と対策](https://qiita.com/Tw_Mhage/items/34be8e8b42580c449b56)

3500円程度の安価なデバイスなので、そこまで品質を求めるわけではないですが、
今回実装していて、mp3再生時の最初に「ブッー。ザザザーーーー。」という結構大きいノイズが結構びっくりする音量で再生され、その後にmp3が普通に再生されるという状況がありました。
色々試したのですが、暫定的にmp3ファイルの最初に無音期間を0.3秒程度入れると、ノイズが小さくなりました。
音質と定常ノイズ的に使いかたに成約があると思いますが、こういった効果音やアラート程度にmp3等を再生するのはユースケースとして向いているのかなと思いました。
（ビンボーな会社や個人の為の）単純な機能検査をする為の治具作り。その１：キーデバイスの選定

# 機能検査する為の治具作り。
ものづくりに於いて検査は欠かせません。専用の検査機などが使えれば良いのですが、コストが許さなかったりで見た目での検査になることがあります。
こうした検査を官能検査と呼びますが、人の主観に頼る官能検査はミスが起こりやすいものです。出来れば OK/NG のはっきりした機能検査するのが望ましいです。
長生きはするもので、昔はワンチップマイコンを搭載したボードは高額なものが多かったり入手性の悪いものが多かったのですが、現在は非常に安価で其れこそAmazonでも買える時代になりました。良い時代です。
## 単純な機能治具のキーデバイスに求められる条件
1. 安価である事。
2. 入手性が悪くないこと。
3. 入手出来る資料（情報）が多いこと。・・・　主たるドキュメントは日本語が望ましいですが、英語であっても可としました。日本語に拘ってしまうとルネサス製に限定され、ボードの価格が上がってしまうためです。
4. 今現在、キーデバイスを用いた活動が世界で活発であること。
5. ある程度の汎用性があること。
6. 開発環境が無償で特別なドングルを必要としないこと。

## 検討の上、選択したキーデバイス
以下の様な候補が挙がりました。上の条件を基に検討した結果、1のArduinoを選択することにしました。
1. Arduino
2. PIC
3. Renesas
Slackでbotユーザーを作る手順

タイトルの通りですが、Slackでbotユーザーを作る手順を紹介します（何度やっても忘れるので自分用にまとめる目的の記事です）。

## Appsから作る手順

現在のSlackではこちらの手順が推奨だと思います。

 * Slackの「[Your Apps](https://api.slack.com/apps)」に移動
 * 「Create New App」ボタンから新しいアプリを作成
 * 「Your Apps」ページに戻って作ったアプリを選択
 * 左メニューから「Bot Users」を選択
 * 「Add a Bot User」ボタンからユーザー作成
 * ユーザー名などを適切に入力して「Add Bot User」
 * 左メニュー「Basic Information」からアイコンを登録
 * 左メニュー「OAuth & Permissions」を選択
 * 「Bot User OAuth Access Token」が表示されているので、botプログラムで利用する

## Custom Integrationから作る手順

Custom Integrationは現在非推奨だと思います。また、こちらから作ると一部機能が制限されることがあります。

 * Slackの[Appsトップページ](https://my.slack.com/apps)へ移動
 * 「Bots」を検索、追加
 * 「Add Configuration」
 * ユーザー名を指定して「Add Bot Integration」ボタンを押す
 * アイコン設定などをする
 * 「API Token」が表示されているので、botプログラムで利用する

## 参考URL

- [Enabling interactions with bots \| Slack](https://api.slack.com/bot-users)
  -  botユーザー作ってプログラム書いて動かすところまでの説明
- [Bot Users \| Slack](https://api.slack.com/custom-integrations/bot-users)
  -  古いドキュメント