OmniAICreator/Qiita-1.07M huggingface dataset:
GUIでgRPCを叩けるツール「omgRPC」を使ってみる

RESTではcurlやPostmanを使ってURLを叩くだけで簡単に動作確認することが出来ます。
一方gRPCではそのように簡単に動作確認することができません。
クライアントを実装する必要があるからです。

そういった問題を解決するために様々なツールがリリースされています。
例えば「[grpcurl](https://github.com/fullstorydev/grpcurl)」はcurlのようにターミナル上でgRPCを実行することが出来ます。

```bash
$ grpcurl -plaintext -import-path . -proto proto/hello.proto -d '{"name": "Morix"}' localhost:5000 hel
lo.HelloService/Hello
{
  "message": "Hello, Morix"
}
```

これはこれで簡単なのですが、どうせならGUIでポチポチやりたいところです。
ということで、「[omgRPC](https://github.com/troylelandshields/omgrpc)」というツールを見つけたので、それの紹介です。

## omgRPCとは
そのまんまで、GUIでgRPCを実行できるツールです。
上記のgrpcurlの例で見せたものをomgRPCで実行すると以下のようになります。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/152303/58becedf-14fa-b377-52b6-c127c5aaf086.png)

## インストール
まず動作確認環境は以下のようになってます。

* OS
    * macOS High Sierra
* Node.js
    * 8.14.0
        * 10系だと動作しませんでした

### 手順
npmが必要なのでNode.jsは上記の通り8系でやりましょう。

```bash
$ git clone git@github.com:troylelandshields/omgrpc.git && cd omgrpc
$ npm install -g nwjs node-pre-gyp nw-gyp
$ nw install 0.25.0-sdk
$ npm install
$ npm rebuild grpc --build-from-source --runtime=node-webkit --target=0.25.0 --target_arch=x64 --target_platform=darwin
```

特になにもエラーがない人は、次の手順は飛ばしてください。

僕の環境では最後のrebuildで以下のようなエラーが出て失敗しました。

```bash
$ npm rebuild grpc --build-from-source --runtime=node-webkit --target=0.25.0 --target_arch=x64 --target_platform=darwin

> grpc@1.8.4 install /Users/morix/tools/omgrpc/node_modules/grpc
> node-pre-gyp install --fallback-to-build --library=static_library

xcode-select: error: tool 'xcodebuild' requires Xcode, but active developer directory '/Library/Developer/CommandLineTools' is a command line tools instance

xcode-select: error: tool 'xcodebuild' requires Xcode, but active developer directory '/Library/Developer/CommandLineTools' is a command line tools instance
```

どうやらXcodeを使うようです。
MacにXcodeをインストール後、以下のコマンドを実行して再度`rebuild`したらうまく動きました！

```bash
$ sudo xcode-select -s /Applications/Xcode.app/Contents/Developer
```

## 使い方
以下のコマンドでomgRPCが起動します。

```bash
$ nw .
```

起動すると以下のような画面が出るはずです。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/152303/464e4e84-03ac-1ed6-7842-e02b22eca5f8.png)

右上の「New Protofile」に叩きたいgRPCサービスのprotoファイルを選択します。
サンプルは以下のものを使ってみます。

```proto:hello.proto
syntax = "proto3";

package hello;

message HelloRequest {
  string name = 1;
}

message HelloResponse {
  string message = 1;
}

service HelloService {
  rpc Hello(HelloRequest) returns (HelloResponse) {}
}
```

サーバーなどのソースは以下を使ってます。参考に使ってみてください。
https://github.com/morix1500/grpc-web-nginx

protoを選択すると、gRPCサーバーのアドレスを聞かれます。自分で設定したところを選択します。
Clusterはminikubeのままで問題ないです。
「Hello」というタブがあり、これが関数になってます。関数ごとにタブが増えていきます。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/152303/4ff07a8b-bc77-2606-8e77-494c3b6dd9de.png)

Metadataを設定できるようです。
またリクエストはJSON形式で送る必要があります。それもある程度は事前に入力しててくれます。

「Try Experimental Form」はJSONではなく以下のようにテキストフィールドで入力できるようにしてくれてます。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/152303/66adba55-ef64-c66c-3ccc-38d05f6e2bd2.png)

あとは必要なものを入力すると、レスポンスがJSONで返ってきます。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/152303/976c8226-5b02-6558-5d51-8b27fe6a27b5.png)

簡単ですね！！！
HTML5のinput type=fileで許可するファイルを制御できます。

# はじめに
HTML5のinputにてtype=fileの場合、accept属性を使用すれば、指定できるファイルを制御できます。


## 設定方法と制御できるファイル
```
<input type="file" accept="[mine type]">
```

