OmniAICreator/Qiita-1.07M huggingface dataset:
kintoneで複数フィールドのchange系イベントハンドラを美しく書く

ほぼ自分用メモの、コードスニペットです。

# やりたいこと

* `last_name`と`first_name`を連結して`full_name`を作成
* `submit`ではなく`show` `change`の際に連結処理を走らせる
* krewSheetとkintone標準UIのどちらでも動くように
* なるべく美しく書く

こんなロジックだけなら標準機能の計算式でやりますが、
まぁそこはサンプル用ということで・・・

普通に書くと、イベントハンドラをこんな感じで膨大に列挙することになります。
これが気持ち悪いので、なんとか美しく書きたいという話がメインでーす。

```js
kintone.events.on(
  [
    'app.record.create.show',
    'app.record.edit.show',
    'app.record.index.edit.show',
    'app.record.create.change.first_name',
    'app.record.create.change.last_name',
    'app.record.create.change.full_name',
    'app.record.edit.change.first_name',
    'app.record.edit.change.last_name',
    'app.record.edit.change.full_name',
    'app.record.index.edit.change.first_name',
    'app.record.index.edit.change.last_name',
    'app.record.index.edit.change.full_name',
  ],
  event => {
    // ...
  }
)
```



# 結果
こうです！
僕は美しいと思うのですが、どうでしょうか？

```js

const FIELDS = ['first_name', 'last_name', 'full_name']
// reduce使うことで美しく書ける！
const EVENTS = FIELDS.reduce(
  (events, field) => [
    ...events,
    `app.record.create.change.${field}`,
    `app.record.edit.change.${field}`,
    `app.record.index.edit.change.${field}`,
  ],
  ['app.record.create.show', 'app.record.edit.show', 'app.record.index.edit.show']
)

// kintone JS APIとkrewSheet JS API両方で使えるように、コールバックは変数にしておく
const callback = event => {
  const { record } = event

  // krewではdisabled制約は未対応だけど、エラーは出ないので気にしないw
  // full_nameに入力しても、その瞬間にchangeハンドラが走って再度リセットされる
  record.full_name.disabled = true

  // 苗字と名前を連結
  const firstName = record.first_name.value || ''
  const lastName = record.last_name.value || ''
  record.full_name.value = `${lastName} ${firstName}`

  return event
}

// kintone JS API向け
kintone.events.on(EVENTS, callback)

// krewSheet JS API向け
kintone.events.on('app.record.index.show', event => {
  // EVENTSにはkrew未対応のイベントも入ってるけど、エラーは出ないので気にしないw
  krewsheet.events.on(EVENTS, callback)
})
```

ではまた〜。
【Unity】Google PlayにAPKをアップロードできないときに試したこと

# 問題
Unityでビルドを行い、APKファイルを書き出した後、Google Playにアップロードしようとしたら、
> アップロードできませんでした
アップロードされた APK または Android App Bundle がデバッグモードで署名されています。APK または Android App Bundle はリリースモードで署名する必要があります。詳しくは、署名についての説明をご覧ください。

と表示されてアップロードできませんでした。

# 原因
理由はGooglePlayに言われた通り、Unityで書き出したAPKファイルがリリースモードではなくデバッグモードで署名されていたためです。

# 解決法
署名をしていない状態だと、自動的にデバッグモードであると判断されるようです。
以下が署名する方法です。
Unityで Edit > Project Setting > Player
でAndroidのタブに切り替えて、
Publishing Setting > Keystone Manager > Keystone > Create New
で名前を付けてkeystoreファイルを保存します。

