OmniAICreator/Qiita-1.07M huggingface dataset:
【2019年7月版】Elvis は Primitive を返せない。@Elasticsearch, Painless

# Elasticsearch のパイプラインにて

Elasticsearchのパイプライン処理にて `script` Processorを使用してデータの加工などを行ってみようかと、以下のようなPainlessスクリプトを書いて・・・

```painless
int len = array?.length ?: 0;
```

パイプラインを`PUT`したら以下のように怒られました。

```
lang: 'painless',
     caused_by: 
      { type: 'illegal_argument_exception',
        reason: 'Elvis operator cannot return primitives' } },
  status: 400 }
```

`Elvis operator cannot return primitives` !!!
`Elvis operator cannot return primitives` ですって!!!
いや～、マジすか？！プリミティブ型扱えないとめっちゃ不便じゃん～。。。っていうかマジすか？どうなってるの？！と不満タラタラで納得いかないのでエルビス演算子のテストケースを見てみましたよ！

- [elasticsearch/modules/lang-painless/src/test/java/org/elasticsearch/painless/ElvisTests.java](https://github.com/elastic/elasticsearch/blob/master/modules/lang-painless/src/test/java/org/elasticsearch/painless/ElvisTests.java)

以下のようになってます。

```java:ElvisTests.java
...
        // Assigning to a primitive
        assertCannotReturnPrimitive("int i = params.a ?: 1; return i");
        assertCannotReturnPrimitive("Integer a = Integer.valueOf(1); int b = a ?: 2; return b");
        assertCannotReturnPrimitive("Integer a = Integer.valueOf(1); int b = a ?: Integer.valueOf(2); return b");
        assertEquals(2, exec("int i = (params.a ?: Integer.valueOf(2)).intValue(); return i"));
        assertEquals(1, exec("int i = (params.a ?: Integer.valueOf(2)).intValue(); return i", singletonMap("a", 1), true));
        assertEquals(1, exec("Integer a = Integer.valueOf(1); int b = (a ?: Integer.valueOf(2)).intValue(); return b"));
        assertEquals(2, exec("Integer a = null; int b = (a ?: Integer.valueOf(2)).intValue(); return b"));
...
```

ちゃんと `assertCannotReturnPrimitive` のケースが書かれてますね。。。
そしてその下では `assertEquals(2` とか `assertEquals(1, ` とかでint型の値を扱ってるじゃないですか！

結局のところ、エルビスの後半で `Integer.valueOf` のようにボックスを返してあげれば式全体が参照を返すもんだと認識されて、宜しくコンパイルしてくれるんですね。そして `intValue` でプリミティブ値を取り出しています。

ちょっとめんどくさいですが、上記の方法で行けそうです。
というわけで最初の箇所は以下のように修正して無事にPUTできました。

```painless
int len = (array?.length ?: Integer.valueOf(0)).intValue();
```

ですがちょっと長いので以下のように修正しました。

```painless
def len = array?.length ?: Integer.valueOf(0);
```

後の処理で暗黙のアンボックスに期待、という方針で、今回はここでは参照型のまま受け取るということにいたしました。

う～ん、`Painless` 。。。
PHP実行すると dyld: Library not loaded: /usr/local/opt/icu4c/lib/libicui18n.62.dylib のエラーが起きる。

Neovimで[Coc](https://github.com/neoclide/coc.nvim)入れて、PHPの定義元移動試してみたら、下記のようなエラー。

```shell
dyld: Library not loaded: /usr/local/opt/icu4c/lib/libicui18n.62.dylib
  Referenced from: /usr/local/bin/php
  Reason: image not found
```

最初Cocかnodeかで起きてるのかと思ってicu4cをアップデートも考えたんだけど、phpが参照元って書いてあるので、phpを叩いてみると同じエラーが起きる。

```shell
$ /usr/local/bin/php
dyld: Library not loaded: /usr/local/opt/icu4c/lib/libicui18n.62.dylib
  Referenced from: /usr/local/bin/php
  Reason: image not found
```

何だお前、最近使わなかったけど、動いてなかったんだな……。

```shell
$ brew upgrade php
php 7.2.12 -> 7.3.7
==> Upgrading php
==> Installing dependencies for php: apr, openssl, argon2, brotli, c-ares, libidn, libmetalink, libssh2, jansson, libev, libevent, nghttp2, openldap, rtmpdump, curl-openssl, freetds, libpng, freetype, pcre, readline, sqlite, python, glib, libpq, libsodium, libzip, libtiff and webp
==> Installing php dependency: apr
・
・
・
$ /usr/local/bin/php --version
PHP 7.3.7 (cli) (built: Jul  5 2019 12:44:05) ( NTS )
Copyright (c) 1997-2018 The PHP Group
Zend Engine v3.3.7, Copyright (c) 1998-2018 Zend Technologies
    with Zend OPcache v7.3.7, Copyright (c) 1999-2018, by Zend Technologies
```

PHP新しくしたら **このエラーは** 起きなくなった。Cocの定義元移動は[後編](https://qiita.com/masakuni-ito/items/790cf9d4ba8dbec9cf10)に続く。
第１１回　Raspberry Pi で監視カメラを作ろう！　～動画保存編～

Raspberry Piと専用のカメラモジュールを使用し、ONVIF対応の監視カメラを作成する[シリーズ記事](https://qiita.com/lis-hanzomon/items/cc1f7f316fbeb9579b28)です。
本記事は[リンク情報システム株式会社](https://www.lis.co.jp/)の有志が作成しています。

---

今回は動画データのファイル保存について説明します。

#動画保存
####ffmpegを使用してTSファイル保存
・動画のファイル形式について
H.264形式の動画ファイルのファイルコンテナとしては、MP4,AVI,TS等が考えられます。
全体の再生時間や含まれる映像データ、音声データの形式といった情報と実際のデータを保存する仕組みがファイルコンテナになります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/399637/886a6991-71e4-42c2-2e5f-2d8fe4722871.png)

今回は複数のファイルを単純に連結するだけで、１つの長い動画が作成できる、TS形式で動画ファイルを作成します。

ffmpegを使用した動画ファイル作成処理は、以下の様な処理になります。

```c
// ファイル出力用のコンテキストを割り当てる
ic = avformat_alloc_context();

// フォーマットを設定
AVOutputFormat* fmt = av_guess_format(NULL, "dummy.ts", NULL);
ic->oformat = fmt;

// 動画を追加
AVStream* st = avformat_new_stream(ic, NULL);
st->codec->codec_type     = AVMEDIA_TYPE_VIDEO;
st->codec->codec_id       = AV_CODEC_ID_H264;
st->codec->width          = m_width;
st->codec->height         = m_height;
st->time_base.num         = ts_time_base.num;
st->time_base.den         = ts_time_base.den;
st->codec->extradata_size = video_extradata_size;

st->codec->extradata = (uint8_t*)av_malloc(video_extradata_size + FF_INPUT_BUFFER_PADDING_SIZE);
memcpy(st->codec->extradata, video_extradata, video_extradata_size);
memset(st->codec->extradata + video_extradata_size, 0, FF_INPUT_BUFFER_PADDING_SIZE);

if (fmt->flags & AVFMT_GLOBALHEADER)
{
st->codec->flags |= CODEC_FLAG_GLOBAL_HEADER;
}

// ヘッダを出力
avformat_write_header(ic, NULL);

while(指定された時間繰り返す)
{
  // 動画データを出力
  av_interleaved_write_frame(ic, &inpkt);
}

// フッダを出力
av_write_trailer(ic);

// ストリーム出力を開放する
av_free(ic->pb);
ic->pb = NULL;
avformat_free_context(ic);
```

上記の例では記載していませんが、いろいろな再生アプリで再生可能な、互換性が高いファイルを作成するには、以下のような工夫をする必要があります。

・一番最初に出力する動画データは、IDRフレームの動画データにする。
・IDRフレームの前には、必ずSPS、PPSを付与する。

このルールを守っていないと、TSファイルとしては正しいのですが、アプリケーションによっては再生できない事があります。

ですので、一定時間でファイルを分割する場合は、IDRフレームに到達した時点で、それまでのファイルを閉じ、IDRフレーム以降を新しいファイルに出力する必要があります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/399637/b996fd2f-0999-f6d4-2102-30c4398032f3.png)

---
[インデックス記事へ](https://qiita.com/lis-hanzomon/items/cc1f7f316fbeb9579b28)
[第１０回記事へ](https://qiita.com/lis-hanzomon/items/055ebf703026734cd97f)
[第１２回記事へ](https://qiita.com/lis-hanzomon/items/d103e2d72c2f571dcba5)

---
[リンク情報システム株式会社](https://www.lis.co.jp)では一緒に働く仲間を[随時募集](https://www.lis.co.jp/employ_top)しています！
また、お仕事のご依頼、ビジネスパートナー様も募集しております。[お気軽にご連絡](https://www.lis.co.jp/inquiry)ください。
VBSでWEBアプリの負荷テストする

業務アプリの負荷試験のために検索ボタン連打するスクリプトを作成。
JSとかSeleniumとかその辺使ったらいいんじゃね？とは思いつつ、vbsという要件だったので。
サンプルなのでbingを例にしてるけど、開発環境とか負荷テストが許容されるとこでのみ実行してね。

```vb:Bing検索を連打するテスト
Dim SLEEP_TIME
SLEEP_TIME = 1000

Dim LOOP_COUNT
LOOP_COUNT = 3

Dim objShells
Dim objInpTxt
Dim objFrame

Set objShells = CreateObject("Shell.Application")

For Each objWindow In ObjShells.Windows
	If typeName(objWindow.document) = "HTMLDocument" Then
		If ObjWindow.document.Title = "bing - Bing" Then
			For i = 1 To LOOP_COUNT
				Set objInpTxt = objWindow.document

				objInpTxt.all("go").Click

				Do While objWindow.Busy = True or objWindow.readyState <> 4
					WScript.Sleep SLEEP_TIME
				Loop
			Next
		End If
	End If
Next
```
・既存のWindowを探すにはshell経由でやる([Shell.Application](https://docs.microsoft.com/ja-jp/windows/win32/shell/shell-application))
・objInpTxtはループの度に取得しなさないといけない場合もある[^1]
・途中で止めたかったら別ページに遷移するなりすればエラー出て止まります
・条件入力とかしたかったら以下の記事を参照するとよいかも
[VBSを使ってIEの操作を自動化する](https://qiita.com/itsumoonazicode/items/810e00008c10fdaa927b9)

 [^1]: たぶん、ボタン操作の結果でDOM構造が変わる場合とかで必要になりそう

```vb:【おまけ】フレーム使ってるならこんな感じ
Set objFrame = objWindow.document.frames

' アプリの構造次第で、何枚目なのか指定変えないとあかん
Set objInpTxt = objFrame(2).document
```

##感想
VBSってVBAとは完全に別物で、細かい文法違うのね。[^2]
As Objectとか Next iとか書いてたけど文法エラーになって、ウーンってなった。

あと、本当はWin32API叩いてsetForegroundしたかったけど
結局Excel.Application経由しないといけなさそうだったのであきらめた。
それなら最初からVBAで書くよねって話で。

まあVBSもIEも、そのうちいなくなるハズなので、やるならpowershell使ったほうがいいと思う。
[powershell+IE11](https://qiita.com/fujimohige/items/5aafe5604a943f74f6f0)
[powershell+他ブラウザ](http://www.mita.nu/blog/windowspowershell%E3%82%92%E3%81%A4%E3%81%8B%E3%81%A3%E3%81%A6%E9%80%A3%E7%B6%9A%E4%BD%9C%E6%A5%AD)

[^2]: でもインドとインドネシアくらいは違わない
APEXの忘備録

# APEXって忘れちゃうよね
ググればいいのかもしれないけど、つい忘れちゃうこと
忘備録なので内容は保証できないっす。
## レコードタイプを楽にとる
schema使うのがトレンドってやつだぜ。
`schema.SObjectType.オブジェクト名（Accountとか）.getRecordTypeInfosByDeveloperName().get(レコードタイプの開発名).getRecordTypeId()`
むかしはNameでしか取れなかったのにいい時代になった。
でもschema使うからループとかで回すと速度が酷いことになるかも。。。
マイナーな言語で遊ぼう Part1【EB GUIDE】

<font color='00000f'>C++,Python,Java...
数あるプログラム言語の中で忘れ去られた過去の遺産と化してしまった悲しみの言語が存在します。
今回紹介するのは**過去の遺産**ではなく2003年にElektobit社が自動車会社であるAudi社向けに開発した、現在も進化し続けているが、あまり世間的には知られていない[EB GUIDE](https://www.elektrobit.com/jp/products/ux/eb-guide/)を紹介します。</font>

#はたしてどんな言語なのか？
<font color='00000f'>EB GUIDEは<font color='ff0000'>EB GUIDE Scripts</font>と言う名の、C#やC++に近い言語を使います。</font>

```
function(v:arg0::int)
{
	v:this.x = v:arg0
	false
}
```

<font color='00000f'>EB GUIDE Scriptsの最大の特徴は戻り値を表す**return**を書かないこと。</font>

<font color='00000f'>実際の開発画面では下記のように、自動的に戻り値と引数が記載されます。
そのためこのような形でも迷う事はあまりなく、[ドキュメント(英語)](https://d23rjziej2pu9i.cloudfront.net/wp-content/uploads/2019/06/27112100/EB-GUIDE-Studio.pdf)やサンプルがしっかりとあるので開発自体は容易です。</font>
![キャプチャ2.PNG]
(https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/289160/5f44e934-8dd0-8a74-db5c-9ae8ff6959ce.png)

#本来のEB GUIDE

<font color='00000f'>本来のEB GUIDEは[HMI](http://e-words.jp/w/HMI.html)の開発を目的としてツールです。
比較的簡単にボタン等のパーツを配置することが可能で、下記のような画面がすぐに作れるのも特徴的です。</font>
![キャプチャ3.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/289160/811f720c-3fa1-b76f-f846-3eb62566c3cb.png)

<font color='00000f'>日本語にも対応している且つ、画面のUIも拘って作られていて、説明書がなくてもHMIを作れてしまいます。</font>

![キャプチャ.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/289160/a1fb5d96-5460-2d40-59a5-6edeff4261a9.png)

#後書き
<font color='00000f'>私はEB GUIDEを仕事でかじった程度しか触っていませんが、本当にHMIを作るだけに存在するツールとしか存在意義がなく、HMIを作るなら最適で、デモ画面がてらにサクッと作るにはいいかも知れません。
画面遷移の設定も可能なので、[sketch](https://www.sketch.com/)等では再現出来なかった細かい動きを作ることもできるので、デザイナーにお勧めするツールになるかもしれません。</font>
【C#】メールをHTML形式で送信【Outlook】

##概要
タイトルまんま。
OutlookをC#で動かして、HTML形式でメールを送る。
（ハイパーリンクを使いたかったのだが、検索してもなかなか使い方がわからなかった。検索の仕方が悪いのか…）
自分用の備忘録に

##コード
```C#
using System;
using Outlook = Microsoft.Office.Interop.Outlook;

namespace HTMLsample
{
    class Program
    {
        static void Main(string[] args)
        {
            try
            {
                Outlook.Application outlookApp = new Outlook.Application();
                Outlook.MailItem mail = outlookApp.CreateItem(Outlook.OlItemType.olMailItem) as Outlook.MailItem;
                mail.Subject = "HTMLsample";
                Outlook.AddressEntry User = outlookApp.Session.CurrentUser.AddressEntry;

                String sHtml;
                sHtml = "<HTML>\n" +
                   "<HEAD>\n" +
                   "<TITLE>Sample GIF</TITLE>\n" +
                   "</HEAD>\n" +
                   "<BODY>\n" +
                   "<p><a href=\"hogehoge\">foofoo</a></p>\n" +
                   "</BODY>\n" +
                   "</HTML>";
                mail.HTMLBody = sHtml;

                mail.Recipients.Add("送信先");
                mail.Recipients.ResolveAll();
                mail.Send();
            }
            catch
            {
                Console.WriteLine("メールは送信できませんでした");
            }
        }
    }
}


```

以上。
テキストエディタでHTML書いて、それをコピペしても上手くいかなかった。
この書き方なら反映される。なぜ？？？

↓参考にした
https://support.microsoft.com/en-us/help/310262/how-to-use-the-microsoft-outlook-object-library-to-send-an-html-format
CentOS6からCentOS7へアップグレードでdev.centos.orgがリンク切れになっていた

## はじめに

まず最初に言っておきたいのが、CentOS6からCentOS7へアップグレードするよりも、
CentOS7を一から構築する方が圧倒的に楽なので、どうしても<b>アップグレードする必要がある</b>人向けです。

私はそんな稀有な状態でしたので、下記の<b>ありがたい記事</b>を参考にアップグレードさせてもらおうと思ったんですが、2019年7月現在では`http://dev.centos.org`がリンク切れだった為、
「upgrade toolのインストール」の項目だけ別でインストールする必要がありました。

[CentOS6からCentOS7へアップグレードする - Qiita](https://qiita.com/toshiro3/items/0422280e3ea336c8415e)

## 対応
`https://buildlogs.centos.org/`というところから、upgrade toolを確認しましたので、
今回はそちらを利用させていただきました。

```
# 例
rpm -ihv https://buildlogs.centos.org/centos/6/upg/x86_64/Packages/preupgrade-assistant-1.0.2-36.0.1.el6.centos.x86_64.rpm
rpm -ihv https://buildlogs.centos.org/centos/6/upg/x86_64/Packages/preupgrade-assistant-contents-0.5.14-1.el6.centos.noarch.rpm
rpm -ihv https://buildlogs.centos.org/centos/6/upg/x86_64/Packages/preupgrade-assistant-ui-1.0.2-36.0.1.el6.centos.x86_64.rpm
rpm -ihv https://buildlogs.centos.org/centos/6/upg/x86_64/Packages/redhat-upgrade-tool-0.7.22-3.el6.centos.noarch.rpm

```

これでうまくいくかと思いきや、最後のコマンドでエラーが発生

```
# redhat-upgrade-tool-cli --network 7.0 --instrepo http://mirror.centos.org/centos/7/os/x86_64/
setting up repos...
.....(略)....
Downloading failed: invalid data in .treeinfo: No section: 'checksums'
```

同エラーが発生した方は下記の記事を参考にオプションを追加して再実行してみてください
[CentOS6.9を7.3にアップグレード | Akashic Records](http://a-records.info/upgrade-centos69-to-centos-73/)

## オプションを追加して再実行
```
# redhat-upgrade-tool-cli --network 7 --cleanup-post --instrepo=http://vault.centos.org/centos/7.2.1511/os/x86_64/ --addrepo=CentOS7=http://mirror.centos.org/centos/7/os/x86_64/
setting up repos...
.....(略)....
Finished. Reboot to start upgrade.
```

## 最後に注意点

`Finished. Reboot to start upgrade.`とあるんですが、そのままrebootすると<b>SSH接続ができなく</b>なります
※systemdのsshdサービスが自動起動ではない為

私の場合、vagrantだったり、VPSだったりするんで、直接入って`systemctl start sshd`でしまいですが、
もし<b>データセンターにあるサーバでバージョンアップ</b>する場合は、<b>それなりの覚悟</b>が必要になりますので、お忘れなく。

CentOS6のサポート終了が来年に迫っているんで、少し早いかもしれませんが、参考になれば幸いです。
[各OSのリリース日とサポート終了日を表にまとめてみた - Qiita](https://qiita.com/yunano/items/4757f86f9e92bb4f503f)

やはりこれからはクラウド化してChefかなんかでにコード化しておくべきですね。

## 参考
[CentOS6からCentOS7へアップグレードする - Qiita](https://qiita.com/toshiro3/items/0422280e3ea336c8415e)
[CentOS6.9を7.3にアップグレード | Akashic Records](http://a-records.info/upgrade-centos69-to-centos-73/)
【備忘録】Git configの個人的Aliasの頻出設定＋α

#標準系
##ブランチ基本操作
- ご存じとは思いますが、実際に入力する際は、<b>git st = git status</b> と読み替えられます
- もちろん、<b>git branch -a</b>なども<b>git br -a</b>で使えます

実行例（ブランチ削除）： `git br -d hogehoge`

```
st = status
br = branch
```
##着手・切り替え
```
ft = fetch origin
co = checkout
cb = checkout -b
```
##修正中
<b>git stash</b>をはじめて知ったときは感動しました
関係ないものをポイできるのは大変助かります

```
df = diff
sts = stash
stss = stash save -m
stsl = stash list
stsc = stash clear
```
コメントなしでも保存できますが、より内容が理解しやすくなります。
実行例：　`git stss "test"`
### Quiita 関連記事
- <a href="https://qiita.com/keisuke0508/items/4ad7caf544b1ad631fd7">git: git stashの使い方</a>
- <a href="https://qiita.com/jkr_2255/items/ea3e50a99baca37a42de">git stashよりgit branch</a> 

##コミット
コミットのmオプション、知るまでは毎回コメント入力の画面開いてました
（今思うとどれくらいの蓄積に…）
<b>git log -> rebase -> #rebase部分の処理</b>という流れ

```
#通常
ci = commit
cim = commit -m
ps = push origin HEAD

# rebase
ciam = commit --amend -m
psf = push -f origin HEAD
```
<font color="red">強制プッシュは確認不要な場合の短縮なので、自己責任でお願いします</font>

# 関数定義
どこか時間をつくってやってみたい
## 候補生
何気にメンドクサイ、コミット操作
結局手入力してしまって使われていないので、汎用化できれば定着させたい

```
rb1 = rebase -i HEAD~1
rb2 = rebase -i HEAD~2
rb3 = rebase -i HEAD~3
```

# 最後に
- 基本的に、originとのやりとりを想定しています
- 会社や学校など環境によって命名が決まっているところは適宜置き換えてください
- 類似したページが多いと思いますが、何か参考になれば幸いです

gitconfig転載用URLはこちらです。
https://github.com/satinoue/practice/blob/master/gitconfig

# 今後の課題
- 設定方法の補足（参照ページなど）
- 候補の再チャレンジ
Windows環境下のPythonのprintで豆腐文字が出る問題への対策

# はじめに

Windowsでbash + python の環境を作っていた時に、標準出力のprintで、日本語が豆腐に文字化けする現象が発生したので、その対応策に関するメモです。

この記事に書いてあること

- Windows上のPythonで標準入出力が文字化けする OR エラーを吐く 時の対処方法
- Windows上のPythonでファイル読み書きが文字化けする OR エラーを吐く 時の対処方法


# 環境

- OS: Windows10
- 環境
    - 裏: git-for-windowsのbash および Msys2のzsh
    - 表: Cmder
- python: anaconda python 3.7


# 何が問題か？

Python上で標準出力をしたとき、日本語が□（いわゆる豆腐）として表示されます。
よくある文字エンコーディング問題の一種で、matplotlibとかでよく見るやつです。

普段MacとLinuxしか使わないため、標準出力でこんな現象が発生すること自体知りませんでした。

# 対策

一昔前にデフォルトエンコーディングを設定したようなノリで、`sitecustomize.py`を以下のように書き加えておきます。

```python
import io, sys

# sys.stdin = io.TextIOWrapper(sys.stdin.buffer, encoding='utf-8')
sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding='utf-8')
sys.stderr = io.TextIOWrapper(sys.stderr.buffer, encoding='utf-8')
```

これは標準出力と標準エラー出力をutf-8で吐き出せという命令です。これでutf-8で標準出力されるようになります。

※ sys.stdinは標準入力用。標準入力でも同じような問題が起きるため、ついでに追加しておくことをお勧めします。

# 余談：openのwirteでも似た問題が

```python
fo = open('out.txt', 'w')
fo.write('正しく書き出せない')
```

ファイルオブジェクトにwriteしたときにも同様の問題が発生します。

標準出力の問題と同じように`sitecustomize.py`をいじるとなんとかなるかもしれないが、最近はファイルオブジェクトを開くときに文字エンコードを指定してやるのがスタンダードらしいので、私もそれに従うことにしました。

```python
fo = open('out.txt', 'w', encoding='utf-8')
fo.write('正しく書き出せる')
```
Apex Basic

先日 2019.07.17(水) 、弊社の大阪オフィスにてApex初級レベルの勉強会を開催しました。
:point_right: https://accenture-technology.connpass.com/event/137259/

コンセプトは、理解してから書くのではなく**「書いてから理解する」** ことです。理解するまでに時間を使うよりも、とにかく書いて眺めることからはじめましょう、という想いを込めています。教材コンテンツは GitHub に公開していまして、これからも育てていきたいと思っています。
:point_right::point_right: https://takahitomiyamoto.github.io/apex-basic/

より多くの人の目に留まるよう、Qiita でも紹介させていただきました。フィードバックございましたらどうぞよろしくお願いいたします。
PwC’s Cyber Security 2 days Workshop

<!--Event_page-->
## 概要
PwC’s Cyber Security 2 days Workshopは、現場で活躍する現役コンサルタントと一緒に、社会的重要課題であるサイバー攻撃やセキュリティの仕組みを学習するワークショップです。 

### Day 1
PwCがクライアントに提供している、サイバー攻撃を疑似体験する対戦型ゲーム「Game of Threats™」を用い、サイバーセキュリティの重要性、企業のリスク感覚を体感します。
2016年から、定期的に学生の皆さま向けに開催しており、「サイバーセキュリティの難しさ、奥深さ、楽しさが分かり、今後も学びたいと感じた。」「学生にとって情報を守ることを意識する機会が少ないので、とても貴重な経験であった。」「企業の限られた予算の中で見えない敵の攻撃を防ぐことの難しさを体感できた。」など非常に高い評判を頂いています。
[![動画を開くことができませんでした。](https://i.ytimg.com/vi/qAfwCEHLxko/mqdefault.jpg)](https://youtu.be/qAfwCEHLxko)

### Day 2
チームに分かれて、コンサルティングワークに取り組みます。
現役コンサルタントがチューターとして、コンサルタントの考え方や仕事の仕方を指導します。
取り組むテーマは、実際のコンサルティングの仕事内容をリアルに再現したものとなっています。
ワーク後、チューターから、1日を通じて良かった点や課題、改善するための助言など個別でフィードバックさせて頂きます。
また、チームメンバーや社員とフランクにお話頂ける懇親会も予定しています。


### こんな人にぜひ！
- 社会的に重要な課題の解決に取り組みたい人
- サイバーセキュリティに興味がある人
- テクノロジーに興味がある人
- サイバーセキュリティの仕事を体験してみたい人
- ご自身のテクニカルスキルを試してみたい人

## 実施詳細
- 開催日：
    - Day 1：2019年9月24日(火)～9月26日(木)16:00-20:30
    - Day 2：2019年9月28日(土)10:00～21:00
- 実施場所：PwCコンサルティング合同会社　丸の内パークビルディング21F
- 服装：自由
- 交通費：遠方から新幹線もしくは飛行機で参加される方には、弊社規定に従い、交通費をお支払いいたします。（国内のみ）
- 定員：約50名(※1)
- 参加資格：2021年3月卒業/修了見込みかつ2021年4月/10月入社が可能な方
- 応募方法：当社採用ウェブサイトのマイページに登録後、イベントにエントリー
    - 当社採用ウェブサイトURL：http://bit.ly/2YylytK
- 応募締切：2019年8月23日(水)23:59
 
(※1)応募者多数の場合、抽選となります、予めご了承ください。
Javascriptの関数の引数でよく見る（{ id }）ってどういう意味？

VueやReactを書いていると、こんな感じの関数をよく見ます。

```javascript:sample.vue
methods: {
  userData({ id }) {
    // 処理
  }
}
```

Vuexのactionでも({ commit })という記述をよく見ますよね。

正直、初めて見たときは意味不明でした。引数に波括弧ってどういうこと？みたいな。

同じように思っている人も多い（はず）なので、以下でこの独特な記法について解説していきます。

## 上記の書き方はES6の分割代入の一種っぽい

分割代入とは、以下のようなものです。

```javascript
const data = {
  id: 1,
  name: 'taro'
}

const { id, name } = data;

console.log(id); // 1
console.log(name); // taro
```

dataオブジェクトはidとnameというプロパティを持っています。代入したい変数名とプロパティ名が一致している場合、上記のように書くことで1行にまとめることが可能です。

関数の引数に出てくる波括弧もよく似たもので、上の考え方を少し応用すれば理解できるかと思います。

```html:sample.vue
<template>
  <div>
    {{ displayUserData(userData) }} // taroと表示される
  </div>
</template>

<script>
export default {
  data() {
    return {
      userData: {
        id: 1,
        name: 'taro'
      }
    }
  },

  methods: {
    displayUserData({ name }) {
      return name
    }
  }
}
</script>
```

displayUserDataメソッドの引数は({ name })となっています。これは、引数として渡されたオブジェクトのプロパティにnameがあれば、それを利用するという意味です。

このメソッドを使う場合、上記のようにuserDataオフジェクトをそのまま放り込みます。userDataはnameプロパティを持っているので、この場合は'taro'が表示されます。

これは以下の書き方と同義です。

```html:sample.vue
<template>
  <div>
    {{ displayUserData(userData.name) }} // taroと表示される
  </div>
</template>

<script>
export default {
  data() {
    return {
      userData: {
        id: 1,
        name: 'taro'
      }
    }
  },

  methods: {
    displayUserData(name) {
      return name
    }
  }
}
</script>
```

displayUserDataの引数から波括弧がなくなり、加えて呼び出し時にuserData.nameと、プロパティを指定しています。

## ということは、({ commit })はどういう意味？

Vuexのactionsを定義する際、下記のような書き方をすることが多いかと思います。

```javascript:sample.js
actions = {
  somethingAction({ commit }) {
    commit('somethingMutation')
  }
}
```

実は、上記についてはこのように書くこともできます。

```javascript:sample.js
actions = {
  somethingAction(context) {
    context.commit('somethingMutation')
  }
}
```

Vuexのactionsはdispatchされると、contextオブジェクトを受け取ります。そしてcontextオブジェクトは、以下のようなプロパティを持っています。

```
{
  state,
  rootState,
  commit,
  dispatch,
  getters,
  rootGetters
}
```

ただ、commitしか使わないケースが大半なので、({ commit })と書くことで簡略化することが多いかと思います。


上記の通り、contextオブジェクトはdispatchプロパティも持っているので、以下のような感じにすればactionから別のactionを呼び出すことも可能です。

```javascript

actions = {
  somethingActions({ commit, dispatch }) {
    commit('somethingMutation')
    dispatch('otherAction')
  }
}
```

公式ドキュメントにより詳しく書かれているので、もっと詳しく知りたい人はそちらを見てください。。

[vuex公式ドキュメント](https://vuex.vuejs.org/ja/api/#mutations)

## まとめ

jsフレームワークのconfigファイルとかでもよく出てくる記法なので、理解しておくと便利です。

これらについては、「呼びされるときに呼び出し元からオブジェクトを渡される」ということを知っておくと、より理解しやすいかなと思います。
PHP5.2（Windows Server2016）からPHP7.0（CentOS7）に移行したときのメモ

できるだけ現行の資産を生かして、CentOSサーバでPHPのシステムを動作させたい

【現行環境】
Windows Server2016
IIS10
PHP5.2
MySQL 5.0
【移行先環境】
CentOS7
Apache
PHP7.0
MariaDB10

【作業】
・PHP7.0 インストール
・apache インストール
・mariaDB インストール・データ移行
・下記で必要なPEARパッケージインストール
Archive_Tar      1.3.2 
Auth             1.6.1 
Console_Getopt   1.2.3 
Crypt_Blowfish   1.0.1 
Crypt_RC4        1.0.2 
DB               1.7.13
HTML_Common      1.2.4 
HTML_QuickForm   3.2.10
HTTP             1.4.1 
HTTP_Download    1.1.3 
HTTP_Header      1.2.0 
Log              1.11.3
MIME_Type        1.2.0 
Mail             1.1.14
Mail_Mime        1.5.2 
Mail_mimeDecode  1.5.0 
Net_GeoIP        1.0.0 
Net_SMTP         1.3.2 
Net_Socket       1.0.9 
PEAR             1.7.1 
Pager            2.4.6 
Structures_Graph 1.0.2 
XML_Util         1.2.1 


・mysqliインストール


【ファイル修正】
・シンタックスエラー　&を削除。
Parse error: syntax error, unexpected 'new' (T_NEW) in 
/usr/share/pear/Auth/Auth3.php on line 469

https://accelboon.com/tn/wirdpressphp7-1%E3%81%A7%E3%82%A8%E3%83%A9%E3%83%BC%E3%81%8C%E7%99%BA%E7%94%9F%E3%80%8Cexec-php%E3%80%8D%E3%82%92%E4%BF%AE%E6%AD%A3/


・元のPHPがShuift-jisで作られているため、php.ini shift-jisに変更
default_charaset
mbstring.internal_encoding


・htmlspecialchars の文字コードエラー
PHP5.4のhtmlspecialcharsに非互換問題
（全ファイルutf8で動作するように変更したほうがいいかも）
対応策：htmlspecialchars($s, ENT_QUOTES, 'UTF-8');

・Fatal error:uncaught Error
DBのテーブルが通らなかった。大文字でも小文字でも動作するよう対応
mariaDB設定変更
http://osprey-jp.hatenablog.com/entry/2017/06/02/092419
基本的なGitのコマンド

Gitで使用する基本的なコマンドを簡潔にまとめてみました。


# コマンド集
```
$ git init
```
リポジトリを作成します。
Gitを使用するための準備として実行されます。

```
$ git clone
```
ディレクトリを共有します。


```
$ git add ファイル名
```
ファイル選択します。

```
$ git command -m “メッセージ”
```
選択したファイルを記録します。
メッセージにはどんな変更を行ったかを具体的に書きましょう。

```
$ git remote add リモート名(origin) URL
```
リモートを登録します。
リモート名は何でもいいですが、一般的に"origin"というのがよく使用されます。

```
$ git push リモート名(origin) master
```
登録したリモートにファイルをアップロードします。

```
$ git pull リモート名(origin) master
```
リモートからファイルをダウンロードします。

```
$ git status
```
変更したファイルのファイル名を表示します。
変更したファイルは赤色、addしたものは緑色で表示されるため、一目でaddしたかどうか確認できます。

```
$ git diff
```
変更内容を表示します。
変更前を赤色、変更後を緑色で表示するので、どこがどう変わったのかが分かりやすいです。
変更内容に問題がなければaddしましょう。

```
$ git log
```
自分や他人のコミットメッセージを表示します。

```
$ git log -p
```
誰がどこを変更したのかを確認できます。
また、上下キーで自由に移動ができ、Qキーで終了します。


# まとめ
以上です。
コマンドはまだまだあるので、学習したら随時追加していきたいと思います。
bitnamiのRedmineでファイルアップロードするとInternal Server Errorが発生


## 前提状況
AWS EC2で個別に立てていたRedmineサーバーをLightsailへ移行した。
移行した時のファイルは表示されていたが、Wikiでファイルアップロードした時にInternal Server Errorが発生。

## 環境情報
- AWS LightsailのBitnami製Redmine
- Redmine 4.0.3.stable
- Ruby 2.5.5-p157
- Rails 5.2.2.1

## エラー関連

### エラーログの場所
`/home/bitnami/apps/redmine/htdocs/log/production.log`


### エラー内容
```
Saving attachment '/opt/bitnami/apps/redmine/htdocs/files/2019/07/1907300123225_dada222e5919600905458212341.pptx' (116098 bytes)
Completed 500 Internal Server Error in 11ms (ActiveRecord: 4.0ms)

Errno::EACCES (Permission denied @ rb_sysopen - /opt/bitnami/apps/redmine/htdocs/files/2019/07/1907300123225_dada222e5919600905458212341.pptx):

app/models/attachment.rb:120:in `initialize'
app/models/attachment.rb:120:in `open'
app/models/attachment.rb:120:in `files_to_final_location'
app/controllers/attachments_controller.rb:105:in `upload'
lib/redmine/sudo_mode.rb:63:in `sudo_mode'
```
Internal Server Errorの原因は*権限がない*のが原因と判明。
では適切な権限とは・・・？？

### 検証方法
確認方法としては移行したfilesディレクトリを一旦別名で退避させて、画面上でファイルをアップロードすると新規でfilesディレクトリが作成される。その時に作成されたディレクトリと同じ権限/ユーザー/グループを適切に設定してあげれば問題なし。という判断ができる。

今回の場合は権限ではなくディレクトリのユーザーとグループが違うことが原因である。

## 対応
Redmineのfilesを移行した時にredmineディレクトリと同様の`ユーザー：bitnami``グループ: bitnami`で作成されている。しかし、ファイルアップロードするユーザーorグループは`daemon`であるため変更する必要がある。必要であれば775(drwxrwxr-x)権限に変更する。

```bash
sudo chown -R daemon:daemon /opt/bitnami/apps/redmine/htdocs/files
sudo chmod -R 775 /opt/bitnami/apps/redmine/htdocs/files
```

これでファイルアップロードができる！！！
pthread_cond_timedwaitとpthread_cond_timedwait_relative_npに惑わされた話

# 前置き
- 内製ツールでpthread_cond_timedwaitを使って数秒waitさせたい処理が、実はwaitできてなかった

# どういうこと？
- プリプロセッサシンボルの定義状態から、 `pthread_cond_timedwait` と `pthread_cond_timedwait_relative_np` とを使い分ける処理が存在
- 使い方のノリがほぼ一緒であった
- Androidの64bit対応する折に、 `error: '::pthread_cond_timedwait_relative_np' has not been declared` となり、releative_npの方を使わないようにする対応が必要となった
- そのまま処理を流用したら、なぜか全くwaitしてくれなくなった

こんなイメージ

```C++:XXXThread.cpp
#if XXX //今まではこっちが通るようにシンボル定義してあった
	struct timespec ts;
	long sec = timeoutInUsec / 1000000;
	long mod_sec = timeoutInUsec % 1000000;
	ts.tv_sec = sec;
	ts.tv_nsec = mod_sec * 1000;
	int result = ::pthread_cond_timedwait_relative_np(&m_signal, &m_mutex, &ts);
#else  //★今回の対応で通るようになったスコープはコチラ
	struct timespec ts;
	long sec = timeoutInUsec / 1000000;
	long mod_sec = timeoutInUsec % 1000000;
	time_t now = 0;
	ts.tv_sec = sec + time(&now);
	ts.tv_nsec = mod_sec * 1000;
	int result = ::pthread_cond_timedwait(&m_signal, &m_mutex, &ts);
#endif
```

# なんでか？
`pthread_cond_timedwait_relative_np` は名前の通り、相対時間を入力にwaitしてくれる。
対して `pthread_cond_timedwait` は絶対日時を入力にwaitしてくれる。
つまり、上記のイメージの処理だと、 nsecの指定を `ts.tv_nsec = mod_sec * 1000;` としているが、これは相対時間なので、ほぼほぼ実時間未満の数値が入り、想定している時間でwaitできてなかった。

# つまりこんな感じで修正すれば最終的にOKだった
- clock_gettimeでnsecの精度で現在時刻を取得するようにした
- 現時刻をベースにwaitしたい時間を加算してあげるようにした
- 桁あふれを考慮した

```C++:XXXThread.cpp
#if XXX //今まではこっちが通るようにシンボル定義してあった
	struct timespec ts;
	long sec = timeoutInUsec / 1000000;
	long mod_sec = timeoutInUsec % 1000000;
	ts.tv_sec = sec;
	ts.tv_nsec = mod_sec * 1000;
	int result = ::pthread_cond_timedwait_relative_np(&m_signal, &m_mutex, &ts);
#else  //★今回の対応で通るようになったスコープはコチラ
	struct timespec ts;
	long sec = timeoutInUsec / 1000000;
	long mod_sec = timeoutInUsec % 1000000;
	clock_gettime(CLOCK_REALTIME, &ts);
	ts.tv_sec += sec;
	ts.tv_nsec+= mod_sec * 1000;
	if (1000000000 <= ts.tv_nsec)
	{
		ts.tv_nsec -= 1000000000;
		ts.tv_sec  += 1;
	}
	result = ::pthread_cond_timedwait(&m_signal, &m_mutex, &ts);
#endif
```

# 参考
- [PTHREAD_COND](https://linuxjm.osdn.jp/html/glibc-linuxthreads/man3/pthread_cond_wait.3.html)
- [CLOCK_GETRES](https://linuxjm.osdn.jp/html/LDP_man-pages/man2/clock_getres.2.html)
- [時間情報の取得方法と扱い方](https://www.mm2d.net/main/prog/c/time-05.html)
Lambdaでsoxを使用して音声を左右のチャンネルに分割する

**※ 2019年末にNodejs:8.10が非推奨になるので、Nodejs:8.10にてLambdaの作成・更新が出来なくなった場合、以下の手順は実現できなくなります。**

AmazonConnectの録音ファイルが顧客とエージェントで左右のチャンネルに分割されている為、それを分割しようとした時のメモです。

> Q: エージェントと顧客の音声は別々のステレオ音声チャネルに保存されるのですか?
>
> はい。エージェントの音声は右チャネルに保存されます。エンドカスタマーやカンファレンスに参加した人など、すべての着信音声は左チャネルに保存されます。
> [AWSより引用](https://aws.amazon.com/jp/connect/faqs/)

## ハマった事

lambdaのランタイムを`nodejs10.x`で検証していたのですが、soxが動作しませんでした。

## 解決策

lambdaでsoxを動作させたい場合は、`nodejs8.10`をランタイムに設定しましょう。

## 分割していく

**AmazonConnectからS3に通話ろファイル(.wav)が格納された際にLambdaが実行される前提となっています。**

soxを使うために`lambda-audio`をインストール。

```
npm i lambda-audio
```

typescriptで書いてます。

```typescript

import {Handler} from 'aws-lambda';
import {S3} from "aws-sdk";

class S3Service {
    constructor(private s3: S3) {
    }

    async get(bucketName, key) {
        const params = {
            Bucket: bucketName,
            Key: key
        };
        return await this.s3.getObject(params).promise();
    }

    async put(bucketName, key, body) {
        const params = {
            Bucket: bucketName,
            Key: key,
            Body: body,
        };
        return await this.s3.putObject(params).promise();
    }
}

export const handler: Handler = async (event: any) => {
    const s3 = new S3Service(new S3());

    const fs = require('fs');
    const lambdaAudio = require('lambda-audio');

    const nowTime = (new Date()).getTime();
    const wavPath = '/tmp/' + nowTime + '.wav';

    // S3に格納された.wavの情報を取得する
    for (let record of event.Records) {
        const key = record.s3.object.key;
        const bucketName = record.s3.bucket.name;
        const object = await s3.get(bucketName, decodeURIComponent(key));

        await fs.writeFile(wavPath, object.Body, 'binary', err => {
            if (err) {
                console.error(err);
                return;
            }
        });
    }

    // ここで左のチャンネルを抽出している
    const leftOutput = `/tmp/${nowTime}_output_l.wav`;
    await lambdaAudio.sox([wavPath, leftOutput, 'remix', '1'])
        .then(response => {
            console.log(`soxLeft: ${response}`);
        })
        .catch(errorResponse => {
            console.log('Error from the sox command:', errorResponse)
        });

    // ここで右のチャンネルを抽出している
    const rightOutput = `/tmp/${nowTime}_output_r.wav`;
    await lambdaAudio.sox([wavPath, rightOutput, 'remix', '2'])
        .then(response => {
            console.log(`soxRight: ${response}`);
        })
        .catch(errorResponse => {
            console.log('Error from the sox command:', errorResponse)
        });

    // S3へ格納(※1)
    await s3.put('BUCKET_NAME', `${nowTime}/l.wav`, fs.readFileSync(leftOutput));
    await s3.put('BUCKET_NAME', `${nowTime}/r.wav`, fs.readFileSync(rightOutput));

    return {}
};
```

※1 `'BUCKET_NAME'`に保存先となるS3を指定

## まとめ

顧客、エージェントの音声を分割することにより、文字起こし等に使用する際に便利になると思います。
ファイルサイズが2倍になるため、利用料金は2倍になりますが、、、
ローカル実行用の docker-compose.yml はバージョン 2 系で

# バージョン 3 は Docker Swarm 用

バージョン 3 以降削除されている機能がありますので、ローカルのテスト環境構築などに使う場合はバージョン 2 系を使う方が便利なのでした。

詳しい話は反響次第で。
Amazon Workspace(Linux)から、RemminaでWindowsにリモートデスクトップ接続（RDP）

AWSのWorkspaces（Linux）から、WindowsにRDP接続したいと相談した所、Remminaがイケテルという事だったので、試して見ました。

以下、Remminaのインストール手順です（yum repoよく分かってないので、冗長かも知れませんが、覚書的にメモメモ）

## 環境

- AWS Workspaces(Amazon Linux2)
- Remmina(+RDPプラグイン）

接続先は、EC2(Windows Server 2016)で試しました。

## インストール

まず、EPELを入れます。

```bash
wget https://dl.fedoraproject.org/pub/epel/7/x86_64/Packages/e/epel-release-7-11.noarch.rpm
sudo rpm -ivh epel-release-7-11.noarch.rpm 
```

NUX REPOをインストールします。

```bash
sudo rpm --import http://li.nux.ro/download/nux/RPM-GPG-KEY-nux.ro
sudo yum -y install epel-release
sudo rpm -Uvh http://li.nux.ro/download/nux/dextop/el7/x86_64/nux-dextop-release-0-5.el7.nux.noarch.rpm
```

EPELとNUXがリポとして追加されている事を確認します。

```bash
$ yum repolist
..
..
..
epel/x86_64                           Extra Packages for Enterprise L 13,040+288
nux-dextop/x86_64                     Nux.Ro RPMs for general desktop   2,658+44
```

で、remmina（とRDPプラグイン）を、yumでインストール。

```bash
sudo yum --enablerepo=nux-dextop install remmina remmina-plugins-rdp
```

## 使い方

メニューのどこかに「Remmina Remote Desktop Client」があるので、それで起動。

接続名、接続先情報（SERVER, USER, PASSWORD）を入れて、接続出来ればOK。

## 参考URL

- EPELの設定方法
  - https://qiita.com/azushink/items/752d80c77484b7699521
- NUX REPOの設定方法
  - https://www.tecmint.com/enable-nux-dexktop-repository-on-rhel-centos/
- remminaのインストール手順の説明
  - https://remmina.org/how-to-install-remmina/#fedora-and-red-hat
PDS・情報銀行・データ取引市場の概要とこれからについて

#PDS・情報銀行・データ取引市場の定義
![n1201010.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/472815/95cdfb14-5628-998f-0d28-71a1eeeb04b9.png)
（出典）IT総合戦略本部 データ流通環境整備検討会「AI、IoT時代におけるデータ活用ワーキンググループ 中間とりまとめ」（2017）

##PDS（Personal Data Store）
個人が自らデータを蓄積・管理し、他者と ⾃由に共有して活⽤する仕組みです。その運用形態には分散型と集中型があります。
![Information_bank_2017_001_R.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/472815/6d0e8a36-6197-4353-4ffd-338b31efaddc.jpeg)
（出典）IT総合戦略本部 データ流通環境整備検討会「AI、IoT時代におけるデータ活用ワーキンググループ 中間とりまとめ」（2017）
##情報銀行
「PDS」等のシステムを活用してパーソナルデータを管理するとともに、個人の許可に基づき個人に代わって企業等の第三者に貸し出すもので、本人にはデータの提供・活用に関する便益が還元されます。
![Information_bank_2017_002_R.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/472815/7cf8dd72-38c1-7f18-2c9a-03d3834ba68b.jpeg)
（出典）IT総合戦略本部 データ流通環境整備検討会「AI、IoT時代におけるデータ活用ワーキンググループ 中間とりまとめ」（2017）

##データ取引市場
［データ提供者］と［データ提供先］の間には、直接取引（相対取引）および、データ取引市場運営事業者を介しての市場取引が存在します。
![aaa.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/472815/954e2b16-7318-ad58-bbec-6fdd3912c210.png)

以上がPDS・情報銀行・データ取引市場の概要です。
もっと詳しく知りたいって方はググってください！

#主な関連事業者一覧
##情報銀行（PDS含む）
| 企業名|サービス名|
|:-----------------:|:------------------:|
| 三井住友信託銀行  |『データ信託』サービス（仮） |
|フェリカポケットマーケティング|地域振興プラットフォーム（仮）|
|三菱UFJ信託銀行|DPRIME（仮）|
|マイデータ・インテリジェンス|MEY|
|DataSign|paspit|
|日立製作所/東京海上日動火災保険/　日本郵便など|-|
|大日本印刷/中部電力・JTB|-|

##データ取引市場
| 企業名|サービス名|
|:-----------------:|:------------------:|
|EverySense|EverySense Pro/EveryPost|
|株式会社日本データ取引所|-|
|株式会社アイディオット|DP2|

##その他
| 企業名|サービス名|
|:-----------------:|:------------------:|
|KPMGコンサルティング株式会社|情報銀行設立支援サービス|

#PDS・情報銀行・データ取引市場の課題
これに関しては、NRI（野村総合研究所）のレポートが良くまとまっているので、
そちらをご紹介します。こちらは「情報銀行の課題」という名目で挙げられております。

- 当面はデータの価値に見合った対価の設定がカギを握る。  
個人情報を預かるだけに、情報銀行の運営主体には、高度なデータ管理体制が求められる。
- いかに多くのデータ（from 消費者）とスポンサー企業を集められるか  
    - 消費者は、単なるディスカウントクーポンや「抽選で〇〇名様にプレゼント」程度では、  
      反応しない可能性  
    - 情報銀行と提携するスポンサー企業（広告主など）は、少数の消費者のデータには興味を示さない  
    - これまで、GAFAやアドネットワークなどから安価にデータを入手していた企業からすれば、  
      確度の高いデータであるとしても割高に感じる可能性が高いであるとしても割高に感じる可能性が高い
- 消費者からの同意の取得方法とユーザーフレンドリーなデータコントロール機能の実装
    - 確実な同意取得手段の検討とデータの提供範囲・提供先などに関するコントロール機能が必須
- 情報管理体制の強化
    - 消費者から収集するデータがセンシティブ（資産・健康情報など）になればなるほど、  
      事故時の被害は甚大  
    - そもそもパーソナルデータを安心して預けられる企業なのか  
  （出典）：情報銀行と信用スコアリングビジネスの展望　野村総合研究所

#色々調べてみた感想
日本でこういったデータ流通市場なるものが成熟するか否かは神のみぞ知る状態かなと思った。
日本人の特性として？（先進各国同じかもしれないが）相当な対価を提供してもらわない限り、自分に関するデータを外に出すというのは相当な忌避感があるんでないかと思う。
しかし、個人情報が漏れるのが怖いと言いながら、Facebookやtwitter等のSNSにガンガン自分の個人情報を晒すという、ダブルスタンダードな素敵な方々も多数いるので、もしかしたら流行る可能性も！？  
長々書いてきましたが、AI、IoT、ロボティクスの時代に入り、データの流通が上手いこと流れていくという試みは重要だと思うので、個人的には市場が盛り上がることを願っています。
皆さんも意見等あれば是非コメントお願い致します！！！
ExcelのLEFTB/MIDB/RIGHTBで半角スペースを殺すユーザ定義関数

# 概要
Excelの`LEFTB()`/`RIGHTB()`/`MIDB()`関数は切り出した文字の先頭/末尾が2バイト文字の途中だった場合、その文字が半角スペースになってしまいます。
この時に半角スペースを入れないで切り出す関数を`LEFTBS()`/`RIGHTBS()`/`MIDBS()`関数としてVBAで作成します。

# ソース
基本方針は、VBAで`MidB`関数を使って2バイト文字の途中を切り出した場合に戻り値が`0`になることを利用して、切り出し位置と切り出しバイト数を調整します。
全角2バイト、半角1バイトとして切り出せるように`strConv`でUNICODEからShiftJISに変換して判定する必要があることに注意。

## `LEFTBS(文字列[, バイト数])`
`LEFTBS`の場合は単純で、判定結果が`0`だったら切り出しバイト数を`-1`するだけです。

```vb
Public Function LEFTBS(strParamString As String, Optional lngParamByte As Long = 1) As String
    Dim lngByte
    lngByte = lngParamByte

    If lngParamByte >= LenB(StrConv(strParamString, vbFromUnicode)) Then
        LEFTBS = strParamString
    Else
        If MidB(StrConv(strParamString, vbFromUnicode), lngParamByte, 1) <> 0 Then
            lngByte = lngByte - 1
        End If

        LEFTBS = StrConv(LeftB(StrConv(strParamString, vbFromUnicode), lngByte), vbUnicode)
    End If
End Function
```

## `RIGHTBS(文字列[, バイト数])`
`RIGHTBS`の場合、`MidB`で判定する最初の1バイトが`全体のバイト数 - 切り出しバイト数`になります。

```vb
Public Function RIGHTBS(strParamString As String, Optional lngParamByte As Long = 1) As String
    Dim lngByte As Long
    lngByte = lngParamByte

    If lngParamByte >= LenB(StrConv(strParamString, vbFromUnicode)) Then
        RIGHTBS = strParamString
    Else
        If MidB(StrConv(strParamString, vbFromUnicode), LenB(StrConv(strParamString, vbFromUnicode)) - lngParamByte, 1) <> 0 Then
           lngByte = lngByte - 1
        End If
        RIGHTBS = StrConv(RightB(StrConv(strParamString, vbFromUnicode), lngByte), vbUnicode)
    End If
End Function
```

## `MIDBS(文字列, 開始位置, バイト数)`
`MIDBS`の場合、先頭1文字の判定結果が`0`だった場合開始位置を`+1`し、その分切り出しバイト数を`-1`します。
続いて末尾1文字を判定して、`0`だった場合は切り出しバイト数をさらに`-1`する、という流れです。

```vb
Public Function MIDBS(strParamString As String, lngParamStart As Long, lngParamByte As Long) As String
    Dim lngStart As Long
    lngStart = lngParamStart
    Dim lngByte As Long
    lngByte = lngParamByte
    
    If MidB(StrConv(strParamString, vbFromUnicode), lngParamStart, 1) = 0 Then
       lngStart = lngStart + 1
       lngByte = lngByte - 1
    End If

    If MidB(StrConv(strParamString, vbFromUnicode), lngParamStart + lngParamByte, 1) = 0 Then
       lngByte = lngByte - 1
    End If

    MIDBS = StrConv(MidB(StrConv(strParamString, vbFromUnicode), lngStart, lngByte), vbUnicode)
End Function
```
最新ではない特定のバージョンの Unity を UnityHub からインストールする

現在、2019.1 や 2017.4 など、ある程度メジャーなバージョンごとの
最新の Unity は UnityHub からインストールできます。

<img width="478" alt="unity archive 01.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/31480/99ee7696-7ee2-f34b-7080-ef55796fc6c6.png">

2019.1 でいうと 2019.1.11f1 など、最新ではないバージョンはこの一覧には表示されませんが、
あえて最新ではないバージョンをインストールしたいこともあるかもしれません。
例えば、最新のものでは過去に修正された問題が再発しているので直るまではその前のものを使いたい、とか。

また、Hub一覧には載っていない5.6など古めのものを使いたいというケースもあるかもしれません。

そういう時は [Download Archive](https://unity3d.com/jp/get-unity/download/archive) を活用します。
こちらのページでは、 Unity3.4以降のエディター、ビルトインシェーダーなどがダウンロードできます。また、5.6以降では UnityHub ボタンから Unity Hub を立ち上げ、 Hub 経由でインストールすることができます。

<img width="478" alt="unity archive 02.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/31480/4641771c-b840-7fcb-635d-838647bf4f76.png">

あとは通常のインストールと同じ手順でインストールできます。
ArgumentError: Missing required arguments: aws_access_key_id, aws_secret_access_key

awsのs3を導入して、capistranoを使っていた時エラーが出ました。
(unicorn,nginx使用)
どうやら、keyが見当たりませんと出たので、確認しに行った。

でも、環境変数はちゃんと登録されていたし、なぜだろうと思った。

原因は、unicornの設定fileのpathが間違っていた。
working_directoryあたり。
ちゃんと、pathがcurrentになっていますか？

pathがcapi使った時にcurrentになるので、ちゃんとcurrent指定をしてあげましょう。
また、working_directoryが二重になっていないかなども確認するといいかもです。
【JavaScript修行】シンボルって？イテレーターを自作する

本日はJavaScript本格入門の２70p〜から学習しています。
参考サイト：https://qiita.com/kura07/items/cf168a7ea20e8c2554c6
https://uhyohyo.net/javascript/16_4.html

##シンボル
ES6から導入された新しいプリミティブ型。
オブジェクトのプロパティのキーにできる。**文字列ではない！**

```javascript
const obj ={};
const sym = Synbol();
obj[sym] = "mow";
```
キーとして、シンボルのsymが使われています。

キーの特徴はこちらです。

```javascript
let sym1 = Symbol('sym');
let sym2 = Symbol('sym');
console.log(sym1 === sym2); //falseになる
```
同じsymにも関わらず、比較演算子では異なる結果になっています。
唯一絶対なんですね。
しかも暗黙の型変換が行われないので、文字列/数値になりません。(booleanは除く）

```javascript

console.log(sym1 + ''); //エラーになる
```

###symbolどう使う？
定数指定に便利です。
普通定数っていうと

```javascript
const MONDAY = 0;
const TUESDAY = 1;
```

って感じで書きますが、これにはいくつか問題があります。
・const FRIDAY = 0　などが追加されるとバグに
・数字比較を行うと可読性が悪い
・数値としての利用ができてしまう（識別したいだけなので本来必要ない）

そこで`Symbol`の出番です。

```javascript
const MONDAY = Symbol();
const TUESDAY = Symbol();
```
同じ名前でもシンボルはユニーク（唯一絶対無二）なので、これで識別可能です。

##プライベートメンバにもなる！

```javascript:App.js
const SECRET = Symbol();    //シンボル

export default class{
   constructior(secret){
      this[SECRET] = secret;   //symbolで作られたプロパティで初期化を行う。
   }

   checkValue(secret){
      return this[SECRET] === secret;   //プライベートメンバを扱うメソッド
   }
}
```

```javascript:private.js
import App from ./App.js

let app = new App('1234');
for(let key in app){
   console.log(key);    //secretは表示されない
}

console.log(JSON.stringify(app));  //JSON文字列にしても表示されない

console.log(app.checkValue('1234')); //true
```

ただし注意点がいくつかあります。

 - `Object.getOwnPropertySymbols`でアクセスできてしまう
 - モジュールの中ではSECRETからアクセスできてしまう。


##イテレーターって？
**イテレーター**・・・オブジェクトの内容を列挙するための仕組みを備えたオブジェクト！
組み込みオブジェクト系も`for..of`を使って列挙できますね。




```javascript
let ary = ['いぬ','さる','ねずみ'];
for(let item of ary){
    console.log(item);
}
```

そういった処理が実際内部でどうなっているか探るため、
自分で内部処理を書いてみます。

```JavaScript
let ary = ['いぬ','さる','ねずみ'];
let itr = ary[Symbol.iterator]();
let d;
while(d = itr.next()){
    if(d.done){break;}
    console.log(d.done);
    console.log(d.value);
}
```

みたこのないメソッドがいっぱいあります！
一個一個みていきます。

`Symbol.iterator`・・・Iteratorオブジェクトを返す。
`next（）`・・イテレーターがもつメソッド。配列の要素を取り出す。
`done`・・・イテレータが終端に達したかをブーリアンで返す。
`value`・・・次の要素の値を返す。

上のコードでは、`d.done`がfalseになるまで（終端に達するまで)
`itr.next()`で要素をとり続けています。

`for..of`はこのような内部処理でvalueを取り出すシンタックスシュガーとも言えます。

##イテレーターを自作してみよう！
`for..of`文は[Symbol.iterator]メソッド経由でイテレータを取り出していたので、それと同じようにメソッドを実装すればOKです。

```javascript:自作イテレータ
class Iterator{
    constructor(str){
       this.str = str;
    }
 
    [Symbol.iterator](){
       let current = 0;
       let that = this;
       return{
          next(){
             return current < that.str.length ?
                {value: that.str[current++],done:false} :
                {done:true};
          }
       };
    }
 }
 
 let itr = new Iterator(['ごま','さば','食べたい']);
 for(let item of itr){
    console.log(item);
 }
```

`[Symbol.iterator]()`の内部処理でvalueとdoneが含まれたオブジェクトを返しています。
`for..of`で１つ前のコードのような処理が走って、見事オブジェクトの内容を列挙するイテレーターが
作れました！

今回ちょっと難しかった...
ARCoreで平面に実寸大ポスター(PNG)を貼る

ハッカソンでARCoreを用いて画像データを平面に貼る機会があったので備忘録として残しておきます。
使用したサンプルプログラム：https://ktaka.github.io/codelab/sceneform-ar-ja/#0
上記のサンプルプログラムをベースに行う

# 貼りたい画像（PNG）をBlenderでOBJ形式変換する
https://qiita.com/nutti/items/5e9ebe9c28751066b688
上記を参考にImport Images as Planeを入れる
File -> Import -> Images as PlanesをクリックしてPNGからPlaneを生成する
<img width="475" alt="スクリーンショット 2019-07-30 15.25.34.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/472958/343f8b22-0e4e-dd61-2255-e01e3cbf312b.png">

Location,Rotationを調整する（全て０）
<img width="169" alt="スクリーンショット 2019-07-30 15.26.14.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/472958/ba3c6d6e-6342-6aca-2d95-6a3dcb860a65.png">

Export -> Wavefront(.obj)で書き出す
<img width="487" alt="スクリーンショット 2019-07-30 15.26.47.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/472958/449b74e1-846c-31b8-7efa-463f346cd917.png">

# OBJ形式をプロジェクトに取り込む
blenderで生成した.objファイルと.mtlファイルが生成されるのでそれをAndroid Studioのプロジェクトに入れる。

Android Studio > Preferences > PluginsでGoogle Sceneform Tools (Beta)を入れる
<img width="967" alt="スクリーンショット 2019-07-30 15.32.50.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/472958/98992607-f328-6658-0329-d4999d935e7f.png">

対象の.objを右クリックするとImportSceneform Assetが表示されるのでクリックしてFinishを押す
<img width="479" alt="スクリーンショット 2019-07-30 15.29.47.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/472958/f4f284d7-49d3-e276-2ffe-37bcac13f9fd.png">

sfbファイルが出力されるのでsamplers.params.usage_typeを"Color"に変更
model.scaleを好きな値（実際試してみて調整）にする
<img width="363" alt="スクリーンショット 2019-07-30 15.36.44.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/472958/f46b9b9f-cf64-a0c5-9c22-1ae1114bcff0.png">
あとはベースとなっているサンプルと同様にMainActivityを書き換えて表示する

* 微妙に本来透明な部分が半透明になってしまうので原因がわかる人がいましたら教えてください！
Xcode11のエディタ横に表示されるミニマップを非表示にする方法

現在SwiftUIのチュートリアル中なのですが、
最近全然Xcode11に触っていなかったので、ちょくちょく触り始めましたが、わからないことだらけなので、備忘録兼ねて書きます。
#環境
Xcode11-beta3
MacOS 10.14.5

#Xcode11のエディタ横に新しいミニマップが表示されている
sublimeTextなどのエディタにもありますが、僕はどうもこれいらないんですよね。
なので非表示にしたい。

#ミニマップを非表示にする方法
簡単です。
エディタの右上の+ボタンの隣にあるボタンををタップして、**Hide Minimap**をタップで非表示にできます。
![xcode_image1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/184792/a1c8815f-2348-444f-4b6d-29b48794f62d.png)


これでミニマップが非表示になりました。

<img width="1179" alt="スクリーンショット 2019-07-30 14.51.54.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/184792/385e09ac-4451-adf2-dfef-a72147541dbd.png">

また細々とした備忘録載せます。

お読みいただきありがとうございました。
SQL Server パーティション構成したDBで断片化の状態によってインデックスを再構成または再構築する方法（再構築はオンラインで実施）

#既存の断片化対応から改善
SQL ServerをEnterprise Editionに変えたのでオンラインオプションをつけた。
パーティション構成にすると指定オプションが増える。

#作業
* 「メンタナンス プラン」でスケジュール構成
  * T-SQLステートメントの実行タスク

```sql
USE target-db
EXEC up_UpdateIndex
```

  * up_UpdateIndex

```sql
ALTER PROCEDURE [dbo].[up_UpdateIndex]
AS
BEGIN
	SET NOCOUNT ON;

	DECLARE @cnt int, @i int, @sql nvarchar(2000), @isOnline tinyint, @tar varchar(2000)
	DECLARE @SchemaName nvarchar(128), @ObjectName nvarchar(128), @IndexName nvarchar(128)
		, @avg_fragmentation_in_percent float

	--パーティション構成テーブルはパーティション番号を指定するため
	SET @tar = '[table_1],[table_2],[table_3],......'

	DECLARE @tbl table(
		ID int identity(1,1)
		, SchemaName nvarchar(128)
		, ObjectName nvarchar(128)
		, IndexName nvarchar(128)
		, avg_fragmentation_in_percent float
	);

	INSERT INTO @tbl(SchemaName, ObjectName, IndexName, avg_fragmentation_in_percent)
	SELECT QUOTENAME(S.name) AS SchemaName, QUOTENAME(O.name) AS ObjectName,
		QUOTENAME(I.name) AS IndexName, PS.avg_fragmentation_in_percent
	FROM sys.dm_db_index_physical_stats (DB_ID(), NULL, NULL , NULL, 'LIMITED') AS PS
		INNER JOIN sys.objects AS O ON PS.object_id = O.object_id
		INNER JOIN sys.schemas AS S ON O.schema_id = S.schema_id
		INNER JOIN sys.indexes AS I ON PS.object_id = I.object_id AND PS.index_id =  I.index_id
	WHERE avg_fragmentation_in_percent >= 1.0 AND PS.index_id > 0;

	SELECT @cnt = Count(*) FROM @tbl;

	SET @i = 1;

	WHILE @i <= @cnt
	BEGIN
		SET @isOnline = 0

		SELECT @SchemaName = SchemaName, @ObjectName = ObjectName
			, @IndexName = IndexName, @avg_fragmentation_in_percent =  avg_fragmentation_in_percent
		FROM @tbl
		WHERE ID = @i;

		IF @avg_fragmentation_in_percent < 30.0
		BEGIN
			SET @sql = N'ALTER INDEX ' + @IndexName + N' ON ' + @SchemaName + N'.' +  @ObjectName + N' REORGANIZE';
		END
		ELSE
		BEGIN
			--断片化が30%以上だと再構築をオンラインで実施
			SET @sql = N'ALTER INDEX ' + @IndexName + N' ON ' + @SchemaName + N'.' +  @ObjectName + N' REBUILD';

			set @isOnline = 1
		END

		--この部分はパーティション構成ではなければ無視
		IF (SELECT CHARINDEX(@ObjectName, @tar)) > 0
		BEGIN
			SET @Sql += N' PARTITION = 1'
		END

		IF @isOnline = 1
		BEGIN
			SET @Sql += N' WITH(ONLINE = ON)'
		END

		EXEC (@Sql);
		SET @i = @i + 1;
	END
END
```


#参考
https://sql55.com/query/reorganize-rebuild-index.php
Hyperledger Iroha v1.0 環境構築

# 概要
AWS EC2 (Amazon Linux AMI) にHyperledger Irohaの環境構築を行う

# 環境
- AWS EC2 (Amazon Linux AMI)
- Git

# Docs
Hyperledger Irohaドキュメンテーション
https://iroha.readthedocs.io/ja/latest/index.html

# 環境構築手順

### Docker インストール & 起動

```console
# インストール
$ sudo yum install -y docker

# 起動
$ sudo service docker start

# dockerグループにec2-userを追加
$ sudo usermod -a -G docker ec2-user
$ cat /etc/group | grep docker

# 一度リモートからログアウトして、再度ログイン
$ exit

# dockerが追加されていることを確認
$ docker info | grep docker
```

### Docker Compose インストール

```console
# docker-compose インストール
$ sudo curl -L "https://github.com/docker/compose/releases/download/1.23.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose

# 権限設定
$ sudo chmod +x /usr/local/bin/docker-compose
```

### Docker 操作

```console
# Docker ネットワークを作成
$ docker network create iroha-network

# PostgreSQLのコンテナを起動
$ docker run --name some-postgres \
-e POSTGRES_USER=postgres \
-e POSTGRES_PASSWORD=mysecretpassword \
-p 500:500 \
--network=iroha-network \
-d postgres:9.5

# Blockstoreを作成
$ docker volume create blockstore

# 設定ファイルの準備
$ git clone -b develop https://github.com/hyperledger/iroha --depth=1

# Irohaコンテナを起動 & ログイン
$ docker run -it --name iroha \
-p 50051:50051 \
-v $(pwd)/iroha/example:/opt/iroha_data \
-v blockstore:/tmp/block_store \
--network=iroha-network \
--entrypoint=/bin/bash \
hyperledger/iroha:develop
```

### Iroha 起動（コンテナ内で操作）

```console
# Irohaデーモン（バックグラウンドで動作するプロセス）起動
$ irohad --config config.docker --genesis_block genesis.block --keypair_name node0
```

これでIrohaが起動されます。
Typescript + Webpackのビルドで、TypeScript emitted no output for

Webpack＋TypeScrptでビルドしたら、以下のエラーが出ました。

```
ERROR in ./src/javascript/types/index.d.ts
Module build failed (from ./node_modules/ts-loader/index.js):
Error: TypeScript emitted no output for /var/www/src/javascript/types/file-loader.d.ts.
    at makeSourceMapAndFinish (/var/www/node_modules/ts-loader/dist/index.js:78:15)
    at successLoader (/var/www/node_modules/ts-loader/dist/index.js:68:9)
    at Object.loader (/var/www/node_modules/ts-loader/dist/index.js:22:12)
 @ multi ./src/javascript/config/Routes.tsx ./src/javascript/containers/components/Footer.tsx ./src/javascript/containers/components/forms/TextInput.tsx ./src/javascript/containers/components/Header.tsx ./src/javascript/containers/pages/SignIn.tsx ./src/javascript/index.tsx ./src/javascript/modules/i18n.ts ./src/javascript/types/index.d.ts app[7]
```

### 結論
webpackのentryに`declare`ファイル(*.d.ts)が含まれていた為。


### 状況
どんな感じだったかというと、`declare`ファイルを`/src/javascript/types/index.d.ts`に配置していて、Webpackのビルド対象になっていました。

#### wepack.config.js
```javascript
const utils = require('./utils')

module.exports = {
  entry: utils.entryPaths(),
  output: {
    path: `./dist`,
    filename: '[name].js'
  },
```

#### utils.js
```javascript
exports.entryPaths = () => {
  const jses = getFiles(`src/javascript/**/*.{ts,tsx}`)
  return { 'app': jses }
}

const getFiles = (path, options={}) => {
    return glob.sync(path, options).map((file) => {
        return file
    })
}
```

### 修正後
`/src/javascript/types/index.d.ts` -> `/src/types/index.d.ts`に移動して、tsconfig.jsonを以下のように修正しました。
（webpackのentryから外すけど、tsconfigの対象にする感じ。）

#### tsconfig.json
```json
{
  "compilerOptions": {
    〜〜〜 省略 〜〜〜
    "typeRoots": ["src/types", "node_modules/@types"]
  },
  "include": [
    "src/**/*",
  ]
}
```
【Mac】VSCodeでエディターのタブが消えてしまった時の対応

## 突然エディターのタブが非表示に

VSCodeを用いて開発中に、以下のようにタブになっていて開発できていたものが

![スクリーンショット 2019-07-30 15.24.50.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/33557/939fb678-9f7c-8388-b8fa-9040a7018a67.png)

突然、以下のようにタブが無くなってしまった。

![スクリーンショット 2019-07-30 15.25.16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/33557/e1e673a8-54b3-b70f-ee70-b4865b1c95f2.png)

ファイルを変更したのかどうかが一目でわからなくなって困った。

## 対応

`⌘ + Ctrl` + `w` で切り替えられました。

どこかでうっかり押してしまったんだろうなぁ。

## バージョン

VSCode: 1.36.1