OmniAICreator/Qiita-1.07M huggingface dataset:
bookmarks（20180201-20180225）

# Javascript/jQuery

■【JavaScript】日付処理
https://qiita.com/kazu56/items/cca24cfdca4553269cab#

■JavaScriptで月日を２桁表示にするスマートな方法
http://digitra.hatenablog.com/entry/2016/02/15/213313

■jQuery：画像や要素をランダム出力する方法の備忘録
https://www.nxworld.net/tips/jquery-random-snippets.html

■縦スクロールができるスライダー「jquery.bxslider.js」
ダウンロード…https://bxslider.com/
使い方
・jquery.bxslider.jsを使ったサンプルいろいろ（http://cly7796.net/wp/javascript/examples-that-use-the-jquery-bxslider/）
・jquery.bxslider.jsの使い方やオプションなどのまとめ（http://cly7796.net/wp/javascript/plugin-jquery-bxslider/）

# CSS

■アイコン読み込みがJavaScript+SVG描画に変わった「Font Awesome 5」に変更してみた
https://creatorclip.info/2018/02/fontawesome-5-change/

■CSSで変数（カスタムプロパティ）を使ってみよう
https://www.webcreatorbox.com/tech/css-variables
※IE・Android非対応

# UXデザイン

■ゴーストボタンを使う際の注意点と使いどき
http://uxmilk.jp/70907

■レスポンシブデザインとアダプティブデザイン、それぞれの長所と短所
http://uxmilk.jp/68884

# 仕事の進め方

■小規模な組織でのデザイナー教育で工夫してること
https://note.mu/kazuma_nishiwaki/n/n9b17cc301d06

■デザインのバージョン管理をGitHubでしてみたら修正点が3秒で分かるようになった話
https://moneyforward.com/engineers_blog/2018/01/23/designers-github/

# その他

■テレビ視聴率ならぬ「視聴質」を計測するTVISIONが1.5億円を融資により資金調達
http://jp.techcrunch.com/2018/02/19/tvision-raised-150-m-yen/

■やりたいことが見つからない人にセルフ鎖国のススメ
http://blog.btrax.com/jp/2018/02/05/sakoku/

■英語で表現する「紫色」、purpleやvioletその他の表現の違い
https://eikaiwa.weblio.jp/column/phrases/vocabulary/purple-violet
メンテナンスしやすいコードを書こう（その２）　名称編