Aliasに自分で決めたKeyの名前、
Passwordにパスワード、
Country Codeにjp(日本の場合)と記入し、Add Keyをクリックしてください。
(他の項目についてはhttps://www.clrmemory.com/unity/android-get-keystore/ を参考に適当に埋めてください)
最後にAliasでKeyを選択して下さい。
これでリリースモードで署名されたはずです。

# 追記
Build SettingでDevelopment Buildにチェックが入っているとデバッグモードで署名されてしまうので気をつけて下さい。

# 参考文献
以下のサイトを参考にさせて頂きました。
https://www.clrmemory.com/unity/android-get-keystore/
https://teratail.com/questions/172045
Openstackで立てたVMのフレーバー情報を確認するコマンド

## 概要

払い出したVMのフレーバーを確認するために1つ1つのVMをGUIなどで確認するのは手間がかかるため、novaコマンドを利用してコマンド一発で全VMのフレーバーを確認するスクリプトを作成してみました。

#### 使うこと

- python2
- VMの一覧を確認するために`nova list --fields` を使います。このとき、VMのidは数字および小文字の羅列が8文字以上存在することを想定しています。
- フレーバーの一覧を確認するために`nova flavor-list`を使います。このとき、Is_Public列のTrueとFalseで必要な行を取得します。
- テナントIDを引数として渡します。(テナントIDを調べるのもぶっちゃけ面倒なので、テナント名に命名規則があるなら、それを特定するようなコードを挟むと良いです。)

```python
# -*- coding: utf-8 -*-

import sys
import commands

# nova listの結果からVM名、flavorIDだけ取り出してリスト化します。
def flavorCount(tenant):
    dic = flavorDict()
    novaResult = commands.getoutput("export OS_TENANT_ID=" + tenant + " ; nova list --fields name,flavor | grep '[0-9a-z]\{8\}' | awk -F '|' '{print $3 $4}' | sed -e 's/[ ]^*//'")
    for column in novaResult.splitlines():
        vm = column.split()
        if len(vm) == 2:
            vm[1] = dic[vm[1]]
            print(vm)

# nova flavor-listの結果からflavorID, Nameを取り出して辞書化します。
def flavorDict():
    fravorDictionary = {}
    flavorListResult = commands.getoutput("nova flavor-list | grep -e 'True' -e 'False' | awk -F '|' '{print $2 $3}' | sed -e 's/[ ]^*//'")
    for column in flavorListResult.splitlines():
        vm = column.split()
        if len(vm) == 2:
            fravorDictionary[vm[0]] = vm[1]
    return fravorDictionary

if __name__ == '__main__':
    args = sys.argv
    if len(args) < 2 or len(args) > 2:
        print('usage: thiscode.py tenant_id')
        sys.exit()

    tenant = args[1]
    flavorCount(tenant.decode())

    print('Completed.')
```



実行例

```bash
$ python thiscode.py 5wfd9ab3109aee53bbb8e91ad6a4523d
['vm1', 'm1-large']
['vm2', 'm1-small']
['vm3', 'm2-small']
['vm4', 'm1-medium']
Completed.
```

## 今後

VMごとの起動時間・課金情報とかと組み合わせると、VMのフレーバー別の使用状況も見れたりしてよさそうです。
モノビットエンジンでリアルタイム通信のオンラインゲームを作る：ボールを跳ね返す

どうもnisokaです。
前回はシンプルなPingPongゲームに、座標のリアルタイム同期処理を実装しました。
今回も引き続き、モノビットエンジンを使ってオンライン化を目指していきたいと思います。

環境は以下の通りです
*win10 64bit, Unity2018.3.3f1, Monobit Unity Networking2.0 v2.6*

##やること
**パドルに当たったボールを相手に跳ね返せる**ようにしたいと思います。
各クライアントとの同期をおこない、ラリーをしている様子を確認するところまで作ります。
![image1.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/401086/a0bf9472-1a32-1d9b-5ff8-e5603510aa3f.png)

##考え方
ホストは自分とゲスト両方のパドル情報を持っています。
ということは、ホストはゲストのパドルが球に当たったことも検知できます。
なのであとは、ゲストが球に当たったらホスト側で球の進行方向を逆向きに変えればよいです。
これが簡単な跳ね返し処理の考え方です。

##座標同期する
まず、前回やったようにボールの座標を同期させます。
手順は以下の通りです。
1. 該当するボールコンポーネントへMonobitView.cs&MonobitViewTransform.cs追加
2. MonobitView.csへMonobitViewTransform.csをアタッチ
3. 該当するボールコンポーネントのスクリプトでMonobitEngine.MonoBehaviourを継承

詳しい手順は[<前回の記事>](https://qiita.com/nisoka/items/b6064946f3184f85d323)をお読みください。

注意点として、ボールはホストが生成したので、所有権はホストが持っています。
その為、Update内はすべて`MonobitNetwork.isHost`または`monobitView.isMine`のif文で囲むべきです。

##はね返す
```C#:
private void OnTriggerEnter2D(Collider2D collision) {
    if(MonobitNetwork.isHost) {
        if (collision.tag == "Paddle") {
            // 向きを変える
            direction.x = -direction.x;
        }
    }
}
```
ホスト側では両方のパドルの当たり判定を監視します。
いずれのパドルに当たってもボールの進行方向を逆にするだけです。

##最後に
いかがだったでしょうか。
モノビットエンジンが大体のことをやってくれるので、なんとこれだけで実装完了です。
次回はRPCメッセージについて少し触れたいと思います。
tsconfigのmoduleの設定値の違い: commonjs, amd, system, umd, es6, es2015, esnext, none

本稿では、tsconfigの`module`の設定値によってどのようなJavaScriptコードが生成されるかを確認するものである。次の設定値を試す: commonjs, amd, system, umd, es6, es2015, esnext, none。

コンパイルしてみるTypeScriptコード。

```main.ts
export const a = 1;
```

## 未指定または、"commonjs"

```main.js
"use strict";
exports.__esModule = true;
exports.a = 1;
```
* CommonJSと呼ばれる規格。
* Node.jsなどサーバサイドコードで一般的。

## "amd"

```main.js
define(["require", "exports"], function (require, exports) {
    "use strict";
    exports.__esModule = true;
    exports.a = 1;
});
```

* Asynchronous Module Definition (AMD)と呼ばれる規格。
* クライアントサイドコードで一般的。

## "system"

```main.js
System.register([], function (exports_1, context_1) {
    "use strict";
    var a;
    var __moduleName = context_1 && context_1.id;
    return {
        setters: [],
        execute: function () {
            exports_1("a", a = 1);
        }
    };
});
```

* SystemJSとESモジュールローダーに対応。
* [systemjs/systemjs: Dynamic ES module loader](https://github.com/systemjs/systemjs)
* AMD, CommonJS形式に対応している。

## "umd"

```main.js
(function (factory) {
    if (typeof module === "object" && typeof module.exports === "object") {
        var v = factory(require, exports);
        if (v !== undefined) module.exports = v;
    }
    else if (typeof define === "function" && define.amd) {
        define(["require", "exports"], factory);
    }
})(function (require, exports) {
    "use strict";
    exports.__esModule = true;
    exports.a = 1;
});
```

* Universal Module Definition (UMD)と呼ばれる規格。
* AMDとCommonJSの両方をサポートする。

## "es6", "es2015", "esnext"

```main.js
export var a = 1;
```

* ES6 Moduleと呼ばれる規格。
* `export`キーワードのブラウザ対応状況は[export - JavaScript | MDN](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Statements/export)で確認できる。
* Node.jsでは`--experimental-modules`オプションを使うとES6 Moduleが使える。
    * 参考: [Node.jsでES Modules（export/import）ができなかったので軽く調べた - Qiita](https://qiita.com/s-yoshida/items/af23897e096e3e18e765)

## "none"

    main.ts:1:1 - error TS1148: Cannot use imports, exports, or module augmentations when '--module' is 'none'.
    
    1 export const a = 1;
      ~~~~~~~~~~~~~~~~~~~


    Found 1 error.


## 参考

* [Compiler Options · TypeScript](https://www.typescriptlang.org/docs/handbook/compiler-options.html)
* [node.js - Difference between module type in tsconfig.json - Stack Overflow](https://stackoverflow.com/questions/41326485/difference-between-module-type-in-tsconfig-json)
* [[意訳]初学者のためのJavaScriptモジュール講座 Part1 - Qiita](https://qiita.com/chuck0523/items/1868a4c04ab4d8cdfb23)
1分でわかるインセプションデッキとビジネスモデルキャンパスの使い分け

# 1分でわかるインセプションデッキとビジネスモデルキャンバスの使い分け

## はじめに
　新規サービスの企画を考え始めたとき、
　顧客課題や商品価値、競合、販売チャネル、リソース等を整理したく、
　ツールとして**ビジネスモデルキャンバス**を使おうとしました。そんなときに、
　「そういえば別の企画で**インセプションデッキ**を見たことあるな。」と思い出しましたが、
　使い分けを知らなかったので、調べてみた私なりの理解を紹介します。

## インセプションデッキ
　プロジェクトメンバー間で共通理解を得るためのツール。*アジャイル開発*でよく聞く。
　10個の質問をベースにやること・やらないことを整理する。
　プロジェクトの大枠を決めた後に、メンバー間で同じ方向を向くためのアウトプット。
> 　インセプションデッキのテンプレートはこちらを参照：
> 　https://github.com/agile-samurai-ja/support/tree/master/blank-inception-deck

## ビジネスモデルキャンバス（BMC）
　事業創出のツール。ビジネスマネジャーがビジネスオーナー（投資者）への説明に使う。
　*デザイン思考*の代表ツール。バリュープロポジション、チャネル、顧客セグメント、
　コスト、リソース等の9つ観点で、一枚の紙に可視化する。
　ビジネスの芽を多角的に分析するためのアウトプット。
　（実は競合との比較は直接出てこない）

## まとめ
　二つのツールで似たような機能もありますが、一番は使う目的やフェーズが違いました。
　サービスの企画を説明する相手や場面に応じてツールを使い分けましょう。
　インセプションデッキのエレベータピッチは、BMCを端的で示すものに使えそう。

### 余談
　両者を調べているうちに、新規サービスの利用者分析の観点がすっぽり抜けていたことに気づき、
　私に本当に必要だったものはペルソナシートやカスタマージャーニーマップでした、というオチ。
DockerでNodeとMysqlのセットアップをする。

#バックグラウンド

私は1年半ぐらいをITエンジニアに対していろいろのウェブのプロジェクトを開発しました。ドキドキ一つではなくテーマで仕事している。その時には問題がある。一番大きいの問題はアプリのバージョンが同じじゃないとかパソコンの環境が別別などの問題が大きいでした。そして新しいのクライアントから一つプロジェクトを貰いました。そのプロジェクトはDockerを使えました。Dockerを使って時前言ったの問題はあまり出てきました。そのプロジェクトがあるから。私はこのDockerを使ってNodeとMysqlのバースを勉強したいです。

# インストール
始めるまえにDOCKERのインストールが必要です。[DOCKER DOWNLOAD](https://www.docker.com/products/docker-desktop)でクダウンロードすることができる。

# DockerでMysqlをセットアップする

↓のセットアップはMYSQLの作るのためにセットアップする。

File : docker-compose.yml

```
version: '3.3'
services:
  db:
    // DBのVERSIONを決める
    image: mysql:5.7
    restart: always
    // DBのデータをセットアップする
    environment:
      MYSQL_DATABASE: 'db_name'
      # Password for root access
      MYSQL_ROOT_PASSWORD: 'mysql'
    ports:
      # <Port exposed> : < MySQL Port running inside container>
      - '3306:3306'
    expose:
      # Opens port 3306 on the container
      - '3306'
      # Where our data will be persisted
    volumes:
      - my-db:/var/lib/mysql
volumes:
  my-db:
   driver: local
```

# DockerでNodeをセットアップする

↓NodeJSのセットアップする。

File : docker-compose.yml

```
  # Names our volume
  node:
    build:
      context: .
      dockerfile: Dockerfile
    container_name: node-js
    volumes:
      - ./backend_node:/backend_node
    ports:
      - 3000:3000
    working_dir: "/backend_node"    
    command:
      sh -c 'npm i && nodemon'
```

↓のファイルは環境のためにセットアップする。

File : Dockerfile

```
FROM node:8-alpine

RUN npm install -g nodemon

# Create app directory
RUN mkdir -p /backend_node
WORKDIR /backend_node

COPY backend_node/package*.json ./

# Bundle app source
COPY backend_node/ .

RUN npm install

# Exports
EXPOSE 3000
CMD [ "nodemon" ]
```

## nodeをinstallする。

初めに新しいNODEプロジェクトを作る。

ー Npm Init -y

↓のデータを自動に作る。

File : backend_node/package.json


```
{
  "name": "backend_node",
  "version": "1.0.0",
  "description": "Nabkend Code For data",
  "main": "app.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "repository": {
    "type": "git",
    "url": "https://github.com/andybit-okutama/benkyou_da_you.git"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "dependencies": {
    "express": "^4.16.4"
  }
}
```

このプロジェクトでExpressのパッケージをインストールする。

ー npm install express --save-dev



File : backend_node/app.js

```
// server.js
const express = require('express');
const app = express();

 app.get('/', (req, res) => {
    return res.send('Hello world');
});

 const PORT = process.env.PORT || 3000;
app.listen(PORT, () => {
    console.log(`Server listening on port ${PORT}`);
}); 
```

## Dockerに動くする。

```
docker-compose build
docker-compose up
```

画面のプロジェクトは「http://localhost:3000」でチェックすることができる。
MySQL でサンプルデータなどをMySQlにインポートする　(超初心者)

#なぜ書こうと思ったのか？
MySQLを使ってSQLを練習をしたと思ってサンプルデータをMySQLに取り込もうとしたら
インポートできなかったので自分しかこんな問題起こさないと思いますが
<b>自分用</b>に記事を残しています

#とりあえずデータをインポートしてみよう
windows10

```
cd /(cドライブに飛びます)
c:\> cd xampp 
c:\xampp> cd mysql
c:\xampp\mysql> cd bin
c:\xampp\mysql\bin> 
c:\xampp\mysql\bin>mysql -u root 
DBに入る

```

/ ←(windowsのエンマークです)

```
MariaDB [(none)]>use main
MariaDB [(main)]> source import data
 
```
これでインポートできます
source コマンドの後にインポートしたいデータのパスを指定します
まぁパスがわからなかったら.sqlファイルを直接その場所に落としても大丈夫だと思います
ちなみに自分が出たエラーは＃1046でしたｗｗ
入れる箱も選んでないのに無理やり入れようとしてたみたいです( *´艸｀)
Javaの元号対応がなんか変だ

[java.time.chrono.JapaneseEra#REIWA](http://hg.openjdk.java.net/jdk/jdk/file/3d8934bf505a/src/java.base/share/classes/java/time/chrono/JapaneseEra.java#l157)がなんか変です。

```java:JapaneseEra.java（抜粋）
public static final JapaneseEra MEIJI = new JapaneseEra(-1, LocalDate.of(1868, 1, 1));

public static final JapaneseEra TAISHO = new JapaneseEra(0, LocalDate.of(1912, 7, 30));

public static final JapaneseEra SHOWA = new JapaneseEra(1, LocalDate.of(1926, 12, 25));

public static final JapaneseEra HEISEI = new JapaneseEra(2, LocalDate.of(1989, 1, 8));

private static final JapaneseEra REIWA = new JapaneseEra(3, LocalDate.of(2019, 5, 1));
```

なんで`private`にしたし。
[最新のソース](http://hg.openjdk.java.net/jdk/jdk/file/152c6c501ba5/src/java.base/share/classes/java/time/chrono/JapaneseEra.java)では`public`になっているものの、４月17日に公開された Java SE 8 Update 211/212 では`private`のまま。
実害はゼロだけどちょっと気持ち悪い。

楽しいゴールデンウィークをお過ごしください。
SlackAPIを使うまでのメモ

# はじめに
SlackAPIを初めて使う方向けの、
SlackAPIの権限設定からデバッグまでのメモです。

おおまかな流れは、
１．Token（特定のSlackチャンネルにアクセスするキー情報）の発行
２．APIデバッグ用のページで実際に使用できるかのテスト
３．実装

以上。

##１．Tokenの発行方法
https://api.slack.com/apps
１）ログイン（ワークスペースの選択）
２）Tokenの目的設定
３）ワークスペースのインストール

たったこれだけ。

Slack API 推奨Tokenについて　@ykhiraoさん
https://qiita.com/ykhirao/items/3b19ee6a1458cfb4ba21
でとてもわかり易くまとめられています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/316594/0ac86012-7ecc-e8a9-5272-ed80d1aaba05.png)


##２．Tokenのスコープ
わからないところはサクッと（使うことがあれば追記していきます。）

###Incoming Webhooks
メッセージ受信

###Interactive Components
メッセージ送信

###Slash Commands
コマンド実行

###OAuth & Permissions
APIの許可権限設定
迷ったらこれ
例）Access information about user’s public channels
　　channels:read
　　ユーザーの公開チャンネルに関する情報にアクセスする
　　チャンネル：読み込み権限

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/316594/ddb55ca2-237a-4c6c-e380-bea2cb7e5da6.png)

###Event Subscriptions
通知機能

###Bot Users
BOTユーザ作成

###User ID Translation
グローバルIDをローカルユーザIDに変換する。

##３．SlackAPIの種類について
https://api.slack.com/methods

##４．テスト方法
https://api.slack.com/methods/channels.list/test

入力例
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/316594/9bad7ab7-debe-cbf8-e26e-f0fd016e0ba0.png)

###失敗

>```
{
	"ok":"false",
	"error":"not_allowed_token_type"
}
```

Tokenのスコープ設定を見直して、
OAuth & Permissionsに権限を追加。
変更するとトークンを再インストール（関連付け）する必要があるので実行する。

###成功（Jsonファイルが取得できる）
>```
{
	"ok":"true",
	"channels":[
		{
			"id":"XXXXXXXXX"
			"name":"test"
			(省略)
		}
	]
}
```

あとはAPIをスクリプトで実行すればよいだけ。


#トラブルシューティング
１）missing_scope（権限が足りないよ）

>```
[19-04-25 17:41:20:665 JST] {needed=chat:write:user, provided=identify,channels:read,files:read,files:write:user, ok=false, error=missing_scope}
```



>needed:
chat:write:user, 
provided=identify,
channels:read,
files:read,
files:write:user

この権限が必要です
chat:write:user, 
provided=identify,
channels:read,
files:read,
files:write:user

>ok=false

だめでした

>error=missing_scope

権限が足りないよ

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/316594/49375ad5-3092-f1e9-799b-5de7a9e47b79.png)

さくっと追加して。成功。
UiPath Developer Community 第11回ワークショップ 覚え書き。AI Computer Vision  とUiPath 2019 Fast Trackの新機能 紹介。

[UiPath Developer Community 第11回ワークショップ](https://www.uipath.com/ja/resources/knowledge-base/tag/japan-developer-community) で聞いてきた内容の覚え書き。。

いってきました。第11回。[前回](https://qiita.com/masatomix/items/90393bdbb7824c551106)がおカタい感じだったということで、今回はもうすこしフレンドリーにしたとのことで、ユルーく始まりました。
初めは席ごとにチームに分かれて、クイズ。。フレンドリーって、そういう方向性なのね :-)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/73777/b9a6e9df-47f2-4519-9788-67ced6a31108.png)

クイズに正解した方には、まえのノベルティだった下記のヤツ :-)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/73777/2327d951-68de-3193-d0b1-204b7d07c189.png)


面白い企画としては、ワークショップのその場でリアルタイムにアンケートがとられていました。どんな機能が欲しいですか？みたいなのもあったので、、、「Orchestratorが開発環境にない場合を考慮して、AssetなどのOrch依存する機能のスタブみたいな機能があるといいなあ」 って書きました。みなさんどうやってるんでしょうか。。ソリューションをしりたいです。。



そのあとはユーザ様のユーザ事例をお話しされた後、下記の [AI Computer Vision](https://www.uipath.com/ja/resources/knowledge-base/ai-computer-vision-2019) と、

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/73777/d1500989-17d6-cb60-a2ca-e86826e65562.png)

UiPath 2019 Fast Trackの新機能紹介でした。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/73777/af484c6b-4ae3-0b1e-7c7c-efb0ad02de8b.png)

メインはやっぱり、AI Computer Vision と UiPath 2019 Fast Trackの新機能紹介 ですかね。。


## AI Computer Vision


どうも、機械学習を用いることにより、画面イメージからUI要素を抽出してくれるアクティビティのようですね。これによって、リモデなどVDI経由でもUI要素をいいあんばいに抽出してくれる、、と。。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/73777/a7d3ebd0-1fa0-126d-02e7-628d64875603.png)

うんたしかにリモデ経由でも認識している。。

どうもクラウドのサーバに情報を投げるようで、構成的にややこしくなりそうです。。 あとはそのように「画像からボタンなどを抽出する」**ではない**ところがUiPathのいいところだったのでは？といまいち理解にまで至りませんでした。。。

ベータ版がすでに動かせるようなので、後日実際にやってみようとおもいます。


## UiPath 2019 Fast Trackの新機能紹介
スピーカーが津田さんにかわり、いつもの新機能紹介。。まだわたしは触れてないのですが、いま時点(2019/04/25)では、2019.4まででてる、、のかな。。

2019.1。うーん、とくに目新しいところが、、。話には出なかったけど、コマンドライン制御が充実したんなら嬉しいですね、、。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/73777/6e6d7589-b6e2-02bd-0ed3-4ef94d840e87.png)

2019.2。正規表現ビルダはデモがありましたがとてもよさそう。。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/73777/6bf43f1a-7d96-b1ca-897a-ffeb0e34498a.png)

