OmniAICreator/Qiita-1.07M huggingface dataset:
aws環境でnode.js、lambda、CodeCommit、CodeBuild、CloudFormation、CodePipelineを使って開発作業を自動化する

# はじめに
システムを作成する上で、運用や諸々の管理にかかる手間は相当なものです。そのため運用にかかる作業を自動化することで、本来注力したい付加価値を生むクリエイティブな仕事に専念できるようにしようと言われています([Twelve-Factor App](https://12factor.net/ja/)や[AWS Well-Architected](https://aws.amazon.com/jp/architecture/well-architected/)等)。そこで本記事ではawsでサーバレス環境を構築する上で必要なデプロイや管理作業を自動化し、開発者の作業ミスや手間を減らし、開発作業を効率化していくための情報をまとめます。


**例えば、リモートリポジトリに変更をコミットするたびに自動的にテストが実行され、テスト結果がエラーの場合はメールで通知し、エラーがなかった場合はデプロイを実行するといった処理を自動化します。**

# 各記事
以下に本稿のテーマに沿って作成した各記事へのリンクを貼ります。

## Cloudformationを使ったlambda単体のデプロイ
デプロイの自動化のシンプルな例として、**Cloudformationを使ったlambda単体のデプロイ**について以下にまとめています。
[CloudFormationを使ってlambda(node.js)環境を構築する](https://qiita.com/kyuaz/items/c1374c8d0711fd400aaa)

## lambdaの起動条件（トリガー）込みでデプロイする例
lambda単体ではなく、**lambdaの起動条件（トリガー）込みでデプロイする例**について以下記事にまとめています。
[CloudFormationを使ってCloudWatch Eventsでスケジュール起動されるlambdaをデプロイする](https://qiita.com/kyuaz/items/b263de53d15f646901dc)

## CodeBuildを使ってデプロイおよびテストを実行する
(JenkinsのようなCIツールである)**CodeBuildを使ってデプロイおよびテストを実行する**手段について以下にまとめています。
[aws CodeBuildを使ってlambda(node.js)環境をテスト→デプロイする](https://qiita.com/kyuaz/items/604d11b8af1921112f99)

## コミットする度に自動テスト実行し、エラーならメール通知する
**リモートリポジトリにコミットする度に自動的にテストを実行し、テストでエラーが出た場合メールで通知する仕組みの構築**について以下にまとめています。
[aws CodeBuildとAmazon SNSを組み合わせて単体テストエラー時にメールする](https://qiita.com/kyuaz/items/93a4e0e6a636d1301df7)

## cloudformationのテンプレートをチェックしてからデプロイする
CodeBuildでデプロイする時に、**事前にテンプレートファイルの文法チェックやスタックの存在有無をチェックしてからデプロイするように改良を加えたもの**を以下にまとめています。
[CodeBuildからCloudFormationを使ってデプロイする時にテンプレートファイルの文法チェックやスタックの存在有無をチェックしてからデプロイする](https://qiita.com/kyuaz/items/26beef67bff4f4fa12fb)

各記事と使用しているawsサービスの関係をまとめると以下表のようになります。

| 記事 | Lambda | CloudFormation | CodeBuild | CodeCommit | CodePipeline |aws cli| CloudWatchEvents | Amazon SNS |
|:----|:------:|:--------------:|:---------:|:----------:|:------------:|:-------:|:----:|:----:|
|[CloudFormationを使ってlambda(node.js)環境を構築する](https://qiita.com/kyuaz/items/c1374c8d0711fd400aaa)|○|○||||○|||
|[CloudFormationを使ってCloudWatch Eventsでスケジュール起動されるlambdaをデプロイする](https://qiita.com/kyuaz/items/b263de53d15f646901dc)|○|○||||○|○||
|[aws CodeBuildを使ってlambda(node.js)環境をテスト→デプロイする](https://qiita.com/kyuaz/items/604d11b8af1921112f99)|○|○|○|○||○|||
|[aws CodeBuildとAmazon SNSを組み合わせて単体テストエラー時にメールする](https://qiita.com/kyuaz/items/93a4e0e6a636d1301df7)|○|○|○|○|○|○||○|
|[CodeBuildからCloudFormationを使ってデプロイする時にテンプレートファイルの文法チェックやスタックの存在有無をチェックしてからデプロイする](https://qiita.com/kyuaz/items/26beef67bff4f4fa12fb)|○|○|○|○||○|||

# まとめ
本記事では、aws上でサーバレスなシステムを構築する上で、デプロイや開発に伴う作業等を自動化する手段を、私が今まで記事にしたものをまとめています。新たに記事を書いたら、ここに追加していきたいと思います。
Visual Studio 2017 Linux C++ ワークロードをDockerでデバッグ

# バージョン
Visual Studio 2017: 15.9.4
Docker for Windows: Engine: 18.09.0 Compose: 1.23.2

# Linux C++ ワークロード
Visual Studio 2017でLinuxターゲットのC++プロジェクトが作れてしまう、クロスプラットフォームな奴。Linuxといいつつ実際はGNUツールチェインが相手なので、Linuxカーネルでなくても使えそう。
SSHでつないでgcc-g++とgdbserverを叩く。

# 元のDockerイメージ
私のターゲットがAWS Lambdaなので、[quiltdata/lambda](https://github.com/quiltdata/lambda)。

# Dockerfile
公開鍵認証でログインしたいところが、Visual Studio 2017の15.9.4は[このバグ](https://developercommunity.visualstudio.com/content/problem/374945/key-openssh-is-not-supported.html)が再発している模様なので、パスワードでログインする。
たくさんyum installするので時間がかかる。

```Dockerfile
FROM quiltdata/lambda

ARG USER

RUN yum -y update && yum -y install openssh-server && yum -y install sudo && yum -y install passwd && yum -y install gdb-gdbserver && yum -y install gcc-c++ && yum -y install gdb
RUN adduser $USER && echo abcd | passwd --stdin $USER
RUN echo "$USER ALL=(ALL) NOPASSWD:ALL" >> /etc/sudoers
RUN sed -ri 's/PasswordAuthentication no/PasswordAuthentication yes/g' /etc/ssh/sshd_config

CMD /etc/init.d/sshd start && tail -f /dev/null
```

# docker-compose.yml
SSHのポートは2022にフォワーディング。SYS_PTRACEはgdbに必要。

```docker-compose.yml
version: '2'
services:
    app:
        build:
            context: .
            args:
                USER: user1
        container_name: lambda
        stdin_open: true
        tty: true
        ports:
            - "2022:22"
        volumes:
            - .:/share
        cap_add:
            - SYS_PTRACE
        security_opt:
            - seccomp:unconfined
```

# Dockerイメージのビルド・実行
Dockerfileとdocker-compose.ymlを同じフォルダに入れて、そのフォルダにcdしてdocker-compose build
起こすときはそのフォルダでdocker-compose up -d
寝かすときはそのフォルダでdocker-compose stop

# Linux C++ワークロードプロジェクトのリモートデバッグ
Visual Studioのツール→オプション→クロスプラットフォーム→接続マネージャーでSSH接続を追加する。ポートは2022、ユーザ名はuser1、パスワードはabcd。
SSH接続は問題なく作れたのにリモート実行できないときは、ソリューションのリビルド。

# 参考
[amazon linuxのイメージを使用してsshできるコンテナを作る](https://qiita.com/takeshi_miyajim/items/92a525e6beddd438c76b)
[Build Lambda deployment packages faster with Docker](https://github.com/quiltdata/lambda)
SQLServerにてトレースログを取る方法

2017での確認。バージョンでの差異はあるかもしれない。

##トレース取得準備
1.SSMSを起動し、[サーバーへの接続]ダイアログから任意のサーバーに接続する。
　→ログイン状態となる
2.メインメニュー[ツール]->[SQLServer プロファイラー]を選択する。
　→アプリケーション[SQLServer プロファイラー]が起動し、[サーバーへの接続]ダイアログが表示される

<img width="512" alt="無題1.png" src="https://qiita-image-store.s3.amazonaws.com/0/48302/a924bb1a-e33c-573b-5ed0-bdadc14a754f.png">

3.[サーバーへの接続]ダイアログから任意のサーバーに接続する。
　→[トレースのプロパティ]ダイアログが表示される

<img width="491" alt="3.png" src="https://qiita-image-store.s3.amazonaws.com/0/48302/8b6319ee-b4c1-1a01-b9e3-82966704ddec.png">

4.設定を変更せず[実行]ボタンを押下する。(ファイル保存したい場合はトレース名は変更しておくこと)
　→トレースウィンドウが開かれる。

<img width="764" alt="4.png" src="https://qiita-image-store.s3.amazonaws.com/0/48302/b86fcf27-2651-5b8a-b970-0c018c1756b2.png">


##トレース取得と目的外のデータの除去
以下は一例。各自使いやすい方法で問題ない。
なお、[レコード表示リスト]とは読んで字の如くレコード一覧の表示エリアを指す。

・メインメニュー下のアイコンの消しゴムアイコンは[レコード表示リスト]をクリアする。
・ポーズアイコンは押下されたタイミング以降の[レコード表示リスト]の更新を停止する。
・トレースはSQLServerが処理を行う都度出力される。

従って、以下の手順で不純物の少ないトレースを取得することが可能。

1.消しゴムアイコンを押下し、[レコード表示リスト]を消去する
2.トレースを取得したい機能を実行する※。
3.登録が正常終了後、一時停止アイコンを押下する。

※ex:スタッフマスタの登録クエリを取得したい場合、画面から登録ボタンを押下する、等

<img width="960" alt="5.png" src="https://qiita-image-store.s3.amazonaws.com/0/48302/c4ee96eb-ea9e-1321-be69-2848f49b5ed5.png">

取得されたレコードは以下のように表示される。
よくある部署マスタを登録するEntityFrameworkからのクエリの結果。


でもこれだとTriggerの実行結果は取得できない模様。困るね。
CentOS7でのiptablesの設定

iptablesの設定

 sudo systemctl stop firewalld
 sudo systemctl disable firewalld
 sudo systemctl status firewalld
 sudo iptables -nL
 sudo yum -y install iptables-services
 sudo iptables -F
 sudo iptables -nL
 sudo /usr/libexec/iptables/iptables.init save
 sudo systemctl start iptables.service
 sudo systemctl enable iptables.service
 sudo reboot

参考
https://qiita.com/miosee/items/0599baa3a01301265a43
https://qiita.com/takc923/items/782bf58b3dd8b7b452a3
https://qiita.com/fbs884/items/492f7596553b7f384236
ReactNativeで電車遅延のメールを送信する


## はじめに
この記事はウェブクルー Advent Calendar 2018の13日目の記事です。
昨日は@wc_tanaka_rinさんの[PythonでBigQueryの差分更新をする方法](https://qiita.com/wc_tanaka_rin/items/92b0050b6c22ecb47c62)でした。

## 概要
[Microsoft Flowのアプリからワンクリックで定型文のメールを送信する]() をReact Nativeで実装してみようと思います。

## なぜReact Nativeなのか
- React Native勉強会を社内で開催したという軽い気持ちです

## React Nativeの開発環境構築
- [React Nativeのドキュメント](https://facebook.github.io/react-native/docs/getting-started)を参照してください
- Macの場合は以下でOKです

``` 
brew install node
brew install watchman
npm install -g expo-cli
```



## React Nativeでやる事
- メール送信ボタンを用意する、ボタン押下時にメール送信APIにリクエストする

### ボタンにReact Native Elementsを利用する
- [React Native Elements](https://react-native-training.github.io/react-native-elements/)

```
npm install react-native-elements
```

### ボタンの実装
``` App.js
import {Button} from 'react-native-elements';

~~ 中略

_handleButtonPress = () => {
  クリック時の処理
};

<Button
  title = '遅延のメールを送信する'
  buttonStyle = {styles.buttonStyle}
  onPress = {this._handleButtonPress}
/>

const style = StyleSheet.create({
  buttonStyle: {
    backgroundColor: "rgba(92, 99, 216, 1)",
    width: 300,
    height: 45,
    borderColor: "transparent",
    borderWidth: 0,
    borderRadius: 5
  },
})

```

### APIのリクエスト実装
``` App.js
_handleButtonPress = () => {
  this.sendEmail()
};

sendEmail() {
  return fetch('Send Mail API URL')
   .then((response) => {
     if (response.ok) Alert.alert('処理OK')
     else Alert.alert('処理NG')
    })
   .catch((error) => Alert.alert('処理NG'));
}

```


## メール送信のAPIを用意する
- 今回はHerokuとSendGridを用いて、APIにリクエストを投げると定型文を送信する処理を実現しています
- 詳しくは[ドキュメント](https://devcenter.heroku.com/articles/sendgrid)を参照してください

### Herokuの環境準備
- 詳しくは[ドキュメント](https://devcenter.heroku.com/articles/heroku-cli)を参照してください

### Herokuに書いたコード
``` index.php
<?php
require 'vendor/autoload.php';

$from = new SendGrid\Email(null, "test@mail.com");
$subject = "Test Mail";
$to = new SendGrid\Email(null, "test@mail.com");
$content = new SendGrid\Content("text/plain", "Test Mail");
$mail = new SendGrid\Mail($from, $subject, $to, $content);
$apiKey = getenv('SENDGRID_API_KEY');
$sg = new \SendGrid($apiKey);
$response = $sg->client->mail()->send()->post($mail);
echo $response->statusCode();
echo $response->headers();
echo $response->body();
```

- [今回のReact Nativeコード](https://github.com/DotaKobayashi/send-email)
- [今回のPHPコード](https://github.com/DotaKobayashi/send-mail-php)


## まとめ
- Microsoft Flowだとノンコーディングでサクッと実現できたのが
自前で実現しようとすると色々面倒ですね。

ウェブクルーでは一緒に働いていただけるエンジニアを[随時募集](https://hrmos.co/pages/1004681658307198976/jobs/0000027)しております。
お気軽にエントリーくださいませ。
個人的に詰まったポイントメモ #git

適宜追加/調整予定

# 前提
- 開発サイクル
    - 最終的な目標を`README.md`などに記載。
        - ついでにディレクトリ構造などのメモも書いておく。
    - 上位側からファイル/ディレクトリを作成していく。
        - 名付けでガッツリ悩む。そして多々無駄になる。
        - 作成ついでにコメント(マイルストーン)作成。  
    - 実装
    - テスト・リファクタリング
- gitとgitlabの違いを理解しておく  
  でないと問題の切り分けが出来ない。
    - git
        - ソースコードなどのバージョン管理をする為のもの。
    - gitlab
        - プロジェクトを管理する為のもの。  
          gitはその手段。
        - CI/CD(自動テスト)などプロジェクト管理に必要な物が揃っている。

# git
- 各コマンドのタイミング
    - commit  
      ほぼいつでも。  
      - 機能作成の決定
      - マイルストーン設定
      - テスト前後
      - リファクタリング前後
    - merge  
      機能に一区切りついてテストが終わったら。
- clone時などで認証を抜けない
    - ホストにgitユーザは居るか？  
      gitlabのアカウントとgitを動かすアカウントは別。居ないユーザにアクセスは出来ない。  
      自分はこれで数日無駄にした。
- 何故か湧く改行差分
    - `git reset --hard @`で死ぬ
- 紛らわしい機能
    - ブランチのどこを指しているか
    `git reset`や`git restore`の際に困る
        - `head`
            - リポジトリ内の代表
        - `@`
            - 今居るコミット  

# gitlab
自宅鯖で構築中。
- `$git clone git@home.com:gitlab/xxxxx.git`からの
  `fatal: 'gitlab/xxxxx.git' does not appear to be a git repository`とかで動かない。
    - とりあえず動かしたいだけならsshではなくhttpで対応しよう。
    - `$git clone http://home.com/gitlab/xxxxx.git`で可能。
Libertyのdocker imageを使った際、標準出力が文字化けする件について

#背景
公式のlibertyイメージを動かした時に、コンテナーログに日本語を出力すると???となって文字化けしてしまうことがある。この対応を備忘録として残しておく。
[docker hub](https://hub.docker.com/_/websphere-liberty/)

#原因
Libertyの標準出力は、OSのlocale設定を参照している模様。またLibertyイメージのUbuntuは日本語ロケールがないようで，”export LANG=ja_JP.UTF-8”しても英語表示のままになってしまう。 

#解決策
language-pack-jaパッケージをインストールすることによって解消される。
以下を参考にしました。
[Ubuntuに日本語localeを追加する。](http://www.dreamedge.net/archives/111)

まずは、環境変数にLANG=ja_JP.UTF-8を指定してコンテナーを起動する。

```
$ docker run -e LANG=ja_JP.UTF-8 -it websphere-liberty /bin/bash
root@b93ade08b2db:/# 
root@b93ade08b2db:/# 
```

apt-getを使用してlanguage-pack-jaをインストールする。

```
root@b93ade08b2db:/# apt-get install language-pack-ja
Reading package lists... Done
Building dependency tree       
Reading state information... Done
E: Unable to locate package language-pack-ja
```

このままではエラーで弾かれます。そこで以下を参考にしてリポジトリ情報をアップデートします。
[DockerのUbuntuイメージでapt-getするには](https://qiita.com/pochy9n/items/69ab8fc071c187a1f5f8)

```
root@b93ade08b2db:/# apt-get update
Get:1 http://security.ubuntu.com/ubuntu xenial-security InRelease [107 kB]
Get:2 http://archive.ubuntu.com/ubuntu xenial InRelease [247 kB]
・
・
・
Fetched 25.8 MB in 12s (1999 kB/s)                                                                                                                         
Reading package lists... Done
```

改めて、パッケージをインストールします。

```
root@b93ade08b2db:/# apt-get install language-pack-ja
Reading package lists... Done
Building dependency tree       
Reading state information... Done
The following additional packages will be installed:
・
・
・
Generating locales (this might take a while)...
Generation complete.
```

うまくインストールできました。

パッケージをインストールしたことによって、設定自体は変わりませんがlocaleも確認しておきます。

```
root@b93ade08b2db:/# locale                          
LANG=ja_JP.UTF-8
LANGUAGE=
LC_CTYPE="ja_JP.UTF-8"
LC_NUMERIC="ja_JP.UTF-8"
LC_TIME="ja_JP.UTF-8"
LC_COLLATE="ja_JP.UTF-8"
LC_MONETARY="ja_JP.UTF-8"
LC_MESSAGES="ja_JP.UTF-8"
LC_PAPER="ja_JP.UTF-8"
LC_NAME="ja_JP.UTF-8"
LC_ADDRESS="ja_JP.UTF-8"
LC_TELEPHONE="ja_JP.UTF-8"
LC_MEASUREMENT="ja_JP.UTF-8"
LC_IDENTIFICATION="ja_JP.UTF-8"
LC_ALL=
```

Libertyを起動します。

```
root@b93ade08b2db:/opt/ibm/wlp/bin# server start defaultServer
サーバー defaultServer を始動中です。
サーバー defaultServer がプロセス ID 934 で始動しました。
```

日本語で起動できました！

ちなみに、language-pack-jaのインストールとlocaleの設定の順番はどちらが先でも問題なさそうでした。

以上
Power BI 生産ライン遅延の可視化

製造業の工場など、機械による生産ラインにおいて
遅延箇所を見える化したときの備忘メモです。

#生産ラインの可視化
- 生産ラインはいくつかの工程に分かれており、それぞれ機械で加工します。
- 各工程の開始時刻、終了時刻を記録したログを分析します。
- 機械が故障するとその工程はストップし、修理完了したら再開します。
- ストップしていた工程をPowerBIの分析レポートで可視化します。

###今回の細かい設定
- 製造工程は３つ。工程A～工程Cとする。
- 製品は100個。製品ID(ロットID)を 001～100 とする。
- 工程Bにて、80個目の製品を加工中に機械が故障してラインが滞留し始めたとする。
- 機械の故障はすぐに修理されて、90個目あたりで再開したとする。

#今回の目標（こんなグラフを作ります）
![完成グラフ.png](https://qiita-image-store.s3.amazonaws.com/0/239983/658b8f24-234b-98d9-7e90-56d7d9afa453.png)
製品ID 80～90 はグラフが上に伸びてますが、これが遅延発生していた状態です。
その内訳は黒の面積が広いので、工程Bに問題があったことがわかります。

#作り方

##元データの準備

|製品ID|処理工程|開始時刻|終了時刻|
|---|---|---:|---:|
|001|工程A|9:00|9:16|
|001|工程B|9:16|9:21|
|001|工程C|9:21|9:32|
|002|工程A|9:17|9:32|
|002|工程B|9:32|9:38|
|002|工程C|9:38|9:48|
|･･･|･･･|･･･|･･･|
|082|工程A|20:50|21:05|
|082|工程B|21:05|22:05|
|082|工程C|22:05|22:10|
|･･･|･･･|･･･|･･･|
|100|工程A|23:11|23:26|
|100|工程B|23:26|23:31|
|100|工程C|23:31|23:42|
これをPowerBIにインポートします。

##処理時間の算出
インポートしたテーブルに、各工程でかかった 処理時間(分) を追加します。
*(2018/12/13 追記:DATEDIFF関数に変えました)*

```text:新しい列の追加
処理時間(分) = DATEDIFF( [開始時刻], [終了時刻], MINUTE )
```

`処理時間(分)`のデータ型は 時刻 ではなく**10進数**にするのがポイント。
理由は PowerBIでは、時刻型を[値]に設定すると、集計方法で[合計]が選べない からです。
<font color="LightGray">
*【ひとりごと】*
*一般的に日付時刻データ型はコンピュータ内部で実数値として扱われているはずなので、合計するのは難しくないはず、、、*
*と思ってたのですがPowerBIは違うんでしょうか。*
</font>


##グラフ作成
積み上げ棒グラフを選択
![作り方.png](https://qiita-image-store.s3.amazonaws.com/0/239983/0524ca7f-1d9e-2583-914e-15c1cdec16c1.png)

##完成！！
![完成グラフ.png](https://qiita-image-store.s3.amazonaws.com/0/239983/ecb1caa6-31a8-c99b-ced2-4f5935707a8f.png)

最後までお読みいただき、ありがとうございました。
php-master-changes 2018-12-12

今日はメモリマネージャに is_zend_ptr() を追加する修正があった！

# 2018-12-12
## dstogov: Provide is_zend_ptr() function to check if a pointer lays in Zend MM heap.
- https://github.com/php/php-src/commit/4d0a2f68a9063cd6befe3ce459f91cdad755996f
- ポインタが Zend MM (Memory Manager) の管理するヒープ内にあるかをチェックする is_zend_ptr() を実装
SambaによるADにユーザを追加してGitLabにコミット～EHW2018「開発環境整備④」

# 概要

このエントリは、「Enterprise "hello, world" 2018 Advent Calendar 2018」の12/11向けのものです。このAdvent Calendarでは、複数個のエントリにまたがる話の流れも鑑みつつ、なるべく1エントリで1つのトピックをカバーできるようにする予定です。

このエントリで記載するトピックは、SambaによるActiveDirectory(AD)にユーザを追加してGitLabにコミットです。Advent Calendarの12/8-12/10で作ってきた環境をベースにしています。

# 前提

## おことわり

- このEnterpfise "hello, world"シリーズは、ネタのためのエントリです。実環境でそのまま利用ことを目的とはしていません。
- 動かしやすさを優先してセキュリティを意図的に低くする設定など入れてありますのでご注意ください。

## 想定読者

「Enterprise "hello, world" 2018」的なネタとしては、下記のような状況を想定しています。

> 開発環境の一部ができたので、ここいらでユーザを作ってGitにコミットできるか試しておく

# Samba側の作業

## dockerコンテナでの作業準備

ここからの作業は、dockerコンテナ内のシェルで実施します。まずはコンテナに入ります。

```shell-session
$ sudo docker exec -it 944 /bin/bash
root@localdc:/# 
```

## ユーザ一覧の確認

[samba-tool](http://www.samba.gr.jp/project/translation/4.0/htmldocs/manpages/samba-tool.8.html)を用いて、ユーザの管理を行います。

まずはユーザ一覧を確認してみます。

```
root@localdc:/# samba-tool user list
Administrator
krbtgt
Guest

## ユーザを追加する

ユーザ追加は、samba-toolの「user add」を使います。ここでは、ユーザ"john"を追加しています。
パスワードは、要件を満たすものをセットします。
下記例では、パスワードを"yoko"としてみたのですが、短すぎるので使えませんでした。

```
root@localdc:/# samba-tool user add john
New Password:
Retype Password:
ERROR(ldb): Failed to add user 'john':  - 0000052D: Constraint violation - check_password_restrictions: the password is too short. It should be equal or longer than 7 characters!
```

ユーザが追加されていることを確認します。

```shell-session

root@localdc:/# samba-tool user add john
New Password:
Retype Password:
User 'john' created successfully
root@localdc:/# samba-tool user list
Administrator
krbtgt
Guest
john
```

# GitLab側の作業

## ログイン

前述の方法で作ったユーザ「john」でサインインできることを確認します。

「LDAP」のタブで、ユーザ名とパスワードを指定し、サインイン。

![login_gitlab.png](https://qiita-image-store.s3.amazonaws.com/0/65002/834d64a4-aa97-0f35-c878-3a1ffe41e51e.png)

問題がなければ、ホーム画面に移動します。右上のユーザのアイコンをクリックして確認すると、「john」となっています。

![home_gitlab.png](https://qiita-image-store.s3.amazonaws.com/0/65002/cc2d4490-ee8e-e84c-260f-04e01cbcff98.png)

## リポジトリを作って、コミット

ホーム画面で「Create a project」を選択します。

適当に名前を入れて、「Create project」

![newproject_gitlab.png](https://qiita-image-store.s3.amazonaws.com/0/65002/9fc7b126-5b2e-a3ee-6b1f-0aeaa214382d.png)

リポジトリの初期画面が現れます。

![vanilla-java_gitlab.png](https://qiita-image-store.s3.amazonaws.com/0/65002/121d4b87-13cf-291d-cf37-5c2f731619d0.png)

ページ内の手順に従って、git cloneして、あれこれします。

ここで、ページ手順には、「gitlab.ehw2018.local」というドメインが指定されているのですが、本エントリではまだ名前解決は実現しちえないので、仮想マシン上のVMの中のdockerへの転送用のポート番号（GitLabのUIを見ているポート番号）に置き換えています。

git pushまで終わり、GitLabのページを再読み込みすると、リポジトリへの格納まで成功していることが確認できます。

![result-gitlab.png](https://qiita-image-store.s3.amazonaws.com/0/65002/88f0ef75-b69f-46da-08e3-813127a0d41a.png)

以上で、SambaのADに追加したアカウントで、新しいgitリポジトリを作り、コミットすることができました。

# まとめ

このエントリでは、「Enterprise "hello, world" 2018 Advent Calendar 2018」(EHW2018)の11日目として、SambaによるActiveDirectory(AD)にユーザを追加してGitLabにコミットすることをトピックとして取り上げました。

EHW2018のネタとしては、このあと、ここで作ったユーザとGitLabのプロジェクトをベースに、アプリを作っていく予定です。。
JavaScript Setオブジェクト

##Setオブジェクトとは
ES2015(ES6)から導入された、重複した値がないことを保証したコレクション。
以下のような特徴があります。

* 値が一意であることが保証されている
* 順序を持たず、インデックスでアクセスできない


##Setの使い方

####動作確認環境
* Windows8.1
* Node.js v10.14.1

####Setの作成
```js
var set = new Set();
```

これで作成することができます。
中身が空のSetオブジェクトが作成されます。

コンストラクタに初期値を渡すこともできます。
初期値として渡すことができるのは、Iteratorオブジェクトです。
Iteratorについてこちらの記事がとても分かりやすかったため、リンクさせていただきます。
[JavaScript の イテレータ を極める！](https://qiita.com/kura07/items/cf168a7ea20e8c2554c6)

以下の例では、Iteratorオブジェクトである配列を初期値として渡します。

```js
var set = new Set(["value1", "value2", "value3"]);
console.log(set.size);
// 3
```

####サイズの取得
`size`プロパティを参照することで、Setオブジェクトに含まれる値の数を取得します。

```js
var set = new Set(["value1", "value2", "value3"]);
console.log(set.size);    // 3
```

####値の追加 add
`add(value)`で、値を追加することができます。
すでに同じ値がSetオブジェクト内にある場合は無視されます。
(エラーにはなりません。)

```js
var set = new Set();

set.add("apple");
set.add("banana");

console.log(set.size); // 2

// すでに存在する値を追加
set.add("banana");
console.log(set.size); // 2
```

####値の削除
`delete(value)`で、その値をSetオブジェクトから削除します。

```js
var set = new Set(["value1", "value2", "value3"]);
console.log(set.size);    // 3

set.delete("value2");
console.log(set.size);    // 2
```

####全ての値を削除
`clear()`で、Setオブジェクトのすべての値を削除します。

```js
var set = new Set(["value1", "value2", "value3"]);
console.log(set.size);    // 3

set.clear();
console.log(set.size);   // 0
```

####値が存在するかどうかの確認
`has(value)`で、その値がSetオブジェクトに存在するかどうかを確認できます。

```js
var set = new Set(["value1", "value2", "value3"]);
console.log(set.has("value1"));   // true
console.log(set.has("value5"));   // false
```

####反復処理

#####for...of
Setへの追加順に要素を取り出せます。

```js
var set = new Set();

set.add("apple");
set.add("banana");
set.add("melon");

for (var value of set) {
  console.log(value);
}

// apple
// banana
// melon
```
Google Cloud StorageのバケットにCORS設定をする方法

[前回](https://qiita.com/kai_kou/items/45c34576604ec8f6a3d1)、Google Cloud Storage(GCS)の署名付きURLを作成して、Webサービスから直接アップロードできないか検証していたのですが、GCSにCORSの設定をしてあげないとだめでした。


## 手順

公式にドキュメントがあったのでそのままです。

クロスオリジン リソース シェアリング（CORS）の設定  |  Cloud Storage ドキュメント  |  Google Cloud
https://cloud.google.com/storage/docs/configuring-cors?hl=ja

>バケットの CORS 構成を設定するには、受け入れられるリクエストのタイプを識別する情報（HTTP メソッドや発信元のドメインなど）を指定します。バケットの CORS 構成の設定には、gsutil コマンドライン ツール、XML API、JSON API、Cloud Storage のクライアント ライブラリを使用します。


```sh
> touch cors_setting.json
```

```json:cors_setting.json
[
    {
      "origin": ["http://example.appspot.com"],
      "responseHeader": ["Content-Type"],
      "method": ["GET", "HEAD", "DELETE"],
      "maxAgeSeconds": 3600
    }
]
```


```sh:CORSを設定する
> gsutil cors set cors_setting.json gs://[バケット名]
```

```sh:CORSを確認する
> gsutil cors get gs://[バケット名]
```


## 参考

クロスオリジン リソース シェアリング（CORS）の設定  |  Cloud Storage ドキュメント  |  Google Cloud
https://cloud.google.com/storage/docs/configuring-cors?hl=ja

FirebaseのHostingとCloud Functionsを利用してStorageからファイルをダウンロードするデモアプリケーション - Qiita
https://qiita.com/rubytomato@github/items/31c6098eb9804d9547ed#%E5%8B%95%E4%BD%9C%E7%A2%BA%E8%AA%8D-1
RDSのレプリケーション機能の比較

この記事は[ハンズラボ Advent Calendar 2018](https://qiita.com/advent-calendar/2018/handslab) 13日目の記事です。

SAA試験勉強中の@sr-mtmtです。
awsのリレーショナルデータベースサービス、RDSには
可用性を高めるための機能で、レプリケーションという機能があるらしいということはわかったんですが

- 同期レプリケーション(非同期レプリケーション)
- 物理レプリケーション
- 論理レプリケーション

ピンとくるようなこないような名前でぜんぜん頭に入ってこない・・・。
そもそも昔からこの「物理」「論理」っていう名前のつけられ方が苦手。
クラウドっていうと全部論理みたいなふうな気持ちになるけどちがうの・・・？

某製薬会社くらいわかりやすい名前をつけてあげたい！、ということで
それぞれどういう機能なのか調べ直しました。

# そもそもRDSのレプリケーションとは

マルチAZ配置といって
マスターと呼ばれる実際にデータ処理が行われるRDSインスタンスと
そのインスタンスがあるAZとは別のAZにスレーブと呼ばれるRDSインスタンスが自動的に用意され、
そこにデータを複製することで可用性を高めてくれます。
細かな設定をあれこれせずともこのレプリケーションが使えるというのはRDSの特徴のひとつです。

# それぞれの違い

## 同期レプリケーション

- 整合性重視のやり方
- マスターの変更後、スレーブを変更し、スレーブの変更が確定してから応答する
- そのためスレーブの変更確定を待たずに応答する非同期レプリケーションに比べて若干応答までに時間がかかる
- ただしRDSは高速回線を使ってるから言うほど時間はかからない（数ms）
- **RDSのマスター・スレーブ間のレプリケーションはすべて同期レプリケーション**

#### 命名
「みんな揃うまで待つくん超特急」

## 物理レプリケーション

- DBエンジンがMySQL, MariaDB, PostgreSQL, Oracleのときに選べるのは物理レプリケーション
- スレーブのデータをマスターに合わせて最新の状態に維持
- awsが提供している機能
- DB作成時にマルチAZ配置にするか選択することで適用される

![2018121301.png](https://qiita-image-store.s3.amazonaws.com/0/210788/4359fc7e-7a52-f4fb-c746-80bc41f1f51e.png)

#### 命名
awsの「オプション　データコピーくん」

## 論理レプリケーション
- DBエンジンがSQLServerの場合は論理レプリケーション
- スタンバイしているデータをプライマリに合わせて最新の状態に維持、という機能は物理レプリケーションと同じ
- SQLServerが提供しているミラーリングテクノロジーという方法で実現している
    - ミラーリングの場合は「マスター/スレーブ」を「プリンシパルサーバー/ミラーサーバー」と呼ぶ
    - コミット済みのトランザクションのデータをスレーブに反映
    - 今年の11月からこの機能は明示的に設定しなくても「Always On 可用性グループ」で自動的にマルチAZ配置になるみたい

#### 命名
SQLServerの「有無を言わさずデータコピーくん」

# まとめ

SQLServerのミラーリングであってもawsのレプリケーションであっても
マルチAZ配置にするということはその分インスタンスを立てるということなので
コストは上乗せされます。
そこまでの可用性が求められないのであればマルチAZにしないことでコストを下げられるなぁとか考えて
DBエンジンを選んだりできるのかな？と思ったりしました。

論理物理ふやふや難問については
[Microsoftのドキュメント](https://docs.microsoft.com/ja-jp/sql/database-engine/database-mirroring/database-mirroring-sql-server?view=sql-server-2017#HowWorks)に
> 論理レベルで機能するレプリケーションとは異なり、データベース ミラーリングは物理ログ レコードのレベルで機能します。

と書かれていて「えーっ、こっちが論理レプリケーションなんじゃないの・・・」と
ますます迷宮入り・・・。誰かたすけて・・・。

明日は@rednesさんのVPCのお話です。


# 参考
[Amazon RDS マルチ AZ 配置](https://aws.amazon.com/jp/rds/details/multi-az/)
[Microsoft SQL Server でのデータベースのミラーリングによるマルチ AZ 配置](https://docs.aws.amazon.com/ja_jp/AmazonRDS/latest/UserGuide/USER_SQLServerMultiAZ.html)
[Amazon RDS for SQL Server が Always On 可用性グループをサポート](https://aws.amazon.com/jp/about-aws/whats-new/2018/11/amazon-rds-for-sql-server-now-supports-alwayson-availability-groups/)
[データベース ミラーリング (SQL Server)](https://docs.microsoft.com/ja-jp/sql/database-engine/database-mirroring/database-mirroring-sql-server?view=sql-server-2017)
軽快に動くNimのREPLを作った

Nim Advent Calendar の枠が空いてたのでストックを投下します。

実は既に[nrpl](https://github.com/wheineman/nrpl)というのがあるのですが、私の環境(Nim0.19.0)だとnimbleでインストールした時にこける(開発が止まったままバージョンが上がって互換性がなくなったと思われます)のと、一回ずつ愚直にコンパイルしているようであんまり速そうではありません。そこでちょっと工夫して、PythonのREPL並みにサクサク動くものを作りました。

# 動作原理

実はNimにはNimScriptというバーチャルマシン上で動くサブセットが標準でついてきます。最初これはパッケージマネージャのnimble上で動く簡易的なやつかと思ってたんですが、Nimのコンパイル時計算はどうもこいつがやっているそうで、それならREPL的なやつが作れるんじゃないかと思ったわけです。

# DEMO

![replim.gif](https://qiita-image-store.s3.amazonaws.com/0/263653/c85ee5ae-dae3-224b-a1e0-0dbecc9b7fb5.gif)


これで等倍速です。かなりいい感じじゃないですか？

# 成果物

ここにおいてあります。
https://github.com/gmshiba/replim

あるいは

```
nimble install replim
```
でインストール出来ます。

# 注意

NimScriptの仕様というか限界でimpure(nimのみで書かれていない)なライブラリはimport出来ないようです。例えばnreとかhttpserverとかをimportするとエラー吐かれます。あしからず...
XAMPPで動くLaravelのサンプルアプリを作成する 2018年12月版

この記事は、「[【連載】初めてのWindows用Laravel 5.7開発環境構築入門](https://qiita.com/hitotch/items/a646972fe1992611e92b)」の子記事です。環境などの条件は、親記事をご覧ください。

---
　今回から、データベースを取り扱うサンプルアプリを作っていきます。

# サンプルアプリの方針

　サンプルアプリはあとでレンタルサーバーにアプリをアップすることを考えながら作ります。Laravelのインストールはそれが簡単になるプロジェクトローカルインストールとします。

　[前の記事](https://qiita.com/hitotch/items/d22fa4c12d0f15f7adc4)による http://example.com プロジェクトに組み込んでいきますので、実際に手順を踏んでいく場合は前回までの環境を作っておいてください。

　サンプルアプリでは、データベースにユーザーテーブルを作ってその中にユーザーを登録しておき、Webアプリでユーザー一覧と詳細画面を見せるところまで動作させます。本来CRUDアプリでは、C=新規追加、R=読み込み、U=更新、D=削除といった機能があるべきですが、今回はとりあえず動作させてレンタルサーバーで動くところまで持っていく方法を知ることが目的なので、機能はR=読み込みのみとします。
　Laravelが初めてな方は、まずは本稿にそってLaravelを動作させて全体像を掴んでから、ゆっくりより深くLaravelの勉強をされることをおすすめします。
　Laravelの実践的なCRUDアプリ作成方法については、[こちらの記事](https://qiita.com/sutara79/items/ef30fcdfb7afcb2188ea)(@sutara79氏)が大変参考になります。

# 孫記事

以下のステップに分けて、孫記事にしてきます。

- [Laravelアプリ用のデータベースの作り方](https://qiita.com/hitotch/items/142d8f102cfebe38dc30)
- [LaravelでCRUDを作る](https://qiita.com/hitotch/items/d12d53e2c30f9b5d9ec1)

# 謝辞

この記事およびこの孫記事では、[こちらの記事](https://qiita.com/sutara79/items/ef30fcdfb7afcb2188ea)を参考にさせていただきました。@sutara79氏による貴重な記事に感謝いたします。
プログラマなのでCLIで自己紹介したい

こんにちわ

普段、みなさんはプレゼン資料を作る時に自己紹介を入れると思いますが、
多分こういう風に箇条書きが多いのではないでしょうか？

- 名前
- 年齢
- スキル
...

自分も今まで同じ様にやってきましたが、
プログラマっぽいことしたいので、[aboutme](https://github.com/skanehira/aboutme)という簡単な自己紹介CLIツールを作ってみました。

# どんなやつ
こんなやつ。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/66178/9069ccdc-716c-45ca-83ed-5f53081806dd.png)

複数に引数を指定した場合まとめて表示するようになっています。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/66178/d8f929ff-f178-d8dc-55af-38ef1316e9bc.png)

# 使い方
インストールしたら、
[aboutme](https://github.com/skanehira/aboutme)の`aboutme.yaml`を`$HOME/.aboutme.yaml`にコピーして、あとは好きなように書換えてください。
基本yamlに書いたモノを表示させているだけです。

```yaml
status:
    name: "ゴリラ"
    age: 26
    species: "霊長目ヒト科ゴリラ属"
    sex: "オス"
sns:
    - name: "Twitter"
      id: "gorilla0513"
      url: "https://twitter.com/gorilla0513"
    - name: "Github"
      url: "https://github.com/skanehira"
    - name: "Qiita"
      id: "gorilla0513"
      url: "https://qiita.com/gorilla0513"
(略)
```

Go側で構造体を定義していて、yamlは構造体に合わせてあるので、
新しい項目を追加したい場合はフォークして自分で追加するか、プルリクください。

できればみんなで項目を追加してより細かく情報を設定できるようにしたいと考えています。

引数は以下になっています。
各種プロファイルを個別で表示したいときに使用してください。
すべてを表示する時は`-all`を指定すればOKです。

```shell-session
$ aboutme -h
Usage of aboutme:
  -all
        all of profile
  -db
        about db
  -fw
        about framework
  -job
        about job history
  -lang
        about programming language
  -os
        about os
  -sns
        about sns
  -stat
        about status
  -tool
        about tool
```

# 終わりに
経歴書の変わりにCLIをインストールすれば私のすべてがわかりますって言える時代が来たらいいですねー
mysqlから持って来たデータをjsonで返すapiをflaskで作る

# 動機
pythonのflaskを使って、MySQLから持って来たデータをjson形式で返すAPIを作りたい

# はまったところ
1.MySQLから持って来たデータをどうやってjson形式（≒辞書型）にするか
2.辞書型で取り出した後に遭遇した `TypeError: Object of type 'datetime' is not JSON serializable` というエラー

# 解決策
### 1.普通にデータを取得するとタプルで返ってくるが、下記のように`dictionary=True`を渡すと辞書型で返ってくる。

```python

query = 'SELECT * FROM tablename WHERE dataid = ' + str(dataid)
cursor = conn.cursor(dictionary=True)
cursor.execute(query)
```

### 2.`TypeError: Object of type 'datetime' is not JSON serializable`の対策
[[Python] dateやdatetimeをjson.dumpでエラーなく出力する
](https://www.yoheim.net/blog.php?q=20170703)
ここを参考に、下記のような処理を挟んだ。

```python

def json_serial(obj):
    if isinstance(obj, (datetime, date)):
        return obj.isoformat()
    elif isinstance(obj, timedelta):
        return str(obj)
    raise TypeError("Type %s not serializable" % type(obj))
```

mysqlの結果がdatetimeだったりすると見出しにあるエラーが出るので、個別に処理している。
また、timedeltaについてはdatetimeと同様の処理だと下記のエラーが出るので上のソースでは別処理として追記している。
`'datetime.timedelta' object has no attribute 'isoformat'`

# 全体のソース
下記は例です

``` python
from flask import Flask, send_file, make_response, jsonify
import requests
from datetime import datetime, date, timedelta
import json
import mysql.connector

app = Flask(__name__, static_folder=None)

def json_serial(obj):
    if isinstance(obj, (datetime, date)):
        return obj.isoformat()
    elif isinstance(obj, timedelta):
        return str(obj)
    raise TypeError("Type %s not serializable" % type(obj))

@app.route('/data/<string:dataid>', methods=['GET'])
def getData(param, dataid):
    response_data = {}

    conn = mysql.connector.connect(
        host='hostname',
        port=3306,
        user='dbuser',
        password='dbpass',
        database='dbname',
    )

    query = 'SELECT * FROM tablename WHERE dataid = ' + str(dataid)
    cursor = conn.cursor(dictionary=True)
    cursor.execute(query)
    data = cursor.fetchall()
    conn.close()

    response_data["body"] = data
    response_data["status"] = "200"

    return make_response(json.dumps(response_data, default=json_serial))

# main
if __name__ == "__main__":
    print(app.url_map)
    app.run(host='localhost', port=5000)
```

# 参考にしたページ
[[Python] dateやdatetimeをjson.dumpでエラーなく出力する
](https://www.yoheim.net/blog.php?q=20170703)


# 追記：MySQLdbを使う場合
事前に　`pip install mysqlclient` でインストールをしておいて、下記で行けるようです。

```python
connection = MySQLdb.connect(
        host='localhost', user='root', passwd='testpass', db='sample_db', charset='utf8')
    cursor = connection.cursor(MySQLdb.cursors.DictCursor)
```
API Gatewayとかを組み合わせてキューイングシステムをつくった話(概要編)

# はじめに
この記事は[Sansan Advent Calendar 2018](https://adventar.org/calendars/3423)の13日目の記事になります。

ちょうど、業務の方でシステム間を連携させる仕組みとしてAPI Gateway+SNS+SQSを組み合わせてキューイングシステムを構築しました。この組み合わせはちょっと珍しいかなと思ったので、そのアーキテクチャのポイントについて書きたいと思います。

# アーキテクチャ

図で示すとこんな感じのアーキテクチャをつくりました。
送受信できるようにそれぞれ２系統を用意しています。

![Untitled Diagram (5).png](https://qiita-image-store.s3.amazonaws.com/0/80062/85704a6b-0177-62a4-0e99-ac6426f90d91.png)

Publisherがpublishするときは、API GatewayのAPIのURLにJSONをPOSTします。そうすると、SNSにJSONを含んだメッセージが転送され、フィルタリングで振り分けられ、指定のSQSのキューにメッセージがエンキューされます。Subscriberは好きなタイミングでSQSからメッセージをsubscribeすることで、対向システムの可用性や処理時間を気にすることなく疎結合なシステム間連携ができます。

# SQS単体で使うのと何が違う？

## API Gateway
JSON Schema(Swagger)を設定してバリデーションができるため、PublisherとSubscriberとのデータの取り決めを厳密に行えます。そのため、Subscriber側のバリデーションの負担が軽くなります。また、必要なときには認証がかけられるため、セキュリティ的にコントロールしやすくなります。

## SNS
Publisher側の処理の抽象化ができます。また、フィルタリング機能で複数キューへの振り分けや複製を行えます。

# さいごに

今回はさらっと概要だけ述べました。ちょっと思うように時間が取れなかったので、構築編をまたあげようと思います。
Windows10とUbuntu18.04を別ディスクで簡単デュアルブート

## はじめに
これは私がWindows10のデスクトップPCに、Ubuntu18.04を新たなドライブに入れてデュアルブートした記録です。
１つのドライブでパーティションを分けてやるよりも単純にできるのでデュアルブート初心者の私でも簡単にできました。
VMを動かすのが面倒になった方、本格的にLinuxに触ってみたくなった方はこの方式だと楽だと思います。

## 用意したデスクトップPC
* CPU Corei7-6700
* メモリ 16GB
* SSD
    *  Sandisk Ultra 480GB : Windows10のブートディスク
    *  Samsung SSD 860EVO 256GB : Ubuntuのブートディスク

## 手順
### 参考URL
[Windows10とUbuntu16.04のデュアルブート環境構築](https://qiita.com/medalotte/items/4bb5cfa709e93d044f1c)
[UbuntuとWindowsのDualboot環境を構築する](https://ja.unflf.com/dualboot-ubuntu-windows/)
[Ubuntu16.04をWindows10とデュアルブート in UEFI](https://www.g104robo.com/entry/ubuntu-dualboot-win10-uefi)
[Ubuntuのインストール](https://eng-entrance.com/ubuntu-install)

### 1. Ubuntu18.04のブートができるUSBを用意
適当なUSBを用意すればよいので、今回はたまたま持っていた8GBのUSBを利用しました。
以下のリンクからubuntu-18.04.1-desktop-amd64.isoをダウンロードしました。
[Ubuntu18.04のダウンロードページ](http://releases.ubuntu.com/18.04/)

[参考URL](https://qiita.com/medalotte/items/4bb5cfa709e93d044f1c)ではUSBのフォーマットを行っていますが、自分のUSBではそのまま[UNetbootin](https://unetbootin.github.io/)を利用して書き込みました。書き込む時間は自分の環境で20分近くかかりました。

### 2. デスクトップPCの準備
今回は別のSSDを用意してデュアルブートを行うため、参考URLのようなパーティションの分割は行わないません。
3つ目の[参考URL](https://www.g104robo.com/entry/ubuntu-dualboot-win10-uefi)のように、UEFIの設定を行えばそのままWindowsのブートドライブが繋がった状態でUbuntuを新たに別のドライブに入れることもできますが、操作をミスするとWindowsのドライブに書き込んでしまう可能性があるので、私はUbuntuを入れるSSD以外はすべて物理的に外しました。
もしWindowsのドライブを外さずに行う場合はSSDを全く別のメーカのSSDにすると判別がつきやすくなるのでおすすめです。

UEFIの設定を行い、USBからブートできるようになったら再起動してUbuntuのインストールに入ります。

### 3. Ubuntuのインストール
4つめの[参考URL](https://eng-entrance.com/ubuntu-install)と同じ手順でインストールを行っていきます。
今回はSSDをまるごとUbuntuのドライブにするためデフォルトのままインストールしていきます。

### 4. grubの設定
以上でUbuntuのインストールが終わり、Ubuntuの利用が可能となります。
この時点でWindowsのブートドライブをつなぎ直して結構です。どちらのOSを起動するかはブートローダーによります。
起動するOSを変更するにはUEFIから起動するディスクを変更することもできますが、Ubuntuではgrubを用いて起動するOSを変更できます。
インストールした状態ではgrubがWindows10を認識できず、必ずUbuntuが起動してしまいます。理由としては```/boot/grub/grub.cfg```にWindowsの記述がないため、自動的にUbuntuが立ち上がってしまいます。
そこでUbuntuの端末で以下のコマンドを入力します。

```
$ sudo update-grub
```

これを実行することで```/boot/grub/grub.cfg```にWindowsの情報があることが確認できると思います。
確認する最も簡単な方法は以下のコマンドを実行することです。

```
$ grep windows /boot/grub/grub.cfg
menuentry 'Windows Boot Manager (on /dev/sda2)' --class windows --class os $menuentry_id_option 'osprober-efi-4A71-DC25' {
```

このような実行結果になればOKです。再起動するとブートするOSを選択する画面が表示されて、Ubuntuを起動するかWindowsを起動するか選択できるようになります。

## まとめ
以上の手順でデスクトップPCでWindows10とUbuntu18.04を別ドライブでデュアルブートできました。
私のようなデュアルブート初心者でもパーティションのことを考えずにできるので、ノートPCでWindowsとLinuxのデュアルブートをやるよりは簡単にできると思います。また更にOSを入れることもその都度ドライブを用意すれば良いので、3つ以上のOSをブートできるようにするにはこの方式が一番だと思います。

同じことをやろうとする方への参考となれば幸いです。
Rでロジスティック回帰～csvでの出力

まぁ色々あってロジスティック回帰をRでやることになりました。
ググり力を総動員したもののｃｓｖで吐いてもらうのに手間取ったのでメモ。
何かの参考になれば。

```
#とりあえず関数作るところは省略
result<-glm(従属~独立a+・・・+独立x)
summary(result)

#なにかしらの変数を作る。
result_sum<-summary.glm(result)$coefficients
write.csv(result_sum,file="任意の場所"

```

詰まったのは二か所。
1.sresultから直でcsv吐いてくれると思った。
write.csv(result)でやったらエラー吐かれてビビる。
まぁ当たり前なんですけどエラー吐くわな。なのでまた変数作って解決。
キモは$coefficientsだと思う。知らん。

2．file Pathの設定をミスる。
特に何も考えないでプロパティから選択してパスに突っ込んだらエラー
→Winのデフォを張り付けるとC\（場所）ってなってるけど\が良くないっぽいので/に書き換えて解決。もうそんなんやったらgetwd()でよかったんやってなる。

csvの整形とかはかなりできるっぽいけど関係ないので省略。ただそもそもデフォで結構がちがちなので

|a|b|c|
|:---:|:---:|:---:|
|1|
|2|
|3|

↓

| |a|b|c|
|:---:|:---:|:---:|:---:|
|1|
|2|
|3|

にするくらいかと思う。

なんしか[ココ](http://a-habakiri.hateblo.jp/entry/2016/12/12/222806#writecsv)に詳しく書いてあったのでこの記事では省略。
プログラミングパラダイムについて簡単にまとめました

今週はプログラミングパラダイムを勉強しました。
自分なりの理解をわかりやすくまとめていきたいと思います。

####プログラミングパラダイムとは
プログラミングのスタイルをその特徴に応じて分類する方法です。
今回は代表的なものを紹介したいと思います。


#####命令型プログラミング
単純にコンピューターに命令するための構文です。
プログラミングが普及し出した1960年代によく用いられたgo to文を始めとして、お馴染みのifやwhileなどの条件分岐もこれに当てはまります。
フローチャートをイメージすればわかりやすいです。

#####宣言型プログラミング
命令型のように、導き出したい対象を出力するための処理方法を記述するのではなく、対象の性質などをそのまま宣言することでプログラミングすることです。
つまり、変数や関数がこれに当てはまります。

#####関数型プログラミング
処理方法を記述するのではなく、ユーザーの入力に対して必要な結果を導く関数を用意し、その関数を組み合わせて記述することです。
変数の参照や変更が無く、入力としたデータのみが変化していく方式ですので内容が簡潔でエラーが起きにくいです。

#####構造化プログラミング
命令型プログラミングの一部を今で言う関数やメソッドを使い抽象度の高いものに置き換えたものです。
単純なgo toを使わずにforやifなどのループや条件分岐などを用いて記述します。
これにより、大規模なシステムがつくりやすくなりました。
命令型プログラミングを1つのフローチャートとしたとき、構造化プログラミングは、簡潔化したフローチャートをたくさん組み合わせたイメージです。

#####オブジェクト指向プログラミング
現在主流であるパラダイムであり、原理原則は構造化プログラミングに似ています。
プログラミングを開発するとき、一連の機能を複数のモジュールに分割して開発する方法があります。
この方法では、モジュールは独立性が高いほど良いとされ、それぞれでコンパイルやデバックを可能にしている場合が多いです。
しかし、この場合1つ1つのモジュールで関数の定義などをしないといけないため、定義に対する値（インスタンス）が複数存在することになり、統合するときに混乱します。
その問題を解決するためにオブジェクト指向プログラミングが生まれました。
これは、単なるモジュールではなく、複数のインスタンスを整理して管理する仕組みを備えたものです。
代表的な特徴として、カプセル化・多態性・継承・委譲の4つあります。
詳しくはまた次回まとめていきたいと思います。

ここまでお読みいただきありがとうございました。
IntelliJ IDEA上でjava非標準ライブラリを使う方法

*初投稿です*

##IntelliJ IDEAを使って、javaの勉強をしていたところ困ったことをまとめます。

###javaで標準に含まれていないクラスの活用

####やり方1　ソースコードをもらう
####やり方2　バイナリモジュールをもらう
*バイナリモジュールとはコンパイル済みのコードのことを示す*

**そして、一般的にJARファイルに複数のクラスがまとまったライブラリをもらうことが多い**
**しかし、普通にimportしてもライブラリが動かない!**

**この原因はjavaがクラスパスで指定されたパスしか探索しないからで解決方法は2つ**
####①環境変数CLASSPATHに宣言する
####②javacなどのコマンド実行時に-cpオプションをつける


#ここからが本題
###では、上記のことをIntelliJ IDEAのGUIでやってみよう!

練習として,commons-logging:ログ出力を簡単にするためのクラス群をApacheソフトウェア財団のサイトからzipでダウンロードします
[ここからcommons-loggingをダウンロードできます](http://commons.apache.org/proper/commons-logging/download_logging.cgi)

そして、展開したファイルを同じディレクトリに配置してください。

<img width="300" alt="スクリーンショット 2018-12-13 2.58.02.png" src="https://qiita-image-store.s3.amazonaws.com/0/263492/a1764671-9acb-6d45-a544-fb5c431e1e6d.png">
赤色になっていて、まだ使えないことがわかります。


<img width="768" alt="スクリーンショット 2018-12-13 3.05.31.png" src="https://qiita-image-store.s3.amazonaws.com/0/263492/50e2bdfd-18f1-5c0a-70ea-50c31b24a3ce.png">
右クリックを押してAdd as Libraryを押します。

<img width="369" alt="スクリーンショット 2018-12-13 3.08.12.png" src="https://qiita-image-store.s3.amazonaws.com/0/263492/73fb757d-cdc8-b182-5e90-8093797d9a04.png">

こういうのが出てくるので自分のディレクトリを選んでOKを押せば完了です!

<img width="543" alt="スクリーンショット 2018-12-13 3.10.04.png" src="https://qiita-image-store.s3.amazonaws.com/0/263492/ef4e578c-8a25-53e7-3304-a53f678479c1.png">

ちゃんと動作しているのがわかります。これで完了です

初心者が最初JARファイルを利用・再利用するにはどうしたらいいかわからないときにやってみるといいかもしれません。
以上
初心者プログラマーからでした
Webエンジニアから見たAWS RoboMaker

## TL;DR
* かなり柔軟な開発環境
    + Cloud 9ベースの自由度の高いセキュアな開発環境構築が可能
* 便利なRoboMaker Cloud Extensions
    + 個人的に便利そうだと思うのがkinesis video streamsへの画像トピックの配信
* Greengrassと連携したデプロイが非常に便利


※ 基本的には、 [RoboMaker開発者ガイド](https://docs.aws.amazon.com/robomaker/latest/dg/index.html)に書かれている内容です
※ Simulationやカスタマイズ性については言及できていません


## RoboMakerとは...
AWSのre:invent2018でリリース発表のあったロボット用ソフト(ROSベースのシステム)の開発・リリースなどのワークフローを楽にするためのサービスです.
[![](https://img.youtube.com/vi/U1ukEpzKCYY/0.jpg)](https://www.youtube.com/watch?v=U1ukEpzKCYY)

開発環境構築やデプロイなどを任せるWebエンジニアにとってはセキュリティ, デプロイ等がすごく気になるところです.


## 開発環境構築について
開発環境自体の中身は, DockerベースのAWSのマネージドIDE(統合開発環境)である **Cloud9** である.
[![](https://img.youtube.com/vi/8rG47HjIjA4/0.jpg)](https://www.youtube.com/watch?v=8rG47HjIjA4)

m4.largeという少し小さなインスタンスから, m4.16xlargeと大きなインスタンスが選べる. ただし, p3やg3といったGPUサーバーは選べません. (Cloud9でもGPUサーバーは選べない)

ROSベースのアプリケーションは基本的にエッジで動くという要件を考えると, 消費電力が大きなGPUをエッジ側で使うという選択肢は可能性が薄いため利用用途としても必要に迫られてないのかもしれません.

Cloud9が利用できるということで、一部コマンドを除いて `apt-get` を含め様々なコマンドが発行できるようになっています.
つまり, 次のような自動運転ソフトウェアを頑張れば動かすことも可能.(Robomakerはcolconを用いたビルド前提)
https://github.com/CPFL/Autoware/wiki/Source-Build

#### 「普通のインスタンスと変わらないの? 結局何が便利なの?」
という話だが, 基盤に求められる要件と実際に環境を利用するエンジニアのスキルセットのズレから生まれるプロジェクトのボトルネックを減らすことに意味があります.

AWS SageMakerと似たようなコンセプトだと考えられます.
基盤構築に強くない機械学習リサーチャーやデータサイエンティストが簡単にJupyterNotebookがセキュアに立ち上げられるSageMakerのように, **ロボット屋さんがWeb屋さんの力を借りずに自身でセキュアな環境を構築して色々試せる** ということが魅力の１つとなります．

#### セキュリティについて
Cloud9を用いるので, VPCとサブネットを選択することで簡単にセキュアな環境構築できます.
基盤エンジニアが簡単な準備をし, ルールを敷くことで, ロボット屋さんも安心して開発ができるようになります.
あとは、権限管理などは他サービスと同様IAMで細かくActionやResourceを管理できる.

#### コストについて
基盤構築をしっかりしてスポットインスタンスを積極的に利用するという手もありますが, よっぽどの大きなチームでないと実現不可能です.
Cloud9にはハイバネーション機能が付いており, インスタンスを放置しておくと勝手に停止してくれ, 監視などの基盤管理便利ツールを作り込まなくてもコスト面でもある程度安全に使えます.


## RoboMaker Cloud Extensions
次のサービスと連携できるが....

* Amazon Kinesis & Amazon Rekognition
* Amazon Lex
* Amazon Polly
* Amazon CloudWatch Logs
* Amazon CloudWatch Metrics

気になったのが, **[Amazon Kinesisの拡張](https://github.com/aws-robotics/kinesisvideo-ros1)**.
画像をROS Topicに配信したあとにROSBAGデータにして, そのファイル形式で再生するのは若干手間だったり, メディアの保存形式とはベストと言い難く, もっと簡単に見たいという気持ちになることがよくあります.
そんな時に拡張を用いて簡単に画像のROS TopicのメッセージをKinesis Video Streamsに配信,  簡単に動画配信と組み合わせた振り返りツールが作れることになります.
Web屋さんはROSのAPIを深く理解する必要がなくなるし, Robot屋さんもライブ配信技術について不得手でも大丈夫で, スモールチームでスピード感を持って開発していく状況においては良い選択肢となりそうです.
[![](https://img.youtube.com/vi/STEMa3t5NOQ/0.jpg)](https://www.youtube.com/watch?v=STEMa3t5NOQ)

#### 料金体系
拡張自体は無料(Apache Software License 2.0)で使え, 使用したKinesis Video Streamsなど連携するマネージドサービス利用料金だけで利用可能となっており導入しやすい印象です.


## デプロイについて
AWS IoT Greengrassとの連携ができ, バージョン管理やアプリケーションのダウンロードやエッジ端末のローリングアップデートが容易に管理できます.

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

またRoboMaker専用のGreengrass設定APIがあり, 起動方法の設定などもROSではお馴染みlaunchファイルを指定するだけで済んだり, 簡単な設定項目でデプロイ準備ができます.
ただし, 一部パッケージの差分更新のような機能がないため必要以上のダウンタイムが発生するなどといった課題はあります.

## おわりに
Web畑出身でROSを触り始めた会社員エンジニアにとっては, 非常にありがたいツールが豊富に揃っていました.

AdventCalendarに合わせてもう少しトライしようとしましたが、簡単なドキュメントサマリになってしまいましたので, もっと触りつつSimulationの話などカスタマイズ性についても言及した記事に加筆修正しようと思います.
Cloud Functions でソースコードサイズの割当の追加はできないよっていうお話

## 本編
**事の発端**
cloud functions で `"Your proposed upload is larger than the maximum object size specified in your Policy Document."` と言われた。

なんでもかんでも同じプロジェクト内に functions のコードを追加し続けたら以下のエラーで怒られた。

```
Status: [400:<?xml version='1.0' encoding='UTF-8'?><Error><Code>EntityTooLarge</Code><Message>Your proposed upload is larger than the maximum object size specified in your Policy Document.</Message><Details>Content-length exceeds upper bound on range</Details></Error>]
```

きれいにプロジェクトを分割して保守性を高めなければなあ。
と思いつつもソースコードに割り当てられているストレージのサイズを挙げて応急処置。

[![Image from Gyazo](https://i.gyazo.com/56a0cee072f4cbb2224776a9bdc5e8b7.png)](https://gyazo.com/56a0cee072f4cbb2224776a9bdc5e8b7)

と思いきや…

コードのサイズ的な項目がない…????

ドキュメントを参照してみると…

[割り当て  |  Cloud Functions のドキュメント  |  Google Cloud](https://cloud.google.com/functions/quotas)

[![Image from Gyazo](https://i.gyazo.com/360d8e7cb7ff2e4f952b5efe9c458ea7.png)](https://gyazo.com/360d8e7cb7ff2e4f952b5efe9c458ea7)

できない!!!

おとなしく function ごとに分割してプロジェクトを作り直します。

## 追記

pipenv を導入した際に `venv`ディレクトリが生成されたのを完全に忘れていた。(そらサイズも大きいわ。)

`.gcloudignore`ファイルに以下を追記して解決された。
(ついでに 動作確認で使っていた jupyter のファイルたちもアップロードしないように変更)

```text:.gcloudignore
...

# jupyter notebooks
*.ipynb

# pipenv
venv

...
```
railsでコーディングするときにとりあえず入れとくGem５つ

#はじめに
railsを書き始めてはや8ヶ月が経ちますが、個人開発とかでも絶対に使うgemがまとまってきたので紹介します。
#1,pry-rails
みんな使ってる（と思いたい）railsのデバッグツール！
 ```binding.pry```をコード内に記述します
![スクリーンショット 2018-12-13 0.51.57.png](https://qiita-image-store.s3.amazonaws.com/0/281558/ef19dfa5-2923-e059-ae28-8f90af6abbb1.png)
それをすることでそこを通るとき処理を中断してくれます！
中断した内容はコンソール上で見ることができます
<img width="896" alt="スクリーンショット 2018-12-13 0.52.45.png" src="https://qiita-image-store.s3.amazonaws.com/0/281558/31c06720-e149-031f-34ff-570796ec3c49.png">
そこでどんな値が飛んできているのかということや、どんな動作をしているのかを確認することができます

おそらくプログラミング初期の頃はなんでこんなものが必要かわからないと思いますが、エラーしたときにとりあえずエラーしてるところに ```binding.pry```挟んでみるみたいなことしていればいつの間にか無くてはならない物になっていると思います。

#2,devise
ユーザー登録の機能をめちゃくちゃ簡単に作ってくれるすぐれもの！

```console
rails g devise:install
rails g devise User
bundle exec rake db:migrate
```
このgem入れて
とりあえずこの上の3行をコンソールで実行して以下のURL行けば
[http://localhost:3000/users/sign_up](http://localhost:3000/users/sign_up)
<img width="377" alt="スクリーンショット 2018-12-13 1.13.59.png" src="https://qiita-image-store.s3.amazonaws.com/0/281558/47b0ce7c-bec1-4a86-8f79-8355fb920e10.png">
こんな感じのログイン画面が出来上がりますｗ
拡張機能でTwitterログインFacebookログインもできますし、パスワード忘れたときの再発行メールの設定とかも簡単にできます。


細かい設定や使い方は下のに記事を参考にしてください
https://qiita.com/cigalecigales/items/73d7bd7ec59a001ccd74

#3,ransack
モデル内のカラムの検索を簡単に行ってくれるgemです
![スクリーンショット 2018-12-13 1.28.26.png](https://qiita-image-store.s3.amazonaws.com/0/281558/182c279f-d101-b0e1-0b9a-115394aee3eb.png)
![スクリーンショット 2018-12-13 1.28.49.png](https://qiita-image-store.s3.amazonaws.com/0/281558/6b18881d-dab4-43f4-12e0-e2a2fbead569.png)
本来このような検索フォームを作る場合SQL文を覚えて実装を行わなければいけませんが、このgemを使うことでかなり容易に検索フォームを作成することができます。

詳しくは以下の記事が参考にしてください
https://qiita.com/nishina555/items/2c1f8bae980e426519bc

#4,rails-erd
このgemはプロダクトのテーブル構造とアソシエーションを以下のように可視化してくれるgemです
下はLINEのような個人間のメッセージアプリを作った際のテーブル構造です。
<img width="1092" alt="スクリーンショット 2018-12-13 1.52.32.png" src="https://qiita-image-store.s3.amazonaws.com/0/281558/13fbe4a0-2848-b141-8466-329dfd9bd562.png">

使い方は簡単で
このgemを入れたあと
```bundle exec rake erd```
とコンソールで叩くだけで
このようなPDFファイルを生成してくれます。
めちゃ便利ですｗ
#5,bootstrap
超有名なcssテンプレートですね！
あまりにもつかわれすぎてエンジニアからしたらbootstrapを使っていることは即バレしてしまいますが、やはり圧倒的に楽なので自分で開発を行うときは必ず入れてます。
レスポンシブ対応が簡単にできますし
ボタンの種類とかも豊富ですしね！
![スクリーンショット 2018-12-13 2.06.20.png](https://qiita-image-store.s3.amazonaws.com/0/281558/9ce8c4b6-d37d-e956-31b6-28264de1b0fc.png)

#まとめ
ということでいかがだったでしょうか？
超王道なgemが多かったと思いますが、少なくともどんなサイトを作るにしてもかなり力になってくれる
gemたちだと思うのでおすすめします！

gemを追加したあとは
```bundle install```
と
railsサーバーの再起動を忘れずに！

それでは！
(3分でわかる)UNIXコマンドを使った容量の検索と削除

自分用メモついでに便利だったので
常識と言われたら常識かもしれませんが温かい目で見てください
#そもそも
PCの中身ってブラックボックスになりませんかね．私は5年間容量不足で悩まされ続けてます．
容量貴族になれればいいのですがそういうわけにもいかないのでとりあえずどのフォルダが容量食ってんだろって調べるコマンドを探してみました．
#環境
Macbookair 2013年モデル128GB
MacOS Mojave.ver10.14
iTerm2
#容量の検索
容量の検索コマンドは

```
$du
```

でこれをうまく扱うと容量をいい感じに検索できます．

```
$ du
16	.
```
アクセス権がない場合があるので***sudo***コマンドも同時に使い管理者として使いましょう．

#引数
duコマンドにはオプションを設定できます．というか設定しないと512byte単位で容量が出力されるのでとてもみづらいです．

|オプション|意味|
|:-:|:-:|
|-a|ディレクトリだけじゃなくファイルの容量も表示する|
|-h|適切な容量で表示される|
|-c|合計を表示する|
|-d"数字"|集計する階層を設定する|
|-x|違うファイルシステムを集計から外す|

などなどです．
#例えば
私が使ったオプションを使って検索してみると

```
$sudo du  -d1  -h
Password:
616K	./Chrome Apps.localized
 12K	./Mountain.app
636K	.
```

このように表示されます．
ディレクトリだけでなくファイルの容量を見たいのならば-aをオプションに追加しましょう．

```
$ sudo du -c -h
4.0K	.
4.0K	total

$sudo du -c -h -a
4.0K	./test.c
4.0K	.
4.0K	total
```

#おまけ
##ディレクトリの削除
中身が空のディレクトリの削除なら

```
rmdir ファイル名

```
でよいのですが中身が入ったディレクトリでは消せません．

```
$rmdir test
rmdir: test: Directory not empty
```

というわけで中身ごと削除したい時には

```
rm -rf ファイル名
```

という形になります．ただし大事なファイルだろうがなんであろうが消してしまうので気をつけて行いましょう(これで失敗しても責任は取れません．)
#終わりに
PCがブラックボックスになるのはとてもよろしくないので定期的に整理しましょう
golang で libvterm

空いていたので穴埋め

# libvterm とは

libvterm は libtermkey の作者でおなじみの Paul Evans 氏によって作られた、VT220/xterm/ECMA-48 といった端末エミュレータの仕様を抽象化し疑似する為のライブラリです。このライブラリの仕様に従ってプログラミングするとプラットフォームや GUI/CUI に依存せず端末エミュレータが扱えるという物です。neovim や vim の `:terminal` 機能として使われています。

libvterm はシェルではありません。またユーザインタフェースでもありません。純粋な仮想端末エミュレータの実装です。ですのでキーも読み取りませんし、何も描画しません。出来るのは端末のセルに対するエスケープシーケンス等の書き込みと、それによって制御された端末の出力結果を取得出来るのみです。

ですので例えばシェルを起動しユーザと対話できる端末エミュレータを作る場合、プログラムは子プロセス(シェル)を起動し、その pty 出力を読み取って libvterm に流し込みます。また libvterm からのコールバックイベントに伴い端末のセル情報を読み取って独自 UI にレンダリングする事になります。

![libvterm](https://qiita-image-store.s3.amazonaws.com/0/665/eb5862b8-4ee4-ffcf-3296-449486562eb1.png)

# libvterm をGo言語から使いたい

以前 libvterm をGo言語から扱う為のパッケージを書きました。

https://github.com/mattn/go-libvterm

このパッケージを使って、80x25 の端末に赤字で「Hello」緑色で「World」と表示するプログラムを書いてみます。

```go
vt := vterm.New(25, 80)
defer vt.Close()

vt.SetUTF8(true)

screen := vt.ObtainScreen()
screen.Reset(true)

_, err := vt.Write([]byte("\033[31mHello \033[32mGolang\033[0m"))
if err != nil {
	log.Fatal(err)
}
screen.Flush()
```

このコードを実行しても実際には何も表示されません。「これのどこが良いか分からない」そう思われるかもしれません。では続けて以下のコードを書いてみます。

```go
	rows, cols := vt.Size()
	img := image.NewRGBA(image.Rect(0, 0, cols*7, rows*13))
	draw.Draw(img, img.Bounds(), &image.Uniform{color.Black}, image.ZP, draw.Src)

	for row := 0; row < rows; row++ {
		for col := 0; col < cols; col++ {
			cell, err := screen.GetCellAt(row, col)
			if err != nil {
				log.Fatal(err)
			}
			chars := cell.Chars()
			if len(chars) > 0 && chars[0] != 0 {
				drawChar(img, (col+1)*7, (row+1)*13, cell.Fg(), string(chars))
			}
		}
	}
	f, err := os.Create("output.png")
	if err != nil {
		log.Fatal(err)
	}
	defer f.Close()
	err = png.Encode(f, img)
	if err != nil {
		log.Fatal(err)
	}
```

こうする事で、80x25 の端末のスクリーンショットが撮れる訳です。

![output.png](https://qiita-image-store.s3.amazonaws.com/0/665/acf4cc04-272a-0f51-da1a-d5f2fc8f0e2b.png)

プログラム全体のコードを Gist に貼り付けておきます。

https://gist.github.com/mattn/06bfda007b8fc66890190052e06782d7

# go-libvterm で出来ること

アプリケーションがデバイスに依存しない端末用キャンバスを内蔵できる事になるので、例えば Windows の仮想端末実装である winpty と合わせて使うと、コマンドプロンプトに tmux の様な枠を作りその中でさらにコマンドプロンプトを住まわせる事も出来るのです。

![terminal6.gif](https://qiita-image-store.s3.amazonaws.com/0/665/66475bf4-25d9-d77a-5a61-6f62dd654adf.gif)

自分で作ったウィンドウアプリケーションの一部分に、Visual Studio Code の端末機能や Vim/neovim の `:terminal` 機能を付けたい場合には libvterm が便利です。そしてそのアプリケーションが Go で実装されているならば go-libvterm を使う事が出来ます。

宜しければご利用下さい。
12-13 mp4sa

https://adventar.org/calendars/3353 の13日目エントリーです。

## mp4saとは?

音楽の表現としてstandard MIDI fileを使うことを考えた時、まっ先に表出するであろう問題点は、再生するMIDIデバイス環境によって全く異なる音楽になってしまうということです。20世紀にまだ日本国内でRoland音源とYAMAHA音源がGS/XGで競っていた頃は、「XX音源専用」のようなMIDI楽曲を見かけることがよくありました（SoundBlaster環境で再生することが前提だったものもあることでしょう）。当時MIDIのような方式で音楽を表現するにはコンピューティングリソースの都合上やむを得なかったでしょう。

現在はコンピューター上でソフトウェア・シンセサイザーを利用して作曲するのも現実的になっており、特定のハードウェアに依存せずに、制作環境と同様にMIDIのような方式で制作された音楽を再生することは可能になりつつあります。MIDIのような方式で全トラックを何の問題もなくフル再生できるかというと、実際のところはまだパフォーマンス上の問題はあるのですが、現実的にはなりつつあります。

しかしMIDIという仕様を越えて楽曲と楽器の表現を標準化するという動きは未だにありません。特定の「ソフトウェア」（特に「音源」）に依存せずに音楽を作るのは、これだけでは無理そうです。誰かが作ったものを、限りなくそのままに近い環境でそのまま再生でき、その演奏データも見ることが出来て、どのように作られているのか、World Wide Webのように知見が共有されて広まっていく時代は来ないのでしょうか?　同じサウンドエクスペリエンスの共有が可能になると、楽しみが増すはずだ、とわたしは確信しています。

実のところ、MIDIを越えて音色定義なども標準化しようという試みはかつて存在していたようです。そのひとつ(?)がMPEG-LAによるMP4-SA (Structured Audio)という仕様です。MP4のISO/IEC仕様の一部になっているのです。割とビックリですね。

https://en.wikipedia.org/wiki/MPEG-4_Structured_Audio

## SAOLとSASL

MP4-SAの目的は、どのような環境であろうと、MP4-SAに準拠して記述された音楽は、同じ音として再現できるというものです。構造化された音楽データ構造を規定します。

MP4-SAについては、公式サイト(?)が一番詳しくまとめています。

https://john-lazzaro.github.io/sa/book/index.html

MP4-SAでは、SAOL (Structured Audio Orchestra Language)というオーディオプログラミング言語(APL)とSASL (Structured Audio Score Language)という独自の音楽記述言語によって、音楽を表現します。前者がプログラム／バンク定義を、後者がMIDIメッセージを、それぞれ担当すると考えれば分かりやすいです。

これらの言語で記述された音楽は、`sfront`というツールによってWAVファイル等に変換できます。使い方は簡単そうです。

```
 sfront -orc sine.saol -sco sine.sasl -bitout sine.mp4 -aout output.wav
```

SAOLはDSPを設計するようなコードを書くことになりますが、同種の言語は数多く存在するので、ここで紹介する意味はほぼ無いでしょう。公式サイトにあるSASLのサンプルはこんな感じです:

```
0 tempo 110
2 tempo 112.1
4 tempo 114
6 tempo 116
8 tempo 118

1 vtone   1.5 52 
3 vtone   1.5 64 
5 vtone   1   63 
6 vtone   0.5 59 
6.5 vtone 0.5 61 
7 vtone   1   63 
8 vtone   1   64 

10 end
```

パッと見た感じでは、BASIC言語のように行頭の数字が処理順を定義していて（ただし小数値も指定可能…!）、別のSAOLファイルで定義されている`vtone`という音色を使って、3列目の1.5、1、0.5といった音長、4列目の52、64、63…といった音階のノート命令を実行する、という内容であるようです。便利なのかそうではないのかよくわかりませんが、人間が記述するための言語でないことは見て取れます。Pure Dataなどが近い文法であるというべきでしょうか。

いずれにせよ、これだけではまだ到底使い物になるとは言えず、標準仕様として策定までされているものの、一向に使われる気配がないのも、まあ致し方ないかな…とは思います。SAOL部分をVSTなどに変換できるようにすれば実用性も上がるのでしょうか…（とても上がらない気がしますが）。この辺りは、もう少しオープンソース開発での動向を見てから標準化に流れてもいいのかもしれません。伏線のようになってしまいましたが、日を改めて考察を続けたいと思います。