#1. 今回お話しすること
+ 「メンテナンスしやすいコード」という軸でまとめたよ
+ [前回](https://qiita.com/tie1120/items/2f491469f7f384db6715)の続きだよ
+ 今回は「変数やメソッドの名称」の話に絞って、具体的なテクニックを紹介するよ
+ Javaやjavascriptコードで説明を書くけど、全言語共通で使えるテクニックだよ
+ 私個人の考えなので、「いいな」と思うものだけピックアップしてもらえたら何よりです


#2. 雑談
[前回「メンテナンスしやすいコードを書こう（その１）」](https://qiita.com/tie1120/items/2f491469f7f384db6715)の記事に対し、とても多くの意見をいただきました。ありがとうございます！
少し個人的な話になりますが、私は今の会社に新卒入社して6年目、30歳の若手エンジニアです。大学や大学院では化学が専攻だったため、プログラミング歴はほぼ入社歴と同じです。私なりに今の正解を綴っているつもりですが、まだまだ井の中の蛙感が拭えません。内容の誤りや、よりよい方法、また違った視点などをコメントいただけるととても勉強になります。是非お願いします。

#3. テクニック集

##3.1. メソッドや変数の名前には中学レベル以上の英語は使わない
プログラミングで使う文字はアルファベットが基本ですので、やはり英単語を使う方が違和感がありません。
ですが英単語を使わ「ないと」と思っていると、メンテナンスしにくいコードになることがあります。

例えば、以下のような意味を持つ変数に名前を付けるとしたら、どんな名前にするでしょうか。

---
業務報告書をあらわすクラスを考えます。

+ 「報告書作成日」を示す変数名
+ 「業務実施日」を示す変数名
+ 「上司確認／決裁日」を示す変数名（複数の上司がいる想定で正規化・・・とかここでは考えずに）

---

もちろん、100点の正解はありません。
ちなみに単純にgoogle翻訳さんで英語に直してみると・・・

+ 報告書作成日：Report creation date
+ 業務実施日　：Business Implementation Date
+ 上司確認日　：Boss confirmation date／Resolved date of the boss

となりました。

・・・

僕ならこんな感じにすると思います。

+ 報告書作成日： date_created／dateCreated
+ 業務実施日　： date_jisshi／dateJisshi
+ 上司確認日　： date_kakunin／dateKakunin

Implementationという英単語は中学では使わないでしょう。（今回は一応[このサイト](http://www.eigo-duke.com/tango/chu1.html)で英単語を見てみました。）これを一目で「実施」と読めない人は、プロジェクトメンバーにもいるはずです。あまりに制限しすぎると「わかる人」が作りづらくなりますし、とはいえそうでない人にもっと英単語勉強せいやと言っても難しいところもあるかと思います。その折衷案が「だいたい中学英語まで」という話です。もちろん、難しい単語であっても、その業界などでよく使われているものであれば、使ってしまったほうがいいと思います。

ちなみに安易に連番などを名称にいれることもお勧めしません（date_01とか）。膨大な数の変数名を決めなければならず、かつ連番を振っても違和感がないくらい密接な関係性のあるもの同士なら許容しますが、そうでない場合は後で見た時に「この変数はどんな意味なのか」が追いづらくなります。（コメントで見たらある程度分かりますが、逆に言えばコメントをわざわざ見ないとわかりません。）

##3.2. 2単語以上の名前の場合、順番を意識しよう
3.1の節で、私が考える変数名は「date_XXX」としていました。この節では、ここで"date"を前に持ってくるのか、後ろに持ってくるのか、という話をしようと思います。この答えももちろん、時と場合によります。なので、僕が指針として持っている考え方について触れたいと思います。

まず私の中で一番軸になっているのは、「将来ありうる改良を想像したときどの単位でまとまっていると見やすい／わかりやすいのか」です。3.1節の例で考えてみましょう。

今回の例では『「日付でソートがかけたいな。日付は日付なんだけど、このオブジェクトってどんな日付持ってたかな？何でソートするのが使いやすいかな』」という感じで考える将来の改良を想像しました。逆に、『報告書作成日はすでにあるけど、作成者も追加したいな。あ、業務実施者もほしいし、決裁者もほしい！』という改良も想像できますよね。そうなったときには、逆にcreate_XXXやjisseki_XXXという軸でまとまっていたほうが使いやすいかもしれません。

これについては明確な正解はないですが、まったく考えないのも悪ですね、くらいの注意喚起としてとらえてください。この命名を決めるのに2時間3時間かけるのは時間の無駄だと思います。


##3.3. 中身に合った名称にしよう
みなさん、以下のメソッド名を見たときに、どんなメソッドを想像しますか？
ちなみに初めて出てきた　```int categoryId```は、多数あるItemを分類分けするためのカテゴリのキー値だと思ってください。そしてItem一覧が表示されるwebの画面上に「カテゴリ」というプルダウンがあり、そこを変更するとそのカテゴリのItem一覧に絞って再表示するような画面のロジック処理の一部を想像してください。

```
 public static List<String> getListItemTitle(int categoryId) {
  // 処理内容

  }
```

「DBアクセスして、categoryIdをキーにItemのリストを取得してくるんだろうなー」とか、「すでにオブジェクトとして取得済みのItemListから、該当のcategoryIdのものだけを抽出してくれるのかなー」とか、そんな感じのことを想像すると思います。

でも実はこのメソッド内では、そのような一覧取得のSELECTのほか、「このユーザがこのカテゴリIDで検索した、という検索履歴テーブルにINSERTを走らせています。」と聞いたらどうですか？「え？DB更新してんの？！」となりませんか？

たしかに、カテゴリで絞ってSELECTをかけたときに、かならず履歴の登録とペアで実行したいという要件はあると思います。でもそうであれば、メソッド名のどこかで、INSERTもしているよとわかる名称にすべきです。名称をみただけである程度の大枠で何をしているメソッドかわかる状態にしておかないと、将来の改良で意図せず再利用して変なDBレコードができあがることになりかねません。

「そうするとメソッド名長くなるよね？」とも思いますが、「短くしたいがために重要な情報を持っていない」名称になるよりかは、「必要十分な情報が入っているが長い」名称の方がよっぽどメンテナンスしやすいです。とはいえ100文字200文字を許容したいわけではないので、節度は大事ですけどね。


---
次回も名称関連の話を続けようと思います。
Quicksort 1 -PartitionにPHPで挑戦!! 文系学生がやってみた!!

##はじめに
インターン先でプログラミング勉強中の文系学生。

「QuickSortやろうか!!」

????

##Quicksortとは
まず、Quicksortって何さ。

社員さんに説明してもらったところ、以下の内容だと理解した(はず)。
>ある数字を設定して、配列に格納されている数字の大きさを比較して場所を並び変えること

例としては、
>3 1 7 6 5

みたいな配列があって、4を設定し、大きい数字を右側に配置する場合、
>4と3を比較→3と4の場所を交換するから、
>3 4 1 7 6 5

これを繰り返して、

>1 3 4 6 5 7

にするのか。

そのためには、もっと複雑な仕組みが必要なんだろうけれど、今のところはこれが限界。


##基礎学習
### アルゴリズム
社員さんから与えられた課題を取り組む前に、Quicksortの基礎を学んでおこう。

「Quicksort PHP」で検索すると、
[PHPでクイックソートというものをやってみた](http://d.hatena.ne.jp/lagos_on/20090515/1242403775)
というサイトを発見!!

このサイトによると、Quicksortは次の流れで進んでいくみたい。
 1.最初に比較するピボットの設定(中央値が望ましい)
 2.ピボットよりも小さい数を前に、大きい数を後ろに並び変える「分割」という作業をする
 3.分割されたそれぞれのデータを配置する

あ、そうか。
さっきの認識だと、一つずつ入れかえっていったけど、それだとしっかり並び替えできないか。
つまり…
>4(ピボット)
>3 1 7 6 5(配列)

これを

>3 1 (ピボットよりも小さい数)

>7 6 5(ピボットよりも大きい数)

に分割するのね。

で、その後、分割したそれぞれのデータの中で比較していって、

>1 3


>5 6 7

のデータにして、データの間にピボットを置くのか。

まとめると、こんな感じ

 1.ピボットと配列の設定
 >4(ピボット)

 >3 1 7 6 5(配列)

 2.配列に設定された数字をピボットよりも小さいか、大きいかで分ける(分割)
 >3 1 (ピボットよりも小さい数)

 >7 6 5(ピボットよりも大きい数)

 3.分割したデータの並び替え

 >1 3


 >5 6 7

 4.データとピボットの配置
 >1 3 4 5 6 7

まぁ、例としては、ピボットの設定が悪かったかもね。
よくわかってなかったから、しょうがないしょうがない。

###実践演習
じゃあ、大体理解できたところで挑戦してみよう!!
今回挑むのは、Hackkerrankの[Quicksort1 - Partition](https://www.hackerrank.com/challenges/quicksort1/problem)


やるべきことは、quicksortの仕組みかな?
`Complete this function`の所を埋めればいいみたい。

それじゃあ、やっていこう!!
 
###　1.内容理解(最初のif文)

　なんにせよ学習量が乏しいから、もうちょっと構文見てみよう…
　[PHPでクイックソートというものをやってみた](http://andrewbaxter.net/quicksort.php)を
　見てみることにしよう。
　これを見て分かったのは、一番最初に必要なif文。

　 最初に書くのは、`1回目の処理は並び替え、2回目の処理では並び替えた$arrを返す`if文ね。
　
  
###　 2.内容理解(並び替え処理)
  　 まぁ、まずは`$equal`とかを定義しないとだめだよね。

　この[サイト](http://andrewbaxter.net/quicksort.php)を例にして、`$equal`、`$right`、`$left`の定義を埋めてみよう。

　並び替えの処理も、同じサイトを参考にすればできるよね。
　　
　 `array_marge`って何…?
　 調べてみたら、配列を組み合わせてくれるみたい。
　 じゃあ分割した物を組み合わせればいいのか。

###　 3.テスト
　自分で考えた構文ができたら、`Run Code`をポチっと…
　お、ちゃんとできてる。

　じゃあ、`Submit Code`をクリックっと…
　
　どうかな…?

　できたー!!


##まとめ
今回はQuickSortの基礎を学習しました!!
最初はピボットを分割した2つの配列に入れると考えていたけど、そうじゃないみたい。
ピボットは並び替えるために必要な要素なだけなのね。
>4(ピボット)
>3 1 7 6 5(配列)

だったら、
>1 3
>7 6 5

に分割して、

>1　3　7　6　5

になると。

クイックソートは並び替え処理の基礎の基礎みたいだから、これからも色んな並び替え処理を勉強していこう!!
Cognos TM1 をWindowsサーバーに導入した際のウィルススキャンS/W設定

#概要
Cognos TM1 をWindowsサーバー上に実装する場合に、ウィルススキャンS/Wの対象とすべきファイル・フォルダに関する情報です。

Virus ScanのS/Wをただ入れるだけで、そのままでOKとしている環境は無いでしょうか。
Virus Scanの対象外にしなければいけないフォルダは、一番下のリンクにあるようにしっかりとガイドされていますので、ガイドに従って除外設定するようお願いします。

基本はPlanning Analytics Localでも同様だと思いますので、ご参考にして頂ければと思います。

#スキャン除外対象一覧
**TM1インストールディレクトリ**
Cognos TM1やPALの導入先ディレクトリです。通常、以下になります。
C:\Program Files\ibm\cognos\tm1_64

**TM1データディレクトリ**
各TM1サーバーのデータディレクトリです。Tm1s.cfgファイルの「DataBaseDirectory」パラメーターで指定されるディレクトリです。

**TM1ログディレクトリ**
各TM1サーバーのログ出力ディレクトリです。Tm1s.cfgファイルの「LoggingDirectory」パラメーターで指定されるディレクトリです。
「RawStoreDirectory」を指定している場合は、こちらも対象外となります。

**Tm1s.cfgファイルのディレクトリ**
Tm1s.cfgファイルが存在するディレクトリも対象外です。

**Excelシートがアップロードされるディレクトリ**
WebシートとしてのExcelシートがアップロードされるディレクトリも対象外です。

**データのインポート元、書き出し先ファイル**
Turbo Integratorのプロセスなどで、データのインポート元のファイルの置き場所や、ASCIIOutputなどで書き出し先のファイルの置き場所も対象外です。

**データソースとなるデータベース**
Oracle、SQL Server、DB2など、TIプロセスの参照元となるデータベースも対象外です。

**TM1Web/TM1WebExフォルダ**
Cognos TM1 10.1.0以前は、C:\inetpub\wwwroot配下に存在したフォルダです。
それ以降のバージョンでは、TM1のインストールディレクトリを対象外としておけば大丈夫です。

**TM1Webを使う場合のEXCEL.EXE**
Cognos TM1サーバーにExcelの導入は現在は不要ですが、過去のバージョンで導入している場合は、そのフォルダも対象外となります。
C:\Program Files (x86)\Microsoft Office\OfficeXX
C:\Program Files\Microsoft Office\OfficeXX


#参考情報
**TM1 and virus scan software**
http://www-01.ibm.com/support/docview.wss?uid=swg21458762
rubyファイルと同じフォルダにあるerbファイルをERBテンプレートにインスタンス化するワンライナー

です(自分用)

```ruby
require 'erb'
ERB_TEMPLATE = ERB.new(File.open(File.join(File.dirname(__FILE__), 'erb_filename.erb'), 'r:utf-8'){|f| f.read})
```

ワンライナーなのに、２行になっとる！
【Swift4】UIColorをRGB(0~255)で指定したい

SwiftのUIcolorのRGB値は、256段階ではなく、0~1.0までの値で指定するようになっています。
https://developer.apple.com/documentation/uikit/uicolor

まあこれが指定しにくい...

そんなときは、UIcolorのextentionを作るか、UIcolorのRGB値の引数に255で割った値を直接渡しちゃいましょう！

## extentionを作る
```swift
extension UIColor {
    class func rgba(red: Int, green: Int, blue: Int, alpha: CGFloat) -> UIColor{
        return UIColor(red: CGFloat(red) / 255.0, green: CGFloat(green) / 255.0, blue: CGFloat(blue) / 255.0, alpha: alpha)
    }
}

//使い方
let button = UIButton()
button.backgroundColor = UIColor.rgba(red: 117, green: 194, blue: 57, alpha: 1)
```

## RGB値を直接渡す
こっちが手っ取り早い。

```swift
let button = UIButton()
button.backgroundColor = UIColor(red: 117/255, green: 194/255, blue: 57/255, alpha: 1)
```
Docker導入 in mariadb and php and nginx

特に難しいことをするわけではない。

単純にdocker触って見たかった。
目標設定としては、チームの開発環境共通化を目指した。

# 初期だけだなら超簡単に進む
チュートリアルではあまりやりたいことがなかった。
チュートリアルをちゃんとやればdockerってこういうものというある程度の理解は得られると思う。

# つまったところ
## 静的ファイルの扱い(nginx
dataフォルダからマウントしないとちゃんと静的ファイルとして認識されなかった。
例えばcodeというフォルダから

```
volumes:
      # サイトデータ
      - ./code:/var/www/html
```

とするとtext/htmlでしか読まれないとか。
mime.typesがうまく動いてないのかとか色々とやったけど無理で、nginxの設定ファイルをいじったらこんどは４０４になったりした。

これには大分困らされた。
なんでなのか知ってる方がいたら教えて欲しい。
一週間くらいあらゆる手をつくした。

```
Resource interpreted as Stylesheet but transferred with MIME type text/html
```

dataフォルダをvolumesの対象にすることで解消できた。
こうするとほぼ初期設定で全て読み込んでくれる。

```
volumes:
      # サイトデータ
      - ./data/code:/var/www/html
```

悲しい。


## コンテナ間のアクセス(dbとphp
DBとphpの接続ができなかった。
普通にコンテナ同士なのでportに気をつけて、hostの対象をつけたdbコンテナ名で指定すればつながる。

```
mysql:host=db;port=3306;dbname=dbname;charset=utf8
```

## phpの拡張(php
これはそれほどでもないけれど、若干詰まった。
phpのコンテナ側で起動時に拡張を入れてあげる必要があった。

```text:Dockerfile
RUN apt-get update \
  && apt-get install -y libfreetype6-dev libjpeg62-turbo-dev libpng12-dev libmcrypt-dev \
  && docker-php-ext-install pdo_mysql mysqli mbstring gd iconv mcrypt
RUN apt-get install -y git unzip

RUN apt-get install libldap2-dev -y && \
    rm -rf /var/lib/apt/lists/* && \
    docker-php-ext-configure ldap --with-libdir=lib/x86_64-linux-gnu/ && \
    docker-php-ext-install ldap

RUN curl -sS https://getcomposer.org/installer | php

RUN mv composer.phar /usr/local/bin/composer
RUN composer self-update
RUN composer install --dev --no-interaction
```

だいたいこんな感じ

# やってみて
環境関連の共通化自体は超楽になると思う。
とりあえずwindowsとmacが入り乱れている状況なのでこれ使っていきたい。
「[2,3,4,1]」を 「2 3 4 1」 と出力したい場合(python3)

#HackerRankでたまーにある出力形式で困る

sample outputをみると

```text
2 3 4 1
```

と書いてある。

何も考えずにリストを普通に出力すると…

```py:コード
print(arr)
```

出力結果
![image.png](https://qiita-image-store.s3.amazonaws.com/0/238739/d77ba679-32d9-ca67-3bec-7602a2550356.png)


いや、もうこれは正解やーーん！！笑

これでは、だめらしいですね…

#解決策

```py:コード
print(' '.join(map(str,arr2)))
```

出力結果
![image.png](https://qiita-image-store.s3.amazonaws.com/0/238739/0a57399e-f301-6a95-d56e-0e0c0af41c32.png)


[追記]
コメントをいただいて、かなり簡単な方法があったので、追記します。

> ```py:コード
arr = [2, 3, 4, 1]
print(*arr)
```

> ```text:出力結果
2 3 4 1
```

めっちゃ簡単ですね！！
Python > scpの処理速度を測定する (精度は悪い) | scp -C > 圧縮しながらコピー (速度2倍)

```txt:動作環境
Xeon E5-2620 v4 (8コア) x 2
32GB RAM
CentOS 6.8 (64bit)
NCAR Command Language Version 6.3.0
for WRF3.7.1, WPS3.7.1
  openmpi-1.8.x86_64 とその-devel
  mpich.x86_64 3.1-5.el6とその-devel
  gcc version 4.4.7 (とgfortran)
for WRF3.9, WPS3.9
  Open MPI v2.1.1
  gcc version 4.9.2 (とgfortran; devtoolset-3使用)
　NetCDF v4.4.1.1, NetCDF (Fortran API) v4.4.4
Python 2.6.6 (r266:84292, Aug 18 2016, 15:13:37) 
Python 3.6.0 on virtualenv
GNU bash, version 4.1.2(1)-release (x86_64-redhat-linux-gnu)
date (GNU coreutils) 8.4 
tmux 1.6-3.el6
```

35GBのデータを別のサーバーからscpにて取得中。

遅そうなので、取得中に速度を測定するPython scriptを組んでみた。

### 関連

- [Python3 + subprocess > crontabの設定を読取り、実行するスクリプト > string not in ... | string.lower() | subprocess.getoutput()](https://qiita.com/7of9/items/869636e627f4de329946)

### 処理

- `du -k`の最後に表示されるディレクトリサイズを使う
- インターバル時間の前後でのサイズの変化を取得する
- ある程度の速度だけ知りたいので、精度は望まない

### code

```check_dirsize_180226.py
import subprocess as sb
import time


def get_dir_size():
    CMD = 'du -k'
    res = sb.getoutput(CMD)
    res = res.replace('\t', '')
    res = res.replace('.', '')
    return int(res.split('\n')[-1])

INTERVAL_SEC = 5

dirsiz1 = get_dir_size()
time.sleep(INTERVAL_SEC)
dirsiz2 = get_dir_size()

print(dirsiz1, 'kB')
print(dirsiz2, 'kB')
inkB = ((dirsiz2 - dirsiz1) / INTERVAL_SEC)
print('%dkB /sec' % inkB)
print('%dMB /sec' % (inkB / 1024))

```

```txt:run
$ python3 check_dirsize_180226.py 
20670836 kB
20724596 kB
10752kB /sec
10MB /sec
```

35GBあるので、あと1536秒(25分)程度かかる。

使用環境が特殊なので速度が出ない（未解決)。

### scp -C

https://unix.stackexchange.com/questions/218668/what-does-the-c-flag-exactly-do-in-scp

`scp -C`にしてみた。

ばらつきはあるが、平均的に2倍の速度になった。
(補足: 当然、bz2などの圧縮済みのファイルに対しては速くはならない）。

```bash
$ python3 check_dirsize_180226.py 
739188 kB
882384 kB
28639kB /sec
27MB /sec
$ python3 check_dirsize_180226.py 
1776460 kB
1890544 kB
22816kB /sec
22MB /sec
$ python3 check_dirsize_180226.py 
2733952 kB
2819580 kB
17125kB /sec
16MB /sec
```

やり直したので、35GB / 20MB = 1792秒かかる。
(将来の処理時間短縮につながるので、今回の処理時間増加は問題ない）。
Adafruit_Sensor.h: No such file or directory

Arduino で Adafruit のライブラリを include して、`Adafruit_Sensor.h: No such file or directory` が出たとき。

よく心を落ち着けてみてみよう。`Adafruit_Sensor.h` はインクルードしたファイルじゃない。

実は `Adafruit Unified Sensor` という「共通ライブラリ」が必要なので、ライブラリマネージャでインストールして、再ビルドしよう。

https://forum.arduino.cc/index.php?topic=471001.0
Twitter拡張すごい:勢い編

アドレスバーからリアルタイム検索を可能にする拡張
[OmniRT - アドレスバーからリアルタイム検索 - Chrome ウェブストア](https://chrome.google.com/webstore/detail/omnirt-%E3%82%A2%E3%83%89%E3%83%AC%E3%82%B9%E3%83%90%E3%83%BC%E3%81%8B%E3%82%89%E3%83%AA%E3%82%A2%E3%83%AB%E3%82%BF%E3%82%A4%E3%83%A0%E6%A4%9C%E7%B4%A2/hdjanjddafhdndfobjjobgibifllgoaf/details?hl=ja)

そのブログ
[Google Chrome拡張『OmniRT』でリアルタイムを簡単に : Blog @narumi](http://narumi.blog.jp/archives/4508251.html)

これでノンTwitterユーザでもTwitter検索捗る

]追記:訂正感謝です
Node-RedでPepperとMQTT連携する


## 今回の仕組み
今回の仕組みはRaspberry PiにNode-REDとMQTTブローカー（Beebotte）を使用して、ALMemoryを介してPepperに指示を出してアニメーション付きのセリフをしゃべらせます。
![ChoregrapheMQTT-02-1.png](https://qiita-image-store.s3.amazonaws.com/0/239292/10e9e029-fa60-8f13-ec4d-089e73706949.png)


※今回の記事は、Rasberry Pi、Node-RED、MQTT、Choregrapheの知識があることを前提としています

Pepper 開発ツールChoregraphe（コレグラフ）のインストールについては以下を参照ください。
[Pepper 開発ツールのインストール](https://qiita.com/minatomirai117/items/1a6ec8abf2e0ad356746)

Node-REDとMQTTブローカー（Beebotte）については、以下の記事等をご参照ください。
[Beebotte（MQTT Broker）の設定とRaspberry Pi（Node-RED）の設定](https://qiita.com/minatomirai21/items/4c4e777b43ede1e42900)
[Beebotte の WEBコンソールを利用した MQTTメッセージの送受信テスト](https://qiita.com/minatomirai21/items/a43d9b4aba1a081740cb)

## Pepperの作業
Pepper側の処理は、Pepperの開発ツールChoregraphe（コレグラフ）を使います。

MQTTのやりとりに使うライブラリ「[Paho](http://www.eclipse.org/paho/)」の読み込み処理から追加して Python ボックスを使用してPepper用 MQTT Publisher/Subscripterボックスを作る必要があります。
今回は以下のMQTT Adapterボックスを利用します。
まずはダウンロードしておきます。
https://github.com/yacchin1205/pepper-web-boxes

## MQTT Adapterボックスの読み込み
1. Choregrapheの画面左下の[ボックスライブラリ]パネルから[ボックスライブラリを開く]を選択します。
![ChoregrapheMQTT-03.png](https://qiita-image-store.s3.amazonaws.com/0/239292/c3e5242b-e5ac-f701-4bd4-35655d516c9b.png)

2. GitHubからZIPダウンロードもしくはcloneしたディレクトリのうち、以下のディレクトリを選択します。
    - ディレクトリ：web-boxes
    - ファイルの種類：ボックスライブラリのディレクトリ(Directories) 

3. [ボックスライブラリ]に web-boxes ボックスライブラリが表示されます。

## MQTT Adapterボックスの配置
1. web-boxes ボックスライブラリの [Network] > [MQTT Adapter]ボックスを「フローダイアグラム」にドラッグ＆ドロップします。※MQTT Adapterボックスをドラッグ＆ドロップすると自動的にpaho というモジュールがプロジェクト中にインポートされる

2. MQTT Adapterボックスの設定ダイアログを開き、以下のパラメータを設定します。
    - Host ... MQTT Brokerのホスト名(例：mqtt.beebotte.com)
    - Port ... MQTT Brokerのポート番号(例：1883)
    - Username ... MQTT Brokerの接続用ユーザ名
    - Password ... MQTT Brokerの接続用パスワード
    - Key-Topic Bindings ... ALMemoryのキーとMQTTのトピックとの紐づけ（例:MQTT/Fsathon3:Ras/good）
 
3. MQTTアダプターボックスは起点となる[onStart]からつなげて、起動時にすぐMQTTがつながるようにします。

4. 「フローダイアグラム」の左側にある＋[ALMemoryからのイベントの追加]を選択し、[メモリイベントの選択]画面の左下[新しいキー追加]をクリックして、ALMemoryとMQTT の Key-Topic Bindings（例：MQTT/Fsathon3:Ras/good）の[MQTT/Fsathon3]を相互接続されるように追加します。
![ChoregrapheMQTT-04.png](https://qiita-image-store.s3.amazonaws.com/0/239292/85e30fdc-1f44-6086-7625-345faa717ae6.png)
![ChoregrapheMQTT-05.png](https://qiita-image-store.s3.amazonaws.com/0/239292/e155e0a2-9c70-2add-0e5a-4f3aa1b0a9ff.png)

5. [フローダイアグラム]に [Animated Say] ボックスをドラッグ＆ドロップし、以下を設定します。
    - Voice shaping (%) : 100%
    - Speed (%): 100%
    - Text : congratulations
    - Speaking movement mode : disabled
    - Animation : Stand/Gestures/Hey_2
    - ロボット上の変の自動更新：チェックあり

6.  [Animated Say] ボックスを[MQTT/Fsathon3]につなげます。
![ChoregrapheMQTT-06.png](https://qiita-image-store.s3.amazonaws.com/0/239292/f5f57103-e399-abe1-0a2d-a7cd6f27b3eb.png)

7. バーチャルロボットでメニューの「再生」をクリックして、PepperとNode-REDをつないでみます。
※[ログビューア]のログに「Connedted with result code 0」が表示されたら、無事つながっているようです。
8. 最後はNode-RED側からメッセージを送信後にPepper がジェスチャーしながらしゃべります。
  ※動作されない場合は、[Animated Say] ボックスに到達されているか[ログビューア]を確認してください。
Linux > lastコマンド > crash | down日時の情報を得る 

```txt:動作環境
Xeon E5-2620 v4 (8コア) x 2
32GB RAM
CentOS 6.8 (64bit)
NCAR Command Language Version 6.3.0
for WRF3.7.1, WPS3.7.1
  openmpi-1.8.x86_64 とその-devel
  mpich.x86_64 3.1-5.el6とその-devel
  gcc version 4.4.7 (とgfortran)
for WRF3.9, WPS3.9
  Open MPI v2.1.1
  gcc version 4.9.2 (とgfortran; devtoolset-3使用)
　NetCDF v4.4.1.1, NetCDF (Fortran API) v4.4.4
Python 2.6.6 (r266:84292, Aug 18 2016, 15:13:37) 
Python 3.6.0 on virtualenv
GNU bash, version 4.1.2(1)-release (x86_64-redhat-linux-gnu)
date (GNU coreutils) 8.4 
tmux 1.6-3.el6
```

週末に処理をしていたCentOSサーバーにつながらない。

再起動後にcrash, down情報を見てみた。

### lastコマンド

FreeBSD 2.2.8の時に使っていたlastコマンドをふと思い出した。
(下記、ユーザ名とIPアドレスは公開用に書替えしている)

```bash
$last
xxx  pts/0        192.168.7.9      Mon Feb 26 09:58   still logged in   
xxx  pts/0        :0.0             Mon Feb 26 09:56 - 09:58  (00:02)    
xxx  tty1         :0               Mon Feb 26 09:55   still logged in   
reboot   system boot  2.6.32-642.el6.x Mon Feb 26 09:53 - 09:59  (00:05)    
xxx  pts/0        192.168.7.9      Fri Feb 23 20:24 - crash (2+13:29)   
xxx  pts/0        192.168.7.9      Fri Feb 23 14:33 - 20:08  (05:34)    
xxx  pts/0        192.168.7.9      Fri Feb 23 11:46 - 14:28  (02:42)    
xxx  pts/0        192.168.7.9      Fri Feb 23 11:18 - 11:33  (00:15)    
xxx  pts/0        192.168.7.9      Fri Feb 23 11:17 - 11:18  (00:00)    
xxx  pts/0        192.168.7.9      Fri Feb 23 11:09 - 11:17  (00:07)    
xxx  pts/0        192.168.7.9      Fri Feb 16 19:52 - 19:23 (4+23:30)   
xxx  pts/0        192.168.7.9      Thu Feb  1 14:34 - 11:11 (3+20:36)   
xxx  pts/0        192.168.7.9      Thu Feb  1 10:25 - 14:15  (03:50)    
xxx  pts/0        192.168.7.9      Wed Jan 31 11:13 - 10:04  (22:50)    
xxx  pts/1        localhost:10.0   Tue Jan 30 08:30 - 10:48 (1+02:17)   
xxx  pts/0        192.168.7.9      Tue Jan 30 08:28 - 10:48 (1+02:19)   
reboot   system boot  2.6.32-642.el6.x Mon Jan 29 18:42 - 09:59 (27+15:16)  
xxx  pts/0        192.168.7.9      Thu Jan 25 18:16 - crash (4+00:26) 
```

- https://linuxjm.osdn.jp/html/SysVinit/man1/last.1.html

### crash日時

GNU coreutilsのdateコマンドで上記のcrash日時を見てみる。

参考: [GNU coreutils > date > 日時指定 + days, hour, minuteを進める|戻す > 例: date --date="2017-08-03 12:30:45 1 hour ago" | 二回引くワンライナー](https://qiita.com/7of9/items/745cfce5d722ff6907fd)

```bash
$ date --date="2018-02-23 20:24 2day 13 hour 29 minute"
Mon Feb 26 09:53:00 JST 2018
```

### 再起動

同じシステムで今度は再起動がかかっていた。

何が起きているのか？
[Swift]Codableで詰まったパターン

# jsonにキーが含まれない時

```swift
var json = """
{"hoge":"hi"}
"""

struct Hoge: Decodable {
  var hoge: String
  var fuga: String
}

let res = try! JSONDecoder.init().decode(Hoge.self, from: json.data(using: .utf8)!)
```

jsonにfugaが無いので、tryで落ちる

```
Fatal error: 'try!' expression unexpectedly raised an error: Swift.DecodingError.keyNotFound(__lldb_expr_39.Hoge.(CodingKeys in _62E2347B8FAED974B75E794A46D74006).fuga, Swift.DecodingError.Context(codingPath: [], debugDescription: "No value associated with key fuga (\"fuga\").", underlyingError: nil)): file /BuildRoot/Library/Caches/com.apple.xbs/Sources/swiftlang/swiftlang-900.0.74.1/src/swift/stdlib/public/core/ErrorType.swift, line 181
```

## 存在しないキーがOptionalの時

```swift
var json = """
{"hoge":"hi"}
"""

struct Hoge: Decodable {
  var hoge: String
  var fuga: String?
}

let res = try! JSONDecoder.init().decode(Hoge.self, from: json.data(using: .utf8)!)
```

fugaにはnilが入り、マッピング出来る

## 存在しないキーに既に値が入っている時

```swift
var json = """
{"hoge":"hi"}
"""

struct Hoge: Decodable {
  var hoge: String
  var fuga: String? = "fuga"
}

let res = try! JSONDecoder.init().decode(Hoge.self, from: json.data(using: .utf8)!)
```

**fugaにはnilが入った状態でマッピングされる**

# 特定のプロパティをマッピングさせない

```swift
var json = """
{"hoge":"hi"}
"""

struct Hoge: Decodable {
  var hoge: String
  var fuga: String = "fuga"
  
  private enum CodingKeys: String, CodingKey {
    case hoge
  }
}

let res = try! JSONDecoder.init().decode(Hoge.self, from: json.data(using: .utf8)!)
```

CodingKeysに存在しないプロパティはマッピングされない。（fugaには"fuga"が入っている）
なお、デフォルト値は必須
Google Homeをブラウザから喋らせてみる

## はじめに
Google Homeを最近買ったのでいろいろ遊んでみました。

Google Homeでは自発的に喋らせる機能が標準で備わっていません。
しかし、[google-home-notifier](https://github.com/noelportugal/google-home-notifier)を使うと、コマンドで喋らせることが可能です。

↓こちらの記事が参考になりました。
[Google Home開発入門 / google-home-notifier解説](https://qiita.com/SatoTakumi/items/c9de7ff27e5b70508066)

ちょっと試してみましょう。

## コマンドで喋らせてみる
### google-home-notifierをインストール
```shell
$ npm init
$ npm i -S google-home-notifier
```

### jsファイルの作成
```js:main.js

/**
* 設定
*/
const googlehome = require('google-home-notifier');
const msg = process.argv[2] || 'なんか喋ってよ'; // process.argv[2]で引数を取得。ない場合はデフォルトメッセージを代入


/**
* 喋らせる関数
*/
function say(text, language = 'ja'){
  googlehome.device('Google-Home', language);
  googlehome.notify(text, function(res) {
    console.log(res);
  });
}

say(msg); // 英語にしたい場合は第二引数を'en'にする
```

あとは、以下コマンドを叩くだけ！
`main.js `の後に好きな日本語を書くと、その通りにGoogle homeが喋ってくれます。

```shell
$ node main.js 私はGoogleだっ！
```

ただし、実態はGoogle Text To Speachを使って音声ファイルを再生しているので、Google Homeが喋ってるわけではありません。（Google Homeよりちょっとカタコトです）

うーん、ちょっと残念。
早くGoogle Homeに直接喋らせるAPIができて欲しいです。

## ブラウザから実行できるようにする
コマンド打つのは面倒だし、誰でも気軽にできるように、ブラウザから実行できるようにしてみようと思います。

### 必要なプラグインをインストール
```shell
$ npm init
$ npm i -S express body-parser
```

### 先ほどの`main.js`を以下のようにカスタマイズ
コマンドではなく、postで受け取ったタイミングで実行するようにしています。

```js:main.js
/**
* 設定
*/
const googlehome = require('google-home-notifier');
const express = require('express');
const bodyParser = require('body-parser');
const app = express();
const msg = process.argv[2] || 'なんか喋ってよ'; // process.argv[2]で引数を取得。ない場合はデフォルトメッセージを代入
const port = 8001;


/**
* ローカルサーバー起動
*/
app.use(bodyParser.urlencoded({extended: true}));
app.use(bodyParser.json());
app.use(express.static('./'));
app.listen(port, ()=> {
  console.log(`http://localhost:${port}/`);
});


/**
* 喋らせる関数
*/
function say(text, language = 'ja'){
  googlehome.device('Google-Home', language);
  googlehome.notify(text, function(res) {
    console.log(res);
  });
}

/**
* POST時の処理
*/
app.post('/', function(req, res){
  let msg = req.body.msg;

  say(msg);
  res.send({ response : msg });
});
```

### htmlを作成する
あとは、上記`main.js`をブラウザから実行できるように`fetch()`でpostします。

```js:index.html（主要な部分だけ）
fetch('./', {
  method: 'POST',
  cache: 'no-cache',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({ msg: '★ここに喋らせたい内容を投げ込む' })
})
.then(res => res.json())
.catch(error => console.error('Error:', error))
.then(response => console.log('Success:', response));
```

### 画面の作成
あとはこんな感じの画面を作って上記scriptを実行させるだけです。
（コードは割愛します）

![画面](https://qiita-image-store.s3.amazonaws.com/0/33699/77cb6227-ca19-2e37-81e0-57aecb7c34c0.png)


### コマンドを実行
`main.js`を実行します。

```shell
$ node main.js
```

これでローカルサーバーが立ち上がるので、[http://localhost:8001/](http://localhost:8001/) にアクセスして遊んでみましょう

また、`http://***.localhost:8001/`のURLでスマホからもアクセスできるので、手軽に遊べます。（`***`はMacのマシン名）

ただし、Macがスリープしちゃうともちろん実行できなくなくなるので、ご注意を。


## 最後に
意外とカンタンにGoogle Homeを喋らせることができました。
ただ、今回のサンプルでは自宅内でしかできないので、外部から実行ができません。
Raspberry Piなどで自宅サーバーを作ればいいんでしょうけど、そこまでするのは面倒。。
なので、そのうちGoogle公式で便利な機能を提供してくれるといいなーと思っています。
LibreOfficeでダイアログボックスを作成しPythonマクロから利用する

このページの意味がほとんどなくなってしまったのですが、
「LibreOfficeでダイアログボックスを作成しPythonマクロから利用する」
https://p--q.blogspot.jp/2016/01/libreoffice521guipython.html

Python で OpenOfficeマクロ
ダイアログ・エディタの利用とコード上でのイベント関連づけ
http://psyto.s26.xrea.com/python/ooomacro_dialog.html

のリンクとして残しておきます。

##Python で OpenOfficeマクロ
#####ダイアログ・エディタの利用とコード上でのイベント関連づけ
http://psyto.s26.xrea.com/python/ooomacro_dialog.html

#####ダイアログボックスを作成します。
~~私は、最初~~　
https://p--q.blogspot.jp/2016/01/libreoffice521guipython.html
~~を参考にしてダイアログボックスを作成し、マクロを実行したのですが line13~~
~~dlg_ctrl = dp.createDialog("vnd.sun.star.script:Standard.Dialog1?location=application")~~
~~でエラーが出て解決出来なかったので~~
http://psyto.s26.xrea.com/python/ooomacro_dialog.html
~~のコードに変更して実行しました。~~

#####コード「 simpledialog_test.py 」
を
/home/ユーザ名/.config/libreoffice/4/user/Scripts/python/　(Ubuntuの場合)
C:\Users\ユーザ名\AppData\Roaming\LibreOffice\4\user\Scripts\python　(Windowsの場合)
に保存します。

~~dlg_control = dp.createDialog("vnd.sun.star.script:Standard."+dialog_name+"?location=application")~~
~~をダイアログボックスの名前を「simpleDialog」の場合は、~~
~~dlg_control = dp.createDialog("vnd.sun.star.script:Standard.simpleDialog?location=application")~~
~~に変更します。~~
ダイアログボックスの名称は、
dialog_name = "simpleDialog"
で設定します。

「 simpledialog_test.py 」実行するとダイアログボックスが表示され、ボタンをクリックするたびに1,2,3・・・と数字が増えていきます。
Rubyの配列のmap, eachやら簡潔に書く方法をまとめてみた。


rubyを簡潔に書く方法に[Enumerableモジュール](http://ref.xaio.jp/ruby/classes/enumerable)が存在します。
今回は、Enumerableモジュールを用いて配列を操作してみます。

## map, each

各要素に対して処理を行います。
mapとeachは実行後の返り値が異なります。mapはブロック文内の返り値、eachはブロックの引数を返します。

```ruby
array = [1, 2, 3]
p array.each{|item| item * 2}
# [1, 2, 3]
p array.map{|item| item * 2}
# [2, 4, 6]
```

## inject

injectは、配列の各要素をまとめた結果を扱いたい時に使います。each、mapとは異なり初期値を設定することができます。

```ruby
a = [12, 4]

p a.inject(:gcd)
# 4
p a.inject(0){|sum, i| sum + i}
# 16
```
lambda関数を引数として処理することもできます。

```ruby
add = ->(x,y){ x + y }
p a.inject &add
# 16
```

## select, find
ブロック内の条件式が成立する要素を検索します。
要素が存在する場合には、selectは全ての要素を返し、findは先頭の要素を返します。
要素が存在しない場合には、selectは空配列、findはnilを返します。

```ruby
a = [1, 2, 3]

p a.select{|i| i % 2 == 1}
# [1, 3]
p a.select{|i| i > 3}
# []

p a.find{|i| i % 2 == 1}
# 1
p a.find{|i| i > 3}
# nil
```

## zip, flatten
zipは二つの配列を要素番号順に結合してくれます。
flattenは配列の入れ子構造を平らにしてくれます。また、階層を指定することもできます。

```ruby
a = [11, 12]
b = [21, 22]
p a.zip(b)
# [[11, 21], [12, 22]]

a = [0, [1, [2]]]
p a.flatten
# [0, 1, 2]
p a.flatten(1)
# [0, 1, [2]]
```

- [Rubyでキーの配列と値の配列からハッシュを作る](http://mikeda.hatenablog.com/entry/20090201/1233487891)
- [flatten, flatten! (Array) - Rubyリファレンス](https://ref.xaio.jp/ruby/classes/array/flatten)

## all?, any?, none?, one?
条件判定を行う時に用い、all?は全件一致、any?は一部一致、none?は一致なし、oneは一件のみ存在する場合を検索します。

```ruby
a = [1, 2, 3]
p a.all?{|i| i % 2 == 1} # false
p a.any?{|i| i % 2 == 1} # true
p a.one?{|i| i % 2 == 1} # false
p a.none?{|i| i % 2 == 1} # false

a = [1, 3, 5]
p a.all?{|i| i % 2 == 1} # true
p a.any?{|i| i % 2 == 1} # true
p a.one?{|i| i % 2 == 1} # false
p a.none?{|i| i % 2 == 1} # false

a = [2, 3, 4]
p a.all?{|i| i % 2 == 1} # false
p a.any?{|i| i % 2 == 1} # true
p a.one?{|i| i % 2 == 1} # true
p a.none?{|i| i % 2 == 1} # false
```

参考文献

- [ドキュメント Enumerable](https://ref.xaio.jp/ruby/classes/enumerable)
- [rubyのeach, mapの違い](http://manji602.hatenablog.com/entry/2016/01/01/145346)
- [mapなどの配列の値を操作するメソッドまとめ](https://qiita.com/shibukk/items/d985d014de598d925b8b)
- [Ruby injectメソッド](https://qiita.com/cooltiger/items/1706893cb17e19cc4ff2)
Angularで作るER DIAGRAM TOOL - 第四回　データ用クラスの準備と、データサービスの作成からDIまで。

このアプリで扱うデータは、
基本的に dog-ears/crud-d-scaffold の crud-d-scaffold.json と
同じような形にします。

■crud-d-scaffold.json.sample
https://github.com/dog-ears/crud-d-scaffold/blob/master/crud-d-scaffold.json.sample


```
- param1
- models[
	{
		model1
		- param1
		schemas[
			{
				shcema1
				- param1
			},{
				shcema2
				- param1
			},{
				shcema3
				- param1
			}
		]
	},{
		model2
		- param1
	}
]
```

基本的なデータ構造は、上記のようになります。



##（１）Classの準備
Data、Model、Schemaのクラスを作成する

/src/app/class/data.ts
https://github.com/dog-ears/er-diagram-tool/commit/67a16b293469c6be5621352f750f59c88000fd48#diff-ba726bfa70586322bd593dddb7beaf87

/src/app/class/model.ts
https://github.com/dog-ears/er-diagram-tool/commit/67a16b293469c6be5621352f750f59c88000fd48#diff-15a154169b0b6112f2adcdf51a565ee2

/src/app/class/schema.ts
https://github.com/dog-ears/er-diagram-tool/commit/67a16b293469c6be5621352f750f59c88000fd48#diff-43602a3f26ba4b6bcf22b9c72c3fec66

・各Classは、Constructor()内で、初期化される。
・dataは_next_model_idを、modelは_next_schema_idを持ち、それぞれ新規IDを返す関数を持つ。
・schemaには、parent_idという項目を持たせて、単体でどのモデルが親かわかるようにしています。


##（２）dataServiceの作成

データを管理するサービス。
データの追加、削除は必ずここを通る。
各コンポーネントはこのサービスをDIして、サービスのメソッドを呼び出します。

/src/app/service/data.service.ts
https://github.com/dog-ears/er-diagram-tool/commit/4f9a158e23f44d51f7a0b7b61068c26e87e3da08#diff-ae990bb302f27e60323deb45d6746b17

・メンバ変数dataを持ち、constructor()で、初期化します。



##（３）dataServiceのDI

/src/app/app.module.ts を修正
https://github.com/dog-ears/er-diagram-tool/commit/386590142cc8f49c0471749d876e12e65b8e8d2d#diff-fc6b22833aeaf77f8440c4970ade705e

・DataServiceのimport
・providersにDataServiceを追加

/src/app/app.component.ts を修正
https://github.com/dog-ears/er-diagram-tool/commit/386590142cc8f49c0471749d876e12e65b8e8d2d#diff-5c26d2c8f8838f32ace87fdecd6344ea

・Data、DataServiceのimport
・メンバー変数 data の追加
・ConstructorでDataServiceのDI、および初期データ格納

/src/app/app.component.html を修正
https://github.com/dog-ears/er-diagram-tool/commit/386590142cc8f49c0471749d876e12e65b8e8d2d#diff-465e9f13ce23ec4a1e366935273fdbb6

左カラムにER図を描くエリア、右カラムにdataの内容を表示する情報エリアを置きました。
情報エリアは、不要な気もしますが、デバッグに便利なため、入れています。

![cap03.png](https://qiita-image-store.s3.amazonaws.com/0/103767/89663501-089a-1700-b12f-0f975040e5ba.png)

![cap03_2.jpg](https://qiita-image-store.s3.amazonaws.com/0/103767/3d4f6bca-3345-39c8-8ad6-dae59a57df73.jpeg)

ちなみに、各コンポーネントのメソッドには、
最初にconsole.logを入れるようにしています。
データの流れが追いやすいので、オススメです。

次回は、再びnavbarにもどり、
Dataを更新するModalの設定をしようと思います。
Domo のデータセットの一覧を取得する (go)

こちらのプログラムを go で書きました。
[Python で Domo のデータセットの一覧を取得する](https://qiita.com/ekzemplaro/items/1efb65fcae5a826fa9b7)

```go:get_list.go
// ----------------------------------------------------------------
/*
	get_list.go

					Feb/25/2018
*/
// ----------------------------------------------------------------
package main
import (
	"fmt"
	"os"
	"log"
	"io/ioutil"
	"net/http"
)

// ----------------------------------------------------------------
func list_dataset_proc (access_token string) {
	fmt.Fprintf (os.Stderr,"*** list_dataset_proc ***\n")

	url_datasets :="https://api.domo.com/v1/datasets"
	url_datasets += "?sort=name&offset=0&limit=50"

	req, _ := http.NewRequest("GET", url_datasets, nil)
	req.Header.Set("Authorization", "Bearer " +  access_token)

	client := new(http.Client)
	resp, err := client.Do(req)

	if err != nil {
		log.Fatalln(err)
		fmt.Printf("%s", err)
		os.Exit(1) 
	} else {
		defer resp.Body.Close()
		contents, err := ioutil.ReadAll(resp.Body)
		if err != nil {
			fmt.Printf("%s", err)
			os.Exit(1)
			}

		json_str := string(contents)
		fmt.Printf("%s\n", json_str)
		}
}

// ----------------------------------------------------------------
func main() {
	fmt.Fprintf (os.Stderr,"*** 開始 ***\n")

	access_token := get_token_proc ()

	fmt.Fprintf(os.Stderr,"%s\n", access_token)

	list_dataset_proc (access_token)

	fmt.Fprintf (os.Stderr,"*** 終了 ***\n")
}

// ----------------------------------------------------------------
```

get_token.go はこちらです。
[Domo の アクセストークンを取得する (go)](https://qiita.com/ekzemplaro/items/675804b80933317e5ccf)

```text:Makefile
get_list: get_list.go get_token.go
	go build get_list.go get_token.go
clean:
	rm -f get_list
```
Domo のデータセットのデータをイクスポートする (go)

こちらのプログラムを go で書きました。
[Python で Domo のデータセットのデータをイクスポートする](https://qiita.com/ekzemplaro/items/0d5494cc87cc74fecdd1)

```go:export_dataset.go
// ----------------------------------------------------------------
/*
	export_dataset.go

					Feb/26/2018
*/
// ----------------------------------------------------------------
package main
import (
	"fmt"
	"os"
	"log"
	"io/ioutil"
	"net/http"
)

// ----------------------------------------------------------------
func export_dataset_proc (access_token string,dataset_id string,file_out string) {
	fmt.Fprintf (os.Stderr,"*** export_dataset_proc ***\n")

	url_datasets :="https://api.domo.com/v1/datasets/" + dataset_id + "/data"
	req, _ := http.NewRequest("GET", url_datasets, nil)
	req.Header.Set("Authorization", "Bearer " +  access_token)
	req.Header.Set("Content-Type", "text/csv")

	client := new(http.Client)
	resp, err := client.Do(req)

	if err != nil {
		log.Fatalln(err)
		fmt.Printf("%s", err)
		os.Exit(1) 
	} else {
		defer resp.Body.Close()
		contents, err := ioutil.ReadAll(resp.Body)
		if err != nil {
			fmt.Printf("%s", err)
			os.Exit(1)
			}

		str_csv := string(contents)
		fmt.Printf("%s\n", str_csv)
		ioutil.WriteFile (file_out,[]byte(str_csv),0666)
		}
}

// ----------------------------------------------------------------
func main() {
	fmt.Fprintf (os.Stderr,"*** 開始 ***\n")
	dataset_id := os.Args[1]
	fmt.Printf ("%s\n",dataset_id)
	file_out := os.Args[2]
	fmt.Printf ("%s\n",file_out)

	access_token := get_token_proc ()

	fmt.Fprintf(os.Stderr,"%s\n", access_token)

	export_dataset_proc (access_token,dataset_id,file_out)

	fmt.Fprintf (os.Stderr,"*** 終了 ***\n")
}

// ----------------------------------------------------------------
```

get_token.go はこちらです。
[Domo の アクセストークンを取得する (go)](https://qiita.com/ekzemplaro/items/675804b80933317e5ccf)

```text:Makefile
export_dataset: export_dataset.go get_token.go
	go build export_dataset.go get_token.go
clean:
	rm -f export_dataset
```
LibreOffice Pythonマクロをツールボタンで実行する

https://wiki.openoffice.org/wiki/Python/Transfer_from_Basic_to_Python
Apache OpenOffice wiki
Transfer from Basic to Python

#####ツールバーボタンからマクロを実行する
Pythonでは、割り当てられたツールバーボタンを使って関数が実行されたときに渡される引数を取るために、引数（または可変長引数）を使用してPython関数を定義する必要があります。 

```python:HelloWorld.py
def writeHello(*args):
    # writeHello(arg): is also ok but if you want to call this function 
    # by some ways, define your function takes variable arguments.
    XSCRIPTCONTEXT.getDocument().getText().getEnd().setString("Hello!")
```

例、上記のマクロを
/home/ユーザ名/.config/libreoffice/4/user/Scripts/python/　(Ubuntuの場合)
C:\Users\ユーザ名\AppData\Roaming\LibreOffice\4\user\Scripts\python　(Windowsの場合)
に保存します。

マクロを作成する時の注意は、
def writeHello(*args):
引数に「*args」とします。

#ツールボタンの作成
例、上記マクロの場合

Writerを新規作成します。

表示　ー＞　ツールバー(T)　ー＞　フォームコントロール(L)
フォームコントロールのウインドウが表示されます。

デザインモード（右上）をクリックすると、各ボタンがアクティブになります。

ボタン（OK）左の上から５番目をクリックし、ボタンを配置したい場所でマウス左ボタンをドラッグします。

フォームコントロールのウインドウの選択ボタン（矢印マーク）（左上）をクリックし、今配置したボタンを選択する。

右クリック　ー＞　コントロール(T)　ー＞　属性プッシュボタン　ダイアログが表示されます。

全般タブ：名前等を設定
イベントタブ：「実行時の...」をクリック　ー＞　アクションの割り当て　ダイアログが表示されます。

割り当て「マクロ(A)...」　ー＞　ライブラリで先程保存したマクロを指定します。　マイマクロ　ー＞　HelloWorld　ー＞　マクロ名　ー＞　writeHello　ー＞　OK　ー＞　OK　ー＞　属性プッシュボタン　ダイアログを閉じる。

フォームコントロールのウインドウのデザインモード　をクリックする。

これで実行できる状態になりました。

ボタンをクリックすると、Writerに「Hello!」と表示されます。

#ツールバーにツールボタンを作成する場合
Writerを新規作成する。
例、「無題 1 - LibreOffice Writer」

ツール　ー＞　カスタマイズ(C)...　ー＞　カスタマイズ　ダイアログが表示される

ツールバー　タブ　ー＞　右上の選択ボックスで「無題 1」を選択する。
（ツールバーは「無題 1」だけに追加されます。新しく新規作成してもツールバーはありません。）

２番目中央の「＋」をクリックしてツールバーの名称、を入力します。

カテゴリー(Y)の▲をクリックし「マクロ」を選択します。

機能(F)でマクロを選択する。
例、
マイマクロをダブルクリックする。
Sample - Hello Worldを選択し、➡　をクリックすると、右側に追加されます。

これで、ツールバーに「マクロ名」のボタンが追加されています。

そのボタンをクリックします。

ここで、エラーになった場合、
def マクロ名():
になっている可能性があります。

def マクロ名(*args):
「*args」を追記します。

これで、ボタンをクリックするとマクロを実行します。
4. クラスター計算機で udocker を利用する: 基本コマンド編-2

[基本コマンド編-1](https://qiita.com/percipere/items/e70efe47f6b1aad8bb4b)に引き続いて、基本的なコマンドの実行を行う

## ユーザーを指定してコマンドを実行する: udocker -q run --user=$USER --hostenv --bindhome --hostauth ubuntu コマンド

ユーザーのホスト上での環境変数を引き継いで、udockerを実行する

```bash
$ ./udocker -q run --user=$USER --hostenv --bindhome --hostauth ubuntu whoami; pwd
user12345
/home/user12345
```

* `--user=指定のユーザー`:環境変数の$USERを指定してコンテナ上で利用するユーザーを設定
* `--hostenv`: ホストの環境変数を引き継ぐための設定
* `--bindhome`: ホームディレクトリをそのままバインドするための設定

ここでは架空のユーザー"user12345"の結果を表示している。ユーザーとカレントディレクトリがコンテナ環境で利用できている事がわかる

ここでpythonを実行してみる

```bash
$ python --version
Python 2.7.5
$./udocker -q run --user=$USER --hostenv --bindhome --hostauth ubuntu python --version
Error: command not found or has no execute bit set:  ['python']
```

* 最初のコマンドはホスト上で実行され、ホストのpythonのバージョン番号が表示される
* 次のコマンドはコンテナ上で実行され、pythonが存在しないためエラーとなっている

##コンテナ上にpythonを`apt-get`を利用してインストールしてみる

```bash
$ apt-get
bash: apt-get: command not found...
$ ./udocker -q run ubuntu apt-get install -y python 
Reading package lists... Done
Building dependency tree       
Reading state information... Done
The following additional packages will be installed:
  file libexpat1 libffi6 libmagic1 libpython-stdlib libpython2.7-minimal libpython2.7-stdlib libsqlite3-0 libssl1.0.0 mime-support python-minimal python2.7
  python2.7-minimal
Suggested packages:
  python-doc python-tk python2.7-doc binutils binfmt-support
The following NEW packages will be installed:
  file libexpat1 libffi6 libmagic1 libpython-stdlib libpython2.7-minimal libpython2.7-stdlib libsqlite3-0 libssl1.0.0 mime-support python python-minimal python2.7
  python2.7-minimal
0 upgraded, 14 newly installed, 0 to remove and 0 not upgraded.
Need to get 5714 kB of archives.
After this operation, 25.7 MB of additional disk space will be used.
Get:1 http://archive.ubuntu.com/ubuntu xenial-updates/main amd64 libpython2.7-minimal amd64 2.7.12-1ubuntu0~16.04.3 [340 kB]
Get:2 http://archive.ubuntu.com/ubuntu xenial-updates/main amd64 python2.7-minimal amd64 2.7.12-1ubuntu0~16.04.3 [1261 kB]
...
Setting up libpython2.7-stdlib:amd64 (2.7.12-1ubuntu0~16.04.3) ...
Setting up python2.7 (2.7.12-1ubuntu0~16.04.3) ...
Setting up libpython-stdlib:amd64 (2.7.11-1) ...
Setting up python (2.7.11-1) ...
Setting up libmagic1:amd64 (1:5.25-2ubuntu1) ...
Setting up file (1:5.25-2ubuntu1) ...
Processing triggers for libc-bin (2.23-0ubuntu10) ...
```

ログが長いので途中省略

* 最初のコマンドはホスト上で実行され、`apt-get`が存在しないためエラーとなっている
* 次のコマンドはコンテナ上で実行され、`--user`が指定されていないので、root権限で`apt-get`が実行され、pythonがインストールされる

コンテナ上のpythonのバージョンを確認する

```bash
$ ./udocker -q run ubuntu python --version
Python 2.7.12
```

python 2.7.12がインストールされた事がわかる

ホスト上でrootの権限を持っていなくても、コンテナ上ではroot権限で`apt-get`を利用してパッケージがインストールができる事がわかった
(ここではホストのOSはRed Hat Linuxなので、もし、管理権限を持っていて、ホスト上にパッケージのインストールを行うにとすれば`yum`を利用することになる点に留意）

今日はここまで:smiley:
Domo のデータセットにデータをインポートする (go)

こちらのプログラムを Node.js で書きました。
[Python で Domo のデータセットにデータをインポートする](https://qiita.com/ekzemplaro/items/c29c8dcaa613c2c8d107)

```go:import_dataset.go
// ----------------------------------------------------------------
/*
	import_dataset.go

					Feb/25/2018
*/
// ----------------------------------------------------------------
package main
import (
	"fmt"
	"os"
	"log"
	"io/ioutil"
	"net/http"
)

// ----------------------------------------------------------------
func import_dataset_proc (access_token string,dataset_id string,file_csv string) {
	fmt.Fprintf (os.Stderr,"*** import_dataset_proc ***\n")
	fmt.Fprintf (os.Stderr,dataset_id)
	fmt.Fprintf (os.Stderr,file_csv)
	fp, err := os.Open(file_csv)

	url_datasets :="https://api.domo.com/v1/datasets/" + dataset_id + "/data"

	req, _ := http.NewRequest("PUT", url_datasets, fp)
	req.Header.Set("Authorization", "Bearer " +  access_token)
	req.Header.Set("Content-Type", "text/csv")

	client := new(http.Client)
	resp, err := client.Do(req)

	if err != nil {
		log.Fatalln(err)
		fmt.Printf("%s", err)
		os.Exit(1) 
	} else {
		defer resp.Body.Close()
		contents, err := ioutil.ReadAll(resp.Body)
		if err != nil {
			fmt.Printf("%s", err)
			os.Exit(1)
		}

	json_str_out := string(contents)
	fmt.Printf("%s\n", json_str_out)
	}
}

// ----------------------------------------------------------------
func main() {
	fmt.Fprintf (os.Stderr,"*** 開始 ***\n")
	dataset_id := os.Args[1]
	fmt.Printf ("%s\n",dataset_id)
	file_csv := os.Args[2]
	fmt.Printf ("%s\n",file_csv)

	access_token := get_token_proc ()

	fmt.Fprintf(os.Stderr,"%s\n", access_token)

	import_dataset_proc (access_token,dataset_id,file_csv)

	fmt.Fprintf (os.Stderr,"*** 終了 ***\n")
}

// ----------------------------------------------------------------
```

get_token.go はこちらです。
[Domo の アクセストークンを取得する (go)](https://qiita.com/ekzemplaro/items/675804b80933317e5ccf)

```text:Makefile
import_dataset: import_dataset.go get_token.go
	go build import_dataset.go get_token.go
clean:
	rm -f import_dataset
```
ショートカット演算

・JavaScriptでは、論理演算子の時
　　　　・**空白文字**・**数値の０**・**null、undefined**
　の時はfalseとみなされます。
　　　


name変数は空白文字falseとみなされます。
右側は空白文字、数値の０、nullでないため日本太郎はtrueとみなされ代入されます。
よって日本太郎と表示されます。

```JavaScript:name.js
var name = '';
name = name || '日本太郎';

console.log(msg);      // 結果　日本太郎
```
漫画で学ぶCdr(LISPなり

この漫画でcdrについて識りました:relaxed:
[マンガで分かるLisp (その2)](http://lambda.bugyo.tk/cdr/mwl02/mwl02.html)

ブクマ
[はてなブックマーク - マンガで分かるLisp (その2)](http://b.hatena.ne.jp/entry/lambda.bugyo.tk/cdr/mwl02/mwl02.html)

ちな一話
[マンガで分かるLisp (その1)](http://lambda.bugyo.tk/cdr/mwl00/mwl00.html)

日本のLISPの父？竹内郁雄先生の最終講義-のブログ
[竹内郁雄先生最終講義に参加してきた - 西尾泰和のはてなダイアリー](http://d.hatena.ne.jp/nishiohirokazu/20100304/1267701185)

一話のブコメ
[はてなブックマーク - マンガで分かるLisp](http://b.hatena.ne.jp/entry/lambda.bugyo.tk/cdr/mwl00/mwl00.html)

P.S.
二話以降になると極端にブコメが減るのがはてなのヘルってる所以？シリーズものを無視るのはぼかぁ気に食わないっすけれども‥

:訂正感謝ですがCではなくLISPです.Cについては後ほど
【Unity】生成した空のゲームオブジェクトのローカル座標をVector3.zeroにするエディタ拡張

# はじめに

create-empty-at-zero-positionは生成した空のゲームオブジェクトのローカル座標をVector3.zeroにするエディタ拡張です。
類似のアセットに[Empty At Zero Creator](https://assetstore.unity.com/packages/tools/utilities/empty-at-zero-creator-97576)があります。
今回は既存のショートカット(Ctrl + Shift + N)に適用したかったため開発しました。

# create-empty-at-zero-position

## 導入方法

[create-empty-at-zero-position](https://github.com/tomoriaki/create-empty-at-zero-position) (GitHub)からダウンロードして、インポートしてください。

## デモ

![ss1.gif](https://qiita-image-store.s3.amazonaws.com/0/126970/073c2e22-f8d8-e6c5-9635-28708541c7b4.gif)

# 配布ライセンス

[MIT](https://github.com/tomoriaki/create-empty-at-zero-position/blob/master/LICENSE)

# 使用ライセンス

create-empty-at-zero-positionはEditorExtensionsをベースに作成しています
[Copyright (c) 2017 Stereoarts](https://github.com/Stereoarts/EditorExtensions)
漫画で学ぶLISP

マンガで分かるLisp(Manga Guide to Lisp)
このサイトの漫画でLISPを学びました:relaxed:
[マンガで分かるLisp(Manga Guide to Lisp)](http://lambda.bugyo.tk/cdr/mwl/)

ちょっ,あのちょまどさんも推している！？
<blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr">マンガで分かるLisp<br> <a href="https://t.co/RTFB13BzZt">https://t.co/RTFB13BzZt</a><br><br>出だし<br>&gt; 皆さん括弧は好きですか？<br><br>な、なんだこれは…Σ（・□・；） <a href="https://t.co/Q2gJLGt6FK">pic.twitter.com/Q2gJLGt6FK</a></p>&mdash; ちょまど@エンジニア兼マンガ家 (@chomado) <a href="https://twitter.com/chomado/status/670819318423138305?ref_src=twsrc%5Etfw">2015年11月29日</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>


マンガ Lisp OR xkcd
で検索けんさく
[マンガ Lisp OR xkcd - Twitter検索](https://twitter.com/search?q=%E3%83%9E%E3%83%B3%E3%82%AC%20Lisp%20OR%20xkcd&src=typd)

P.S.
顔文字は必須

追記:訂正感謝です‥
漫画でまねゔぅGit

xkcd で学びましょう:relaxed:

日本記事にsiボルとよい
xkcd git lang:ja
https://twitter.com/search?q=xkcd%20git%20lang%3Aja&src=typd

追記:
xkcd以外にも意外といい漫画あるのでgit comicで検索するといいですね！

git comic OR xkcd lang:ja

https://twitter.com/search?q=git%20comic%20OR%20xkcd%20lang%3Aja&src=typd

リアルタイム検索はハマればすごくヒットしますぅ
https://search.yahoo.co.jp/realtime/search?p=git%20comic
ざっくばらんメモ_25：kaggle bowl2018, Coursera Robotics Perception

###kaggle, bowl2018
[コンペ](https://www.kaggle.com/c/data-science-bowl-2018)
[code](https://github.com/festa78/kaggle_bowl2018)
まずはtensorflowベースのUNetを用いた手法がkernelに公開されているのでそれに沿って
実装を行っていく。
ただそのまま走らせるのでは面白くないので、いくつかdata augmentation手法を適用して
データを増やしたものを用いて学習をする。
ひとまず、そのまま走らせた結果：LB:0.303。
その後、データをいくつか見ると、白黒反転した画像がいくつか含まれている事が分かったので、
data augmentationに白黒反転を追加しテスト。結果：LB:0.341
Leader Boardを見ていると、まだ終盤ではないからか得点が拮抗しておらず、
上位勢においてもばらつきが大きい。
いずれにせよ上位勢はLB0.5を超えているので先は長い。

データをもう少し眺めてみると、比較的白黒に近い画像が多いのに対して、
たまに色がしっかりとついた画像が散在する。
こうした画像に対するロバスト性を上げるための工夫が必要なように思える。

###Coursera: Robotics Perception
前回までは非線形最適化を用いたPnP問題などの解法について学んだ。

今回はOptical Flowについて学ぶ。
Optical Flowでは微小変化した２つのposeから得られた画像を用いてその間の変分量を考える。
この変化量を各画像特徴点ごとに求め、そのベクトルを示したものがoptical flowになる。
その変化量は、pose位置の変化量に対応した特徴点のtranslationとrotationに関する変化の和として考える事が出来る。
ここでrotationは深さに独立した値として求まる。
translationは深さに依存するが、深さセンサ搭載のカメラを利用した場合、解くのは簡単になる。
そうでない場合でも、特徴点、点の移動方向、移動量との幾何学的関係を用いて、移動量に関する最小二乗誤差の問題にできる。
この場合移動量をサンプリングして、最も誤差が少なるものを選び取る手法が用いられる。

続いて、Structure from Motion (SfM)について学んだ。
SfMでは、複数の画像を入力として、画像内の物体を３次元復元し、かつ各画像に対応してカメラ位置を推定する。
この場合、物体の特徴点に関する３次元点から各画像の２次元への写像を考え、
その写像の推定値に関する２次元点の写像誤差を最小化する。
この問題はBundle Adjustmentと呼ばれる。
誤差を最小化は勾配法（Gauss-Newton法）が用いられるがそのためには全特徴点と全パラメータに関する、
ヤコビアン行列Jを求め、そのJ^T*Jの逆行列を計算する必要があり、高コストである。
そこでJに関する変換をいくつか重ねる事で、フレーム間の関係と特徴点間の関係に切り分ける事が可能で、
その事により効率的な計算が可能になる。

SfMに関連した技術としてVisual Odometry (VO)についても学んだ。
VOは複数画像をもとにカメラ位置を推定する点ではSfMに似ているが、
逐次的に前回までの結果から次の画像に関するカメラ位置、つまり軌跡（odometry）を予測していく。
またVSLAMはVOと同一視されるが、VSLAMの場合はさらに復元した３次元特徴を利用した
地図生成までを扱う。
VOにおいても、直近の観測結果を用いてBundle Adjustmentが行われる。
この時、外れ値除去が非常に重要で、どのフレームのどの特徴点対応を用いるかで結果が大きく変わってしまう。
また軌跡を描いていくにあたって、以前訪れた場所に再訪した場合、以前観測した３次元特徴点との対応をとる事も
精度の面で重要で、これはloop closureと呼ばれる。
Twitter検索おぷしょんでSchemerに

REPLの後にORをつけるかはご自由に

この検索おぷしょんでお幸せに:relaxed:
REPL Scheme OR LISP OR Clojure lang:ja OR @abcdefghijklisp

https://twitter.com/search?f=tweets&q=REPL%20Scheme%20OR%20LISP%20OR%20Clojure%20lang%3Aja%20OR%20%40abcdefghijklisp&src=typd

OR検索についての記事
> OR検索
OR (両側に半角スペース)で区切って、2つのワードを指定すると、OR検索を行なうことができます。「巨人、またはジャイアンツ、もしくはその両方のキーワードを含んだツイートを検索したい」という時に使います。ORは大文字でなければいけません。逆にorというキーワードを検索したい場合は、小文字で検索しましょう。
使用例: 巨人 OR ジャイアンツ
サンプル: WEBで検索 / アプリで検索

https://syncer.jp/twitter-how-to-use-search


そのサンプルURL

https://twitter.com/search?q=%E5%B7%A8%E4%BA%BA%20OR%20%E3%82%B8%E3%83%A3%E3%82%A4%E3%82%A2%E3%83%B3%E3%83%84&src=typd
Twitter拡張すぎょい~~TwitterをハックするChrome拡張について~~

[Google検索時に同時にTwitterも検索できる拡張機能『HashPlug』 | ライフハッカー［日本版］](https://www.lifehacker.jp/2012/11/121123hashplug.html)

[Google Chrome拡張『OmniRT』でリアルタイムを簡単に : Blog @narumi :](http://narumi.blog.jp/archives/4508251.html)

~~検索と同時にTwitter検索を可能にするChrome拡張？アドオンがヴァリ便利https://www.lifehacker.jp/2012/11/121123hashplug.html~~
~~追記:
これのマストドン版作りたいのですが‥Railsでやれゔぁいいのでせうか？~~

追記:
Markdownの打ち消し線は~~text~~
PostgreSQLでのC#分散トランザクション

C#で複数のDB(PostgreSQL)に対して登録／更新処理を行う必要があり、トランザクション処理としてはTransactionScopeを使用するとQiitaでの投稿があったので早速実装。

https://qiita.com/take2k/items/90459028933a1085efd4

しかし、Completeを実行していなくてもDMLでコミットされてしまっている。更にネットで検索してみると、どうやらPostgreSQLでは下記のように接続文字列にEnlist=trueが必要らしい。ロジックでの書き方もある模様。

```
Server=localhost;User id=hoge;password=hoge;Enlist=true
```

追記して実行してみると、コミットは回避されたが、今度は2つ目のDBに対して更新を行うと、TransactionScopeがDisposeされるタイミングでトランザクション例外が発生してしまう。TransactionScopeをネストしてDB単位で処理してみることに。

```
using (var ts = new TransactionScope()){
  using (var ts1 = new TransactionScope()){
    ts1.Complete();
  }
  using (var ts2 = new TransactionScope()){
    ts2.Complete();
  }//ここを抜けると例外
    ts.Complete();
}
```

同様に例外発生。
どうやらTransactionのスコープに問題があるようで、最終的には以下のように落ち着いた。

```
using (var ts = new TransactionScope()){
  using (var ts1 = new TransactionScope(TransactionScopeOption.RequiresNew)){
    ts1.Complete();
  }
  using (var ts2 = new TransactionScope(TransactionScopeOption.RequiresNew)){
    ts2.Complete();
  }
    ts.Complete();
}
```
ts1にはTransactionScopeOption.RequiresNewがなくても良かったかと。
突然GitHubとhttps通信できなくなったときの解決メモ

先日githubにpushしようとしたところ、
>error:  while accessing https://＊＊＊＊＊＊@github.com/＊＊＊＊＊＊/＊＊＊＊＊＊.git/info/refs
>
>fatal: HTTP request failed

と言われてしまい、解決するまでに時間を要してしまったのでメモしておきます。

#当方環境
CentOS 6.7(vagrant + VirtualBox)
git version 1.7.1

#結論
`yum update -y nss curl libcurl`
したらいけた。

#解決経緯
エラーメッセージでググってみると
[公式ヘルプっぽいページ(https://help.github.com/articles/https-cloning-errors/)](https://help.github.com/articles/https-cloning-errors/)
がヒット
当方gitのバージョンが1.7.1だったので最新バージョンに上げてみることに。

https://qiita.com/mochimochi-inu/items/914debabca56acc20a6d
の手順を参考にソースから
gitのバージョンを2.16.2に更新

試しにgit fetchしてみると
>fatal: unable to access 'https://＊＊＊＊＊＊@github.com/＊＊＊＊＊＊/＊＊＊＊＊＊.git/': SSL connect error

と出てきてエラーメッセージに変化が！

さらにググると
https://stackoverflow.com/questions/48938385/github-unable-to-access-ssl-connect-error
がヒット

>nssとcurlライブラリの問題だよ
>`yum update -y nss curl libcurl`
>てやったら解決するよ

と言っているようなので言われるまま
`yum update -y nss curl libcurl`
を実行し再びgit fetchすると見事成功！解決しました！

githubさんが古い通信ライブラリからの通信を弾く様にしたのか、原因詳細は定かではありませんが、ひとまずpushできるようになったので良しとしておきます。