2019.3。ようやくGit対応。Githubに上げるときめんどくさいなーって思ってたので、これはいいですね。。あとはOrchestratorのUnattended Robo の障害時に自動でキャプチャを取得するようになったと。地味にイイです。

仕事的に一番響いたのは、所定のディレクトリ配下のプロジェクトの依存関係の一括更新でしたが、、このバージョンのStudioをユーザに導入するのはずいぶん先になりますよね、、、(´Д`;)。。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/73777/98e849d5-9fe4-9d6d-4481-340aefaea795.png)

2019.4。おおーっておもったのが Swagger(WEB上のAPI仕様書)からカスタムアクティビティを自動生成する機能。。

これは実用的なら、ほんっと便利になりそう。あとでさわってみようと思います。。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/73777/813e5a54-fd40-7a2f-7331-ff01b92fdb11.png)

## まとめ

今回のノベルティ。。いつものエナジードリンクとチロルのセットに加え、スチールのマグカップでした。。コレはうれしい。。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/73777/c90a3abd-90ad-c624-2e22-265334e0f2e0.png)

おつかれさまでした。

本日も、、、大手町でUiPath関連の研修です。。昨日とうってかわってスーツなかんじですね、、。
Laravelのenv関数とは

env関数のことがよく分かっていなかったので調べてみました

#env関数とは
Laravelのヘルバ関数の一つで、
環境変数として.envファイルに記述された値をコード上から参照する時に使えるのが、env関数。

#環境変数とは
環境毎に変わる情報（DB接続情報など）を入れる為の変数。
Laravelでは.envファイルで定義する。

#ヘルパ関数とは
Laravelの定義済み関数で、関数を定義せずにいきなり使う事ができます。便利。

#使用例

```php
'default' => env('DB_CONNECTION', 'mysql'),
```

この例だと.envファイルに書かれている環境変数のDB_CONNECTIONの値を参照しています。
第2引数はデフォルト値で、この例だと、DB_CONNECTIONという環境変数が.envに設定されていないと"mysql"という値が返されます。
RiderとXamarin.Macでポストビルドイベントを使う方法

# 症状
Visual Studio for MacXamarin.Macプロジェクトに設定したポストビルドイベントがRiderで走らない。

# 結論
csprojを開き、PropertyGroupの中に、<PostBuildEvent>タグを使ってその中でコマンドを定義する。

```xml
    <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">
        <PostBuildEvent>
            some command
        </PostBuildEvent>
    </PropertyGroup>
```

# 注意
ビルドコマンド内で`$(ProjectDir)`を使っていると、なぜか結果が空白になってしまうので、`$(MSBuildProjectDirectory)`に書き換えると直ります。
そのLambdaの実行…同期？非同期？

# はじめに

AWSでサーバレスアーキテクチャ構築しようとなったときに欠かせないのが AWSLambda ですよね。
基本的に他のサービスからのイベントでinvokeすることが多いと思いますが、その際 **同期呼び出し** でinvokeされるのか、 **非同期呼び出し** でinvokeされるのかを気にしたことはありますか？
今回は今更ではありますが、Lambdaがinvokeされるイベントが同期なのか、非同期なのかをまとめていこうと思います。

## 同期？非同期？

そもそも 同期 / 非同期 で、どんな違いがあるのでしょうか？

### 同期呼び出し

同期呼び出しの場合は直接Lambdaを **1回** 実行します。
Lambdaが実行され、処理が完了してからレスポンスが返ってきます。

### 非同期呼び出し

非同期呼び出しの場合はLambdaを直接実行するわけではなく、キューイングされた後実行されます。
Lambdaの呼び出しに失敗した場合は自動的に2回までリトライされます。
キューイングされたタイミングでレスポンスが返ってきます。

## 呼び出しタイプのコントロール

AWSSDKやCLIからLambdaを実行する際に `InvocationType` を指定することで同期呼び出し(`RequestResponse`)するのか、非同期呼び出し(`Event`)するのかをコントロールすることができます。

### SDK(Node.js)で呼び出す例

```js
exports.handler = async (event) => {
  const lambda = new AWS.Lambda();
  const params = {
    FunctionName: "MyFunction",
    InvocationType: "Event" // Event or RequestResponse or DryRun
  }
  await lambda.invoke(params).promise();
};
```

ですが、Lambdaトリガーになりうるイベントに対して、その呼び出しタイプが同期なのか非同期なのかは基本的に予め決められています。
例えばS3トリガーは非同期、Cognitoトリガーは同期。といった感じです。

### 同期呼び出しのトリガー

- APIGateway (デフォルト)
- Cognito
- Alexa
- Lex

### 非同期呼び出しのトリガー

- APIGateway (ヘッダーでEventを指定した場合)
- AWSIoT
- CloudWatch Events
- CloudWatch Logs
- CodeCommit
- S3
- SNS
- SES
- KinesisFirehose
- CloudFormation
- AWSConfig

### ポーリングするトリガー

実は同期呼び出しでも非同期呼び出しでもないトリガーがあります。
Lambda側から定期的にポーリングして、新しいイベントがあれば処理を実行します。
Lambda側からイベントを取得しに行くので、もちろんそのためのIAMRoleが必要です。(`kinesis:GetRecords` とか `kinesis:GetShardIterator` とかとか……)
ちなみにKinesisDataStreamsは毎秒1回、DynamoDBStreamsは毎秒4回ポーリングをします。
SQSはトリガーごとにポーリング間隔等を設定します。

- KinesisDataStreams
- DynamoDBStreams
- SQS

## さいごに

今まで、 **同期呼び出し** や **非同期呼び出し** があることは知っていましたが、改めてまとめてみて再確認できました。
あまり意識することは無いと思いますが、「なんで複数回実行されてるんだ？」といった現象に出くわした際は、呼び出し方のことを思い出してください。そのLambdaの実行…同期呼び出しかもしれませんよ？
ではまた！！！
【備忘録】 cssで画面の縦横を判別して切り替える

#スマホ用サイトなどで画面の向きに応じてスタイルを切り替えたい場合の記述

```ruby:css
@media screen and (orientation:landscape) {
  /* 横向き用スタイル */
}

@media screen and (orientation:portrait) {
  /* 縦向き用スタイル */
}
```
Virtual Machines作成

#Virtual MachinesでWindowsサーバーを作成
作成手順の備忘録

##Azure portalにログインして「Virtual Machines」,「追加」をクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/309166/8745e0f3-891c-ac43-4d13-c6464a39a54f.png)

##必要情報を入力

今回はWindowsサーバーを作成するので、イメージは「Windows Server 2016 Datacenter」を選択
作成後、RDPでログインするため、RDPのポートだけ解放
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/309166/ddcd5d79-9cf0-3cdd-b1ae-db6bc19f33fc.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/309166/0d7c9ff7-2530-1fb7-5a39-4088d167266b.png)

ディスクとネットワークは特に設定せず、管理の「自動シャットダウン」、「タイムゾーン」を「大阪、札幌、東京」に変更。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/309166/e7557628-6b08-5f1d-f71c-843e5ae47736.png)

詳細はタグは今回はなにも入れず「確認及び作成」

##RDPで接続確認

作成されたVMの上にある接続をクリックするとRDPファイルがダウンロードできる。
もしくは、「リモートデスクトップ接続」でパブリックIPを使ってログイン。

ユーザー名：localhost\ユーザ名（VM作成時に登録したユーザ名）
パスワード：（VM作成時に登録したパスワード）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/309166/6100ba76-8b38-7a63-b883-e29db5be789c.png)

接続成功
最初は英語版になっているため、日本語に修正して完了！！
Rails バリデーションについてまとめてみた。

##バリデーションとは
バリデーションとはデータをフィルターにかけることで、無効なデータの検出を行い、
エラーが出た場合、差し戻す仕組み
##バリデーションの記述先
また、バリデーションはModelに設定していくので、`app/models`の中の任意のファイルに
設定していく。
##バリデーション記述方法
- `validates データ名, バリデーション名`<br>

##よく使うバリデーションヘルパー

- `presence: true`<br>
指定された属性が空でないことを確認する。
- `uniqueness true`<br>
属性の値が一意であり重複していないことを確認する。
- `length:{minumum: 5}`<br>
入力データの長さに関する様々な制限をかける。<br>
ほかにも`maximu: 値`,`in:値..値`,`is:値`がある。
- `acceptance: true`<br>
フォームが送信されたときにUIのチェックボックスがオンになっているかを検証します。

##errorメッセージについて<br>
  `@変数名.errors.messages[:カラム名][0以上の数字]`に格納されている。<br>
  これをフォームのところに表示させたい場合は
  if文を使ってエラーメッセージがあるなら表示という形をとればよい。<br>
  1. `if @post.errors.messages[:title].any?`<br>
  エラーメッセージの有無を確認<br>
  2. `<%= @post.errors.messages[:title][0] %>`<br>
  あるならば、この記述で表示。

##最後に
学んだことをここで項目ごとに投稿しています。追加項目がある場合はその都度編集して追加します。抜けている点多々あると思いますがご了承ください。
GCPの新しいシークレット管理ツール、Berglasを使ってみる

BerglasはGoogleが先日公開した、GCP向けの新しいシークレット管理ツールです。

https://github.com/GoogleCloudPlatform/berglas

内部的にはCloud KMSとCloud Storageが使われているみたいですね。

GKE、Cloud Functions、Cloud Build、Cloud Run等から比較的簡単に、登録した秘匿情報を取得することができそうです。

## セットアップ

gloudコマンドの導入や、アカウントの認証などは完了している前提で進めます。

BerglasはGoのパッケージとして動作するので、まずはこちらをインストールします(Goの環境構築に関しての説明は省きます)。

```
go get github.com/GoogleCloudPlatform/berglas/...
go install github.com/GoogleCloudPlatform/berglas
```

また、公式のDockerImageも公開されているようなので、普段Goを使わない場合はこちらを利用した方が良いかもしれません。

```
docker pull gcr.io/berglas/berglas:latest
```

Berglasを使いたいプロジェクトで、必要なAPIを有効化します。

```
gcloud services enable --project プロジェクトID \
  cloudkms.googleapis.com \
  storage-api.googleapis.com \
  storage-component.googleapis.com
```

Berglasの初期化処理を行います。シークレット情報はGCSに保管されるので、新しく作成されるGCSのbucket名を指定します。

```
berglas bootstrap --project プロジェクトID --bucket bucket名
```

最低限のセットアップはこれだけですね。

## Cloud Buildのサンプル

Cloud buildを使ったサンプルを試してみます。作るのは、Berglasで登録したシークレットをCloud build内で標準出力するだけのものです。

### secretの登録

シークレット情報を登録します。何らかのAPIキーを想定した、**api-key**と言うkeyで登録してみます(`bucket-name`と`project-id`の部分は適宜置き換えて下さい)。

```
berglas create bucket-name/api-key 登録したいシークレット --key projects/project-id/locations/global/keyRings/berglas/cryptoKeys/berglas-key
```

`Successfully created secret: api-key`と表示されれば、登録完了です。

### サービスアカウントへの権限付与

登録したシークレットを読み込むためには、各サービスアカウントやユーザーに紐付ける必要があります。今回はCloud Buildで使いたいので、Cloud Buildのサービスアカウントに紐付けました。

```
berglas grant bucket-name/api-key --member serviceAccount:CloudBuildのサービスアカウントアドレス
```

### cloudbuild.yamlの作成

cloudbuild.yamlを書いていきます。

```yaml
steps:
- id: berglas
  name: gcr.io/berglas/berglas
  env:
  - API_KEY=berglas://bucket-name/api-key?destination=/secrets/api-key
  args: ["exec", "--local", "--", "/bin/sh"]
  volumes:
  - name: secrets
    path: /secrets
- name: 'ubuntu'
  args: ['cat', '/secrets/api-key']
  volumes:
  - name: secrets
    path: /secrets
```

`berglas`ステップと`ubuntu`のステップでボリュームを共有し、共有ボリューム以下にシークレット情報を書き出したファイルを出力すると言う構成です。ちょっと回りくどいのでもっと簡単な方法で実現したいですね。

cloudbuildにあげてみて、登録したシークレット情報が出力されれば成功です。

```
gcloud builds submit --project project-id
```

実行結果

```
~中略~
Finished Step #1
PUSH
DONE
Step #1: 登録したシークレット
```

## 他の環境での実行に関して

### GKEとの統合

GKEに立てたPod内から利用することもできるようですが、準備が若干大変そうです。GKEに関しては今の所k8sのsecretで間に合ってるので、今回は検証しませんでした。

https://github.com/GoogleCloudPlatform/berglas/tree/master/examples/kubernetes

### Cloud Functions

Functionsに関しては、今の所Goしかサポートしていないようです。

https://github.com/GoogleCloudPlatform/berglas/tree/master/examples/cloudfunctions/go

### Cloud Run

最近追加されたCloud Runに関しても、早速対応しています。Go、Node、Python、Rubyのサンプルがありました。

https://github.com/GoogleCloudPlatform/berglas/tree/master/examples/cloudrun

## 最後に

イメージ的にはCloud KMSのラッパーと言った感じなのでしょうか(KMSについてそれほど詳しくない・・・)。
個人的にGKEだとsecretリソースで割りと間に合ってる感じですが、Cloud BuildやCloud Runで比較的簡単に秘匿情報が扱えれば便利かも？
docker-composer build中に仮面ライダーに変身する

#はじめに
`docker-compose build`をしている間に`仮面ライダービルド`に変身したら面白くない? といった技術と時間の無駄遣いを紹介します。 結論から言うと、とりあえず出来はしましたがcliとしてはまだ完成しておらず、変身の際に音声も流れるので著作権の問題もありそうなので配布はしません。なので完全に自己満足の作品です。

# どうやって変身するか?

フローはこんなじ
1. 実行時に「ラビット！ タンク! ベストマッチ!」を流す
2. `docker-compose buid`を走らせながら待機音のループを流す
3. `docker-compose buid`終了のタイミングで変身完了音を流す

#とりあえず見て

<blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr">docker-compose build で仮面ライダーに変身する<a href="https://twitter.com/hashtag/%E6%8A%80%E8%A1%93%E3%81%A8%E6%99%82%E9%96%93%E3%81%AE%E7%84%A1%E9%A7%84%E9%81%A3%E3%81%84?src=hash&amp;ref_src=twsrc%5Etfw">#技術と時間の無駄遣い</a> <a href="https://t.co/mtMpXo9OKF">pic.twitter.com/mtMpXo9OKF</a></p>&mdash; 清水 幸佑 (@thimi0412) <a href="https://twitter.com/thimi0412/status/1121286791154130945?ref_src=twsrc%5Etfw">2019年4月25日</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>




## 音源を用意する
youtubeから取ってきて以下のファイルを作成

- `build1.mp3`がラビット！、タンク！、ベストマッチ！
- `build2.mp3`が待機音デンデンデン、デデンデン
- `build3.mp3`がハンドル回す~ラビットタンク！まで


##環境
- Python: 3.6.5
- docker-compose.yml

`docker-compose.yml`は[以前書いた記事のプロジェクト](https://qiita.com/thimi0412/items/61a27364a09d60a86708)を使用しています。

##コード
```python:main.py
import subprocess
import logging
from subprocess import Popen
import threading
from pydub import AudioSegment
from pydub.playback import play

class Ridocker:

    def __init__(self):
        self.stop_event = threading.Event() #停止させるかのフラグ

        #スレッド
        self.build = threading.Thread(target=self.exec)
        self.begin = threading.Thread(target=self.run_mp3, args=('mp3/build1.mp3',))
        self.standby = threading.Thread(target=self.retry)

    def run_mp3(self, path):
        '''mp3ファイルを再生する
        Args:
            path(str): mp3ファイルのパス
        '''
        sound = AudioSegment.from_file(path, 'mp3')
        play(sound)

    def exec(self):
        '''docker-compose buildを実行する
        '''
        cmd = "docker-compose build"
        popen = Popen(cmd, shell=True)
        popen.wait() # コマンドの処理を待つ
        self.stop() # 待機音のループを止める

    def retry(self):
        '''待機音をループさせる
        '''
        sound = AudioSegment.from_file('mp3/build2.mp3', 'mp3')
        # execが終了するまでループ
        while not self.stop_event.is_set():
            play(sound)

    def stop(self):
        self.stop_event.set() # ループを止める
        self.standby.join()    # 変身待機音が終わるのを待つ
        self.run_mp3('mp3/build3.mp3')

if __name__ == '__main__':
    h = Ridocker()
    h.begin.start()
    h.begin.join()
    h.standby.start()
    h.build.start()

```

[threading](https://docs.python.org/ja/3/library/threading.html)を使用して`docker-compose build`を流しながらmp３ファイルを再生しています。
mp3ファイルの再生には[pydub](https://github.com/jiaaro/pydub)を使用しました。mp3ファイルの再生は他にもpygameの[mixer.music](http://westplain.sakuraweb.com/translate/pygame/Music.cgi)もありましたがmixer.musicは`time.sleep(n)`の処理を行わないと再生できないので今回は見送りました。(無限ループ再生ができるそうです)

# 改善点
1. 現状ではmp3ファイルを同じディレクトリ内に配置しているので`/User/{UserName}`配下にmp３ファイルを置いて読み込めばいいかもしれない
2. `python main.py`で実行しているのでcliとして作成したい `ridocker --no-cache`みたいな感じ
3. 変身音のパターンを増やしたい(ゴリラモンドとか) `ridocker --form gorillamond`
Ruby Sinatraサーバーにhttpclientからファイルアップロードしてみた

すごく簡単に書けたけど、忘れそうなので書いておく。

<font color="red">なおこの記事では、ファイルアップロードの方法を簡潔に記載するため、ディレクトリトラバーサルなどの脅威への対策は一切行っていません。参考にされる方はご注意ください。</font>

```server.rb
require 'sinatra'

set :port, 3000

post '/upload' do
  halt 400, 'please upload file' if params[:file].nil?
  path = "./public/#{params[:file][:filename]}".freeze
  File.open(path, 'wb') { |f| f.write params[:file][:tempfile].read }
  'ok'
end
```

```client.rb
require 'httpclient'

c = HTTPClient.new
url = 'http://localhost:3000/upload'.freeze
path = ARGV.first
c.post(url, file: File.open(path, 'r'))
```
:: (resolution scope operator)=スコープ解決演算子はLaravel view() ヘルパー中の意味

:: (resolution scope operator)=スコープ解決演算子はLaravel view() ヘルパー中の意味

Laravelのコントロールに下記の書き方はあります（特にパッケージ開発時）

```php

Route::get('/', function() {
    return view('packagename::index');
});

```

::スコープ解決演算子の意味は

resources/views/vendor/packagename したの index.blade.php を使ってください。

ちなみにフィアルはない場合は

```php

$this->loadViewsFrom(__DIR__.'/views', 'packagename');
```

で指定している /views/下を探すだそうです。

また

```php
return view('packagename.index');
```

と全く違いますので、ご注意ください。

https://github.com/laravel/framework/blob/5.8/src/Illuminate/View/ViewFinderInterface.php　
定義を参照
micro:BitでDCモーター制御(TOSHIBA TA7291P)

# 背景
microBitでラジコン作りたいと思い，モータードライバーを探していましたが，意外と高いなーと思い，手元にあったTOSHIBA TA7291Pを使ってDCモーターを制御してみました。

この方法を取らなくても[microBit用のモータードライバー](https://www.switch-science.com/catalog/3229/)が売ってるので，そっちを買ってもいいかもです。
# 使用パーツ

- [microBit](https://www.switch-science.com/catalog/5263/)
<img src="https://docid81hrs3j1.cloudfront.net/contents/large/9-5-s.jpg" width="150">

- [microBitピンヘッダ変換基盤](https://www.switch-science.com/catalog/3181/)(無い場合ワニ口クリップでも可)
<img src="https://docid81hrs3j1.cloudfront.net/contents/large/edge_connector_breakout_tDlfOzg_K5Zb7Xg_UoGbw6P_cwhcGCe_vfhAehn_HixGoUc_a_nuP9aQU.jpg" width="150">

- モータードライバー（[TA7291P](https://www.switch-science.com/catalog/1691/)）
<img src="https://docid81hrs3j1.cloudfront.net/contents/large/TA7291.jpg" width="150">

- [DCモーター(今回はギアボックスモータ使用)](https://www.switch-science.com/catalog/2793/)
<img src="https://docid81hrs3j1.cloudfront.net/contents/large/13302-01b.jpg" width="150">

- [単三電池ボックス(単三×4本)](http://akizukidenshi.com/catalog/g/gP-00311/)
<img src="http://akizukidenshi.com/img/goods/L/P-00311.jpg" width="150">


# 配線
![microbit_TA7291P_ブレッドボード.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/191122/2a4e28bf-a361-b45e-7739-6c96d6acbb24.png)
少し見辛いですが，モータードライバーへの配線は，下の対応表のように接続されています。

| 端子番号 | 端子記号 | 説明 |
|:-----------:|------------:|:------------:|
| 1 | GND | ピン0V(GND)に接続|
| 2 | OUT1 | モーター端子に接続　|
| 3 | NC | 接続なし |
| 4 | Vref | 0番ピンに接続 |
| 5 | IN1 | 1番ピンに接続 |
| 6 | IN2 | 2番ピンに接続 |
| 7 | VCC | 3Vピンに接続　|
| 8 | VS | 電源出力に接続 |
| 9 | NC | 接続なし |
| 10 | OUT2 | モーター端子に接続 |


# プログラム
![スクリーンショット 2019-04-25 14.34.05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/191122/a608360a-ba0a-b21c-ab42-85a50288b8b5.png)
プログラムはこんな感じですかね。
一応下のリンクに共有したmicroBitのコード(MakeCode)を貼っておきます。リンクからコードをダウンロードすることも出来ますので，よかったらどうぞ。

https://makecode.microbit.org/_au70A3RkbK5z

# 参考リンク
- [micro:Bit エディター](https://microbit.org/ja/guide/)
- [SWITCH SCIENCE](https://www.switch-science.com/)
- [秋月電子通商](http://akizukidenshi.com/catalog/)

# license
MIT
JavaScriptでモーダルウィンドウを作ろう（ドットインストールから引用）

ドットインストールを参考にしてます。
https://dotinstall.com/
※プレミアム会員のみ閲覧可能

#完成イメージ
<img width="352" alt="スクリーンショット 2019-04-25 14.37.53.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/114933/ba9fa45e-a7d5-6ba1-b4b7-ad155f16240b.png">
　　　　　　　　　　　　　↓
<img width="525" alt="スクリーンショット 2019-04-25 14.38.01.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/114933/bf18c303-54de-b1f9-1a73-240ba3a4e42e.png">

# コード
```html:index.html(jsコードも記載してます)
  <div id="open">
    詳細を見る
  </div>

  <div id="mask" class="hidden">

  </div>

  <!-- モーダルウィンドウ部分 -->
  <section id="modal" class="hidden">
    <ul>
      <li>テスト１</li> 
      <li>テスト２</li>
      <li>テスト３</li> 
    </ul>
    <div id="close">
      閉じる
    </div>
  </section>

<script type="text/javascript">
  const open = document.getElementById('open');
  const close = document.getElementById('close');
  const modal = document.getElementById('modal');
  const mask = document.getElementById('mask');

  open.addEventListener('click', function(){
    modal.classList.remove("hidden");
    mask.classList.remove("hidden");
  });

  close.addEventListener('click', function(){
    modal.classList.add("hidden");
    mask.classList.add("hidden");

  });

  mask.addEventListener('click', function(){
    // modal.classList.add("hidden");
    // mask.classList.add("hidden");
    // 同じ処理なので、このように書き換えが可能
    close.click();
  });
</script>
```

```css
body{
  font-size: 30px;
}

#open, #close{
  cursor: pointer;
  width:200px;
  border:1px solid #ccc;
  border-radius: 10px;
  text-align: center;
  padding: 12px 0;
  /*上に30px,左右はauto,下は0*/
  margin:30px auto 0;
}