## 指定できる[mine type]の一覧
- image/*
  - 画像ファイルのみ
- image/gif
   - gifファイル
- image/png
    - pngファイル
DynamoDBのテーブルからnode.jsでランダムにItemを取ってくる

#DynamoDBのテーブルからランダムにItemを取ってくる方法

たとえば総数10個のレコードある以下のようなsampleテーブルからランダムに1件取ってくる場合、

sampleテーブル：
![HAIKU_table.png](https://qiita-image-store.s3.amazonaws.com/0/307441/4f412b93-4f03-4ff3-90ee-1dc6fd2a7536.png)



RDBならSQL文1行で済みますね。
`select HAIKU from sample order by rand() limit 1`


これを使ってNode.jsでコード書くと、

```
// 接続詞は省略

  connection.query('select HAIKU from sample order by rand() limit 1', function(err, rows) {
    if(err) {
      return console.log(err)
    }else{
      HAIKU = rows[0].HAIKU
      console.log(HAIKU)
    }
  });

```

ああ簡単:expressionless:


<br />

じゃあ、NoSQLのDyanamoDBではどうしましょ・・・


意外とムツカシイ方法でみなさん苦戦しているようなのでこれでいいんじゃないの、という方法を載せておきます。


```
var AWS = require('aws-sdk');
var docClient = new AWS.DynamoDB.DocumentClient();
var util = require('util');

    // DynamoDBのsampleテーブルをScanしItem総数を獲得
    var params = {
        TableName: 'sample',
        Select: "COUNT" // Selectはアイテム総数を返すパラメーター
    };

    docClient.scan(params, function(err, data){
        if(err){
              console.log(err);
        }else{
            util.inspect(data,false,null);
            var length = data["Count"]; 　//data["Count"]に全Item数が入ります
            randomNum = Math.floor(Math.random() * length);
            console.log('randomNumは　' + randomNum);
            callHAIKU(randomNum);
        }
    });



    // ランダム整数randomNumを引数にsampleテーブルからランダムにHAIKU文字列を獲得
    function callHAIKU(arg){
        var randomNum = arg;
        var params = {
            TableName: 'sample',
            Key: {            // SQLのwhere条件文にあたるパラメーター
                'ID': randomNum
            }
        };
        docClient.get(params, function(err,data) {
            if(err){
                console.log(err);
            }else{
                var result = JSON.stringify(data.Item)  
                //data.ItemはJSON文字列の{"ID":3,"HAIKU":"春雨や食はれ残りの鴨が鳴く"}
                var result = JSON.parse(result.HAIKU);            
                //parseしてresultをオブジェクト化する
            }
        })
    }

```

Scanで総件数をまず取ってきて、それをvar lengthに格納。
それを使って

`randomNum = Math.floor(Math.random() * length)`

の式で１〜１０までのランダムな整数をrandomNum変数に格納。

randomNum変数を引数にしてcallHAIKU()関数の中でHAIKU文字列を取ってきます。
最終的にresult変数に俳句の部分だけ、たとえば"春雨や食はれ残りの鴨が鳴く"が格納されます。



<br />


この文字列をランダムにツイートしたりラインで毎朝一斉メッセージしたりするって使い方。

<br />

ただ、

DynamoDBでは一度のScanに１MBの制限があるので注意。テーブルのサイズが大きいと全件数が取ってこれません。


ただ上記のような簡素なテーブルで10レコードなら3KBもないのでその300倍くらいのサイズまで大丈夫。（3,000レコードとか）



それにさ、１MB制限もそのうち１GB制限とかに増えていくんじゃない？:sunny:

<br />
Vue Parent Child

Parent

    <modal
      :newName='newName'
      @changeNewName="changeNewName"
    ></modal>

    data() {
      return {
        newName: '',
    }

    methods: {
      changeNewName(name) {
        this.newName = name;
      }
    }

Child

    <input
      v-model="newNameChild"
    ><input>

    props: ['newName'],
    computed: {
      newNameChild: {
        get() {
          return this.newName
        },
        set(name) {
          if (this.newName !== name) this.$emit('changeNewName', name)
        }
      }
    },
AVSampleBufferDisplayLayerが壊れた時に復旧する方法

AVSampleBufferDisplayLayerはCMSampleBufferを食わせるだけでよしなに映像再生してくれる便利なやつなのですが、バックグラウンドで利用するとすぐ壊れます。

映像が映らなくなったら、`layer.error`や、`layer.status`を参照するとエラーが出ていたりするはずです。

```
Ignoring enqueueSampleBuffer: because status is "failed"
```

というエラーがコンソールに出ることもあります。

基本的にはアプリのアクティブに合わせて、displayerLayerを触らないようにしますがそれでも稀にこれらが発生する事があります。

そのような場合はflushを呼ぶと改善される事があります。

```swift
if displayLayer.status == .failed {
       displayLayer.flush()
}
```
RaspberryPi で人感カメラを作ってみた

# 開始
IoT事業を始める前のスバイクとして、
人感カメラを作ってみました。
人が席に座ると、写真が撮られ、ブザーも鳴なります。
同時にSlackにメッセージを送ります。

# 事前準備
###今回使った器材
・Raspberry Pi Model B+
・Raspberry Pi カメラモジュール
・Raspberry Pi Starter Kit(ブザー、抵抗)
・赤外線障害物検知センサーモジュール
・microSDカード

###Raspberry Piセットアップ
- OSを入れるためSDカードをFAT32フォーマットする。

- Raspberry Piの公式サイトから、NOOBSと言うパックをダウンロードする。
  ダウンロードしたZIPファイルを解凍して、中身を全部SDカードにコピーする。
  公式サイト：https://www.raspberrypi.org/downloads/

- SDカードをRaspberry Piに挿入し、HDMIと電源を繋ぐ。
  画面にガイドが出てきて、それを従ってインストールする。
  NOOBSがOSのRaspbianとLibreELECがすでに内包してるので、
  初心者でも簡単にインストールできる。

セットアップに疑問があるとき、以下の記事を参考してください。
https://raspida.com/raspixnoobs

# ボード接続
![QS_20181210-134141.png](https://qiita-image-store.s3.amazonaws.com/0/322119/f9ff7564-1f2f-48ae-7fea-e3546fbeca91.png)
- 画像の通り、部品を接続する。(赤い線は+、黒い線は-、黄色線はOutput)
- Raspberry Pi カメラモジュールは 中央辺りのカメラ口に接続する。(電源を切る状態で行ってください)

# 制御ファイル作成
今回のプログラムの部分はPythonで作成した。

```python:buzzer.py
#ブザークラス

#GPIO制御ライブラリ
import wiringpi
#タイマーライブラリ
import time

Class Buzzer:
    buzzer_pin = 0
    def __init__(self,pin) :
        self.buzzer_pin = pin
        wiringpi.wiringPiSetupGpio()
        wiringpi.pinMode(self.buzzer_pin,1)  
    
    def buzz(self,second) :
        #鳴り始める
        wiringpi.digitalWrite(self.buzzer_pin,1)
        time.sleep(second)
        #止める
        wiringpi.digitalWrite(self.buzzer_pin,1)

```

```python:watchdog.py
#GPIO制御ライブラリ
import wiringpi
#HTTPリクエストライブラリ
import requerts
from datetime import datetime
#タイマーライブラリ
import time
#RaspberryPiのカメラクラス
import picamera
#ブザークラスをインポート
from buzzer import Buzzer

sensor_pin = 24
wiringpi.wiringPiSetupGpio()
wiringpi.pinMode(sensor_pin,0)
#カメラ設定
with picamera.PiCamera() as camera:
    #カメラ解像度
    camera.resolution = (1024,768)
    #無限ロープで監視
    while True:
        signal = 0
        #センサーの信号を読み取り
        signal = wiringpi.digitalRead(sensor_pin)
        if(signal == 0):
            #ブザーが鳴る
            buzzer = Buzzer(27)
            buzzer.buzz(1)

            #写真を撮り、現在の時刻で命名して保存
            now = datetime.now().strftime('%Y-%m-%d %H:%M:%S')
            camera.capture('monitorphoto/'+now+'.jpg')

            #Slack apiを使用し、メッセージを送る
            requests.get("https:slcak.com/api/chat.postMessage?token=XXX&channel=XXX&text=XXX")
```
# 最後
複雑ではないか、センサー、Raspberry Pi、WEBAPIを
一通り結んだ機能を実現しました。
これからIoT関連調査対して、参考になれます。
WPFでのMultiBindingの使用方法（TextBlockとCheckBoxで若干異なります）

# はじめに
WPF（C#）でMultiBindingで、複数の値をバインディングする方法についてまとめています。

# TL;TD
プロパティがTextの場合は、StringFormatが利用できます。
プロパティがContextの場合は、StringFormatが利用できないので、Converterを介する必要があります。

# コード
- TextBlockの場合はStringFormatで表示ができます。
- 最初にBindingの値を表示する場合は、「{}」を記載しておく必要があります。

```sample1.xaml
<TextBlock>
  <TextBlock.Text>
      <MultiBinding StringFormat="{} {0}:{1}">
         <Binding path={name}/>
         <Binding path={kind_name}/>
      </MultiBinding>
 </TextBlock.Text>
</TextBlock>
```

- CheckBoxの場合はStringFormatが利用できないので、Converterを介して表示する

```sample2.xaml
<CheckBox>
  <CheckBox.Text>
      <MultiBinding StringFormat="{StaticResource hogeConverter}">
         <Binding path={name}/>
         <Binding path={kind_name}/>
      </MultiBinding>
 </CheckBox.Text>
</CheckBox>
```

```hogeConverter.cs
public class hogeConverter : IMultiConverter {
    public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
    {
        return string.Format("{0}:{1}", values[0], values[1]);
    }

    public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}
```

# まとめ
StringFormatが利用できるときは利用して、利用できないときはConverterを使用するといいです。
Python+boto3でS3に画像をアップロードして公開する

# 背景
Pythonでboto3ライブラリを使ってAWSのS3に画像をアップロードする際に、セキュリティの設定でデフォルトは読み書き不可にしている場合に、アップロードしたファイルだけ公開したい場合があります。

# 対応
upload_fileの引数に```ExtraArgs```でjson形式でACLを指定して、公開状態にします。


```python

import os
import boto3

class MyAws():
  def upload_s3(self, original_file_path, upload_folder, upload_filename):
    self.s3 = boto3.client('s3',
      aws_access_key_id=os.getenv('S3_ACCESS_KEY'),
      aws_secret_access_key=os.getenv('S3_SECRET_KEY'),
      region_name=os.getenv('S3_REGION_NAME'))
    upload_filename = os.path.join(folder_name, upload_filename)
    try:
      result = self.s3.upload_file(original_file_path, os.environ["S3_BUCKET_NAME"], upload_filename, ExtraArgs={"ContentType": "image/jpeg", 'ACL':'public-read'})
    except boto3.exceptions.S3UploadFailedError:
      print("S3へのアップロードでエラーが発生しました")
      raise boto3.exceptions.S3UploadFailedError
    finally:
      # 後片付け
````


# 参考
- [Boto 3 Docs 1.9.62 documentation](https://boto3.amazonaws.com/v1/documentation/api/latest/guide/s3.html)

- [boto3でS3にアップロードした画像が、ブラウザで表示するとダウンロードされてしまう時](https://hack-le.com/boto3-s3-browser/)
Ada言語 2日目 変数(Integer型)

#はじめに
前回は入門としてHello Worldしましたが、今回から本格的に始めていこうと思います。
開発環境について学習するのはあとにして、先に基本的な文法をマスターしていきたいと思います。

#今回やったこと
それで今回は小さな一歩ですが、整数型を使って変数について学習しました。
どうやら変数宣言をする場所はアセンブリのdataセグメントみたいに決まっているらしいのです。
実際にソースコード及び実行結果で見てみることにします。

#ソースと実行結果
```main.adb
with Ada.Integer_Text_IO;
use Ada.Integer_Text_IO;

procedure main is

	Integer_value1 : Integer := 1;

begin

	Ada.Integer_Text_IO.Put(Integer_value1, 1);

	Integer_value1 := 2;

	Ada.Integer_Text_IO.Put(Integer_value1, 1);

end main;
```
こちらがソースコードになります。
コンパイル、リンク、実行の手順は1日目と同様、
` gcc -c main.adb `
` gnatbind main `
` gnatlink main `
` ./main `
です。

まず変数宣言ですが、
` 変数名 : 型; `
と宣言するようです。

上のソースでは
` 変数名 : 型 := 初期値; `
としています。

ちなみに初期値を代入しないまま参照するとゴミが表示されます。
さらに`warning: "Integer_value1" may be referenced before it has a value`といったようなワーニングも表示されます。

ここで注意しなければいけないのが変数宣言する場所です。
下のような書き方をすると

```main.adb
with Ada.Integer_Text_IO;
use Ada.Integer_Text_IO;

procedure main is

-- この間で変数宣言すること!
-- ちなみに左のはコメントを表す。

begin

	Integer_value1 : Integer := 1;

	Ada.Integer_Text_IO.Put(Integer_value1, 1);

	Integer_value1 := 2;

	Ada.Integer_Text_IO.Put(Integer_value1, 1);

end main;
```

` declarations must come before "begin" `
と、エラーがでます。

実行結果ですが、` 12 `となります。

今回使用したライブラリと(おそらく)関数については詳しくは学習していませんのでまたいつか。

#今後の予定
当分データ型や変数について学習したあと、条件分岐やループに入っていきたいと思います。

#日記一覧へ
[Ada言語を習得する日記一覧](https://qiita.com/C_Assembly/items/50a0f9d8542679d92ea8)
Vue.DraggableがTypeScriptプロジェクトで使えない問題を解決する

Vueプロジェクトで簡単にドラッグ&ドロップを実現するVue.DraggableというOSSがあるが、2018年12月現在でTypeScript用の定義ファイルが存在せず、普通にimportして使おうとするとエラーが発生し使用できない。

```vue
<template lang="pug">
  div
    draggable(v-model="myArray")
      div(v-for="element in myArray" :key="element.id") {{element.name}}
</template>

<script lang="ts">
import draggable from 'vuedraggable' // Cannot resolve definitions for module 'vuedraggable'
import { Component, Vue } from 'nuxt-property-decorator'
@Component({
  components: { draggable }
})
export default class Hoge extends Vue {
  public myArray: object[] = [
    {
      id: 1,
      name: 'hoge'
    },
    {
      id: 2,
      name: 'foo'
    },
    {
      id: 3,
      name: 'bar'
    }
  ]
}
</script>
```

これを解決するためには、ambient.d.tsファイルにvuedraggableというモジュールを定義したことを伝えるとOK。

```typescript:ambient.d.ts
declare module 'vuedraggable';
```

この定義を加えればエラーが発生せず、TypeScriptプロジェクトでも普通に使えるようになる。
C++ Builder XE4 > UI > 実装: [マウスクリック]と[マウスでの範囲選択]を判別する

```txt:動作環境
C++ Builder XE4
```

### 概要

- マウスクリック
    - 左クリック
    - クリックを離す
- マウスでの範囲選択
    - 左クリック
    - 移動
    - クリックを離す

上記を判別する実装を考えた。

### 実装

```Unit1.h
//---------------------------------------------------------------------------

#ifndef Unit1H
#define Unit1H
//---------------------------------------------------------------------------
#include <System.Classes.hpp>
#include <Vcl.Controls.hpp>
#include <Vcl.StdCtrls.hpp>
#include <Vcl.Forms.hpp>
#include <Vcl.ExtCtrls.hpp>
//---------------------------------------------------------------------------
class TForm1 : public TForm
{
__published:	// IDE で管理されるコンポーネント
	TPanel *Panel1;
	TMemo *Memo1;
	void __fastcall Panel1MouseUp(TObject *Sender, TMouseButton Button, TShiftState Shift,
          int X, int Y);
	void __fastcall Panel1MouseDown(TObject *Sender, TMouseButton Button, TShiftState Shift,
		  int X, int Y);
	void __fastcall Panel1MouseMove(TObject *Sender, TShiftState Shift, int X, int Y);

private:	// ユーザー宣言
	bool m_bfMouseMove; // マウス移動があったかどうか
public:		// ユーザー宣言
	__fastcall TForm1(TComponent* Owner);
};
//---------------------------------------------------------------------------
extern PACKAGE TForm1 *Form1;
//---------------------------------------------------------------------------
#endif

```

```Unit1.cpp
//---------------------------------------------------------------------------

#include <vcl.h>
#pragma hdrstop

#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
	: TForm(Owner)
{
}
//---------------------------------------------------------------------------

void __fastcall TForm1::Panel1MouseUp(TObject *Sender, TMouseButton Button, TShiftState Shift,
		  int X, int Y)
{
	if (m_bfMouseMove == false) {
		Memo1->Lines->Add(L"Click");
	} else {
		Memo1->Lines->Add(L"Range Select");
    }
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Panel1MouseDown(TObject *Sender, TMouseButton Button, TShiftState Shift,
          int X, int Y)
{
	m_bfMouseMove = false;
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Panel1MouseMove(TObject *Sender, TShiftState Shift, int X,
          int Y)
{
	m_bfMouseMove = true;
}
//---------------------------------------------------------------------------

```


### 動作例

![2018-12-10_15h15_36.png](https://qiita-image-store.s3.amazonaws.com/0/32870/9fe20cc8-eece-e23e-109d-ff8e1644c223.png)


### 備考1

「X,Y位置を保持してMouseUp時にずれがないか確認」という案も考えたが、上の実装の方がシンプルだろう。

Panel1MouseUp()のみを使う実装があれば知りたい。


### 備考2

左クリック時に少しでも座標が動くとクリックと認識されない。
「クリックしたの処理されない」とユーザに思われる場面がありそう。

座標の移動量を見て、多少の移動であればクリックとして処理する、などの工夫は必要かもしれない。
C言語初心者が頑張る

#*自己紹介*:runner_tone2:

医療系の夢を抱いていた高校生だったけど
大学では情報工学系の学部に来てしまった（？）
大学２年生女の者です:dress:
授業では1年の時からC言語を習っていましたが、単位を取ることで精一杯...
2年でのC言語の授業（オペレーティングシステムの演習授業）では、課題すら出せずに危機感を感じ、C言語を本格的に習得しなければと思い、この記事を書こうと思いました。
#*どういう方法で勉強を進めていくか*:no_mouth:
勉強方法などはよくわかっていません
先生からはとりあえず、*コードがたくさん書いてある参考書をひたすら手で打って体で覚えろ*といわれたので、最初は参考書のコードを手で打とうと思います・・・
何かほかに良い勉強法あれば教えていただきたいです...
先生が1年生の時に出してくれていた練習問題を解いていくこともたまにしようかと思います。
#*この勉強を通して私がしたいこと*
<dl>
<dt>①パソコンに触れる機会を増やす</dt>
<dd>今のままでは授業中と課題をする際にしかパソコンに触れないので触れる機会だけでも増やしたい！</dd>
<dt>②就活までに授業で習ったことに関してできないことを減らす</dt>
<dd>このままでは就活が本当に恐ろしい！</dd>
<dt>③PCの機能に興味を持つ！</dt>
<dd>みなさんが書いてる記事をほほうと読めるようになりたい！</dd>
<dt>今期の単位を取る！</dt>
<dd>単位をとれますように...</dd>
#*このサイトを使った理由*
課題をする際にほんとうに、皆様の記事に助けられているので、私もいつかは困った人を助けれるような記事を書けたら良いなと思って思い切って始めました。
いつもありがとうございます。
「働きやすい空調環境」を目指して

![adv2018.gif](https://qiita-image-store.s3.amazonaws.com/0/217528/97e5eae5-1d32-5714-45a5-67593487e0f9.gif)

[aratana Advent Calendar](https://qiita.com/advent-calendar/2018/aratana) 2018 15日目の記事です。

こんにちは、アラタナのwebエンジニア、宮崎在住の[川原Pさん](https://www.facebook.com/hiroyuki.kawahara.56)です。
数字やSQLが好きです。

最近冬になって肌荒れの季節になり、手の肌が乾燥で剥けてしまいました。そんな中、会社のみんなにとっての働きやすい空調を目指しました。

## 目指す「働きやすい空調環境」とは

働きやすい快適な空調環境って実は人やその日のファッション次第で、みんなにとっての快適は一様ではありません。
そのため今回は空調環境を見える化して、「一定に保つ」ことを目指したお話をします。

## 「見える化」する機械

今回はNETATMOを使って、空調環境を見える化します。
この機械から温度、湿度、二酸化炭素濃度を見ることができます。
このデータを使い、空調環境から分かる会社の様子をお伝えします。

![DSC_0697.JPG](https://qiita-image-store.s3.amazonaws.com/0/217528/c77bac86-5296-f564-91cd-30f2c07c9d08.jpeg)


## 温度計の様子
<img width="645" alt="スクリーンショット 2018-11-29 23.43.12.png" src="https://qiita-image-store.s3.amazonaws.com/0/217528/8414bf52-ca81-af90-9db4-b6a9950d96c1.png">

11月のある１週間の温度計を載せました。
温度を一定に保つように尽力した成果として、日中帯の温度が一週間通して26℃前後に保つことが出来ました。薄手の長袖でちょうど良いぐらいの温度でしょうか。
また夜間は温度が下がっており、夜間の人の少なさが読み取れるでしょうか。
このように温度計から会社での風景が読み取れます。

## 湿度計の様子

湿度計は去年と今年を比較をします。

去年の様子
![スクリーンショット 2018-11-29 15.05.25.png](https://qiita-image-store.s3.amazonaws.com/0/217528/94d05c4e-d025-ba74-1a7d-e107c8abc7f3.png)

今年の様子
![スクリーンショット 2018-11-29 15.06.44.png](https://qiita-image-store.s3.amazonaws.com/0/217528/623bb3fe-c59e-f0f8-2cce-806c47101bd3.png)

去年と今年の一番の違いは、今年のデータだけ9時ごろから上がり、21時頃から下がっていることです。
この時間は日中帯の加湿器の稼働時間と一致しており、加湿器の稼働状況が確認できます。
また去年は湿度35%でしたが今年は湿度45%以上にキープできていることが確認できます。肌や目、喉の乾きを感じることが減り、仕事しやすい環境になりました。また風邪の予防にもなっており社内で咳の音がしなくなった他、インフルエンザ対策にもなります[1]。

## 二酸化炭素濃度の様子
![スクリーンショット 2018-11-29 16.07.00.png](https://qiita-image-store.s3.amazonaws.com/0/217528/a0e26199-9d44-568f-d99e-b66c8a811d98.png)

最近１週間の二酸化炭素濃度のグラフを載せました。
グラフを見ると、平日と週末で違った傾向が見て取れます。
平日は700ppm以下に抑えられており、以下の表から十分な換気ができていると言えます[2]。

|二酸化炭素濃度|指標|仕事への集中しやすさ|
|:----------------:|:-----------------:|:------------------:|
|330~700ppm|理想的な換気レベル|◎|
|700~1000ppm|換気が充分|○|
|1000ppm~|換気が不十分|△|

## まとめ

数字として見える化し、「一定に保つ」ことでいつもの仕事環境を作ることに注力しました。
エアコンの設定でのけんかもなくなり、みんなにとって動きやすい環境作りが出来たと思います。
また空調のデータから会社のライフサイクルが読み取れることも分かりました。
記録を残すことで時間経過による変化がわかり、その変化を追跡していき楽しみましょう。

## 参考資料
[1]快適な湿度は何％？湿度をコントロールする方法を紹介
https://www.life-rhythm.net/humiditycontrol/

[2]チームラボオフィスの空気環境(CO2)を測定して改善している話
http://ch.nicovideo.jp/tks/blomaga/ar932992
Prevent user spoofing by requiring signed commits.

It is easy to pretend to be another user in git, you simply need to have their displayed user name and email address. There are much better articles out there regarding git user spoofing such as [this][git spoofing] and [this][git spoofing2] so I shall spare you the details.

Instead, let's talk about how we can prevent this using a simple tool called [GnuPG]. It can be easily installed using Homebrew using `brew install gnupg`. GitHub provides a nice set of instructions for [how to generate a GPG key][github 1] and [adding it to your account][github 2], so I shall skip that as well.

I'm simply here to show you what happens when someone spoofs another user's credentials and makes malicious commits.

<img width="999" alt="スクリーンショット 2018-12-10 14.39.56.png" src="https://qiita-image-store.s3.amazonaws.com/0/309888/d64c4c41-a9f6-6dd5-3b65-f46d0b3b0d2a.png">

See the `Verified` and `Unverified` flags?
You can easily prove your own commits simply by adding a set of GPG keys into your account.

What about if we go one step further and require all commits to be signed?

<img width="999" alt="githubSettings.png" src="https://qiita-image-store.s3.amazonaws.com/0/309888/4000d83d-5970-f058-461f-09dd86735976.png">

And now we make another malicious edit and attempt to push again!

<img width="464" alt="スクリーンショット 2018-12-10 15.08.22.png" src="https://qiita-image-store.s3.amazonaws.com/0/309888/4d53fc97-a68f-8b81-a4e5-3e57d3a36389.png">

<img width="535" alt="スクリーンショット 2018-12-10 15.00.36.png" src="https://qiita-image-store.s3.amazonaws.com/0/309888/cbb0bcac-777b-8d4c-d03e-a079eaceef98.png">

Your million dollar git repository is now safe from user spoofing just from two easy and simple steps.

[git spoofing]: https://medium.com/@pjbgf/spoofing-git-commits-7bef357d72f0
[git spoofing2]: https://stackoverflow.com/questions/37295783/git-block-impersonation-of-another-user
[GnuPG]: https://www.gnupg.org
[github 1]: https://help.github.com/articles/generating-a-new-gpg-key/
[github 2]: https://help.github.com/articles/adding-a-new-gpg-key-to-your-github-account/
Windows開発環境の備忘録(?)

#概要

この記事は
自前のWindowsPC開発の環境についてﾁｮｯﾄ書いたものです。

#PCのスペック

|**OS:**|**Windows 10 Home**|
|:---|:---|
|**PC:**|**HP Spectre x360**|
|**CPU:**|**Intel Core i7-7500U 2.70-2.90GHz**|
|**RAM:**|**16GB**|
|**ROM:**|**SSD 512GB**|

![20170422_115424754_iOS.jpg](https://qiita-image-store.s3.amazonaws.com/0/213065/25199ad3-42ee-069c-2499-b5908bbeba08.jpeg)
この2年間愛用しているPC。

##OS

今まで使ったことのある代表的なOSは、
###PC系
**Windows[XP/vista/7/8.1/10]**
**MacOS[バージョン不明]**
**Linux(Ubuntu, LinuxBean等)**
###SP系
**Android[4.X/5.X]**
**iOS[6/7/8/9/10/11]**
**FireOS[バージョン不明]**

個人的には
**PCは"Windows"**
**スマホはiOS**が1番使いやすいと感じます。

##メモリ

**16GB!!**
個人的には充分です。
今のところ不自由はないです。

しかし、メモリ8GB以下だとメモリ不足に陥ってしまいます……。
(たくさんのソフトを一斉に使いたい)

##容量

**512GB**ありますが、
**"圧倒的容量不足です！"**
定期的に外付けにデータ移動をしないとやっていけません。

**IDEやDTM関連、スマホのバックアップデータがかなり容量食います。**
**SSD 1TBパソコンがほしい……。**

##CPU

**充分。圧倒的パワー**
サックサクです。

#IDE

|**IDE:**|**Visual Studio 2017**|
|:---|:---|
|**言語:**|**C11/C++17(11,14,17)**|

VS2017使ってます。
普通に便利。
ゴリラチャット作りました

[クソアプリ2 Advent Calendar 2018](https://qiita.com/advent-calendar/2018/kuso-app2) 15日目の記事です。

**[2021/04/02] チャット廃止しましたので試せません**

こんにちは
ゴリラです。

仲間が欲しくてチャット作りました。
人間の方々の役に立たないです。すみません。

チャットはこんな感じになっています。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/66178/0611aff6-da94-f655-4678-e461e9741e53.png)

# 使ってみる
アカウント不要なので[こちら](https://gorillachat-2018.firebaseapp.com/)にアクセスしてください。
最初いくつか画像を用意してあるので、画像を選択してください。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/66178/8653653f-ac68-3fea-4086-5c33b459aa90.png)

選択してからチャットが表示されるので、あとはメッセージを書き込むだけです。

特に発言内容を制限していないのですが、
他の方が不快になるような発言や誹謗中傷はしないください。
至って常識範囲内のことですが一応念の為…

# モード
左上にスイッチがありますが、こちらを押すとモードが変わります。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/66178/034ec9e9-ed6e-18bc-b6ca-8d116cb0bfb0.png)

- **ゴリラモード**
デフォルトはこちらのモードです。
すべてがゴリラ語で表示されます。
読めない方はゴリラではないので素直に人間モードにしましょう。

- **人間モード**
ゴリラ語を日本語に訳して表示してくれます。
ゴリラじゃない方はこちらのモードをお勧めします。
※ゴリラ語を解読する事をおすすめしません。

# ほんの少しだけ技術の話
##frontend
- vue.js
- elementui

フロントは久しぶりにvue.jsを使ってみましたが、やはり便利ですね。
モードの切り替えによるメッセージ動的変更はvue.jsを使えばサクッとできるので、
特に細かいロジックを書いていません。

仮想DOMのおかげで、サクッと変更できるのはやっぱり良いですね。

あまり話すこともないので、ソースを見てみたい方は開発ツールを使って覗いてください。
手を抜けるところは手を抜きまくっているので、あまり参考にならないと思います…

##backend
チャットの様に、リアルタイムの情報をやり取りするのに、サーバーの実装が結構めんどくさいので、
最近Twitterでよく見かけるfirebaseというサービスを使ってみました。

firebaseで使用したのは`realtime database`と`firebase hosting`です。
`realtime database`を使用することで、dbが更新されるとすべてのクライアントのローカル情報を更新してくれるので、
サーバー側の実装は一切していません。

`firebase hosting`は静的コンテンツのデプロイサービスです。
今回のチャットはhtml、css、jsだけなので、静的コンテンツを無料でデプロイしてくれる機能を使用しました。

# 参考情報
作る上で参考にした記事たちです。
先人様様です。
ありがとうございます。

- [Firebase 入門 - リアルタイムデータベースを使ってみる](https://qiita.com/t_furu/items/665bea8b657c78ab2a22)
- [vueとfirebaseでブラウザチャット](https://qiita.com/nakadoribooks/items/a5c73580039c99a117dc)
新しい姿勢推定のモデルのChainer実装の紹介

# 本日は

姿勢推定（Pose Estimation)　をご存知でしょうか？　人間の関節点（例えば、肩や肘、手首など）をキーポイントとして検知し、それらをつなぎ合わせることで、人の骨格を形成し人の姿勢を推定する技術です。OpenPose は姿勢推定を深層学習で行う手法・実装の一つです。

- https://github.com/CMU-Perceptual-Computing-Lab/openpose
- https://github.com/ZheC/Realtime_Multi-Person_Pose_Estimation

これらのTensorFlowによる実装、Chainerによる実装が各々公開されています。

- https://github.com/ildoonet/tf-pose-estimation
- https://github.com/DeNA/Chainer_Realtime_Multi-Person_Pose_Estimation

今回は最近発表された姿勢推定のモデルである　Pose Proposal Network　[1] とそれの Chainer による実装を紹介をします。

# Pose Proposal Network（PPN)[^1]

- Pose Proposal Network（以下PPNと略す）　は姿勢推定を行うネットワークアーキテクチャの一つです。[論文はこちら](http://openaccess.thecvf.com/content_ECCV_2018/html/Sekii_Pose_Proposal_Networks_ECCV_2018_paper.html) [1]。
- 関節点推定を物体検出の文脈に落とし込みます。　YOLOと同様、入力画像をグリッドで分割し各々のグリットにいる Bounding Box が関節点を検知します。検知された関節点をBottom Up 方式でつなぎ合わせる事で画像内にいる複数の人間を検知することができます。
- PPNのネットワークは特徴量を抽出する役割を果たすベースネットワーク（例えばResNet18）に上記のBBoxのデータおよび関節点同士を結びつけるために必要なデータを持った特徴マップを出力するためのCNNを一つ加えたものになります。OpenPoseに比べると比較的浅いネットワークで実現することができ、推論において高速に姿勢推定を行うことができます。
- 著者の [YouTube デモ動画](https://www.youtube.com/watch?v=4PSm8zFE1Cc) でその速度を実感することができます。

# 実装例の紹介

論文の著者による実装はいまのところ見つかっていません。

ここでは論文をベースに　Chainer　で実装された

https://github.com/Idein/chainer-pose-proposal-net

を紹介します[^2]。

## 動かし方

- [README.md](https://github.com/Idein/chainer-pose-proposal-net/blob/master/README.md)　の通りです。GPU付きUbuntuマシーンであれば [Docker](https://www.docker.com/)、[NVIDIA Container Runtime for Docker](https://github.com/NVIDIA/nvidia-docker) をインストールしておくとスムーズにことが運ぶはず。
- COCO または MPII　によるデータセットで学習することができます。
- 学習済みモデルが近いうちに公開される予定です。
  - 追記：公開されました。リポジトリの releaes ページからダウンロードできます。

## 動かした結果

- ベースをResNet18にして、insize=224x224, COCOをデータセットにした場合の結果です。[^2]
![image.png](https://qiita-image-store.s3.amazonaws.com/0/135978/19b82541-0225-c70c-e733-718a9554c520.png)
- 関節点がバウンディングボックスによって検出されている様子がわかります。
- 紹介しているリポジトリでは　instance　（白色のBBox） を検知することで、人間の存在を確認します。そのあと、　instance から伸びるエッジを辿ることで、上半身から下半身に伸びる形で、関節、関節同士をつなぎ合わせて一つの人間を形成していきます。
- ３０FPSでも速いですが [^2]、オリジナルの論文の結果には届いていません。リポジトリにある `high_speed.py` を実行することで、動画キャプチャー、モデルの推論、後処理を別スレッドで行うことで推論速度を向上させることができます。また、カメラのキャプチャーが遅いとそれ以上のスピードは出ませんので、USBカメラもリ６０FPS出るような高性能のものを用意する必要があります。

## ラズパイ版

- ベースを　MobileNetV2　に, insize 224x224,データはCOCO.
- ![IMG_1020.gif](https://qiita-image-store.s3.amazonaws.com/0/135978/9d7c2a76-f2fb-1d14-6c73-6b483365ae7f.gif)
- できないことはない！　だいたい 0.5 FPS [^3]


## おまけ機能

https://github.com/Idein/chainer-pose-proposal-net/blob/master/video.py#L33

にあるように実は instance をマスクする機能があります。手持ちの画像をリポジトリ直下に `mask.png` としておくと　instance 部分を隠すことができます。MPIIでは instance が顔の周りなので笑い男もどきができます。

# Reference
[1] Taiki Sekii.: Pose Proposal Networks. In: ECCV. (2018)
　
[^1]: 論文のタイトルは Pose Proposal Networks　ですが、論文の中でアーキテクチャの名前は Pose Proposal Network (PPN) となっています。この記事では Pose Proposal Network (PPN) をネットワークの構造を含めた姿勢推定の手法を指すことにしています。
[^2]: 動かした結果は　[こちらで見られます](https://twitter.com/MathSorcerer/status/1064544368940347392)
[^3]: 遅いっちゃ遅い。でも、OpenPoseのを動かすよりは速くなってるはず。
Azure Automationで複数アドレスにメール送信する

Azure Automationの中で、Send-MailMessageコマンドを使ってメール送信する際、複数の宛先に送るやり方です。

# PowerShellの配列でやってみる
* PowerShellで配列を使う場合以下のような書式になります。

```
[System.String[]]　$MailTo = @("mail@example.com","mail2@example.com")
```

* こんな感じでAutomationの中でべた書きすればうまくいきます。(MailTo以外の変数宣言は省略してます)

```
[System.String[]]　$MailTo = @("mail@example.com","mail2@example.com")
Send-MailMessage -UseSsl -From $MailFrom -To $MailTo -Subject $Subject -Body $Body -SmtpServer $SmtpServer -Port $Port -Credential $cred
```

* でも、Automation自体は固定にして、送り先メールアドレスはパラメータで渡してあげたい場合って多くあると思います。
* その場合に、このようなAutomationにして、パラメータを以下のように渡した場合、
    * Mailto : @("mail@example.com","mail2@example.com")

```powershell
Param(
    [parameter(Mandatory=$True)]
    [System.String[]] $MailTo
)
Send-MailMessage -UseSsl -From $MailFrom -To $MailTo -Subject $Subject -Body $Body -SmtpServer $SmtpServer -Port $Port -Credential $cred
```

* エラーメッセージを吐いてコケます。Automationが配列として認識できてないようです。

```
Unable to cast object of type 'System.String' to type 'System.Object[]'.
```

# JSON形式で渡す
* 以下のようにJSON形式で渡すとうまくいきます。
    * Mailto : ["mail@example.com","mail2@example.com"]

```powershell
Param(
    [parameter(Mandatory=$True)]
    [System.String[]] $MailTo
)
Send-MailMessage -UseSsl -From $MailFrom -To $MailTo -Subject $Subject -Body $Body -SmtpServer $SmtpServer -Port $Port -Credential $cred
```

* 気を付けないといけないのが、単一のメールアドレスに送る場合もJSONで渡す必要が出てきます。
    * MailTo : ["mail@example.com"]
mixed-content-crawler というものがあったのでちょっとテスト

# mixed-content-crawler

![demo\.gif \(796×425\)](https://raw.githubusercontent.com/busterc/mixed-content-crawler/76d2c596/demo.gif)

mixed-content-crawler - npm
https://www.npmjs.com/package/mixed-content-crawler


# test

```javascript
const fs = require("fs");
const urls = fs.readFileSync('list-of-urls.txt').toString().split("\n");

const mixedContentCrawler = require('mixed-content-crawler');
urls.forEach(function (url) {
  (async () => {
    const results = await mixedContentCrawler(url, {
      launch: {
        ignoreHTTPSErrors: true
      }
    }
    );
    results.forEach((mixedRequests, page) => {
      console.log(page);
      for (let r of mixedRequests) {
        console.log('->', r);
      }
    });
  })();
});
```

随分気楽に使えて良いな :smiley_cat:
なんだか学ぶことに身が入らない時

個人的には学ぶことが苦手です。

その中で、少し学ぶことに前向きになれた方法を紹介します。


1、今の気持ちを書き出してみる
　
　私自身「なんだか勉強するのいやだなぁ」とか「これやっていて何になるんだ」とか
　ネガティブなことを思うことがありました。

　そんな時にお勧めしています。
　
　思考の整理になり落ち着くことももちろんありますが、
　「自分の気持ちをないがしろにされている」と感じていることもありました。

　そんな時に自分と向き合ってみるのに効果的な方法かと思いました。
Node-Redを使ってAlexaの挨拶スキルを作る

ごきげんよう

この記事は
**「するめごはんのVUI・スマートスピーカー Advent Calendar 2018」**
の10日目の記事です。

以前、Alexaスキルを作るツールとしてNOIDについてこのアドベントカレンダーで触れました
https://qiita.com/surumegohan/items/a4170515010554e229a0

今回は同じくツールとしてNode-Redを使って挨拶スキルを作ります。

#作り方

作り方と言っても、Qiitaや個人ブログに情報はあふれていると思います。

今回は以下の本に従ってみます。

[スマートスピーカーアプリ開発入門 3大スマートスピーカー Amazon Echo Google Home LINE Clova対応](https://www.amazon.co.jp/%E3%82%B9%E3%83%9E%E3%83%BC%E3%83%88%E3%82%B9%E3%83%94%E3%83%BC%E3%82%AB%E3%83%BC%E3%82%A2%E3%83%97%E3%83%AA%E9%96%8B%E7%99%BA%E5%85%A5%E9%96%80-3%E5%A4%A7%E3%82%B9%E3%83%9E%E3%83%BC%E3%83%88%E3%82%B9%E3%83%94%E3%83%BC%E3%82%AB%E3%83%BC-Amazon-Google-Clova%E5%AF%BE%E5%BF%9C/dp/479805481X/)

##1.まずはNode-REDのアカウントを作成

https://nodered.org/

![1_NodeRed.png](https://qiita-image-store.s3.amazonaws.com/0/67398/e621f4d2-0dcd-9f98-d21e-b52fb51f7060.png)


##2.次にIBM Cloudのアカウント作成

https://www.ibm.com/cloud-computing/jp/ja/lite-account/

ライトで大丈夫です。

![2_IBMaccount.png](https://qiita-image-store.s3.amazonaws.com/0/67398/acf0a625-3ffc-3792-427d-c2e32e2cbf71.png)

##3.IBM Cloudにログイン

ここで、アカウントIDはメールアドレスでログインできます。

![3_IBMLogin.png](https://qiita-image-store.s3.amazonaws.com/0/67398/7022f187-9d4b-3420-33c8-14e05d794585.png)


##4.何も考えないと一部英語になる

本の通りに進めていけば問題ないですが、何も考えないでポチポチやっていくと、画面の一部が英語になります。

が、特に躓くような英単語はないと思います。

![4_noderedEnglish.png](https://qiita-image-store.s3.amazonaws.com/0/67398/bdbcfdfd-2229-06d8-1ad2-07b728ddf8dc.png)

##5.作成できる画面

商業誌の内容をそのままは書けないのですが、以下のような画面になります。

話しかけられたら、インテントの種類を判別して起動時はLaunchRequestなのでそのまま挨拶をする。
それ以外はインテントの場合分けをswitchをかませて対応を分岐させ、応答を返したらHttpのResponseにつないであげます。

![5_nodedekita.png](https://qiita-image-store.s3.amazonaws.com/0/67398/546b4701-2aab-ad27-8417-4aad284c7fcc.png)

##6.Alexa Consoleもほぼ通常通り

Node-REDで作成したインテント名で、挨拶のためのインテントを作成してあげます。

![6_AlexaConsole.png](https://qiita-image-store.s3.amazonaws.com/0/67398/9d05f1ed-7008-be04-668a-507f26460b45.png)


ただし、エンドポイントはLambdaではないので、Node-REDで作成したURLをWebhookとして指定します。

![6-2_endpoint.png](https://qiita-image-store.s3.amazonaws.com/0/67398/5225d990-f4c2-50ed-abfd-e21e7992674d.png)


##7.後は話しかけるだけ

きちんと動きます。

![7_test.png](https://qiita-image-store.s3.amazonaws.com/0/67398/2e005d37-98ed-6a53-4546-c04764bd8ac1.png)

もし、「応答に時間がかかっている」というエラーになった場合は、Node-REDの画面で、線がすべて結びきれているか確認してみましょう。
JSONの作成はできていても、レスポンスを返すようになっていない場合があります。


#まとめ

Node-REDでもスキル作成はできますし、本を参考にすれば、Node-REDもAlexaも初体験だったとしても、ぜいぜい2～3時間で作成できると思います。

※Amazonアカウント作成で躓く場合は別

Alexaのスキルをつくることに特化するならNOIDの方が断然楽だと思います。
ただ、Webhookとして、もっと汎用的にいろいろなことをやりたいとなると、Node-REDは選択肢の1つにはなるのではないでしょうか。


今回は以上です。
CWLの出力ファイル名で困った


# CWLで出力ファイル名を指定する

```
class: CommandLineTool
cwlVersion: v1.0
$namespaces:
  edam: 'http://edamontology.org/'
baseCommand: fastqc
inputs:
  - id: fastq
    type: File
    format: edam:format_1930
    inputBinding:
      position: 2
    doc: FastQ file from next-generation sequencers
outputs:
  - id: qc
    type: File
    outputBinding:
      glob: $(inputs.fastq.nameroot)_fastqc.html
label: fastqc
arguments:
  - position: 1
    prefix: -o
    valueFrom: .
hints:
  - class: DockerRequirement
    dockerPull: 'maxulysse/fastqc:latest'
```

こんな感じで指定できる。

# CWLでは '*' を使って出力ファイルを指定できる


```
    outputBinding:
      glob: $(inputs.fastq.nameroot)_fastqc.html
```

この部分を、こう書くこともできる。

```
    outputBinding:
      glob: $(inputs.fastq.nameroot)*_fastqc.html
```


# CWLで '*' を使って困ったこと

```
    outputBinding:
      glob: *_fastqc.html
```
こう書くと、怒られる。

```
../cwltool/cwltool.py 1.0.20181201184214
Resolved 'fastqc.cwl' to 'file:///Users/hachiya/Projects/cwl/test/fastqc.cwl'
I'm sorry, I couldn't load this CWL file, try again with --debug for more information.
The error was: found undefined alias '_fastqc.html'
  in "file:///Users/hachiya/Projects/cwl/test/fastqc.cwl", line 17, column 13
```

先頭で '*' を使う場合は、ダブルクォーテーションで挟むとよい。

```
    outputBinding:
      glob: "*_fastqc.html"
```

これで動いた！
EC2インスタンスのバックアップをスケジュール化してお手軽にバックアップ

# EC2インスタンスのバックアップについて
EC2インスタンスのバックアップを取るには大きく分けて次の2つの方法があります。

- ストレージのスナップショットを取得する
- AMIイメージを作成する

EC2インスタンスの完全なバックアップとしてはAMIイメージを作成するのが一番良いのですが、稼働中のインスタンスからAMIイメージを作成するには原則、インスタンスの停止が必要なのでストレージのスナップショットを取得するほうがお手軽ではあります。
さらに、[Amazon DLM](https://docs.aws.amazon.com/ja_jp/AWSEC2/latest/UserGuide/snapshot-lifecycle.html)を利用することで、スナップショットの取得を自動化&スケージュール化が可能になります。

## Amazon DLMの特徴
Amazon DLMは次のような特徴を持っています。

- EBSストレージのスナップショット作成、保持、削除を自動化する
- スナップショットの作成、保持、削除(世代管理)はライフサイクルポリシーで定義する
- スナップショットを作成する頻度を設定できる(スケージュール化)

## Amazon DLM利用上の制限
Amazon DLMを利用する上で、次のような制限があります(2018.12.10現在)

AWSアカウントあたり

- ライフサイクルポリシーはリージョンごとに最大100まで
- リソースごとに最大50個のタグを追加可能
- ライフサイクルポリシー対して、1つのスケジュールを作成可能

## Amazon DLMの設定

- 前提条件

設定を実施するIAMユーザーにAmazon DLMへのアクセス権が割り当てられていること

```
{
   "Version": "2012-10-17",
   "Statement": [
      {
         "Effect": "Allow",
         "Action": "iam:PassRole",
         "Resource": "arn:aws:iam::123456789012:role/AWSDataLifecycleManagerDefaultRole"
      },
      {
         "Effect": "Allow",
         "Action": "dlm:*",
         "Resource": "*"
      }
   ]
}
```

対象のEBSボリュームにタグが設定されていること。
今回はSnapshotというタグをつけて、値にDLMを設定する。

### ライフサイクルポリシーの作成

1. EC2コンソールから「Lifecycle Manager」を選択
![DLM1.png](https://qiita-image-store.s3.amazonaws.com/0/323900/4bb9dc95-2e26-feb5-5761-66983d7fb6dc.png)

2. 「Create Snapshot Lifecycle Policy」をクリック
![DLM2.png](https://qiita-image-store.s3.amazonaws.com/0/323900/884d4ff9-c72a-5071-1e66-0ae03c246f06.png)

3. 各項目を入力
![DLM3.png](https://qiita-image-store.s3.amazonaws.com/0/323900/8a6b6761-430a-76e5-108a-38493cdd07fe.png)

4. 「Create Policy」をクリックして、ポリシー作成を完了する

5. ダッシュボードに作成したポリシーが表示され、StateがENABLEDになっていることを確認する
![DLM4.png](https://qiita-image-store.s3.amazonaws.com/0/323900/be5caffb-8546-717a-d6e8-a6f26e5a1cd8.png)

##その他の注意点

- 稼働中のインスタンス(EBSボリューム)のスナップショットを作成する場合、完全なコピーではないことを理解すること
- スナップショットは増分で作成されるので、保持するスナップショットの数と合計サイズをきちんと把握すること(コスト管理)
EloquentをLaravelなしに使う

LaravelのORMのEloquentを単体で使う方法を解説する。

`illuminate/database`をインストールする:

```
composer require illuminate/database
```

Eloquent単体での使い方:


```php
<?php

declare(strict_types=1);

require __DIR__ . '/vendor/autoload.php';

use Illuminate\Database\Capsule\Manager as DB;
use Illuminate\Database\Schema\Blueprint;

$db = new DB();

$connectionName = 'default';

// DBの接続設定
$db->addConnection(
    [
        'driver' => 'mysql',
        'host' => '127.0.0.1',
        'database' => 'development',
        'username' => 'root',
        'password' => 'root',
        'charset' => 'utf8mb4',
        'collation' => 'utf8mb4_ja_0900_as_cs_ks',
    ],
    $connectionName
);

// DBへのコネクションを取得する
$connection = $db->getConnection($connectionName);

// テーブルがなければ作る
$connection->getSchemaBuilder()->hasTable('user')
|| $connection->getSchemaBuilder()->create(
    'user',
    function (Blueprint $table) {
        $table->increments('id');
        $table->string('name');
        $table->string('email');
        $table->timestamps();
    }
);

// テーブルを空っぽにする
$connection->table('user')->truncate();

$now = new DateTimeImmutable();

// 1レコードinsertする
$connection->table('user')->insert(
    [
        'name' => 'alice',
        'email' => 'alice@example.com',
        'created_at' => $now,
        'updated_at' => $now,
    ]
);

// insertしたレコードを取得する
$alice = $connection->table('user')->find(1);

// 期待したとおりのレコードが取れているか？
assert(
    $alice == (object) [
        'id' => 1,
        'name' => 'alice',
        'email' => 'alice@example.com',
        'created_at' => $now->format('Y-m-d H:i:s'),
        'updated_at' => $now->format('Y-m-d H:i:s'),
    ]
);
```
Let's Encrypt(Certbot)で発行したワイルドカード証明書を更新する

普通にLet's Encryptで発行した証明書を更新するには
`certbot renew` するだけで全ての証明書が更新できますが、
ワイルドカード証明書を更新するにはひと手間必要だったのでメモ。

ちなみに更新のたびに自分でコマンドを叩いてDNSを更新する手順です。
というかよくよく見たら最初に証明書を発行したときと同じ手順ですね。
すでに証明書がある場合でも、同じコマンドを打つと証明書の更新になるみたいです。

```
certbot certonly --manual --domain *.example.com -d riinswork.space 
--preferred-challenges dns-01 
--server https://acme-v02.api.letsencrypt.org/directory

```

DNSチャレンジの手順は初回発行ができたならそれと同じなので省略。


ちなみに、

```
--manual-auth-hook /etc/letsencrypt/renewal-hooks/hogehoge.sh \
--manual-cleanup-hook /etc/letsencrypt/renewal-hooks/hogehoge.sh
```

みたいな感じのオプションを足してやって、DNSのTXTレコードを更新するshellを自分で書くなりして、
証明書の更新前後にDNSのTXTレコードを更新することができれば certbot renew による自動更新もできるようです。

この辺りはどのDNSサーバを使っているかによると思うので割愛！

DNSサーバにbindを使っているならこちらを参考にすればできるみたいです。

[Certbotによるワイルドカード証明書と自動更新の設定 - nabeの雑記帳](https://nabe.adiary.jp/0599#k599p5)

Conoha ではこの記事で完全に自動化できました。私もやってますがいいですね。
[Let's Encrypt ワイルドカード自動更新（ConoHa） \- eastforest](https://www.eastforest.jp/vps/6149)
【Part1】はじめてのReact勉強メモ

# はじめに

初めまして。新卒入社3年目のフロントエンド（？）エンジニアです。
これまで自社の開発で`Vue + vuex`を使ってきたのですが、ダラっとしたモチベーションの低下と`Vue.js`以外への興味から、とりあえず`React.js(出来ればTypeScriptも)`を触ってみることにしました。

この手の記事の投稿ははじめてなのでとりあえずメモ書き程度にやってことを纏めていきます。お手柔らかにお願いします。

とりあえず`Vue.js`でも良くやっていたHello Worldを出す所から簡単なTodoアプリを作る所までを目標に、公開は導入の部分までをReact.js公式の[Get Started](https://reactjs.org/docs/getting-started.html)を見ながらやってみます。

# やってみる

## 導入

```bash
npx create-react-app my-app
cd my-app
npm start
```

`npx`なるものを使うんですね。知りませんでした。

`npm start`を叩くと自動的にブラウザで`localhost:3000`のURLが開いて以下の画面が表示されました。
この辺りは`Vue.js`と同じような感じですかね。

![hello.png](https://qiita-image-store.s3.amazonaws.com/0/269717/144a1e17-7f84-c842-9f55-931e419fd6c0.png)

## 中身を見てみる

ファイルの構成はこんな感じになってました。

```
- node_modules
- public
  - favicon.ico
  - index.html
  - manifest.json
- src
  - App.css
  - App.js
  - App.test.js
  - index.css
  - index.js
  - logo.svg
  - serviceWorker.js
- .gitignore
- package.json
- README.md
- yarn.lock
```

`src`の中身をもう少し見ていきます。

#### index.js
ここがエントリーポイントですね。
`ReactDOM.render()`で`#root`のエレメントに`App`コンポーネントをバインドしているようです。
`seviceWorker`は使ったことないのでとりあえず置いておきます。

```JavaScript
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import * as serviceWorker from './serviceWorker';

ReactDOM.render(<App />, document.getElementById('root'));

// If you want your app to work offline and load faster, you can change
// unregister() to register() below. Note this comes with some pitfalls.
// Learn more about service workers: http://bit.ly/CRA-PWA
serviceWorker.unregister();

```

#### App.js
上記の`index.js`でバインドしていた`App`コンポーネントの定義が書かれています。
`vue-loader`を使った`Vue.js`の書き方だと`<component>`タグとか`<script>`タグに分けて書いていましたが、`react`だと`class`でコンポーネントを定義するんですね。
`Component`クラスを継承したクラスを作って、`render()`関数内に色々書けばいいみたいです。
`JavaScript`の関数内でそのままタグを各記法（JSX？）も最初は気持ち悪かったんですが、この記事を書いている間に見慣れてきました。

```JavaScript
import React, { Component } from 'react';
import logo from './logo.svg';
import './App.css';

class App extends Component {
  render() {
    return (
      <div className="App">
        <header className="App-header">
          <img src={logo} className="App-logo" alt="logo" />
          <p>
            Edit <code>src/App.js</code> and save to reload.
          </p>
          <a
            className="App-link"
            href="https://reactjs.org"
            target="_blank"
            rel="noopener noreferrer"
          >
            Learn React
          </a>
        </header>
      </div>
    );
  }
}

export default App;
```

#### App.test.js
テストコードですね。とりあえずスクリプトエラーが出ないことを試している程度の様です。
この辺りは基本的な`react`の使い方を知ってからがっつり触りたいですね。

```JavaScript
import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';

it('renders without crashing', () => {
  const div = document.createElement('div');
  ReactDOM.render(<App />, div);
  ReactDOM.unmountComponentAtNode(div);
});
```

#### その他
その他は`.css`とか`package.json`なんかの見慣れたファイルなので省略。

# 終わりに

とりあえず導入して画面を出す所まで、簡単にコードを見てみるところまでをやってみました。
入り口のとっつきやすさは`Vue.js`と同じような感じで、`JSX`の記法も慣れれば違和感はないですね。
次回は公式ガイドの[HelloWorld](https://reactjs.org/docs/hello-world.html)からHandling Eventsぐらいまでをだらだらやってみます。
Homebrew がバージョンアップし過ぎて MacでPHPを使おうとしたら超絶楽だった件

会社に新しいパソコンを買ってもらいました

あまりやりたくはないですが、PHPでフロントエンドを構築してることが多いので、PHPの開発環境を構築しようと思います

# いつものオマジナイ

```bash
$ xcode-select --install
$ /usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
```

これで Homebrew を使う準備が出来ました

```bash
$ brew -v
Homebrew 1.8.4
Homebrew/homebrew-core (git revision 99286; last commit 2018-12-10)
```

# PHP いれるぞー

まずは、Homebrew に存在しているVersion　の確認

```bash
$ brew search php
==> Formulae
brew-php-switcher            php-code-sniffer             php@5.6                      php@7.2                      phpmyadmin
php                          php-cs-fixer                 php@7.1                     phplint                      phpunit
```

あれ。。。

なんだかPHP少ない。。。

[homebrew-php](https://github.com/Homebrew/homebrew-php/) が　[homebrew-core](https://github.com/Homebrew/homebrew-core/) に合流したのでモジュール系がめっちゃあると思ったんだけど。。

とりあえずインストールしてみたらワンちゃん全モジュール入ってんじゃね？という期待をこめてインストール

```bash
$ brew install php@7.1
```

```bash
$ echo -e 'export PATH="/usr/local/opt/php@7.1/bin:$PATH"' >> ~/.bash_profile 
$ echo -e 'export PATH="/usr/local/opt/php@7.1/sbin:$PATH"' >> ~/.bash_profile
$ source ~/.bash_profile
```

んで、phpのモジュール確認

```bash
$ php -m
[PHP Modules]
bcmath
bz2
calendar
Core
ctype
curl
date
dba
dom
exif
fileinfo
filter
ftp
gd
gettext
gmp
hash
iconv
intl
json
ldap
libxml
mbstring
mcrypt
mysqli
mysqlnd
odbc
openssl
pcntl
pcre
PDO
pdo_dblib
pdo_mysql
PDO_ODBC
pdo_pgsql
pdo_sqlite
pgsql
Phar
phpdbg_webhelper
posix
pspell
readline
Reflection
session
shmop
SimpleXML
soap
sockets
SPL
sqlite3
standard
sysvmsg
sysvsem
sysvshm
tidy
tokenizer
wddx
xml
xmlreader
xmlrpc
xmlwriter
xsl
Zend OPcache
zip
zlib

[Zend Modules]
Zend OPcache
```

おぉ！？

これは全部入ってるくさい！！！

# まとめ

Mac でPHP を使う時は迷わずHomebrewのPHPを使えば環境構築に迷わなくて済む！
プロジェクト内パッケージの依存関係をCIでテストする

[PicApp アドベントカレンダー](https://adventar.org/calendars/3448)10日目です。

チーム開発をしている際に、こういうことは起きていないでしょうか。

1. 新しく入ったメンバーにアーキテクチャや設計方針を説明する
2. 実際にコードを書いて Pull Request を投げてもらう
3. 意図しないパッケージにコードを書かれ、パッケージ間の依存関係がぐちゃぐちゃになっている
4. コードレビュー時に「このパッケージはこういう意図で分割しているのだからこのパッケージに依存させないでください」と指摘（そしてレビュワーは依存関係のチェックのために、特に import 文を目を皿にしてチェックする）

あるいは、プロジェクトを引き継いだりしたときも同じような状況が起こりえます。前任者の設計意図が後任者に伝わらずに、自身の価値観で再設計を行って、全体の設計が壊れてしまったりします。

こういったことが起きること自体は極めて自然なことなので、悪いことではありません。しかし、それが引き起こした結果を許容して構築されたシステムが **「悪い設計」** に陥ってしまっているのは間違いないでしょう。多くの開発者はそうならないように、日々血眼になってコードレビューしたり、できるだけ効率よく設計意図を共有するためにペアプログラミングをしたりしているはずです。

## この記事で伝えたいこと

設計とは問題を解決するために適切な分割構造を選択することであり [^b] 、その分割構造の一端はパッケージのツリー構造に現れます。
[^b]: 開発現場で役立たせるための設計原則とパターン https://nekogata.hatenablog.com/entry/2018/09/10/163206
逆に言えば、パッケージツリー構造（依存関係）を設計意図通りに保ちつづけることはプロジェクト全体の設計方針を統一することにつながります。

そのため、これは目視で逐一チェックせず CI でテストすべきなのです。

そして、golang でこれを行うツールとして作ったものが impas です。

https://github.com/tomoemon/impas

## 具体例

具体例を上げましょう。多くのプロジェクトは何らかのレイヤードアーキテクチャを採用しているはずです。下図はいわゆる DDD [^ddd] の簡単な例ですが、UI 層はアプリケーション層やドメイン層、インフラ層に依存することができる一方で、ドメイン層やインフラ層は UI 層には依存させてはいけません。依存関係の方向を制限することで、特定の層の責任を限定し、わかりやすく、かつ拡張しやすい構造を保つことができます。

[^ddd]: DDD 自体に習熟しているわけではないので、間違いがあれば指摘ください

![project_structure](https://raw.githubusercontent.com/tomoemon/impas/master/docs/images/impas.png)

impas がやることはこの依存関係の方向が期待通りになっているか検査することです。

インフラ層（infra パッケージ）の中にあるコードが import していいパッケージをあらかじめ設定ファイルに記載（ホワイトリスト方式）しておくことで、インフラ層から UI 層（ui パッケージ）のコードを import していたら NG を返すことができます。

impas を CI に組み込むことで、自動的にテストに失敗させることができるため、プロジェクト初心者であっても、その import が（少なくともこのプロジェクトの）設計上ダメであることがすぐにわかります。

パッケージの依存関係というのは、プロジェクトを深く知っている人であれば当たり前に認識している、暗黙知になりがちなことで、新しく入ったメンバー全員にすべてを共有することが難しい知識です。CI に組み込んで誰でも明白にわかる状態にしておくことが、チーム開発をスムーズに進める一つの方法になるのではないかと思います。
Link > FastReport VCL 5 User's Manual 

```txt:動作環境
C++ Builder XE4
FastReport VCL 5 
```


- [FastReport VCL 5 User's Manual](https://www.fast-report.com/public_download/FR5UserManual-en.pdf)


公式サイトからリンクが見えないのは不思議
https://www.fast-report.com/en/download/

「最新版」しか掲載しないスタンスなのかもしれない。

他のバージョンについては「Fast report VCL user guide」でgoogle検索すると見つかるかも。
Vue.jsオブジェクトをjQueryのメソッド中で使う方法

[ユアマイスターアドベントカレンダー2018](https://qiita.com/advent-calendar/2018/yourmystar)の10日目の記事です。

## this じゃダメ？
Vue.jsとjQueryでこんなコードを書いたとして…

```sample.html
<script
  src="https://code.jquery.com/jquery-2.2.4.min.js"
  integrity="sha256-BbhdlvQf/xTY9gja0Dq3HiwQF8LaCRTXxZKRutelT44="
  crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.17/dist/vue.js"></script>

<div id="app">
    <button @click="testFunc">
        click
    </button>
</div>

<script>
    var vm = new Vue({
        el: '#app',
        data: {
            data: 'test',
            sum: 0
        },
        methods: {
            testFunc: function () {
                // 1
                console.log(this);
                $.each([1, 2, 3], function (i, elm) {
                    // 2
                    console.log(this);
                });
            }
        }
    })
</script>
```
`testFunc`の中に`console.log(this)`を2つ書きましたが、それぞれの部分で何が出てくるでしょうか？

1つ目の`this`では
`Vue {_uid: 0, _isVue: true, $options: {…}, _renderProxy: Proxy, _self: Vue, …}`
こんなものが出ます。

2つ目の`this`だと
`Number {1}`
が出力されます。

この違いなんですが、見て分かる通り`Vue.jsのオブジェクト`か`jQueryでループしている配列の中身のオブジェクト`か、です。

## vueのデータを追加したい
例えば、ループ対象の配列の値を全て加算して、それをvue側の`sum`に入れたいとします。
もちろん、ループの中で`vm.sum`を呼び出せばいいんですが、変数に代入しておきたくないときもあるかもしれません(少なくとも私はまだ遭遇したことないですが)。
そんな時にどうするのか、ですが、こう書きました。

```sample.html
<div id="app">
    <button @click="testFunc">
        click
    </button>
</div>

<script>
    var vm = new Vue({
        el: '#app',
        data: {
            data: 'test',
            sum: 0
        },
        methods: {
            testFunc: function () {
                var vueObj = this;
                $.each([1, 2, 3], function (i, elm) {
                    vueObj.sum += elm;
                });
                console.log(vueObj.sum);
            }
        }
    })
</script>
```

解説不要かもしれませんが、jQueryでのループ前に`this`を`vueObj`として変数に入れておき、ループの中でその変数を使ってアクセスする、と言う形です。
`this`を呼び出す位置によって中身が変わるのはもちろんですが、変数に入れておくことでいつでも`this(と同じオブジェクト)`を使えます。

## 結論
**変数に入れておけ**

いや当たり前かもしれないんですが、「あれどうしよう……」となる場合がありそうだなと思ったので、記事にしておきます。
jQueryからVue.jsへの移行を始めたばかりのころに起きがちではないかと思ったので、役に立てば幸いです。