OmniAICreator/Qiita-1.07M huggingface dataset:
Dockerを利用してAngularの開発環境を整える

## はじめに

Angularの開発環境はローカルで整えた方が開発しやすいんですが、複数のプロジェクトを同時にこなすような場合に Node.js や Angular CLI のバージョン違いでうまく動かなかったりしたので Docker を利用して Angular の開発環境を整えます。

## 前提条件

* Docker がインストールされていること

## Node.js & Angular の Docker Image の作成

Angular の公式イメージがあるわけではなさそうなので自分で作成します。
バージョンは適宜変更してください。
作成が手間であれば[こちら](https://hub.docker.com/r/shigezo/angular/)を利用してください。

```Dockerfile:Dockerfile
# Node.js のバージョンを変更する場合は以下のURLからタグを確認してください
# https://hub.docker.com/r/library/node/tags/
FROM node:10.13-stretch

# Angular CLI のバージョンを変更する場合は以下のURLからタグを確認してください
# https://www.npmjs.com/package/@angular/cli?activeTab=versions
RUN npm install -g @angular/cli@7.0.6

WORKDIR /app

# EXPOSE 4200
```

Dockerfile をビルドします。

```sh
docker build -t angular:7.0.6 .
```

基本的にはこれだけでコマンドが実行できるようになります。  

```sh
docker run --rm -it angular:7.0.6 npm -v
docker run --rm -it -v ${PWD}:/app angular:7.0.6 npm install
docker run --rm -it angular:7.0.6 ng v
docker run --rm -it -v ${PWD}:/app angular:7.0.6 ng g component my-new-component
```

## 実行 & ビルド 環境の設定

Windows 環境で Linux のコンテナーを実行しており、node-sassを利用している場合はビルドに失敗します。
node_volumes ディレクトリをマウントしないよう設定すれば回避できるのでそのための設定を用意します。

```.dockerignore:.dockerignore  
.vs
.git
dist
node_modules

.dockerignore
.gitignore
```

```Dockerfile:Dockerfile
# Dockerfile
RUN mkdir /app
WORKDIR /app
COPY . /app
RUN yarn --pure-lockfile
```

```yml:docker-compose.build.yml
version: "3"
services:
  client:
    image: angular:7.0.6
    build: .
    command: bash -c "npm install && ng build --prod --aot"
    volumes:
      - .:/app
      - /app/node_modules/
    ports:
      - "4200:4200"
```

```yml:docker-compose.serve.yml
version: "3"
services:
  client:
    image: angular:7.0.6
    build: .
    command: bash -c "npm install && ng serve --host 0.0.0.0"
    volumes:
      - .:/app
      - /app/node_modules/
    ports:
      - "4200:4200"
```

### サーバー実行

ローカルでの実行と異なり、実行中にファイルを変更しても即時反映されないので使い勝手が悪いです。

```sh
docker-compose -f docker-compose.serve.yml up
```

### ビルド実行

```sh
docker-compose -f docker-compose.build.yml up
```

## サンプル

* [リポジトリ(GitHub)](https://github.com/Shigezo32/AngularInDocker)
* [Docker Hub](https://hub.docker.com/r/shigezo/angular/)

## 参考

* [Dockerでnode-SASSを使うとNode Sass could not find a binding for your current environment: Linux 64-bit with Node.js X.X...](https://budougumi0617.github.io/2018/04/04/fail-node-sass-on-docker/)
* [Docker ALPINE Linux throws node-sass missing binding error](https://github.com/sass/node-sass/issues/2165#issuecomment-347043659)
App Store申請に必要な証明書周りの用語について

## 概要
初めてのiOSアプリを開発後、「よしApp Storeにリリースしよう！！」、と言うときに証明書関係で躓いてしまいました。<br>その時にググっても知らない単語がたくさん出てきて結局何が必要なんだ？？、となってしまったので、App Storeへ申請するのに必要なものについて、備忘録としてまとめておきます。

## 用語一覧

### 開発者証明書要求(CSR)
名前の通り、Certificates(開発用証明書 or 配布用証明書)をAppleからもらうためのもの。
公開鍵と暗号鍵の鍵ペアを作成（作成方法は<a href="https://qiita.com/yogita109/items/0c86e7db9e6499b200ee">こちら</a>）し、公開鍵をAppleに渡しておいて、それで暗号化された証明書をAppleからもらう。
もらった証明書をキーチェーンに保存することで、そのMacで実機ビルドできるようになる。（キーチェーンには暗号鍵もセットで保存されている。暗号鍵をなくすとビルドできなくなる。ので要注意）

### Certificates(CER)
いわゆる証明書と呼ばれるもの。
大きく開発用と配布用の2種類に分かれている。
開発・配布元を明らかにするために必要であり、これがないと実機ビルドやAppStoreにリリースできない。
証明書の作り方はこちら。

### AppID
アプリを識別するためのもの。バンドルID とも言う。
↓のBundle Identifierの部分
<img width="1053" alt="スクリーンショット 2018-11-21 1.17.21.png" src="https://qiita-image-store.s3.amazonaws.com/0/261954/1431de13-438e-f7ac-07ed-179cb790566a.png">


### DeviceID
UDID（端末を識別する固有のID）。ここに登録されているデバイスでしか実機ビルドできない。
確認方法は<a href="https://teachme.jp/contents/2074444">こちら</a>。

### Provisioning Profiles
最終的に使用するものである。
上記での３つの情報をまとめているものである。

- Certificate(CER)
- AppID
- DeviceID

### P12ファイル（秘密鍵ファイル）
個人情報交換（.p12)のこと。
秘密鍵をそれと関連する公開鍵証明書とともに保存するために使われるファイルフォーマットのこと。
別のMac環境で開発行うには、証明書+秘密鍵がそれぞれキーチェーンに登録されている必要があるので、別の開発者の環境で開発行う場合、これを渡してあげなければならない。（証明書は公開鍵で暗号化されているので。このP12ファイルで復号化する。）

## まとめ
ここまで、App Storeに申請するために最低限必要な単語を説明してきました。
文字ばかりだとわかりにくいので、画像の挿入など随時入れていきます。

### 参照URL
* https://qiita.com/natsumo/items/d5cc1d0be427ca3af1cb
* https://qiita.com/fujisan3/items/d037e3c40a0acc46f618
@RequestMappingでパスパラメータをバリデーションする

# 概要
- `@RequestMapping`で定義されたURIのパスパラメータ（プレースホルダー）は`{パラメータ名:正規表現}`の形でバリデーションできる。
- たとえば、`@RequestMapping(path="/hello/{name}")`のようにURIが定義されていて、`name`には半角英字以外は受け付けないようにしたいときは、`@RequestMapping(path="/hello/{name:[a-zA-Z]+}")`と書く。
- 正確には、URIのプレースホルダーの構文を取り決めている。

# 前提
- Spring Bootで作ったREST APIを想定。
- `@RestContoller`が付与されたコントローラクラスで使用される`@RequestMapping`のpath属性（またはvalue属性）で構文を決める。

# 環境
- Spring Framework 5.1.2
- Spring Boot 2.1.0
- Java 1.8

# 書き方の例
URIのプレースホルダーに半角英字を入力し、`"hello, {入力した半角英字}"`を返すAPI。

```HelloController.java
@RestController
public class HelloController {

  @RequestMapping(path = "/hello/{name:[a-zA-Z]+}", method = RequestMethod.GET)
  public String hello(@PathVariable String name) {
    return "hello, " + name;
  }
}
```
実行例。

```
bash-3.2$ curl -X GET http://localhost:8080/hello/Freddie
hello, Freddie
```
誤った構文の入力があった場合は、404リソース未検出扱いになる。デフォルトのエラーレスポンスでは以下のとおり。

```
bash-3.2$ curl -X GET http://localhost:8080/hello/0123
{"timestamp":"2018-11-20T16:02:56.401+0000","status":404,"error":"Not Found","message":"No message available","path":"/hello/0123"}
```
他にも、たとえば3桁の半角数字の構文にしたい場合は`@RequestMapping(path="/hello/{id:\\d{3}}")`等、目的の構文を表す正規表現を用いればよい。
※ 念のため、`¥¥d`では正しく動作しない。`\\d`と書く。

### 参考
https://docs.spring.io/spring/docs/current/spring-framework-reference/web.html#mvc-ann-requestmapping-uri-templates
Kubernetesで複数のサービスをIngressで公開する場合はコンテキストパスではなく仮想ホストの方がやりやすい

# 経緯

1つのKubernetesクラスタで複数のサービスをホストしており、それらをIngressでクラスタ外からアクセスする場合のサービスの見せ方についての気づきをメモ。

# 方法

大きく2つの方法があると思います。

## 同一ホスト名をコンテキストパスで分ける

伝統的なJava EEアプリはコンテキストパスを付けるのが一般的なので、こうなりがちです。

```
https://sample.example.com/app1/
https://sample.example.com/app2/
https://sample.example.com/app3/
```

メリットとしては、FQDNが1つで済むこと。

デメリットとしては、コンテキストパスが重複できないこと、Podの実コンテキストパスとの変換が必要になる場合があること。

非コンテナ環境では1つのJava EEサーバに大量のWARをデプロイすることはあまり想定されませんが、Kubernetesでは同一FQDN化でそれがありうるため、コンテキストパスの管理に苦労するかもしれません。

## 仮想ホストで分ける

仮想ホスト名でサービスを区別します。

```
https://app1.example.com/
https://app2.example.com/
https://app3.example.com/
```

メリットとしては、Podの実アプリのコンテキストパスに影響を受けないこと。

デメリットとしては、複数のFQDNを管理しなければならないこと、TLSを使う場合は複数の証明書を用意しなければいけないことです。

# 経験からの学び

伝統的なJava EE脳な私はコンテキストパスを使った方式を採用しました。手動で管理していた頃は、あらかじめ全てのサービスのIngress定義を一括で登録していました。サービスが増えてきてデプロイ作業が大変になったので、Helm Chartを作ってサービス個別にデプロイできるようにしました。このときIngressの定義もHelmでサービス毎にコントロールしたところ、ある問題が発覚しました。それは、Ingressのマニフェストは同一のhostに対し、1つのマニフェストしか使われない（？）、ということです。

## 例

以下は同一のsample.exampe.comに対して異なるサービスを別のマニフェストで定義する例です。定義は一見成功するのですが、実際に有効になったのは片方だけでした。

これが仕様なのか、特定環境での挙動なのかは不明です（詳しい方教えてください）。

```
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: app1
spec:
  rules:
  - host: sample.example.com
    http:
      paths:
      - path: /app1
        backend:
          serviceName: app1
          servicePort: 8080
---
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: app2
spec:
  rules:
  - host: sample.example.com
    http:
      paths:
      - path: /app2
        backend:
          serviceName: app2
          servicePort: 8080

```

これではせっかくHelmでデプロイを一括管理できるようになっても、Ingressは別で管理しなければならないということになります。

## 仮想ホスト方式を簡単にする方法

代わりに仮想ホスト方式を採用することとしました。懸念は前述のとおりFQDNと証明書です。

FQDNは、DNSのレコードでワイルドカードを指定することで、ドメインの個別登録を不要にすることができます（これ、意外に知られていないです）。

TLS証明書もワイルドカード証明書を使うことで、ドメイン個別の購入が不要です。

両者を組み合わせることで、DNSや証明書の考慮が不要となります。

この方式にしたことで新たなメリットも生まれました。それは、公開されているHelm Chartを気軽に使えるようになったことです。公開Chartはコンテキストパスの考慮がされていない場合が多いため、1つのFQDNで使おうとすると頑張ってパスのリライトの設定を研究しなければならなかったのですが、ドメインを好きに追加できるようになったので、この考慮が不要になりました。

というわけで、仮想ホスト方式、おすすめです。
Modelicaで最適化 - Excel編

# Modelicaで最適化を志す 

Modelicaで最適化(動的計画法)を行う場合いくつか選択肢があるが
OpenModelica, JModelicaにはOptimizationクラスが用意されており最適化を行うことが出来る

JModelicaで試した結果はこちら
https://qiita.com/UedaShigenori/items/4452d95cfa440658163a

OpenModelicaで試した結果はこちら
https://qiita.com/UedaShigenori/items/fbd2209363c117476827

結論として両者はあまり使えなかった
OpenModelicaは期待する結果を得る方法が分からなかったし
JModelicaはパラメータ変数に計算式が入っているとダメだし、Fluidパッケージのモデルが全然計算できない

そこでExcelからOpenModelicaで計算を実行するライブラリを昔作ったのでそれを拡張して最適化できるようにしてみる
https://github.com/UedaShigenori/OpenModelica_Excel_Interface_ClassPackage

本当は格好よくPythonとかでやりたいし、OpenModelicaにPython InterfaceもあるのだがPython使えないから仕方ない
またPythonが使えない環境も製造業では多いためVBAで書いていく

試みとしてはまだ途中である

# 実装手順

1. ExcelからOpenModelicaを計算実行出来るようにする

2. それからパラメータを変更出来るようにする
ここでパラスタ機能を付けてもいいかもしれない

3. 計算結果をExcelに取得するようにする

4. 計算結果から次のパラメータを決定出来るようにする

## 1.ExcelからOpenModelicaの計算を実行
以下のExamples1.xlsmはHelloWorld.moをOMShellから実行するサンプルマクロである
https://github.com/UedaShigenori/OpenModelica_Excel_Interface_ClassPackage

先日まではWindows10では動かなかったが、本日動くように修正した

躓いていたのはSendkeysでOMShellにコマンドを送るところで
Win10だとちゃんとコマンドを送れなかった
色々原因はあるらしいが以下のサイトを参考にWSHから送るようにした
https://qiita.com/nukie_53/items/f069a1e48cddca0024c2

ちゃんと動くことを確認できた

# 次のステップ
次はExcelからモデルのパラメータ変更するのだが
OMShellにコマンドが用意されているため用意と思われる

結果の取得もcsvで吐き出せば簡単に読み込める
ただ、結果ファイルは大きいので全部読み込むか、特定の変数の結果のみ読み込むかは後々判断する

難しいのは動的にパラメータを変えることだと認識する

ある目的関数を最小化(最大化)するため、パラメータ変数を変更するのだが
目的関数は時系列で出力されるため、一つの評価関数にする必要がある
最小二乗法などが候補となる

次に、最小化のためのアルゴリズムだが導関数を取得するかどうかで計算コストも変わる
代数的に求める二分法などもあるが、おそらくPythonはこの辺りのライブラリが充実しているのだと思う。
ExcelVBAでそのようなライブラリがあればだれか教えてほしい

ただ、ExcelのSolver機能などのセルに依存した機能は可読性が大きく下がり拡張性も悪くなるので
それ以外でお願い致します。

---
** パラメータを変更する

以下のコードを参照

```
Sub Examples2_2()

'
'    パラメータを変更して計算を実行するマクロです
'    mosスクリプトを書いて､OMShellに投げます
'

    '宣言
    Dim ThisWorkbookPath As String
    Dim mosFileName As String
    Dim modelFile As String
    Dim className As String
    
    'mosファイルの設定インスタンス
    Dim mosScript As MosSetting
    Set mosScript = New MosSetting
     
    'OMShellの操作インスタンス
    Dim OMShell As OperateOMShell
    Set OMShell = New OperateOMShell
    
    '計算を実行するmoファイル, クラス名, mosファイル名. ワークブックパスを定義
    modelFile = "He"
    className = "hel"
    mosFileName = "He"
    ThisWorkbookPath = ThisWorkbook.Path
    
    'mosファイルの設定
    Call mosScript.MakeMos(mosFileName)
    Call mosScript.loadFile(modelFile)
    Call mosScript.build(className, 0, 1, 500, 0.0001, "dassl", "csv")
    Call mosScript.ChangeParameter(className, "a", 100)
    Call mosScript.exe(className, "res14", "csv")
    Call mosScript.EndMos

    'OMShellからmosファイルを実行
    Call OMShell.StartOMShell
    Call OMShell.Cd(ThisWorkbookPath)
    Call OMShell.runScript(mosFileName)
End Sub
```
機械学習の学習（又の名をマイルストーン）

そもそもAIというものに対して”抵抗”をなくす必要がある。
何も知らなくてもできる。けど、とはいえ最低限の仕組みを知っておく必要がある、
し、知っておいた方が”開発（広義の意味でのSE）”がより効果的になる。

車輪の再開発の面
⇨あるものを使えば良いという側面。
一方で、”車輪がどういうものか”を理解しておかなくてはそれどころではない。
学習済みモデル

・我々はどうやってAIを仕事へ取り込んでいくか。
・AIエンジニアとして仕組みが分かった上で、何ができるのか？
アルゴリズムの選択
ハイパーパラメータ

・フレームワークの紹介
karas
chainer
tensor flow

・機械学習
ニューラルネットワーク
重み付け
階層型ニューラルネットワーク
学習の仕組み（誤差逆伝播）

・機械学習とは
教師あり学習
　回帰
　分類
教師なし学習
　クラスタリング

代表的なアルゴリズム（SVMや近傍法とか）の紹介
（これだけやるだけで、適切、不適切がわかると思う）

次元の呪い
次元とは、特徴である。それを判断する材料となる。
（例えば、家賃を推測しようと思った時に、最寄駅とかは参考になると思うが、
　右利きか左利きかは”相関関係”はなさそうだと思える。）

急勾配方を説明したい

以下サイトがとても参考になったのでご紹介。
読み物としてもよみやすい、かつ情報も充実しています。

https://products.sint.co.jp/aisia/blog/tag/ai_blog_basics
メソッド名参考用リンク集

[メソッド(関数)の命名で使えそうな英単語を集めてみた - もふもふ技術部]("https://tech.mof-mof.co.jp/blog/method-name.html)
[プログラミングでよく使う英単語のまとめ【随時更新】 - Qiita]("https://qiita.com/Ted-HM/items/7dde25dcffae4cdc7923)
[うまくメソッド名を付けるための参考情報 - Qiita]("https://qiita.com/KeithYokoma/items/2193cf79ba76563e3db6)
[関数名によく使われる英単語（動詞）の意味とニュアンス | PHP Archive]("https://php-archive.net/php/words-in-function-names/)
[メソッド名、迷った時に参考にできる単語一覧 | iOS & Android & Linux Labs]("https://blog.77jp.net/guidelines-for-variables-and-method-names-summary)
[メソッド(関数)の命名で使えそうな英単語を集めてみた - もふもふ技術部]("https://tech.mof-mof.co.jp/blog/method-name.html)
[Rubyの命名規約 - Qiita]("https://qiita.com/takahashim/items/ccfd489c9b26f15b7193)
IFTTTで簡単！ブログ更新情報をFacebookでお知らせ

## やりたいこと
ブログを更新した際にRSSとIFTTTを使って、Facebookに自動投稿する。
これをやりたい。

## 対象RSS
ヘッドウォータース Tech Note
https://utage.headwaters.co.jp/blog/?feed=rss2

## 対象Facebookページ
ヘッドウォータースのなかの人
https://www.facebook.com/hwsnakanohito/

## 実践
### IFTTTにRSS情報とFacebook情報を登録するだけ！
- IFTTT：https://ifttt.com/

#### RSS情報の登録。
1. My Applets -> New Applets を押下。
2. this を押下。
![img01.png](https://qiita-image-store.s3.amazonaws.com/0/169536/92d083b1-f254-7deb-8300-097f6eccafa4.png)

3. RSS Feed を押下。
![img02.png](https://qiita-image-store.s3.amazonaws.com/0/169536/7071d89e-0ad8-2157-300b-d99483bd7d0b.png)

4. New feed item を押下。キーワードなど取得条件を設定する場合は New feed item Mactces。
![img03.png](https://qiita-image-store.s3.amazonaws.com/0/169536/efa31bfa-0ce3-92bc-9ab1-a46f0db274e8.png)

5. 取得したいRSSのURLを記載して、Create trigger を押下。今回はヘッドウォータース Tech NoteのURL。
![img04.png](https://qiita-image-store.s3.amazonaws.com/0/169536/a0c1dc80-c8c6-a4b3-034d-767a7e440c4e.png)

これでRSSの登録は完成です。続いてはFacebookページの登録です。

#### Facebookページの登録。

1. that を押下。
![img05.png](https://qiita-image-store.s3.amazonaws.com/0/169536/103567b4-e7e8-1f5c-1b2a-7001f3102850.png)

2. Facebook Pages を押下。
![img06.png](https://qiita-image-store.s3.amazonaws.com/0/169536/4257ad59-9725-1003-44a7-901ca21b35e6.png)

3. 自動投稿先のFacebookページにアクセス。
4. Create a link post を押下。使う目的に合わせて変更してください。今回はブログに新規記事が投稿された際のお知らせという目的のため記事リンクを表示させる仕組みにします。
![img07.png](https://qiita-image-store.s3.amazonaws.com/0/169536/f925bb86-f85e-5b88-beec-98164d01c12b.png)

5. 表示する内容を設定。
![img08.png](https://qiita-image-store.s3.amazonaws.com/0/169536/ea1f46fd-5c0e-ff46-6417-a9e4015f86e2.png)

6. 最後にAppletの名前をつけて、finish を押下すれば完成です。
![img09.png](https://qiita-image-store.s3.amazonaws.com/0/169536/80ac57cf-00d6-35b0-4fc9-04ef9d6c8893.png)

## おわりに
とても簡単に設定できました。
こちらの設定により、ブログ記事を書いた際はFacebookページにて自動でお知らせされるようになります。
[cocoa][swift]関東swift勉強会2018-01 を振り返る

<p>2018年1月19日（金）の夜間、東京都豊島区の<a href="http://co-forest.com/">池袋コワーキングスペース OpenOffice FOREST</a>におきまして、「関東swift勉強会2018-01」を開催致しました。</p>

# 勉強会について
<ul>
<li>Cocoa勉強会 関東 Swift分科会 です。</li>
<li>ほぼ毎月、池袋コワーキングスペース OpenOffice FOREST で開催してます。</li>
<li>macOS/iOS/watchOS/tvOSプログラマーのための勉強会です。</li>
<li>プログラムに関する知識や経験を共有を目的としています。</li>
<li>会の活動内容や発表資料、サンプルコードは公開を前提としています。</li>
<li>申し込みは、connpassから。<br /><a href="https://cocoa-kanto.connpass.com/">https://cocoa-kanto.connpass.com/</a></li>
</ul>

# 概要
<ul>
<li>発表資料は<a href="https://cocoa-kanto.connpass.com/event/75006/">connpassページ</a>からどうぞ！</li>
<li>会場の様子は、ハッシュタグ『#cocoaswift #cocoastudy #bukuroswift』でtweetしています。</li>
</ul>

# NSDcoument複数ファイルフォーマット
<p>NSDcoumentで複数のファイルフォーマットをサポートするコード周りの解説でした。</p>

# OpenGLプログラミング
<p>macOSでGLUTのサンプルを試したらエラーになった件の発表です。結局、シェーダーを利用したモダンなコードは大丈夫だったが、古いAPIを利用したコードは上手くいかなかった。</p>

# macOS で eGPU を使って見た
<p>Macintoshで外付けGPUを利用した試行錯誤の発表だ。貴重な情報でeGPUの利用を考えている方にとっては有益だと思う。</p>

# Xcode Tips
<p>各種Tipsの発表でした。ありがとう！</p>

# ユニットテストを導入してみた事例紹介
<p>このような有益な情報は助かります。</p>

【関連情報】
<a href="https://qiita.com/advent-calendar/2018/cocoa">Cocoa Advent Calendar 2018</a><br />
<a href="https://cocoa-kanto.connpass.com/event/75006/">関東swift勉強会2018-01</a><br />
<a href="https://cocoa-kanto.connpass.com/">Cocoa.swift</a><br />
<a href="https://www.facebook.com/groups/cocoa.kanto/">Cocoa勉強会 関東</a><br />
<a href="http://www.bitz.co.jp/weblog/">Cocoa練習帳</a><br />
<a href="https://qiita.com/m_yukio">Qiita</a><br />
【GCP】Google Cloudのストレージ

##Google Cloud Platformのストレージ
Google Cloud Platformのストレージは、
構造化データ、非構造化データ、トランザクションデータ、関連データなど様々な形態のデータを格納できるサービスを提供している。
サービス名称からある程度は推測することができるが、整理のためにそれぞれの特徴や用途を記載する。

##迷ったとき用のフローチャート
![alt](https://cloud.google.com/images/storage-options/flowchart.svg?hl=ja)
これで事足りるのでは？というツッコミはなし

##Cloud Storage
スケーラブル、フルマネージド、高信頼性、費用対効果の高いオブジェクト／blobストア。

- 用途
 - 画像、写真、動画
 - オブジェクト、blob
 - 非構造化データ

- ワークロード
 - マルチメディアの保存とストリーミング
 - カスタムデータ分析パイプライン用のストレージ
 - アーカイブ、バックアップ、ディザスタ リカバリ

##Cloud Spanner
トランザクションの整合性、グローバルなスケール、高可用性を実現した、ミッションクリティカルなリレーショナルデータベースサービス。

- 用途
 - ミッションクリティカルなアプリケーション
 - 高トランザクション
 - スケールと整合性の要件

- ワークロード
 - アドテック
 - 金融サービス
 - グローバルサプライチェーン
 - 小売

##Cloud SQL
Gogleインフラストラクチャの強みと信頼性をベースに構築されたフルマネージドMySQLとPostgreSQLのデータベースサービス。

- 用途
 - ウェブフレームワーク
 - 構造化データ
 - OLTPワークロード（OLTP：オンライントランザクション処理）

- ワークロード
 - ウェブサイト、ブログ、コンテンツ管理システム（CMS）
 - ビジネスインテリジェンス（BI）アプリケーション
 - ERP、CRM、eコマースアプリケーション
 - 地理空間アプリケーション

 （BIアプリケーション：企業に蓄積されたデータを集めて分析し、意思決定を助けるアプリケーション。経営管理や売上のシミュレーションなどに活用される。）

##Cloud Bigtable
リアルタイムアクセスと解析に最適な、スケーラブルなフルマネージドNoSQLワイドカラム型データベース。

- 用途
 - 低レイテンシの読み取り／書き込みアクセス
 - 高スループット解析
 - ネイティブの時系列サポート

- ワークロード
 - IoT、ファイナンス、アドテック
 - モニタリング
 - 地理空間データセット
 - グラフ

##Cloud Datastore
ウェブアプリやモバイルアプリで使えるスケーラブルなフルマネージドNoSQLドキュメントデータベース。

- 用途
 - 半構造化されたアプリケーションデータ
 - 階層データ
 - 耐久性のあるKey-Valueデータ

- ワークロード
 - ユーザープロフィール
 - プロダクトカタログ
 - ゲームデータ

##Google BigQuery
SQLや素早いレスポンス時間を兼ね備えたスケーラブルでフルマネージドのエンタープライズ向けデータウェアハウス（EDW）。

- 用途
 - ペタバイトまで対応したOLAPワークロード
 - ビッグデータの検索と処理
 - ビジネスインテリジェンス（BI）ツールによるレポート機能

- ワークロード
 - 大容量データの分析レポート
 - データサイエンス、高度分析機能
 - SQLを用いたビッグデータ処理

##Persistent Disk
仮想マシンやコンテナに最適なブロックストレージ。

- 用途
 - Google Compute EngineおよびGoogle Kubernet Engine用ブロックストレージ
 - データバックアップ用のスナップショット

- ワークロード
 - 仮想マシン用ディスク
 - 複数の仮想マシンで読み取り専用データの共有


参考サイト
https://cloud.google.com/storage-options/?hl=ja
C#でサイズnの順列をすべて生成したい。

サイズ$n$の順列をすべて生成する処理をC#で実装する機会があったので、そのメモになります。RubyやPythonだと順列の列挙は標準ライブラリに用意されており、ふだんはそういう「出来合い」のものを使うことが多いので、自力で実装するのに思ったよりも時間がかかってしまった(´・ω・｀)

```csharp
using System;
using System.Collections.Generic;
using System.Linq;

namespace permutations
{
    class Program
    {
        static List<List<T>> Permutations<T>(List<T> src, int n)
        {
            // nは1以上かつsrcの長さよりも短い必要がある。
            int len = src.Count;
            if (!(0 < n && n <= len))
            {
                throw new ArgumentOutOfRangeException();
            }

            var permutations = new List<List<T>>();
            var queue = new Queue<List<int>>(Enumerable.Range(0, len).Select(i => new List<int>() { i }));
            while (queue.Any())
            {
                var indexes = queue.Dequeue();

                if (indexes.Count == n)
                {
                    permutations.Add(indexes.Select(index => src[index]).ToList());
                    continue;
                }
                
                for (int index = 0; index < len; index++)
                {
                    if (indexes.Contains(index))
                    {
                        continue;
                    }

                    var newIndexes = new List<int>(indexes);
                    newIndexes.Add(index);
                    queue.Enqueue(newIndexes);
                }
            }

            return permutations;
        }
    }
}
```

- インターネットの広大な海で調べてみると、再帰を利用して実装している例が多かったのですが、今回はQueueを使った幅優先探索にしてみました。再帰は実装がシンプルになる反面、深くなるとStack Over Flowなどの制御が難しくなるため、個人的にはStackやQueueを使うほうが個人的には好みです。
- 生成した順列をすべてリストに格納するため、順列の数が多くなると、それだけメモリの消費量が多くなります。つまり順列の数が多くなることが明らかな場合、上記のような実装では注意が必要です。本来ならば`yield return`やイテレータなどを利用し、メモリの消費量を制限すべきですが、自分が使う分には問題ないので、よしとします(´・ω・｀)

最後に使用方法を2つ示して終わりにしたいと思います。まずひとつめ。

```csharp
var src = new List<string>() { "A", "B", "C", "D", "E" };
var permutations = Permutations(src, 3);
for (int i = 0; i < permutations.Count; i += 5)
{
    int j = Math.Min(i + 4, permutations.Count);
    var tokens = permutations.GetRange(i, j - i + 1).Select(permutation => "[" + string.Join(",", permutation) + "]");
    var line = string.Join(" ", tokens);
    Console.WriteLine(line);
}
```

これを実行すると、以下のような値が標準出力に出力されます。

```
[A,B,C] [A,B,D] [A,B,E] [A,C,B] [A,C,D]
[A,C,E] [A,D,B] [A,D,C] [A,D,E] [A,E,B]
[A,E,C] [A,E,D] [B,A,C] [B,A,D] [B,A,E]
[B,C,A] [B,C,D] [B,C,E] [B,D,A] [B,D,C]
[B,D,E] [B,E,A] [B,E,C] [B,E,D] [C,A,B]
[C,A,D] [C,A,E] [C,B,A] [C,B,D] [C,B,E]
[C,D,A] [C,D,B] [C,D,E] [C,E,A] [C,E,B]
[C,E,D] [D,A,B] [D,A,C] [D,A,E] [D,B,A]
[D,B,C] [D,B,E] [D,C,A] [D,C,B] [D,C,E]
[D,E,A] [D,E,B] [D,E,C] [E,A,B] [E,A,C]
[E,A,D] [E,B,A] [E,B,C] [E,B,D] [E,C,A]
[E,C,B] [E,C,D] [E,D,A] [E,D,B] [E,D,C]
```

2つ目のサンプルはもうちょっとシンプルです。

```csharp
var src = new List<int>() { 1, 2, 3, 4 };
foreach (var permutation in Permutations(src, 2))
{
    Console.WriteLine(string.Join(",", permutation));
}
```
この実行結果は次の通りです。

```
1,2
1,3
1,4
2,1
2,3
2,4
3,1
3,2
3,4
4,1
4,2
4,3
```
とにかく時間がない人のためのGitコマンド

今まで一度も仕事でGitを使ったことがなかった自分が、ひとまずソースコード取ってきて改修してpushするのに取り急ぎ覚えた操作。本当はちゃんと仕組みを理解して使うべきだけど、とにかく時間がないのでとりあえず使いたい人向け。

## とりあえずやる設定

ユーザ名とメールアドレスの設定が必要。リモートからcloneしてくるだけの場合は不要。

```bash
git config --global user.name hoge
git config --global user.email hoge@example.com
```

## リモートのリポジトリ取得

たまに特定のブランチだけを取得したい場合もあると思うので、`-b <ブランチ名>`は覚えておくといいかも。(ググったり英語のhelp読んでると意外と時間とられる…)

```bash
git clone <リポジトリのURL>
# ブランチ指定の場合
git clone -b <ブランチ名> <リポジトリのURL>
```

普通にcloneしたあとからリモートの別ブランチを取得したい場合は以下。

```bash
# リモートの情報取得
git fetch
# リモートのブランチも含めて確認
git branch -a
# 対象のブランチ取得
git checkout -b <ブランチ名> origin/<リモートのブランチ>
```

## 変更をローカルのリポジトリに反映

```bash
git add <対象のファイル>
# とにかく変更したもの全て対象の場合
git add -A
# ローカルのリポジトリにコミット
git commit -m 'コメント'
```

## リモートにpush

```bash
git push origin <リモートのブランチ名>
```

## 新しいリポジトリを作る

### リモートのリポジトリを先に作るパターン

GitHubやGitLab等で先にリポジトリを作成してから以下を実施。

```bash
# 作成した空のリポジトリを取得
git clone <リポジトリのURL>
# 
# ファイルを追加したり作成したり…
#
# ローカルリポジトリにコミット
git add -A
git commit -m 'コメント'
# リモートにpush
git push origin master
```

### ローカルリポジトリを先に作ってからpushするパターン

あまりやらないと思うけど…

```bash
# リポジトリ用のディレクトリを作成
mkdir test-repo
cd test-repo
#
# ファイルを追加したり作成したり…
# 
# ローカルリポジトリ作成
git init
# ローカルリポジトリにコミット
git add -A
git commit -m 'コメント'
#
# GitHubやGitLab等にpush先のリポジトリを作成しておく
#
# リモートのリポジトリの情報を追加
git remote add origin <リモートのリポジトリのURL>
# pushする
git push -u origin master
```

`-u`は`--set-upstream`の略とのこと。デフォルトでpushやpullするときの対象に設定してくれるオプションらしい。
[【Git】リモートにブランチを push してそのままトラックする](https://qiita.com/sunstripe/items/a39f4bb835e1f08760e7)

まだまだ覚えるべき大事なことはたくさんあると思うけど、ひとまずこれだけ覚えておけば全く使えないということはないはず。これも必要そうだなぁ、というものがあれば後で追加するかも。時間ができたら、じっくり調べたり本を読んだりして勉強しましょう。
CloudFront のキャッシュを削除して再生成する ( JavaScript SDK )

AWS CloudFront のキャッシュを JavaScript SDK を使って削除した後に再生成するスクリプトのメモです。

## 背景

CloudFront でキャッシュはしたい。キャッシュはしたいけど、データは更新される。更新されたらキャッシュも更新したい。キャッシュを削除すれば良いけど、そうすると最初のアクセス時にキャッシュ生成コストを負担することになる。その負担をユーザに課したくない。つまり、削除後に再生成するようにしたい。

## やり方

やり方は本当に単純で CloudFront の SDK を使って、指定 URL のキャッシュを削除して、HTTP リクエストでアクセスしてキャッシュを生成するっていうだけです。気をつけなきゃいけないのは CloudFront のキャッシュ条件程度と、HTTP リクエストのタイミングくらいです。

### CloudFront キャッシュ削除の反映

CloudFront は現時点 ( 2018/11/20 ) でキャッシュを削除してから約5秒程度でキャッシュが削除されます。

(*) 90%程度のエッジサーバは5秒、全部に完全に反映するには1〜2分程度というアナウンスが AWS からあったようですがオリジナルソースの URL が今は NotFound 状態で公式アナウンスはありません…

というわけで、５秒後くらいに HTTP リクエストしてあげればキャッシュを再生成できるということになります。

### コード

```javascript
const got = require('got')
const AWS = require('aws-sdk')
const cloudfront = new AWS.CloudFront({
  apiVersion: '2018-06-18',
  accessKeyId: 'ACCESS_KEY',
  secretAccessKey: 'SECRET_KEY',
})

(() => {
  const invalidCache = async () => {
    const timestamp = new Date()
    const string_timestamp = String(timestamp.getTime())
    const invalidate_items = ['/example.json']
    const item_count = invalidate_items.length
    const params = {
      DistributionId: 'DistributionId',
      InvalidationBatch: {
        CallerReference: string_timestamp,
        Paths: {
          Quantity: item_count,
          Items: invalidate_items
        }
      }
    }
    await cloudfront.createInvalidation(params).promise()
    setTimeout(() => {
      got('https://example.com/example.json', {
        headers: {
          'Origin': 'https://example.com'
        }
      })
    }, 5000)
  }
  invalidCache()
})()
```

`createInvalidation` でキャッシュ削除を開始します。Promise の完了時に削除自体が完了しているわけではなく、あくまでスタックに積んだ状態です。なので、そこからおおよそ５秒後には消えているだろうという見積もりで `got` ライブラリを使って HTTP リクエストをしています。

その際に、CloudFront で設定した Headers の値と一致するようなリクエストパラメータにする必要があります。今回のコードだと CORS のために `Origin` ヘッダーをホワイトリストに追加しているので `Origin` ヘッダーを追加しています。

### Invalidation のステータスをポーリング

キャッシュ削除が完全に完了したかどうかを知るには数秒おきにステータス確認するしかないです。２秒おきに `getInvalidation` を叩いて該当 ID のステータスを取得しています。ちなみに実際に試してみると `InProgress` から `Completed` になるまで約２分弱かかりました。

```javascript
const checkStatus = (id) => {
  const params = {
    DistributionId: 'DistributionId',
    Id: id
  }
  cloudfront.getInvalidation(params, (err, data) => {
    console.log(err, data)
  })
}

const invalidCache = () => {
  const timestamp = new Date()
  const string_timestamp = String(timestamp.getTime())
  const invalidate_items = ['/example.json']
  const item_count = invalidate_items.length
  const params = {
    DistributionId: 'DistributionId',
    InvalidationBatch: {
      CallerReference: string_timestamp,
      Paths: {
        Quantity: item_count,
        Items: invalidate_items
      }
    }
  }
  cloudfront.createInvalidation(params, (err, data) => {
    const id = data.Invalidation.Id
    setInterval(checkStatus, 2000, id)
  })
}
```

以上です。完全ではないですが実用性はそれなりにあると思います。実際には AWS Lambda などを使って、データベース更新コールバックなどで実行するような感じになると思います。
rpm作成時%preunと%postunには気をつけよう


# 何が起きたか？

```
// rpmをインストール
# rpm -ivh goblin-slayer-1.00-1.el7.noarch.rpm

// 牛飼娘も女神官もいる :)
# ll /etc/cow_girl.ini
-rw-r--r-- 1 root root 0 11月 20 22:48 /etc/cow_girl.ini
# ll /etc/priestess.ini
-rw-r--r-- 1 root root 0 11月 20 22:48 /etc/priestess.ini

// rpmをアップグレード
# rpm -Uvh goblin-slayer-1.00-2.el7.noarch.rpm

// いなくなってしまった！？ :(
# ll /etc/cow_girl.ini
ls: cannot access /etc/cow_girl.ini: No such file or directory
# ll /etc/priestess.ini
ls: cannot access /etc/priestess.ini: No such file or directory
```

rpmのspecファイルは以下の最低限で、Releaseを1から2に変更しただけです。

```txt:goblin-slayer.spec
Name:     goblin-slayer
Version:  1.00
Release:  1%{?dist}
Summary:  GOBLIN SLAYER
License:  GPL+ or Artistic
BuildArch:  noarch

%description
%prep
%setup -T -c
%files

%pre
touch /etc/cow_girl.ini

%post
touch /etc/priestess.ini

%preun
rm -f /etc/cow_girl.ini

%postun
rm -f /etc/priestess.ini
```


# 原因

rpmのアップグレードは
%pre,%postだけでなく、%preun,%postunも呼ばれるためです。
このため、ファイルが消されてしまいました。


# どうすればいいのか

引数$1に実行時の値が入ってくるのでそれを使って判定します。

[Fedora Packaging Guidelines for RPM Scriptlets \- Fedora Project Wiki](https://fedoraproject.org/wiki/Packaging:Scriptlets)
から表を引用します。

|             |   install   |  upgrade     |    uninstall  |
|:------------|:-----------:|:------------:|:-------------:|
| %pre        |   $1 == 1   |  $1 == 2     |   (N/A)       |
| %post       |   $1 == 1   |  $1 == 2     |   (N/A)       |
| %preun      |   (N/A)     |  $1 == 1     |   $1 == 0     |
| %postun     |   (N/A)     |  $1 == 1     |   $1 == 0     |


整理するとこの順番、この引数の値で呼ばれます。

- 初回インストール時

|             |             |            |
|:------------|:------------|:----------:|
| 1           |   %pre      |  $1 == 1   | 
| 2           |   $post     |  $1 == 1   | 

- アップグレード時

|             |             |            |            |
|:------------|:------------|:----------:|:----------:|
| 1           |   %pre      |  $1 == 2   |  new rpm   |
| 2           |   $post     |  $1 == 2   |  new rpm   |
| 3           |   %preun    |  $1 == 1   |  old rpm   |
| 4           |   %postun   |  $1 == 1   |  old rpm   |

※注意　%preunと%postunは古いパッケージの方のものが呼ばれる。しかも順番は後になる。

- アンインストール時

|             |             |            |
|:------------|:------------|:----------:|
| 1           |   %preun    |  $1 == 0   | 
| 2           |   $postun   |  $1 == 0   | 


# 修正

なので$1が0のときだけと判定するようにします。

```txt:goblin-slayer.spec
Name:     goblin-slayer
Version:  1.00
Release:  1%{?dist}
Summary:  GOBLIN SLAYER
License:  GPL+ or Artistic
BuildArch:  noarch

%description
%prep
%setup -T -c
%files

%pre
touch /etc/cow_girl.ini

%post
touch /etc/priestess.ini

%preun
if [ $1 -eq 0 ]; then
    rm -f /etc/cow_girl.ini
fi

%postun
if [ $1 -eq 0 ]; then
    rm -f /etc/priestess.ini
fi
```


# 参考

[pre,post,preun,postunの$1の値 \- Qiita](https://qiita.com/todanano/items/7ee8bb6f496000b48bae)



[RPM SPEC scriptlet \- ダメ出し Blog](https://fumiyas.github.io/rpm/scriptlet.html)
[論文メモ]Pixie: A System for Recommending 3+ Billion Items to 200+ Million Users in Real-Time 

"Graph Convolutional Neural Networks for Web-Scale Recommender Systems"で

- importance-based neighborhoodの定義のためにrandom walkを使う方法

が引用されていたのでこれらのアルゴリズムをメインに読む。

# 3 Proposed method
- notations
    - $P$: ピンの集合
    - $B$: ボードの集合
    - $P \cup B$: ノードの集合
    - $E$: エッジの集合。$(p, b) \in E$ ならばピン $p$はボード $b$にあるユーザーによって保存されている。
    - $E(p)$: ピン $p$と接続されているボードの集合。
    - $E(b)$: ボード $b$と接続されているピンの集合。
    - $Q=\\{(q, w_q)\\}$: クエリピン$q$とその重要度$w_q$。$Q$はユーザー固有となる。

### Basic Random Walk
![スクリーンショット 2018-11-20 0.33.10.png](https://qiita-image-store.s3.amazonaws.com/0/199247/98b9d3f6-4dc7-3592-4b88-db1bc9565c8e.png)

- この論文では新しいアルゴリズムを提案する。


### Biasing the pixie random walk
- ユーザーごとにrandom walkにバイアスを掛けることが重要である。
- Pinterestでは、異なる言語やトピックが存在し、ユーザーはユーザーの言語や興味のあるトピックに関するリコメンドを好む。
- この論文では、ユーザーの特徴量に応じてrandom walkのバイアスを変化させることを提案している。

![スクリーンショット 2018-11-20 0.49.55.png](https://qiita-image-store.s3.amazonaws.com/0/199247/085beb7d-ced7-d928-75c7-b2e8ad94d662.png)

- PersonalizedNeighbor(E, U)によりユーザーの特徴量に応じてバイアスを掛けている。


### Multiple query pins with weights
- ユーザーごとにリコメンドするためにクエリ$q$ごとに$w_q$を使ってrandom walkのステップ数を決める。
- $N_q = w_q N \frac{s_q}{\sum_{r \in Q} s_r}$ (Eq. 2)   
- $s_q = |E(q)| \cdot (C - \log |E(q)|)$
![スクリーンショット 2018-11-20 9.03.30.png](https://qiita-image-store.s3.amazonaws.com/0/199247/7ca5a58d-2340-c773-da39-094b7a2db305.png)


### Multi-hit Booster
- $Q$に含まれる複数のピンに基づいてレコメンドをしたい。
- 基本的なアイデアは、Qに含まれる複数のクエリに最も関連するピンがレコメンドの候補となる。
- アルゴリズム3の5行目のように、各クエリに対するvisit countを集約することで実現する。
- $V[p] = (\sum_{q \in Q} \sqrt{V_q[p]})^2$


### Early stopping
- Pixieの実行時間はrandom walkのステップ回数に依存する。実行時間を短縮するためにEarly stoppingを行う。
- $n_p$と$n_v$を導入し、訪問回数が$n_v$以上のピンが$n_p$個存在した時点でrandom walkを終了する。
- アルゴリズム2の10から13行目

## 3.2 Graph Pruning
- Graphのサイズを小さくすることにより、精度の向上や計算リソースの削減を行う。
- LDAを使って潜在ベクトルを計算し、エントロピーの大きいボードをグラフから取り除く。
- また、ピンとボードのCos類似度を計算し、類似度の低いピンを取り除く。


# 最後に
- 今回の目的は"Graph Convolutional Neural Networks for Web-Scale Recommender Systems"を理解するためにPixieのアルゴリズムを理解することだったので、アルゴリズム以外のところはそのうちまとめる。
カラーセンサー[S11059-02DT]で取得した色データを、RGBにしてみる

## 目標
カラーセンサーを使用して、環境の色をRGB値として取得したい

## 知識材料 
- [S11059-02DT](https://www.hamamatsu.com/jp/ja/product/type/S11059-02DT/index.html)

## 利用環境
- [Arduino IDE 1.8.7](https://www.ibm.com/cloud-computing/jp/ja/lite-account/)
- [ESP8266 core for Arduino 2.4.2](https://github.com/esp8266/Arduino)
- [ESP-WROOM-02]

今後、取得した色をサーバに送信したかったので、WROOM-02 を使いました。
Arduino Uno などでも動きます。

## 今回のゴール
カラーセンサーの 「赤」「青」「緑」を、なんとなくRGB値として出力

# 実践
## 接続
マイコンとセンサーを接続する。

| Arduino PIN | DST |
| :--- | :--- |
| 3V3 | 3.3V |
| GND | GND |
| IO14 | [S11059]  SDA |
| IO13 | [S11059]  SCL |

## Arduino 側ソースコード
[I2Cコマンドを参考にさせていただいた](http://numanohate.hateblo.jp/entry/2015/08/28/111202)

あらかじめ、センサーに「赤いライト」「青いライト」「緑色のライト」を近づけて、
一番大きかった「赤の値」、「青の値」、「緑の値」を
RGBの 0xFF として得られるように map()関数を設定。


```cpp:s11059.ino
#include <Wire.h>

#define I2C_SDA 14
#define I2C_SCL 13

#define S11059_ADDR 0x2A

void setup() {
  Serial.begin(74880);
  Serial.println("start");

  // Init I2C 
  Wire.begin(I2C_SDA, I2C_SCL);

  // 0x00 = Control 
  // 0x8B = ADC-Reset + High Gain + 179.2ms
  Wire.beginTransmission(S11059_ADDR);
  Wire.write(0x00);
  Wire.write(0x8B);
  Wire.endTransmission();

  // 0x00 = Control 
  // 0x0B = ADC-Run + High Gain + 179.2ms
  Wire.beginTransmission(S11059_ADDR);
  Wire.write(0x00);
  Wire.write(0x0B);
  Wire.endTransmission();
}

void loop() {
  delay(720);

  int h,l ,r,g,b,a;
  // 0x03 Read Data
  Wire.beginTransmission(S11059_ADDR);
  Wire.write(0x03);
  Wire.endTransmission();
  
  Wire.requestFrom(S11059_ADDR,8);
  if(Wire.available()){
    // Red
    h = Wire.read();
    l = Wire.read();
    r = h << 8|l;
    Serial.print(" r:");
    Serial.print(r);
    // Green
    h = Wire.read();
    l = Wire.read();
    g = h << 8|l;
    Serial.print(" g:");
    Serial.print(g);
    // Blue
    h = Wire.read();
    l = Wire.read();
    b = h << 8|l;
    Serial.print(" b:");
    Serial.print(b);
    // Infra red
    h = Wire.read();
    l = Wire.read();
    a = h << 8|l;
    Serial.print(" a:");
    Serial.print(a);

    // It converted to RGB?
    int rr, gg, bb;
    Serial.println(" ");
    rr = map(r, 30, 56000, 0, 255);
    gg = map(g, 30, 41000, 0, 255);
    bb = map(b, 30, 56000, 0, 255);
    Serial.print(rr, HEX);
    Serial.print(" ");
    Serial.print(gg, HEX);
    Serial.print(" ");
    Serial.print(bb, HEX);
    Serial.println("");
  }
  Wire.endTransmission();

}
```
## 実行と結果
動画内に表示される
*r:xxxxx g:xxxxx b:xxxxx a:xxxx* の行は、センサーの値をそのまま出力。
その次の HEX 行は、それぞれ `R`/`G`/`B` に変換した結果。

[![S11059](http://img.youtube.com/vi/z5Hzytl0lkY/0.jpg)](https://www.youtube.com/watch?v=z5Hzytl0lkY)

## まとめ
何に使うかはさておき、
適当なRGB変換処理にしては、それっぽい色味を得られていたと思う。
ネットワークについて

###### ネットワークについて

1.IPv6無効化

``` command:ターミナル
sudo networksetup -setv6off Wi-Fi
```

2.hostsファイル

``` command:ターミナル
vi /etc/hosts
#######::1             localhost
```

3.ネットワーク接続状況

``` command:ターミナル
netstat -na | more
```

4.プロセス情報

``` command:ターミナル
lsof -i TCP
lsof -p <プロセスID>
```
PHPフレームワーク「Laravel」でWEBページを作るにはどこで何をすればいい？

フレームワークとは、ざっくり説明すると開発に役立つ機能群です。
プログラムの書き方は人それぞれです。
しかし、フレームワークを使うことで、効率よく開発できるだけでなく、他の人が見たときにもわかりやすいコードが作成できます。

今回は、フレームワークの中でもWEB開発に役立つPHPフレームワーク「Laravel」のディレクトリ構成をMVCの概念にあわせて、簡単に説明します。

#Laravelはどこに何がある？
Laravelを入れたフォルダに移動すると、このようなファイルやフォルダが入っているのが分かります。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/298418/be57c4e2-8eae-be92-2ceb-139da5cccc5a.png)

適切なフォルダにコードを記入していきます。

今回は開発の目的ごとに、どのフォルダに何をつくればいいのか説明してきます。

##名前で機能をイメージしよう
初見で、どこに何があるのかはわかる人は素晴らしいです。
フレームワークを熟知していない私には、とても無理でした。
しかし、ファイルやフォルダの名前から大体どのような機能が入っているのか想像することはできます。

これを意識するうちに、どのフォルダで何をすればいいかだんだん理解できるようになるかもしれません。

##WEBページを表示したい
基本中の基本、表示したいページのファイル（例えば、index.php）とcssはどのディレクトリ下のファイルに書いたらいいんだろう・・・。
htmlを記述したページのファイルは、`/resources/views/`、
![image.png](https://qiita-image-store.s3.amazonaws.com/0/298418/efb292eb-0424-6ffa-47cd-1380622794f3.png)

cssファイルは、`/public/css`の下に書いていきます。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/298418/ad35f86f-ddb3-0382-933a-e8ed71ff32dd.png)

cssファイルはディレクトリ名がcssなので、分かりやすいですね。

ページとして表示するファイルをviewsディレクトリ下に置く理由を考えるには、MVCという概念を理解することが大切です。

MVCは、それぞれModel、View、Controllerを表していて、このViewに当てはまる処理をviewsディレクトリ下に書いていくのです。
この概念におけるViewとはデータの処理に基づいて、htmlなどの出力を行う処理を表しています。

そのため、ページとして表示するファイルはViewであるから、viewsディレクトリ下に作成すればいいのです。

##メインの処理やデータベースへのアクセス
メインの処理やデータベースへのアクセスは、MVCの概念では、Modelに該当します。

Modelのファイルは`/app/`の下に入れます。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/298418/1aae44b9-3612-e9f4-84af-5142b55f0bd1.png)

ただし、Modelを書く時は、自分でファイルを作成するのではなく、
laravelのコマンドartisanを使って、`php artisan make:model モデル名`で作成するのがおすすめです。

##ユーザーからのリクエストに応じて処理
ユーザーからのリクエストを受けとり、それに応じた処理をModelやViewを制御することで実行するのが、MVC概念のControllerの役割です。

Controllerのファイルは`/app/Http/controllers/`の下に入れます。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/298418/34e2d9cf-6c97-537e-481f-bd2b92f8a225.png)

ControllerもModelと同様に、artisanを使って、
`php artisan make:controller コントローラー名`を実行することができます。
言語によって異なる処理の書き方まとめ

# はじめに

この記事は普段プログラム書いてて「あれ？○○だとこう書くんだけど、この言語はどう書くんだっけ？」ということがよくあるので主に自分向けの備忘録として書いたものです。内容は都度追加していく予定です。
現在、主に使っているのがRuby、Python、JavaScriptなのでそれらの比較が多いです。

# 制御構造

## else if

### Ruby - elsif

```rb
if a > 0
  puts 'plus'
elsif a < 0
  puts 'minus'
end
```

### Python - elif

```py
if a > 0:
  print('plus')
elif a < 0:
  print('minus')
```

### JavaScript - else if

```js
if (a > 0) {
  console.log('plus');
} else if (a < 0) {
  console.log('minus');
}
```

## switch的構文

### Ruby - case when

```rb
case a
when 1
  puts 'one'
when 2
  puts 'two'
end
```

### Python

そんなものはない（関羽略）

### JavaScrpt - switch case

break忘れないように。

```js
switch (a) {
case 1:
  console.log('one');
  break;
case 2:
  console.log('two');
  break;
}
```

# データ型全般

## falseになるもの

### Ruby - nil

むしろfalseにならないものの方が多い。

```rb
p nil || 1
p [] || 1
p '' || 1
p 0 || 1
```

### Python - None、空配列や空文字列、0

Falseになるものが多いのでしばらくPython書いた後に別言語に行くと注意。

```py
print(None or 1)
print([] or 1)
print('' or 1)
print(0 or 1)
```

### Javascript - undefined、null、空文字列、0

空配列はtrue。forとかで回すと結局回らないことになるけど、ifで条件分岐後、for前後で何かしている場合は注意（`arr.len != 0`と条件を書こう）

```js
console.log(undefined || 1);
console.log(null || 1);
console.log([] || 1);  // 空配列はtrue
console.log('' || 1);
console.log(0 || 1);
```

# join

言語により配列（的）クラスにjoinがあるか文字列クラスにjoinがあるかが異なる。

## Ruby - Array#join

```rb
[1, 2, 3].join(',')
```

## Python - str.join

罠のうえに連結要素は文字列じゃないといけない。

```py
a = [1, 2, 3]
','.join([str(e) for e in a])
```

## JavaScript - Array#join

```js
[1, 2, 3].join(',')
```

# 配列

Pythonは配列ではなくリストであり、配列は別にあるのだがここでは「配列」という言葉でまとめる。

## 要素を繰り返し処理

### Ruby - Array#each

```rb
arr = [1, 2, 3]
arr.each {|e| p e}
```

### Python - for in

```py
arr = [1, 2, 3]
for e in arr:
  print(e)
```

### JavaScript - for ofかArray#forEach

for ofの方が関数呼び出しじゃないので好きだけど、for inと間違えやすいからArray#forEachの方がいいのかも。
※対話環境に貼り付け実行しやすいようにvarもletもconstも付けてませんが、もちろんファイルに書くときは適切なものを付けてください。

```js
arr = [1, 2, 3];
for (let e of arr) {
  console.log(e);
}
arr.forEach(e => console.log(e));
```

## 条件を満たすものを取り出す

### Ruby - Array#select

```rb
arr = [1, 2, 3, 4, 5]
p arr.select{|e| e % 2 == 0}
```

### Python - filter

第1引数が条件チェックの関数。
また、filter関数の戻り値はイテレータを実装したfilterオブジェクトなので配列が欲しかったらlist関数に渡す必要あり（ていうかfilterもlistも正確にはコンストラクタ。mapなどの他の関数も同様）

```py
arr = [1, 2, 3, 4, 5]
print(list(filter(lambda e: e % 2 == 0, arr)))
```

↓@shiracamusさんの編集リクエストより。内包表記のような「書き方が大きく異なる（それを忘れることはない）」記述方法は本筋ではないですが、せっかくなので採用させていただきます。
または

```py
arr = [1, 2, 3, 4, 5]
print([e for e in arr if e % 2 == 0])
```

### JavaScript - Array#filter

```js
arr = [1, 2, 3, 4, 5];
console.log(arr.filter(e => e % 2 == 0));
```

# 文字列

## 部分文字列

### Ruby - []でRangeを指定

しばらく触ってないとsubstr的メソッドを探してしまう(笑)

```rb
s = 'abcdefg'
p s[3..-1]
```

### Python - []でスライスを指定

Rubyみたいに`s[3:-1]`だと末尾が含まれなくなるの注意。

```py
s = 'abcdefg'
print(s[3:])
```

### JavaScript - String#substr

substringメソッドもある。

```js
s = 'abcdefg';
console.log(s.substr(3));
```

いつの間にかsubstrは非推奨メソッドになってた。長さで指定できた方が便利なのに、と思ったけどRubyやPythonも末尾指定するときはindexか。
Jenkinsfileのpostブロックでagentを指定する

Declarative Pipelineでも、postブロックの中をscripted pipeline的に書くことでnodeを指定することができます。

```groovy
post {
    always {
        node('master') {
            echo 'post block now'
            sh './cleanup.sh'
        }
        node('slave1') {
            sh './cleanup.sh'
        }
    }
}
```
参考:
https://stackoverflow.com/questions/44531003/how-to-use-post-steps-with-jenkins-pipeline-on-multiple-agents
Vagrant + libvirt の環境構築手順

KVMのVMをVagrantで起動する環境の構築手順です。
KVMはVirtual Boxに比べて、VM起動までの時間が圧倒的に早いです。
なので、VMを作ったり消したりを頻繁にやる人にはオススメです。

ここではKVMの環境を作るために、libvirtを使った手順を説明します。

※注意事項
KVMとVirtual Boxは同じ環境で共存できません。
すでにVirtual BoxでVMを立てている人は全て削除するか、
別の環境を用意してください。

## 1. 環境
- Ubuntu 18.04 LTS
- Vagrant 2.1.5

## 2. 必要なソフトウェアのダウンロードとインストール
aptでインストールすると、古いバージョンのVagrantが入ってしまい、なにかと詰まるので手動で新しいバージョンを入れていきます。

```
$ wget https://releases.hashicorp.com/vagrant/2.1.5/vagrant_2.1.5_x86_64.deb
$ sudo dpkg --install vagrant_2.1.5_x86_64.deb
$ sudo apt update
$ sudo apt build-dep vagrant ruby-libvirt
$ sudo apt install qemu libvirt-bin ebtables dnsmasq
$ sudo apt install libxslt-dev libxml2-dev libvirt-dev zlib1g-dev ruby-dev
```

## 3. Vagrantのプラグインをインストール

```
$ vagrant plugin install vagrant-libvirt
# 終わったら、一旦ログアウトして、再ログインする
```
libvirtを入れるとユーザが追加されるので、ログインし直して設定を反映させます。


## 4. VMを起動してみる
ディレクトリを作って、VMを起動します。
うまく起動できない場合は、トラブルシューティングも見てみてください。

```
$ mkdir vagrant-test
$ cd vagrant-test
$ vagrant init generic/ubuntu1604
$ vagrant up --provider libvirt
```

起動できているか確認します。
"running"になっていれば成功です。

```
$ vagrant status
Current machine states:

default                   running (libvirt)

The Libvirt domain is running. To stop this machine, you can run
`vagrant halt`. To destroy the machine, you can run `vagrant destroy`.
```

初回の起動はboxのダウンロードが入るので、遅いです。
一度、VMを作り直してみると、起動完了までの早さが実感できるかと思います。

```
# VMを消してから、再度起動
$ vagrant destroy
$ vagrant up --provider libvirt
```



## トラブルシューティング

起動時に以下のようなエラーが出る場合は、libvirtdのユーザ追加がうまくいっていない可能性があります。

```
Error while connecting to libvirt: Error making a connection to libvirt URI qemu:///system?no_verify=1&keyfile=/home/vagrant/.ssh/id_rsa:
Call to virConnectOpen failed: Failed to connect socket to '/var/run/libvirt/libvirt-sock': Permission denied
```

### 対処方法
libvirtdのグループにユーザを追加してあげれば直ります。

```
$ sudo adduser $USER libvirtd
Adding user `hoge' to group `libvirtd' ...
Adding user hoge to group libvirtd
Done.

# 一旦、VMを消してから、再度起動
$ vagrant destroy
$ vagrant up --provider libvirt
```
Modelicaで最適化 - OpenModelica編

# Modelicaで最適化を試す 

Modelicaで最適化(動的計画法)を行う場合いくつか選択肢がある
詳細はこちら
https://qiita.com/UedaShigenori/items/aae444326b28ccc8b20f

本稿ではOpenModelicaのOptimizationクラスを使用した場合を詳述する

---

# Optimizationクラスを使用する

## 実行方法

このUser's Guideの内容を実施する
https://www.openmodelica.org/doc/OpenModelicaUsersGuide/latest/optimization.html

最適化はOMShellから実行しないと多分上手くいかない
一応、OMEditからもオプションをつければOptimizationクラスは認識してくれるがたしか計算が回らなかった

まずはOptimizationオプションを有効にする

```
setCommandLineOptions("-g=Optimica")
```

---

以降は参考サイトにあるように以下のmoファイルを読み込んで実行する
inputが値を振りたい変数
optimizationクラスのobjectiveが目的関数
変数の範囲はmin, maxにて設定できる

多分デフォルトではobjectiveで指定された変数が最大化される

```BatchReactor.mo
model BatchReactor
  Real x1(start =1, fixed=true, min=0, max=1);
  Real x2(start =0, fixed=true, min=0, max=1);
  input Real u(min=0, max=5);
equation
  der(x1) = -(u+u^2/2)*x1;
  der(x2) = u*x1;
end BatchReactor;
```

```nmpcBatchReactor.mo
optimization nmpcBatchReactor(objective=-x2)
  extends BatchReactor;
end nmpcBatchReactor;
```

---

計算を実行する

```
//moファイルがあるパスをいれる
cd("C:\hogehoge")
loadFile("BatchReactor.mo")
loadFile("nmpcBatchReactor.mo")
//最適化実行
optimize(nmpcBatchReactor, numberOfIntervals=16, stopTime=1, tolerance=1e-8)
```

matファイルが出力されるのでOMEditなどで読み込む
結果を見ても式が複雑すぎて本当に最適化されているのやら分からない

---

## 分かりやすい問題作成

最適な結果が自明な問題を作成してOpenModelicaの最適化機能を確認してみる

y=-x^2(-1<x<1)で一番yが大きくなるxの値を探す
答えはもちろんx=0のときyは最大で0となる

```test.mo
model test
  Real y;
  input Real x(min=-1, max=1);
equation
  y=-x^2;
end test;
```
```optim.mo
optimization optim(objective=y)
  extends test;
end optim;
```

---

結果はx,yともに0となった。
良さそうだ。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/244254/57a89807-bed0-a8ca-97fc-7968e82b8bbd.png)

---

## 少しだけ難しい問題作成

以下の問題も解いてみよう

```test.mo
model test
  Real y;
  input Real x(min = -1, max = 1);
equation
  y=(x-10)^2;
end test;
```

答えはx=-1のとき、yが最大(121)となる。

---

以下は結果だが、どうしてもx=0, y=100を示してしまう。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/244254/c851ce93-4fcf-5747-33c1-440578cc2427.png)

設定が悪いのだろうか？

誰か分かる人がいれば教えてほしい

とりあえずOpenModelicaのせいと考えてJModelicaで試してみる
-> ToBeContinue
[PowerShell]ある日付から何日か前の日付を取得する To Get Date before X days From Some Day.


2019年5月3日から122日前の日付を取得します。
$dt1に2019年5月3日を代入します。この時VBAで使われるような\#5/3/2019#のような日付リテラルで囲んだりシングルクォーテーション、ダブルクォーテーションで囲まなくてよいようです。
念のためデータの型（Type）を強制するため[DateTime]をつけています
関数としては、ある日付の何日か前はAddDaysに▲の日数を入れて求めます。

```powershell
[datetime]$dt1 = get-date -date 2019/5/3 ;[datetime]$dt2= $dt1.AddDays( -122);Write-Host $dt2
```
pyenv-virtualenvでインストールしたmod_wsgiでDjangoを動かす

研究発表的なものの直前にここにハマるとは。。
後日、きちんと書き直します。
この方法は超insecureです。

# 問題

```bash:シェル
(orf) pip install　mod_wsgi
```
orfはpyenv-virtualenvの環境名。
ここでmod_wsgiをして

```bash:httpd.conf
LoadModule wsgi_module /usr/lib64/httpd/modules/mod_wsgi-py37.cpython-37m-x86_64-linux-gnu.so
WSGIPythonHome /root/.pyenv/versions/3.7.1/envs/orf
WSGIScriptAlias /orf /home/orf/demo/demo/wsgi.py
WSGIPythonPath /home/orf/demo

<Directory /home/orf/demo/demo>
<Files wsgi.py>
Require all granted
</Files>
</Directory>
```

普通にこのような設定ファイルを書いても動かない(LoadModuleのwsgi_moduleの位置だけ変更した)

# 解決法
つまり、apacheユーザがpythonを使えないよ！って言ってるんだってことに気づいた。
それもその通りで、ユーザ配下の~/.pyenv/以下でpythonが動いてるんだから、権限的にapacheはrootの中のものを使えない。
そこで

```bash:シェル
usermod -aG root www
```
上記をうつ。すると、wwwがrootの権限も持つようになる。
ただし、当たり前だけどそんなのは危険極まりないので、本当はrootじゃないユーザでやるべき。
今回は研究実装のdemoであるので、無視することにした。

# 所感
久々にDjangoを立てようとしたら、つらたんだった。
2時間ほどハマってた。。
react-tippyでコンテンツがはみ出るときに無理やりtooltipのwidthを大きくする方法

多分これが一番早いと思います。

[react-tippy](https://github.com/tvkhoa/react-tippy) 便利です。rc-tooltipより簡単にリッチなツールチップを作れるので重宝しています。

react-tippy でコンテンツをカスタマイズするときは `html` という props を渡してあげれば良いのですが、渡すコンポーネントの幅が大きすぎるとツールチップの幅を飛び出してデザインが崩れます。

そういうときはこうしてやります。

```index.css
.tippy-popper {
  max-width: 10000px !important;
}
```

`react-tippy/dist/tippy.js` に `max-width: 450px` と記述されているのでこいつを無効にしてやる必要があるのです。おそらく props に文字列を渡すときはいい感じに改行されてほしいためこんな記述があるのだと思いますが、`html` を渡すときは邪魔なだけなので無効にしてしまって良いのではないでしょうか。

ちなみにこういうのを作っていました（食べ物のサムネイルにホバーすると栄養素を見ることができるやつ）。

<img width="522" alt="スクリーンショット 2018-11-20 22.27.37.png" src="https://qiita-image-store.s3.amazonaws.com/0/3387/6407fb04-7fcd-c398-a885-dc8c3affa398.png">
BitVisorをUbuntu 18.04.1でビルドしてUEFIブートする(GRUB2)

# 必要なパッケージをインストールする
```sh
sudo apt -y install mercurial make gcc mingw-w64
```

# レポジトリをcloneしてビルドする
```sh
$ hg clone https://bitbucket.org/bitvisor/bitvisor
$ cd bitvisor
$ make config
$ make
$ make -C boot/loader
$ make -C boot/uefi-loader
```

# ファイルシステムを調べる
`/dev/sda1`がファイルシステムでマウントポイントが`/boot/efi`であることがわかる．

```sh
moly@yayoi:~$ cat /etc/fstab
# /etc/fstab: static file system information.
#
# Use 'blkid' to print the universally unique identifier for a
# device; this may be used with UUID= as a more robust way to name devices
# that works even if disks are added and removed. See fstab(5).
#
# <file system> <mount point>   <type>  <options>       <dump>  <pass>
/dev/mapper/ubuntu--vg-root /               ext4    errors=remount-ro 0       1
# /boot/efi was on /dev/sda1 during installation
UUID=D9A0-E1B5  /boot/efi       vfat    umask=0077      0       1
/dev/mapper/ubuntu--vg-swap_1 none            swap    sw              0       0
```

# ビルドした結果をマウントポイントに格納する
先程確認したマウントポイント`/boot/efi`にビルドした産物をコピーする．

```sh
sudo cp bitvisor.elf /boot/efi
sudo cp boot/uefi-loader/loadvmm.efi /boot/efi
```

# GRUB2の設定ファイルを書く
設定ファイルは`/etc/grub.d/99_bitvisor`など適当に名付ける．
[BitVisorの開発者メーリングリスト](http://www.bitvisor.org/archives/bitvisor-devel/2017-January/000101.html) によると，multibootではBIOSモードで起動してしまうので，chainloadを使用する必要があるらしい．

```sh
#!/bin/sh
set -e

datarootdir="/usr/share"

. "${datarootdir}/grub/grub-mkconfig_lib"

if [ \! -f /boot/efi/bitvisor.elf ]; then
    exit 0
fi

if [ \! -f /boot/efi/loadvmm.efi ]; then
    exit 0
fi

echo "Found BitVisor image" >&2

cat << EOF
menuentry "BitVisor" {
    echo 'Loading Bitvisor ...'
    insmod chain
    insmod part_gpt
    insmod search_fs_uuid
    search --fs-uuid --no-floppy --set=root ここにさっき調べたUUIDを書く
    chainloader (\${root})/loadvmm.efi
    boot
}
EOF
```

# GRUB2の設定を反映させる
```sh
sudo update-grub2
```
Docker上に最小限のGo開発環境を作る

# この記事の目標
- Docker上にGo開発環境を作る


## コンテナの作成と起動
### 最新のCentOsをpullして起動

```
$ docker pull centos:latest
latest: Pulling from library/centos
aeb7866da422: Pull complete 
Digest: vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
Status: Downloaded newer image for centos:latest
```
## ローカルとdockerをリンクさせる
ローカルのパス（/Users/develop/dockerWork/dockerFile/go/src）をdockerの/homeをリンクさせます。


```
$ docker run -v /Users/develop/dockerWork/dockerFile/go/src:/home/ -it --name golang centos
[root@28e51bf98e70 /]# 
```

## 一旦コンテナから抜ける

```
[root@28e51bf98e70 /]# exit
```

## パスを通す

```
$ vi ~/.bash_profile
以下を追加
↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓
export PATH=$PATH:/usr/local/go/bin
```

## 環境変数を反映させる

```
$ source ~/.bash_profile
```

## 作成したコンテナに接続

```
$ docker attach 28e51bf98e70
[root@28e51bf98e70 home]#
```

## Goをインストールする

```
[root@28e51bf98e70 home]# yum install go
```
## Goで「Hello World」を表示する
Golangディレクトリに**main.go**を作成

```
[root@28e51bf98e70 home]#　mkdir Golang
[root@28e51bf98e70 home]#　cd Golang
[root@28e51bf98e70 Golang]#　touch main.go
[root@28e51bf98e70 Golang]#　vi main.go
```

```main.go
package main

import "fmt"

func main(){
    fmt.Println("Hello, world")
}
```

## main.goを実行する

```
[root@28e51bf98e70 Golang]# go run main.go
```

ひとまず最小限のGo環境をDockerで作ることができた！

```
[root@b556964ac38b Golang]# go run main.go
Hello, world
```