#mask{
  /*aは、透明度*/
  background: rgba(0,0,0,0.4);
  /*全画面に適用*/
  position: fixed;
  top:0;
  bottom:0;
  right:0;
  left:0;
  z-index: 1;
}

#modal{
  background: #fff;
  width:400px;
  padding:20px;
  border-radius: 5px;
  position: absolute;
  top:40px;
  left:0;
  right:0;
  margin:0 auto;
  transition: 0.4s;
  z-index: 2;
}

#modal > ul{
  list-style: none;
  text-align: center;
  padding:0;
}

#mask.hidden{
  display: none;
}

#modal.hidden{
  /*x軸はそのままで、y軸を−にして、上に持っていく*/
  transform: translate(0, -500px);
}
```
rails5.2にアップデートしたら外部キーでマイグレーションが失敗するようになった

## 概要
rails5.0からrails5.2にバージョンを上げた時にマイグレーションが失敗するようになったので，原因の調査と解決を行なった．

## 原因
出力されたエラーは以下で，エラーを読むと，usersテーブルのidをmicropostsテーブルのuser_idの外部キーとして設定することに失敗したことが分かりました．

```sh

ActiveRecord::StatementInvalid: Mysql2::Error: Referencing column 'user_id' and referenced column 'id' in foreign key constraint 'fk_rails_558c81314b' are incompatible.: ALTER TABLE `microposts` ADD CONSTRAINT `fk_rails_558c81314b`
FOREIGN KEY (`user_id`)
  REFERENCES `users` (`id`)

...
Caused by:
Mysql2::Error: Referencing column 'user_id' and referenced column 'id' in foreign key constraint 'fk_rails_558c81314b' are incompatible.
```

原因となっているusersテーブルとmicropostsテーブルのスキーマを調べたところ，userテーブルのidはbigint型，micropostsテーブルのuser_idはint型となっており，型が一致していませんでした．
これはrails5.1からテーブルのidカラムがbigintになったことによって起きたことでした．

```sh
mysql> show create table users \G;
*************************** 1. row ***************************
       Table: users
Create Table: CREATE TABLE `users` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `name` varchar(255) DEFAULT NULL,
  `email` varchar(255) DEFAULT NULL,
  `created_at` datetime NOT NULL,
  `updated_at` datetime NOT NULL,
  `password_digest` varchar(255) DEFAULT NULL,
  `remember_digest` varchar(255) DEFAULT NULL,
  `admin` tinyint(1) DEFAULT '0',
  `activation_digest` varchar(255) DEFAULT NULL,
  `activated` tinyint(1) DEFAULT '0',
  `activated_at` datetime DEFAULT NULL,
  `reset_digest` varchar(255) DEFAULT NULL,
  `reset_sent_at` datetime DEFAULT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `index_users_on_email` (`email`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8
1 row in set (0.00 sec)


mysql> show create table microposts \G;
*************************** 1. row ***************************
       Table: microposts
Create Table: CREATE TABLE `microposts` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `content` text,
  `user_id` int(11) DEFAULT NULL,
  `created_at` datetime NOT NULL,
  `updated_at` datetime NOT NULL,
  `picture` varchar(255) DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `index_microposts_on_user_id_and_created_at` (`user_id`,`created_at`) USING BTREE,
  KEY `index_microposts_on_user_id` (`user_id`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8
1 row in set (0.00 sec)
```

### 解決策
今回は外部キーであるuser_idの型をbigintに変更することで対応しました．
具体的な対応としては，schema.rbを以下のように変更しました．

```ruby
create_table "microposts", force: :cascade, options: "ENGINE=InnoDB DEFAULT CHARSET=utf8" do |t|
    ...
    t.integer   "user_id"
    t.datetime "created_at",               null: false
    t.datetime "updated_at",               null: false
    ...
end

↓

create_table "microposts", force: :cascade, options: "ENGINE=InnoDB DEFAULT CHARSET=utf8" do |t|
    ...
    t.bigint   "user_id"
    t.datetime "created_at",               null: false
    t.datetime "updated_at",               null: false
    ...
end
```

この後，`rails db:setup`を実行することで，無事マイグレーションが成功するようになりました．

## 参考
こちらの記事を参考にさせていただきました．

- https://kamihikouki.hatenablog.com/entry/2017/04/11/141447
.htaccessをローカル環境でも検証環境でも共有してBasic認証を出し分けしたい

# 今更ながら.htaccessを書く機会が増えてきたので

- 検証環境用のリポジトリをcloneして、ローカル環境で検証する際、一々.htaccessを編集してBasic認証を外す作業が面倒くさい

## .htaccessの記述

以下のコードを追加すれば、`localhost`(ローカル環境)ではBasic認証を行わない.

```.htaccess
<If "req('Host') != 'localhost'">
   # Basic認証の設定
</If>
```

## その他思うこと

- [公式ドキュメント](https://blogs.apache.org/httpd/entry/new_in_httpd_2_4)を読むの大事
- てかこれ2012年の記事...
- Apache2.2とか古いのはたぶん使えない
- CentOS7系では確認しましたが、Ubuntuとかで使えるかはわかりません
Nuxt.jsでtypescriptの記法一覧

今回はNuxt.jsでtypescriptをどう書いていったのかを備忘録として残していきたいと思います。

```vuejs

//test.vue
<template>
  <test2/>
</template>

<script lang="ts"> //typescriptで書く際にはここにlangで記述する

/* nuxt-property-decoratorをインポートする
*  {}内には使用したいDecoratorsを記述する
**/
import { Component, Inject, Model, Prop, Provide, Vue, Watch } from 'nuxt-property-decorator'
//他のコンポーネントをimportする際には絶対パスではなく相対パスで記述する
import Test2 from '../../test2.vue' 

@Component({
  Test2
})
export default class Test extends Vue{
  mounted() {
    console.log('test');
  }
  @Prop() //propsの記法
  prop1: number

  @Provide() test: string = 'test' //dataの記法　ここでも型付け（ここでいうとstring）が行える

  //computedの記法
  get foo(): number {
    return this.$store.state.test.id
  }

  //methodsの記法
  getId() {
    //省略
  }

  /* watchの記法
  * immediateをtrueにしておくと値がbindされた段階でメソッドを走らせる
  * deepをtrueにしておくとオブジェクトの監視時にオブジェクト内の変数の値変更もキャッチしてくれる
  **/
  @Watch('bar', {immediate: true, deep: true})
  getId(){}
}
</script>
```

実際にNuxtでの記法に直してみると下記のようになる

```vue

<template>
  <test2/>
</template>

<script>
export default {
  components: {
    Test2: () => import('../../test2.vue')
  }

  mounted() {
    console.log('test');
  }

  props: {
    prop1: Number
  }

  data() {
    return {
      test: 'test'
    }
  }

  computed: {
    foo() {
      return this.$store.state.test.id
    }

    methods: {
      getId() {
        //省略
      }
    }
  }
}
</script>
```
データの可視化シリーズ 第6弾 - 表計算の「累積合計」を使って時系列のトレンドを可視化する

# データの可視化シリーズ 第6弾 - 表計算の「累積合計」を使って時系列のトレンドを可視化する


こんにちは

Exploratoryの[白戸](https://exploratory.io/author/GMq1Qom5tS/notes)です。

[前回](https://qiita.com/takatoshiroto/items/9e76ca4527509852fd06)は、ラインチャートを使用して時系列のトレンドを見ていきました。

今回は、ラインチャートと表計算を使用して新規ユーザーの累積値のトレンドを見ていきたいと思います。



# データの可視化の目的

**目的**

累積ユーザー数の増加のトレンドを理解したい

**使用機能**

* ラインチャート
* 表計算の累積合計値

# 使用データ

今回もこのシリーズで使っている、activitiesというアクセスログのデータを使用します。このデータの取得とインポートは[こちら](https://qiita.com/takatoshiroto/items/281f777ebc9945ecb0c6)の記事にあります。

また今回は、このデータフレームのラングリングの6番目のステップを使用するので、チャートが正しく6番目のステップに「ピン」されていることを確認してください。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/192148/caca6d5f-ea38-8ef8-688a-6250bd9a0a19.png)


もし、ステップのピンの変更方法がわからない場合は[前回の記事](https://qiita.com/takatoshiroto/items/9e76ca4527509852fd06)を参照してください。


それでは、実際にデータの可視化をしてみましょう！

# 可視化

今回は、新規のユーザー数のトレンドを見ていきたいためにチャートはラインチャートを選択します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/192148/6fe48f40-b0ec-91dd-199b-cf2032942c8e.png)


X軸にfirst_activity_dateを選択し、スケールを「週に切り捨て」を選ぶことで、週単位にデータを見れるようにします。

次に、Y軸にはuseridを選択し、集計関数に「一意な数」を選びます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/192148/42ae1d34-f661-5de4-966e-648af7954f46.png)


新規のユーザー数が週単位で表示されました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/192148/8e469e97-b705-4562-bc4a-36cce855bd3a.png)


波がありますが、気になるのは4月以降は新規のユーザー数がかなり少なくなっています。

次に、新規のユーザー数を積み上げた合計値をみていきましょう。

Y軸のメニューをクリックして表計算を選択します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/192148/59ce1b25-d964-cd19-0ab6-250604443923.png)


計算のタイプは累計を選びましょう。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/192148/93248370-fb35-9422-ea7f-bf32deea5f0d.png)


値の集計方法を合計値にします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/192148/c2f4dca6-c1d1-ea86-826c-eed52caabfc7.png)


新規ユーザーの累積値を可視化できました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/192148/d46f610f-cf71-6a84-50e2-a6e80bd9232b.png)


このチャートを見ると、それぞれの時点での累積ユーザーの合計がすぐに分かります。
例えば、最後の月の7月であれば、2885人でした。
5月以降は新規ユーザーの伸びが緩くなっていているようです。


# まとめ

今回はラインチャートと表計算の累積を使用して、新規のユーザー数を積み上げたデータを可視化しました。


次回は**時系列のトレンドを表計算の移動平均**を使用してみていきたいと思います。

* [データの可視化シリーズ 第7弾 - 表計算の「割合」を使って時系列のトレンド を可視化する](https://qiita.com/takatoshiroto/items/73c5f165f1e0e08b731b)

-----

# Exploratoryデータ・アカデミー

データの可視化、またはデータ分析に関してもっと知りたい、学びたいという方は、私達が提供しているトレーニングやセミナーに参加してみてください。

[こちら](https://ja.exploratory.io/data-academy-jp?utm_campaign=chart_intro_6&utm_medium=blog&utm_source=qiita)のExploratoryデータ・アカデミーのページに詳細情報があります。

データを使ってより良い意思決定を行っていきたいと言う方は、ぜひこの機会に参加をご検討ください！
お互いに依存関係のあるrpmは同時にインストールする

# お互いに依存関係のあるrpmは同時にインストールする

## はじめに
* 互いに依存関係のあるrpmのインストールではまったので、備忘用に対応方法をメモ

## 対応方法
* 依存関係のあるrpmを同時にインストールするといける

```sh
rpm -i パッケージ1 パッケージ2
```

## 実際の例
### 以下のような依存関係のあるパッケージがあったとする

```sh:パッケージ1
rpm -qRp nss-softokn-freebl-X.XX.rpm
libc.so.6  
libc.so.6(GLIBC_2.0)  
libc.so.6(GLIBC_2.1)  
libc.so.6(GLIBC_2.1.3)  
libc.so.6(GLIBC_2.3)  
libc.so.6(GLIBC_2.3.4)  
libc.so.6(GLIBC_2.4)  
libc.so.6(GLIBC_2.7)  
libdl.so.2  
libdl.so.2(GLIBC_2.0)  
libdl.so.2(GLIBC_2.1)  
```

```sh:パッケージ2
rpm -qRp glibc-X.XX.rpm
libfreebl3.so  
libfreebl3.so(NSSRAWHASH_3.12.3)  
```

### 個別に実行した時
* それぞれエラーになる

```sh:パッケージ1
rpm -i nss-softokn-freebl-X.XX.rpm
エラー: 依存性の欠如:
        libc.so.6 は nss-softokn-freebl-X.XX に必要とされています
        libc.so.6(GLIBC_2.0) は nss-softokn-freebl-X.XX に必要とされています
        libc.so.6(GLIBC_2.1) は nss-softokn-freebl-X.XX に必要とされています
        libc.so.6(GLIBC_2.1.3) は nss-softokn-freebl-X.XX に必要とされています
        libc.so.6(GLIBC_2.3) は nss-softokn-freebl-X.XX に必要とされています
        libc.so.6(GLIBC_2.3.4) は nss-softokn-freebl-X.XXに必要とされています
        libc.so.6(GLIBC_2.4) は nss-softokn-freebl-X.XX に必要とされています
        libc.so.6(GLIBC_2.7) は nss-softokn-freebl-X.XX に必要とされています
```

```sh:パッケージ2
rpm -i glibc-X.XX.rpm
エラー: 依存性の欠如:
        libfreebl3.so は glibc-X.XX に必要とされています
        libfreebl3.so(NSSRAWHASH_3.12.3) は glibc-X.XX に必要とされています
```

### 今回の例の場合
* nss-softokn-freebl-X.XX.rpmにはglibc-X.XX.rpmが必要だが逆も同じ状態のため、個別にインストールしようとするとエラーになる

### 同時にインストール
```sh
rpm -i nss-softokn-freebl-X.XX.rpm glibc-X.XX.rpm
```

## まとめ
* 依存関係を整理した上で、必要であれば同時にインストールする
【Java】パワーポイント(ppt)からApache POIを使ってテキスト抽出

<h2>はじめに</h2>
大量のパワーポイントファイルからテキスト抽出を行う必要があり、当初はpython-pptxを使う予定でしたが、ファイルがパワーポイント2003までのもの(拡張子ppt)だったため断念しました。
そこでJavaの外部ライブラリの<a href="https://poi.apache.org/">Apache POI</a>を使いテキスト抽出を行うことにします。

<h2>Apache POIとは</h2>
![apache poi.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/215216/93f84b23-ae06-5ae5-1904-1e35e8b675d8.png)
Apache POIとは、Microsoft Office形式のファイルを読み書きできる100% Javaライブラリです。
この記事で扱うパワーポイントだけでなくエクセルやワードの操作も行えます。

<h2>Apache POIのダウンロード</h2>
Apache POIのダウンロードは<a href="https://poi.apache.org/download.html">こちら</a>から行なってください。

<h2>プログラム</h2>
以下のpptファイルの1ページ目のスライドのテキストを取得します。
![ppt2txt.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/215216/47d3df1d-0137-e1a2-506e-24b1328ba356.png)

以下のプログラムで動かします

```PPT2txt.java
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.List;

import org.apache.poi.hslf.usermodel.HSLFSlide;
import org.apache.poi.hslf.usermodel.HSLFSlideShow;
import org.apache.poi.util.IOUtils;

public class PPT2txt {
	public static void main(String[] args) throws IOException {
		File file = new File("./data/test.ppt");
		FileInputStream inputStream = new FileInputStream(file);

		// 読み込むファイルのサイズが大きい場合は最大値を増やす
//		IOUtils.setByteArrayMaxOverride(10000000);

		HSLFSlideShow ppt = new HSLFSlideShow(inputStream);

		// プレゼンテーション内のすべてのスライドの配列を取得
		List<HSLFSlide> slides = ppt.getSlides();

		int page = 1;
		int paragraph = 1;

		System.out.println(slides.get(page).getTextParagraphs().get(paragraph));

		ppt.close();
	}
}
```

<h2>結果</h2>
プログラムを実行すると1ページ目のテキストが取得できます。

```
[1ページ目テキスト]
```

<h2>おわりに</h2>
この記事ではパワーポイント2003までのもの(拡張子ppt)のテキスト抽出の方法を紹介しましたが、もちろんパワーポイント2007以降のファイル形式(拡張子pptx)でも可能です。
その際は、org.apache.poi.hslfではなくorg.apache.poi.xslfを使用します。
また、テキスト抽出だけでなく画像取得やスライド作成などの行えますので、その場合はドキュメント見て頑張りましょう。

最後までお読み頂きありがとうございました。
scp だけを無効化する zsh の設定ハック

[CVE-2019-6111][] により scp の脆弱性が明らかになっているので、 scp を無効化する方法を考えてみました。

[CVE-2019-6111]: https://nvd.nist.gov/vuln/detail/CVE-2019-6111

# そう、 zsh ならね

zsh で scp を使えなくするには、リモート ホストの `~/.zshenv` にこう書きます。 (ログイン シェルを zsh にしている前提です。)

```zsh
scp () {
    echo "Use 'sftp' or 'rsync' instead." >&2
    false
}
```

## 雑な解説

scp コマンドは、 non-interactive (非対話的) シェルで scp をリモート実行しようとするので、前述のシェル関数があると通信が阻害されて以下のようにエラーになります。

```console
% /usr/sbin/scp remote:.zshenv /tmp/
Use 'sftp' or 'rsync' instead.
lost connection
```

絶対パスを指定しないと、もちろん以下のようにローカル側でエラーになります。

```
% scp remote:.zshenv /tmp/
Use 'sftp' or 'rsync' instead.
```

## zsh 以外のシェルの場合

Bash では non-interactive シェルで暗黙的に実行されるスクリプトがないので、設定が面倒なのですよね。