OmniAICreator/Qiita-1.07M huggingface dataset:
WIndows Rドツボりメモ

## 綺麗に書き直しました

以下に書いているようなものを綺麗に書き直した記事をアップしました．
[こちら](https://qiita.com/mokab/items/647b84d05b91f5530634)


## この記事の意義

個人的にRcmdrとか，Rのパッケージインストールが上手くいかない場合のためのもの
for Windows

## 結構あるある問題
- OneDrive同期をしている？
    - パッケージインストール場所問題
    - →　明示的にインストール場所を変更することで対応可能
- ユーザは管理者？
    - パッケージインストール場所問題
    - →　管理者に設定してあげることで対応可能
- ユーザ名に日本語含む？
    - RStudioでドツボる
    - →　2バイト文字を含まない（日本語名ではない）新しいユーザーを作ることで対応可能
        - [こちら](https://support.microsoft.com/ja-jp/help/13951/windows-create-user-account)を参考に，日本語文字を含まない，アルファベットのみのユーザーを作成しましょう．

## Rcmdrインストール時のドツボり

- `dependencies=T`わすれ
    - Rcmdrは依存パッケージがクソおおい．
    - これを忘れるとRcmdr MiscとかCarがなくて動かない場合がある

```R
install.packages("Rcmdr", dependencies=T)
```
これで対応できることが多いイメージ．

## RStudioでknit関係のパッケージをインストールできない

下記のOneDrive連携に関して起こることがあるようです。
困ったら手動インストール

```R
 install.packages(c("evaluate", "digest", "highr", "markdown", "stringr", "yaml", "Rcpp", "htmltools", "knitr", "jsonlite", "base64enc", "rprojroot", "mime", "rmarkdown"), dep = T)
```

## うまくいかないときにチェックするものメモ
以下、2019年5月現在では解決されてるっぽいです。
古いバージョンのWindows、R関係を使っている場合は起こりうるみたいなので、一応残しておきます。

以下は

- `.libPaths()`はどこ？
    - ときどき変な場所に指定されてる．
- OneDrive連携は？
    - 同期設定をONにしてると，インストール先がOneDriveになることがあるらしい．
    - [とりあえずチェック](http://windowsfaq.net/onedrive/to-release/)
    - ~~設定変更の際の注意点~~
        - ~~Miceosoftアカウントをサインアウトせずに上記URLをもとにして，ドキュメントの同期を切る（このPCのみにする）~~　あんまり連携を切らない方がいいかも．（あとで追記する）
    - Special Thanks いぐっさん先輩
- なんかへんな表示が出て，パッケージをインストールをしてもうまくいかない．
    - `.libPaths()`で出てくるドキュメントフォルダ以下に存在する`R`フォルダを削除する．
        - 特になにもしていなければ，このフォルダにインストールされるはず．
        - ![スクリーンショット 2018-04-23 16.38.06.png](https://qiita-image-store.s3.amazonaws.com/0/62741/5096d2be-3980-ffe7-218e-fe8c21d337e8.png)

    - 削除してきれいにしてから，Rを再起動して，パッケージをインストールしなおす．

- Microsoft R Openに関して
    - Microsoft R Open × RStudioを用いている場合，`{rmarkdown}`のインストールで詰まる可能性があります．
    - この場合は，レポジトリを統計数理研究所のCRANにセットすることで解決できます．
        - `options(repos = "http://cran.ism.ac.jp/")`と入力することで可能です．
    - これは，MRANで公開されているバージョンが最新のRStudioのknitに合わない場合に起こりえるものです．
JPEG XSコーデックメモ

#JPEG XS
https://jpeg.org/jpegxs/

低レイテンシ(low-latency)で計算コストの小さい(lightweight)、視覚的ロスレス(visually lossless)品質のデジタル静止画像圧縮技術（コーデック）。


## 特徴と応用先
JPEG XSコーデックの特徴は下記の通り：

- 最大解像度: 8K
- フレームレート: 24 ～ 120fps
- 色空間: RGB, YCbCr(YUV)系
- 品質劣化の小さい視覚的ロスレス
  - 圧縮率 1/2 ～ 1/6 で7回の反復エンコード後 [[IIS-INTRO][iis-intro]]
- 軽量な画像処理のため低消費電力
- 低レイテンシなエンコード／デコード処理
  - 処理レイテンシ＝32ライン未満 [[IIS-INTRO][iis-intro]]
- 比較的簡易なアルゴリズムのため実装が容易
  - 小さなASIC/FPGAハードウェア実装面積
  - SIMD命令やGPU利用による高速なソフトウェア実装

JPEG XSコーデックは、低計算量・低レイテンシが要求されるアプリケーションにおいて、主に「[Mezzanine(舞台下の)](https://ejje.weblio.jp/content/mezzanine)コーデック」としての利用が期待されている。

- ライブ・プロダクション
- 放送・デジタルシネマ ワークフロー
- プロ向け映像市場
- KVM[^kvm]アプリケーション
- VRゲーム など

[^kvm]: KVM = Keyboard, Video and Mouse


### JPEG XSは何ではないか

JPEG XSは、従来の(無印)JPEG, JPEG2000, JPEG XR, WebP, HEIFといった大量データ保存・WEB配信向けコーデックを **置き換える技術ではない**。

JPEG XSのゴールは「少ない計算機資源・**低消費電力でも動作**する」「コーデック**遅延が極小**」「ほとんど**画品質劣化を生じない**」であり、データ削減性能は 1/2～1/6程度 がメインターゲットとなっている。古典的な(無印)JPEGでも1/10程度にデータ削減されるため、JPEG XSは **データサイズ削減が重要なユースケースには不適切** である。


### VR/AR, ストリーミング 向け？
一部記事([engadget](https://japanese.engadget.com/2018/04/16/jpeg-xs-vr/))では “ストリーミング向け” のように紹介されているが、ここでいうストリーミングはインターネットのようなベストエフォート型公衆回線ではなく、映像伝送ケーブル(HD-SDI, DisplayPort, etc.)、ローカルEthernet網～閉域網、5G通信といった高速広帯域ネットワーク上での映像ストリーミングを意図すると思われる。“VR/AR” といった応用も、ケーブル／無線を介したPCからヘッドマウントディスプレイ(HMD)デバイスへの映像伝送を低遅延・高画質に行うことが目的と解釈できる。

（記事タイトルが煽り気味なのはマスメディアの常ですよね...）


## 符号化スキーム

<img width="636" alt="blockdiagram.png" src="https://qiita-image-store.s3.amazonaws.com/0/6657/5b3096ff-90dc-34c0-57c6-934478fe8971.png">
（参考文献[[IIS-INTRO][iis-intro]]より引用）

<img width="620" alt="decodingoverview.png" src="https://qiita-image-store.s3.amazonaws.com/0/6657/b37ea23a-c263-1650-d042-7e7f80ede7d5.png">
（ISO/IEC 21122-1 N77026(CD)より引用）

- 色変換（JPEG2000の可逆変換と同じ）
- Wavelet変換（JPEG2000の5/3フィルタ; 垂直2段／水平5段までのサブバンド分割）
- 量子化/逆量子化
- エントロピ符号化


## 参考情報

- https://www.itscj.ipsj.or.jp/sc29/29w42901.htm#JPEGXS
- [Fraunhofer IIS - JPEG XS](https://www.iis.fraunhofer.de/en/ff/amm/prod/bildkompr/jpegxs.html)
- [A new JPEG format for virtual reality, drones and self-driving cars](https://actu.epfl.ch/news/a-new-jpeg-format-for-virtual-reality-drones-and-s/)
- [Introduction to JPEG XS][iis-intro]

[iis-intro]: https://www.ibc.org/content-management/introduction-to-jpeg-xs/2452.article
utopでDeferredの中身が見えない場合の対処法

結論から言うとOCamlのバージョンを上げてやることで解決しました。

# 問題
本来utopで`'a Deferred.t`型の値を評価すると計算結果(`'a`)を表示してくれるのですが、手元のutop 2.0.1 + OCaml 4.02.3では次のように表示されました。

```text
utop # let three = Async.Std.return 3;; 
val three : int Deferred.t = <abstr>
utop # three;;
- : int Deferred.t = <abstr>      
```

# 対処法
`opam switch`でOCamlのバージョンを変更(4.02.3 -> 4.03.0)します。

```text
$ opam switch 4.03.0
```
基本的にはこれで終わりですが、モジュール等はインストールしなおす必要があります。

```shell-session
$ eval `opam config env`
$ opam install utop core async
```

# 確認
```shell-session
utop # let three = Async.Std.return 3;; 
Characters 12-28:
Warning 3: deprecated: module Async.Std
[since 2017-02] use Async. The Std sub-module is no longer needed
val three : int Async.Deferred.t = <abstr>
utop # three;;
- : int = 3
```
ちゃんと`Deferred`の中身が分かるようになりました。


ちなみにutopのバージョンが原因という場合もあるようです。
[Utop not waiting for Deferred to determine then displaying result · Issue #137 · diml/utop](https://github.com/diml/utop/issues/137)
[Async.Std.Deferred.t not automatically resolving · Issue #219 · diml/utop](https://github.com/diml/utop/issues/219)
オフラインリアルタイムどう書く F10 の実装例(Go)

問題 : http://nabetani.sakura.ne.jp/hena/ordf10updown/
実装リンク集 : https://qiita.com/Nabetani/items/dae474bc17827f9b1537

で。

https://qiita.com/Nabetani/items/1e673478d99e5dbfc1be にある実装のうちのひとつ（ruby の方 ) を、go で書いてみた。

```go:実装
package f10

import (
	"fmt"
	"strconv"
)

func numAt(f map[string]int, x int, y int) string {
	val, ok := f[fmt.Sprintf("%d,%d", x, y)]
	if !ok {
		return "-"
	}
	return strconv.Itoa(val)
}

func solve(src string) string {
	num, _ := strconv.Atoi(src)
	f := map[string]int{}
	phase := 0
	x := 0
	y := 0
	var numx int
	var numy int
	upperbound := num*2 + 100 // 根拠のない計算
	for i := 1; i < upperbound; i++ {
		f[fmt.Sprintf("%d,%d", x, y)] = i
		if i == num {
			numx, numy = x, y
		}
		switch phase {
		case 0:
			y++
			phase = 1
		case 1:
			x++
			if x == y {
				phase = 2
			}
		case 2:
			y--
			if y == 0 {
				phase = 3
			}
		case 3:
			x++
			phase = 4
		case 4:
			y++
			if x == y {
				phase = 5
			}
		case 5:
			x--
			if x == 0 {
				phase = 0
			}
		}
	}
	v0 := numAt(f, numx, numy-1)
	v1 := numAt(f, numx, numy+1)
	v2 := numAt(f, numx-1, numy)
	v3 := numAt(f, numx+1, numy)
	return fmt.Sprintf("%s,%s,%s,%s", v0, v1, v2, v3)
}
```

```go:test
package f10

import (
	"testing"
)

func TestKoch(t *testing.T) {
	var tests = []struct {
		name  string
		input string
		want  string
	}{
		{"0", "10", "9,25,-,11"},
		{"1", "1", "-,2,-,4"},
		{"2", "2", "1,9,-,3"},
		// 中略
		{"35", "6772", "6771,6773,6677,7009"},
	}
	for _, test := range tests {
		got := solve(test.input)
		if got != test.want {
			t.Errorf("%v: solve(%q)=%q, want %q\n", test.name, test.input, got, test.want)
		}
	}
}
```

別に難しいことはなくて、順当な感じ。
後置if がほしいなぁとか、そういう気分。

v0〜v3 への代入をもう少しなんとかしたいところだけど、goならこんな感じかなとも思ったりする。
Macにpythonをインストールしaws-cliが実行できない経緯と解決方法

# 目的
aws-cliを使用したく、pythonを入れて、公式のコマンドを実行しようとしても上手くできなかったので、その備忘録。
ちなみに数年前にanaconda3などをmacに入れた事があったが、その設定がかなり気に入らなかったので、それをアンインストールして、再度インストールしようとした時に問題が発生。
今回はhomebrewを利用してのインストールを試みた。
途中のPATHの設定は色々いじったので、記載を省略。

# 仕様
Macbook: MacOS High Sierra
Homebrew: 1.6.0

# 経緯

## Pythonをインストール
homebrewを利用し、pythonをインストール
`$ brew install python3`

以下で正常にpythonがインストールできていることを確認
`$ python3 --version`
結果は以下
> Python 3.6.5

正常にインストールする事ができた。

## aws-cliをインストール

次にaws-cliをインストール
`$ pip3 install aws-cli`

以下を実行
`$ aws --version`

しかし結果
> -bash: /usr/local/bin/aws: /usr/local/opt/python/bin/python2.7: bad interpreter: No such file or directory

インストールは成功したが、実行できない。

## 不具合調査・解決

以下でどうなっているのか確認
`$ which aws`
結果は以下
> /usr/local/bin/aws

`$ which python3`
結果は以下
> /usr/local/bin/python3

うーん、何故だ。。。
実行時に過去にインストールしたaws-cliが邪魔をしているみたいだ。
（anaconda3を入れる前に、インストールしてたかも…）

そもそもhomebrewのインストール時にエラーが出ていたのではと思い、以下で調査。
`$ brew doctor`
結果は以下
> Warning: You have unlinked kegs in your Cellar
Leaving kegs unlinked can lead to build-trouble and cause brews that depend on
those kegs to fail to run properly once built. Run `brew link` on these:
  awscli

やはり！`brew link`と書いてあるので、`$ brew link aws-cli`を実行する。
> Linking /usr/local/Cellar/awscli/1.15.0... 
Error: Could not symlink bin/aws
Target /usr/local/bin/aws
already exists. You may want to remove it:
  rm '/usr/local/bin/aws'
To force the link and overwrite all conflicting files:
  brew link --overwrite awscli
To list all files that would be deleted:
  brew link --overwrite --dry-run awscli

強制的にlinkしてもいいかなと思いましたが、仕様していないファイルはしっかり消したいので、
`$ rm '/usr/local/bin/aws' `
で削除を実行
再度`$ brew link awscli`を実行
> Linking /usr/local/Cellar/awscli/1.15.0... 
Error: Could not symlink bin/aws_completer
Target /usr/local/bin/aws_completer
already exists. You may want to remove it:
  rm '/usr/local/bin/aws_completer'
To force the link and overwrite all conflicting files:
  brew link --overwrite awscli
To list all files that would be deleted:
  brew link --overwrite --dry-run awscli

が表示されたため、これも削除を実行する
`$ rm '/usr/local/bin/aws_completer' `

再々度`$ brew link awscli`を実行する
> Linking /usr/local/Cellar/awscli/1.15.0... 6 symlinks created

できたっぽい！`$ aws --version`で確認する
> aws-cli/1.15.0 Python/3.6.5 Darwin/17.5.0 botocore/1.10.0

できたー！実際にこの後`aws`コマンドも正常に利用する事が可能となった。

## まとめ
多分知っている人にとってはかなり初歩的な話であったと思う。
一番の原因はanacondaですでに入れており、それをアンインストールする際に色々残っていたのが原因と考える。
初めからCloud9を利用してやって入れば楽であったかも…
色々調べてPathの設定や、pythonについて理解を深める事ができたので良し。

以下のサイトが参考になりました。ありがとうございます。
[MacでPythonが動かない状況をなんとか解決](https://qiita.com/koomaru/items/0c9d669ded8d6d66bd24)
[Homebrewインストールのlinkエラーを修正する方法](http://wtnvenga.hatenablog.com/entry/2017/11/15/125430)
Rails ページ遷移元をコントローラで取得

#目標
ViewでRedirect_to等でページ遷移をおこなった時にViewで条件分岐をするのかControllerで条件分岐をするのかよく考えControllerが最適だと判断した
今回は、
**ページ遷移が起こったとき、ページ遷移先のコントローラ内で、遷移元のコントローラ名を明示して変数を操る**


#補足
スポーツ関連のアプリで、試合（＝Game）を組みたいもの。
ユーザーは基本的な利用では場所情報が入っているPlaceテーブルから最初に開催地を選択しparamsで場所idをとばして試合を組むが、
ユーザーは試合詳細ページから全く同じ条件（場所、参加条件等、　開催日以外）で簡単に試合を開催できる複製機能を設置したかった。


#ソースコード

```rb:games_controller
def new 
 @path = Rails.application.routes.recognize_path(request.referer)
#games#showから遷移。試合の開催日以外は同じ条件で試合の予定を組みたい
 if @path[:controller] == "games"
  @game = Game.find(params[:id])
  @game.fight_time = Time.zone.now.beginning_of_hour;1.week 
 else #place#index等
  @game = Game.new(place_id: params[:id])
 end
end
```

#参考ページ
https://qiita.com/sayama0402/items/ffe96ff76148231a0c22
↑　取得方法について

http://ruby-rails.hatenadiary.com/entry/20141217/1418817120#activesuppor-time-prev-and-next
↑　railsでの時間の操り方
Wi-Fiの位置情報サービスのオプトアウト方法

# はじめに

Wi-FiのSSIDやBSSID(MACアドレス)をかき集めて位置情報データベースを作っているサービスがいくつかある(Google とか Apple とか)。
プライバシー、あるいは位置情報の精度のために、モバイルWi-FiなどのSSID/BSSIDをオプトアウトする方法がいくつか存在するので、とりあえずメモ。

http://takagi-hiromitsu.jp/diary/20111126.html

# オプトアウト方法

## Google

SSIDの末尾に `_nomap` を付けるとオプトアウトされる。

https://support.google.com/maps/answer/1725632?hl=ja

## Apple

オプトアウトの方法はなさそう。

https://mobile.srad.jp/story/16/02/17/0458243/

`http://tsuchinoko.dmmlabs.com/?p=2982` （リンク切れ, [internet archive](https://web.archive.org/web/20160215035539/http://tsuchinoko.dmmlabs.com/?p=2982) )

上記サイトを見ると、Appleの場合には SSID は収集対象になっていないみたい。
つまり現状、BSSID(MACアドレス)のみを収集しているので、SSID によるオプトアウトは不可能だと思われる。

## Microsoft

BSSID(MACアドレス)を登録して除外する

https://support.microsoft.com/ja-jp/help/20039/opt-out-of-location-services

ちなみに位置情報サービスとは別の話だが、「Wifiセンサー」の対象外とするには、SSIDのどこか（末尾でも中間でもOK）に `_optout` を付ける。

https://blogs.technet.microsoft.com/jpsecurity/2015/08/20/windows-10-wi-fi-wi-fi-sense/

## Mozilla

Googleと同様に、SSIDの末尾に `_nomap` を付けるとオプトアウトされる。

https://location.services.mozilla.com/optout

## PlaceEngine

Googleと同様に、SSIDの末尾に `_nomap` を付けるとオプトアウトされる。

http://www.placeengine.com/show/faq/#optout_nomap

## Skyhook

BSSID(MACアドレス)を登録して除外する

https://www.skyhookwireless.com/opt-out-of-skyhook-products

「I do not want Skyhook to use my Wi-Fi access point for positioning or use in Skyhooks positioning system」を選択して、MACアドレスを入力
Windows 8.1のタスクバーに普通にはピン留めできないソフトをピン留めする

# 背景

自分はWindows 8.1がインストールされたタブレット端末を使っているが、
この機種は内部ストレージの容量が約24GBしか無く、
普通にソフトをインストールしていくといっぱいになってしまった。
そこで、大容量のMicroSDカードを挿し、そこにソフトをインストールすることにした。

すると、そこで問題が起こった。
なぜか、MicroSDカードにインストールしたソフトがタスクバーにピン留めできない。
これでは不便なので、ピン留めする方法を探した。

# ダメだった方法

* ソフトを起動し、タスクバー上のアイコンを右クリック
* エクスプローラでソフトの実行ファイルを右クリック
* スタートメニュー上のソフトのアイコンを右クリック
* ソフトのショートカットをCドライブ上に作り、右クリック

全て表示されるはずの「タスクバーにピン留めする」的なメニューが表示されなかった。
ソフトの実行ファイルやショートカットをタスクバーにドラッグ&ドロップしてもダメだった。
エクスプローラやスタートメニューでは「スタートにピン留め」なら表示されたのに。いじわる。

# ある程度うまくいった方法

[Windows 8 のタスクバーにフォルダをピン留めする手順 - けふまな](http://kefumana.net/windows8-folder-pin-taskbar)
このサイトの方法を参考にすることで、ある程度の進展が得られた。
具体的には、以下の方法により、クリックすると目的のソフトが立ち上がるアイコンをタスクバーに作ることができた。

1. デスクトップなど、Cドライブの適当な場所に目的のソフトへのショートカットを作成する。
2. そのショートカットのプロパティを開き、「リンク先」の先頭に`explorer `と書き加え、OKを押す。  
   `explorer`ともとのリンク先の間には半角空白を1個入れる。
3. するとショートカットのアイコンがエクスプローラになるので、  
   もう一回プロパティを開き、「アイコンの変更」から目的のソフトのアイコンにする。
4. このショートカットをタスクバーにピン留めする。  
   このピン留めは、右クリックメニューからでもドラッグ&ドロップでもできた。
5. ここで作ったショートカットは、ピン留めしたら削除してよい。

ただし、この方法でタスクバーにソフトの起動アイコンを作ることはできたが、起動してみると、
起動したソフトのアイコンが作った起動アイコンとは別にタスクバーに表示されてしまった。
そこで、次の手順できちんとアイコンが統合されるようにする。

# さらにもうひと工夫

以下の手順により、タスクバーにピン留めされたアイコンからソフトを起動し、
普通にそのアイコンでウィンドウを切り替えられるようにできた。

1. 上の手順でピン留めしたタスクバー上のアイコンを、Shiftキーを押しながら右クリックする。
2. するとメニューが表示されるので、「プロパティ」を選ぶ。
3. するとショートカットのプロパティが表示されるので、  
   「リンク先」の先頭の`C:\Windows\explorer.exe `を削除し、OKを押す。  
   `explorer.exe`の後の半角空白も消す。

# まとめ

Windows 8.1のタスクバーに、素直に右クリックなどからピン留めできないソフトをピン留めするには

1. デスクトップなど、Cドライブの適当な場所にそのソフトへのショートカットを作る
2. そのショートカットのプロパティを開き、「リンク先」の先頭に`explorer `を追加する
3. そのショートカットのアイコンを目的のソフトのものに設定し直す
4. 作ったショートカットをピン留めし、ショートカット自体は削除する
5. ピン留めしたアイコンをShiftキーを押しながら右クリックし、プロパティを開く
6. 「リンク先」の先頭の`C:\Windows\explorer.exe`を消す
PythonでFactoyMethod

FactoryMethodが便利だったのでメモ。FactoryMethodはデザインパターンの一つで、一般的なインスタンス生成とは異なる方法でインスタンスを生成できます。具体的にはstrを渡してインスタンスが生成できるので、いろいろ使える場面がある気がする。

# 使い方の例
```python
class Dog:
    def bark(self):
        print('ワンワン')

class Cat:
    def bark(self):
        print('ニャーニャー')

def pet_shop(pet):
    # これがFactoryMethod
    pets = dict(Dog=Dog, Cat=Cat)
    return pets[pet]()

my_dog = pet_shop('Dog')
my_dog.bark()
# >> ワンワン
my_cat = pet_shop('Cat')
my_cat.bark()
# >> ニャーニャー
```

参考ページ
[python-patterns](https://github.com/faif/python-patterns/blob/master/creational/factory_method.py)
NVIDIAのライブラリでOpenCL(Windows)

# OpenCL.libのありか
次やる時絶対忘れてる自信があるのでメモ。

NVIDIAのOpenCLライブラリはCUDA SDKにまとめられているので、CUDAのSDKをダウンロードする。

CUDA SDKのパスがCUDA_PATH環境変数に入っているので確認。

```
CUDA_PATH='C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v9.1'
```
このパスのlibの中にOpenCL.libが入っているのでそれを使用する。23kbとかの小さいライブラリファイルだけど、今の所ちゃんと動いてる。

#ついでにRustでOpenCL
Cargo.tomlに

```
ocl = "*"
```
追加。

main.rsとかで

```
extern crate ocl;
```

追加。

あとはとりあえず情報出すコードを書いてビルドが通るか試す。

```
    let platforms = ocl::Platform::list();
    for platform in platforms {
        println!("{}", platform);
    }
```

Cargo.tomlと同じ場所に、先程拾ったOpenCL.libを置いて

```
Cargo build 或いは Cargo run
```
【C#】ショートカットのリンク先取得

# 00. はじめに
ファイルのドラッグ&ドロップを許可する場合、指定のファイルのみだけではなく、ファイルへのショートカットも受け付けるようにした方がUXが良いように思えます。
ここではショートカットのリンク先を取得する方法を記載します。
なお、ここでいうショートカットは".lnk"拡張子であり、".url"のインターネットショートカットではないです。
（".url"はただのテキストファイルですし...）

# 01. 参照の追加
参照マネージャーの"COM"から
"Windows Script Host Object Model"
にチェックを入れます。
![pro01.png](https://qiita-image-store.s3.amazonaws.com/0/235452/ed89f4c5-c6fd-264b-ee9d-3a4387e18f1a.png)

# 02. コード
```cs
// ドロップ時のイベント
private void DragDrop(object sender, DragEventArgs e)
{
    // ドロップされたファイルを順に確認する
    foreach (string file in (string[])e.Data.GetData(DataFormats.FileDrop))
    {
        // ファイルの拡張子を取得
        string extension = Path.GetExtension(file);
        // ファイルへのショートカットは拡張子".lnk"
        if (".lnk" == extension)
        {
            IWshRuntimeLibrary.WshShell shell = new IWshRuntimeLibrary.WshShell();
            // ショートカットオブジェクトの取得
            IWshRuntimeLibrary.IWshShortcut shortcut = (IWshRuntimeLibrary.IWshShortcut)shell.CreateShortcut(file);

            // ショートカットのリンク先の取得
            string targetPath = shortcut.TargetPath.ToString();
        }
    }
}
```

"Windows Script Host Object Model"の詳細は以下を参照
Windows Script Host のオブジェクト モデル | https://msdn.microsoft.com/ja-jp/library/cc392522.aspx

# 98. 参考
C#によるショートカットファイルのリンク先ファイルのパス名取得の試作 | https://blogs.yahoo.co.jp/tinatina_2013/64256895.html

# 99. 更新履歴
|日付|内容|
|:--|:--|
|2018/04/16|投稿|
.NET の Enum に対する不満をいろいろ解消してくれるライブラリ Enums.NET

# enum への不満
.NET の enum のパフォーマンスに対する記事を目にする機会は多いと思います。（[追記あり](#追記2)）

- [enumはenum以外の用途で使うと遅いのは何故か C#+WPFチューニング戦記]
(http://proprogrammer.hatenadiary.jp/entry/2014/08/17/015345)
- [Enum.IsDefinedのパフォーマンス - 匣の向こう側 - あまりに.NETな](http://d.hatena.ne.jp/akiramei/20080613/1213370665)
- [EnumオブジェクトのToStringメソッドはswitch文の100倍以上遅いので<br/>ILGeneratorで動的にswitch文を生成&コンパイルして高速化する方法 @higty](https://qiita.com/higty/items/513296536d3b26fbd033)

他にもジェネリクス関係で `IEquatable<T>`, `IComparable<T>` を実装してないとか、`HasFlag` の制約が甘いとか、`Enum.GetValues` の `typeof` がいちいち面倒臭いなどなど…。

# [Enums.NET](https://github.com/TylerBrinkley/Enums.NET)
そんなときふとこんなライブラリを発見しました。その名も **[Enums.NET](https://github.com/TylerBrinkley/Enums.NET)** ！

どんな機能があるかは [github のデモ](https://github.com/TylerBrinkley/Enums.NET/blob/master/README.md#enumsnet-demo) を見ればおおよそわかると思いますが、何点か特徴をあげます。

- `Enums.GetMembers<T>()` で値と名称をまとめて foreach できる。
- `HasAllFlags<T>()`, `HasAnyFlags<T>()`,  `RemoveFlags<T>()`  等のフラグ操作。
- キャッシュをもつことによる高速化
![alt](https://github.com/TylerBrinkley/Enums.NET/raw/master/performance.png)
[引用元](https://github.com/TylerBrinkley/Enums.NET/blob/master/README.md#performance-comparison)

<br/>
<br/>
<br/>

# …皆さんお気づきだろうか？
あれ！？ Enum ってジェネリクスの制約につかえなくね？（[追記あり](#追記1)）

```csharp
public static void Hoge<T>(this T @this)
  where T : Enum  // コンパイルエラー
{
}
```

しかし、実は C# でできないだけで、MSIL 等で記述すれば可能なのです。
[C# のジェネリックで Enum/Delegate 制約を使う - 捨てられたブログ](https://blog.recyclebin.jp/archives/2499)

Enums.NET では [Fody.ExtraConstraints](https://github.com/Fody/ExtraConstraints) を使って制約を付加しています。
いつも [Fody.PropertyChanged](https://github.com/Fody/PropertyChanged) のお世話になっていて MSIL の件も知っていたのに、こんな発想は1ミリも出てこなかった…。世のエンジニアの方々には脱帽するほかありません。

---

## 追記1
@mak_in さんより C# 7.3 にて Enum と Delegate が制約に使えることを教えていただきました。
まだリリース前なので、アップデートを待ちましょう。
[C# 7.3 の新機能 未確認飛行 C](http://ufcpp.net/study/csharp/cheatsheet/ap_ver7_3/#constraints)

---

## 追記2

.NET Core 2.1 では HasFlag のパフォーマンスが上がるそうです。
[Enum.HasFlag(Enum) のパフォーマンスの測定](https://gist.github.com/ufcpp/79283511d2a10afb34f8c5c837dce1a6)
[Arduino] Windowsで突然コンパイルエラー。(readlink ...The system cannot find the file specified ...Error compiling...)

## やりたいこと
以下の環境で発生するコンパイルエラーを直したい

```
OS : Windows 10 Pro (OS Build 16299.371)  
Arduino IDE : 1.8.5  
スケッチパス : (インストール時のデフォルト)   
Board : Arduino Uno R3
```

## 現象
2カ月くらい前には正常に動いていた Arduino IDE で、
突然コンパイルエラーが発生するようになった。
以下のようなエラーメッセージが出る。

```
readlink C:\Users\goshi\OneDrive\Documents\Arduino\harware: The system cannot find the file specified.
Error compiling for board Arduino/Genuino Uno.
```

## 解決策
以下の情報によると、どうやら、Arduino IDEインストール時に自動で設定されたスケッチ保存ディレクトリのパス OneDrive が怪しい様子。

[Compilation fails with OneDrive / "Cloud reparse points" #254](https://github.com/arduino/arduino-builder/issues/254)
(最近のWindows 10のバージョンとOneDriveを組み合わせると、arduino-builderがファイルを読み取れないという問題が発生といった内容)

現時点では、OneDriveを使用する必要はないので、
スケッチ保存ディレクトリを変更して対応。

```
- スケッチの保存ディレクトリの場所を確認
    Arduino IDE : File ->Preferences -> settings -> sketchbook location 

- スケッチ保存ディレクトリの移動
    OneDrive 配下ではない任意の場所に移動

-　スケッチ保存ディレクトリの場所を再設定 
    Arduino IDE の sketchbook location の設定を変更する  
    
- IDEを再起動
```

これで無事にコンパイルが通るようになった。

なお、OneDriveを無効にする場合は次のリンクを参考にするとよいかもしれない。
[Windows 10でOneDriveを無効・フォルダ場所変更・同期停止する方法](https://pssection9.com/archives/windows10-onedrive-invalid-folder-change-synchronization-stop.html)

## 注意
最初、Arduino 1.8.5 (Windows Store 1.8.10.0)を使っていたが、
スケッチの保存場所を変更しても、再起動のたびに、
再度、OneDrive直下にディレクトリが作成されてしまう謎の現象が発生。

file->preferences->settings に記載のある、preference.txtのパスが、
通常インストールだと、/AppData/Local に設定されるはずが、
/OneDrive 配下になっているのが怪しい。
あまり深追いせず、スケッチ保存場所を退避してから、
Windows Storeの Arduino IDE はアンインストールし、
通常のインストーラーでインストールし直し、上記の解決策を試した。
オフラインリアルタイムどう書くE23の実装例(Go)

オフラインリアルタイムどう書くE23の実装例
問題 : http://nabetani.sakura.ne.jp/hena/orde23nokoch/
イベント : https://yhpg.doorkeeper.jp/events/71800
実装リンク集 : https://qiita.com/Nabetani/items/77e7e2c749767f197c0e

で。

腕力版を go で書いてみた。

```go:実装
package koch

import (
	"strconv"
	"strings"
)

func solve(s string) string {
	separated := strings.Split(s, ",")
	pos, _ := strconv.Atoi(separated[0])
	pos--
	commands := separated[1]
	curve := []int{0}
	for _, cmd := range commands {
		c := make([]int, 0, len(curve)*5)
		for _, e := range curve {
			if cmd == 'a' {
				c = append(c, e+0, e+1, e+2, e+0)
			} else {
				c = append(c, e+0, e+1, e+0, e+2, e+0)
			}
		}
		curve = c
	}
	if len(curve) <= pos {
		return "x"
	}
	return [3]string{"0", "+", "-"}[curve[pos]%3]
}
```

```go:test
package koch

import (
	"testing"
)

func TestKoch(t *testing.T) {
	var tests = []struct {
		name  string
		input string
		want  string
	}{
		{"0", "120,aabb", "0"},
		{"1", "100,a", "x"},
		{"2", "3,a", "-"},
		// 中略
		{"66", "36831104,babbbbbbabab", "+"},
	}
	for _, test := range tests {
		got := solve(test.input)
		if got != test.want {
			t.Errorf("%v: solve(%q)=%q, want %q\n", test.name, test.input, got, test.want)
		}
	}
}
```

手元のマシンで 2秒ちょっと。速いね。
goルーチンを使ったりすればもっと速いかもしれないけど、こんなところで。
micro:bit 入門

今回はmicro:bitを使ってはじめてのガジェット開発をしてみる。
現在の予定ではmicro:bitを使って2，3個の機能を搭載する予定です。

# micro:bitとは
情報教育のために英国放送協会が開発したBBC Microが各学校で使用されたように11歳と12歳の小学生全員に配布される低消費電力、低コストのシングルボードコンピュータ。

![microbit-front-jpg.jpg](https://qiita-image-store.s3.amazonaws.com/0/247084/1a506b54-972a-19ac-d44a-e93d2d9b62e4.jpeg)

# 特徴
- 25個別プログラマブル Led
- 2つのプログラム可能なボタン
- 物理的な接続ピン
- 光と温度センサー
- モーションセンサー (加速度計とコンパス)
- ラジオとブルートゥース経由での無線通信
- USBインタフェースなど

# Hello, World!を表示する
micro:bitはデバイスがなくてもクラウド上で実行ができます。
必要なのはmicrosoftのアカウントだけです！！！
※ただしScratch, JavaScriptのみ
今回はScratchを使ってプログラムします。
![test.gif](https://qiita-image-store.s3.amazonaws.com/0/247084/bbe532ee-dcab-d8cf-a1df-cc69cbe0a762.gif)

JavaScriptのコードは以下のようになります。
<img width="475" alt="キャプチャ.PNG" src="https://qiita-image-store.s3.amazonaws.com/0/247084/b8f0edd8-329c-2634-baa6-44aa4f90db1a.png">

その他にもたくさんの機能が利用できるのでぜひ使ってみてください！！

# 金額
micro:bit本体　　　　　　　　　　2,000円(税込み 2,160円)
micro:bitをはじめようキット　　　2,850円(税込み 3,078円)

 
# 購入先
日本での購入先は以下の2つです

switch education
https://switch-education.com/
SWITCH SCIENCE
https://www.switch-science.com/catalog/list/?keyword=micro%3Abit

Amazonでも購入できますのでぜひ買ってみてください！

# 今後について
今後はさまざまなアイディアを生み出してさまざまなものを作っていきたいと思います。
現在の予定ではmicro:bitを使ったゲームなどを予定しています。
気になる方は次の投稿をお待ちください♪
Git > raw_input() > sys.stdinをopen("/dev/tty")する理由

とある人の疑問

> gitのフックって sys.stdin をopen("/dev/tty") にしないとraw_input 出来ないのね…
この仕様なんなんだろ

ロシア語？のサイト
http://qaru.site/questions/433523/how-is-it-possible-to-use-rawinput-in-a-python-git-hook
> 2 ответов

において、gitコマンドのプロセス(21801)とpythonのプロセス(21802)がある。

21802に対してfd3が`/dev/tty`に紐付いている。

あと、ロシア語は分からない。


https://stackoverflow.com/questions/16960857/how-to-differentiate-dev-tty-with-stdin-stdout-stderr?rq=1
> When you call open you get a NEW file descriptor. 0, 1, 2 are already open when the process starts. So 3 is a newly created file descriptor. Use .fileno() on an existing file object to see the file descriptor number. – jim mcnamara Jun 6 '13 at 11:26 

fdの0, 1, 2はすでに開いていて、3が新たに作られるfile descriptor。

> 21802に対してfd3が`/dev/tty`に紐付いている。

ということで、`sys.stdin=open('/dev/tty')`をしないとダメな気がする。

### link

ロシア人が参考にした英語サイト(Stackoverflow）もあった。上記ロシア語サイトからリンクされている。

https://stackoverflow.com/questions/7437261/how-is-it-possible-to-use-raw-input-in-a-python-git-hook/7437724#7437724

実はgoogle検索するとこちらのサイトが上位に出てきていた。最初からこちらを読めばよかったのか。
S3から別リージョンのS3にオブジェクトをコピーする

コピー元、コピー先両方のバケットを指定してあげる必要がある。

`$ aws s3 cp s3://tokyo.bucket/hogehoge.jpg s3://seoul.bucket/ --source-region ap-northeast-1 --region ap-northeast-2`

- --recursiveオプションで全てのオブジェクトをコピーすることも出来る

`$ aws s3 cp s3://tokyo.bucket/ s3://seoul.bucket/ --recursive --source-region ap-northeast-1 --region ap-northeast-2`
これで便利に！ADユーザ情報を一括で編集するPowerShellスクリプト



すでに登録されているADユーザに対して詳細な情報を一括で編集します。

##編集用CSVファイルを準備する

CSVファイルの中身は下記の項目があればOKです。並び順は関係ありません。
sAMAccountNameでユーザを割り当てますので存在するアカウントを記載してください。

```user.csv
sAMAccountName	sn	givenName	company	msDS-PhoneticLastName	msDS-PhoneticFirstName	msDS-PhoneticDisplayName	mail	MobilePhone	name	cn	displayName
```

##AD情報を変更するPowerShellを準備する

importFilePathに読み込ませるCSVファイルを指定してください。

```powershell:adUserEdit.ps1
#importFilePathの中にCSVファイルデータを格納する
$importFilePath = "C:\ADUser\user.csv"

#上記で作成したimportFilePathから一件ずつループを回していく
import-csv $importFilePath | Foreach-Object {

    #useridという変数に、sAMAccountNameを格納する
    $userid=$_.sAMAccountName

echo $userid
echo $_.mail
    
    #更新用のデータを作成    
    $setuser_args = @{
        
        #更新用のキー
        Identity=$userid
        
	#漢字姓
	Surname=$_.sn

	#漢字名
	GivenName=$_.givenName

	#表示名
	DisplayName=$_.displayName

        #電子メールアドレス
        EmailAddress=$_.mail

	#携帯番号
	MobilePhone=$_.mobilePhone

	#会社名
	Company=$_.company


    };
    
    #Set-ADUserに渡す
    $keys = @($setuser_args.Keys |where {[string]::IsNullOrEmpty($setuser_args[$_])})
    $keys |foreach {$setuser_args.Remove($_)}
    Set-ADUser @setuser_args;

    #フリガナ
    $PhoneticDisplayName = $_."msDS-PhoneticLastName" + " " + $_."msDS-PhoneticFirstName"

    Set-ADUser $userid -add @{'msDS-PhoneticLastName'=$_."msDS-PhoneticLastName";'msDS-PhoneticFirstName'=$_."msDS-PhoneticFirstName";'msDS-PhoneticDisplayName'= $PhoneticDisplayName}

}
```

PowerShellを起動し、下記コマンドを実行します。
ActiveDirectoryに情報を書き込める権限を持ったユーザで実行する必要があります。
例）Domain Adminsに所属するadministratorアカウント等

```powershell
Import-Module ActiveDirectory
adUserEdit.ps
```

エラー処理を入れていないので、エラーの場合にはコンソールにエラーが表示されるだけなので、
そちらの表示を見てエラー対応をしてください。

それではよいWindows Serverライフを！
Windowsのコマンドプロンプトでファイルのハッシュ値を求める

Windowsでファイルのハッシュ値を確認するときは、PowerShellのGet-FileHashコマンドレットを使っていたんだけど、certutilコマンドを使えばコマンドプロンプトからでも確認ができるということを最近知ったのでそのメモ。

# ヘルプ
>C:\>certutil -hashfile -?
>使用法:
>  CertUtil [オプション] -hashfile InFile [HashAlgorithm]
>  ファイルに暗号化ハッシュを生成し表示します
>
>オプション:
>  -Unicode          -- リダイレクトされた出力を Unicode として書き込む
>  -gmt              -- 時刻を GMT で表示します
>  -seconds          -- 時間を秒とミリ秒で表示します
>  -v                -- メッセージを詳細に表示します
>  -privatekey       -- パスワードと秘密キーのデータを表示します
>  -pin PIN                  -- スマート カードの PIN
>  -sid WELL_KNOWN_SID_TYPE  -- 数値 SID
>            22 -- ローカル システム
>            23 -- ローカル サービス
>            24 -- ネットワーク サービス
>
>ハッシュ アルゴリズム: MD2 MD4 MD5 SHA1 SHA256 SHA384 SHA512 ★アルゴリズムを色々選べる
>
>CertUtil -?              -- 動詞の一覧 (コマンドの一覧) を表示します
>CertUtil -hashfile -?    -- "hashfile" 動詞のヘルプ テキストを表示します
>CertUtil -v -?           -- すべての動詞のヘルプ テキストをすべて表示します

# 実行例
>C:\>certutil -hashfile hoge.txt SHA256
>SHA256 ハッシュ (対象 hoge.txt):
>ebecd6eba5206645e5cb94de76b9bf430fc0b5941608758de096bb47be612310
>CertUtil: -hashfile コマンドは正常に完了しました。

# 参考
https://docs.microsoft.com/en-us/windows-server/administration/windows-commands/certutil#BKMK_hashfile
Learning Spatiotemporal Features with 3D Convolutional Networksを読んだ


Du Tran, Lubomir Bourdev, Rob Fergus, Lorenzo Torresani, Manohar Paluri, Learning Spatiotemporal Features with 3D Convolutional Networks, ICCV2015, pp. 4489-4497, 2015.

- [ICCV 2015 open access](http://openaccess.thecvf.com/content_iccv_2015/html/Tran_Learning_Spatiotemporal_Features_ICCV_2015_paper.html), 
[PDF](http://openaccess.thecvf.com/content_iccv_2015/papers/Tran_Learning_Spatiotemporal_Features_ICCV_2015_paper.pdf)
- [arXive](https://arxiv.org/abs/1412.0767), [PDF](https://arxiv.org/pdf/1412.0767)


# 1.どんなもの？
3次元畳み込みネットワーク（3D ConvNets）を使用して時空間特徴学習のための簡単で効果的なアプローチを提案

# 2.先行研究と比べてどこがすごいか
- 3DConvNetsは2DConvNetsと比較して時空間特徴学習に適していること
- 4つの異なるデータセットで最先端の手法より優れていること

![スクリーンショット 2018-04-15 17.17.54.png](https://qiita-image-store.s3.amazonaws.com/0/249838/5e33d25d-874f-be12-06e5-dc6cbed539a4.png)
https://arxiv.org/pdf/1412.0767.pdf

# 3.技術や手法のキモはどこにある？

- フルビデオフレームを入力として受け取るので，前処理に依存しないことで大規模なデータセットに対して簡単にスケーリングできること
- 2DConvNetsは畳み込みの直後に時間的情報を失うのに対して3DConvNetsは時間的情報を保存できる
- VGGNetの知見によりカーネルサイズをkx3x3に固定し，3次元畳み込みカーネルの時間的な深さを変化させ，最適なものを探索

## 探索方法
- 探索にUCF101データセットを使用
- 全てのビデオフレームを128x171にリサイズ
- オーバーラップしていない16フレームのクリップに分割して使用
- 入力サイズが3×16×128×171なのに対して，トレーニングには3x16x112x112になるように画像をランダムクロップする(C3Dモデルは後述)
- 探索結果→カーネルサイズ3x3x3が一番いいことがわかった

## C3Dモデル
![スクリーンショット 2018-04-16 21.19.14.png](https://qiita-image-store.s3.amazonaws.com/0/249838/2a2b1d1a-1253-60ab-1912-5a9fea5e1c77.png)
https://arxiv.org/pdf/1412.0767.pdf

- 畳み込み層のカーネルサイズは3x3x3のストライド1x1x1を持ち，pooling層は第一層を除きカーネルサイズ2x2x2のストライド2x2x2を持つ．第一層は時間情報が早くに併合しないようにカーネルサイズ1x2x2のストライド1x2x2になっている．
- kerasでの実装→https://github.com/axon-research/c3d-keras

# 4.有効性の検証
Sports-1MデータセットとUCF101で検証を行い，slow Fusionなどと比較している．

# 5.議論はあるか？

#６.次に読むべき論文はあるか？

# 7.使えそうなノウハウ
→オーバーラップしていない16フレームのクリップに分割して使用
1動画から訓練データをたくさん作れそう
Googleスプレッドシートに自動取得したQiita記事一覧を月別集計する

# 経緯

[前回](https://qiita.com/FrozenVoice/items/b89e48719906180e060c)でQiitaの記事一覧が取得出来るようになったので月別集計してみる。

## 方針

- Jsonで取得した作成日時は扱いにくいのでGASで年月日形式の日付も出力する
- 別シートで上記年月日を使って月別の集計数を出す

### GASで日付フォーマットをして出力

```javascript
var date = new Date(jsonData[idx]['created_at']);
var formatDate = Utilities.formatDate(date, "JST","yyyy/M/d");
sheet.getRange(i, j).setValue(formatDate);
```

Utilitiesにメソッドが用意されているのでそれを使うのが良さそう。

### 別シートで集計

A列に集計月(2018/04等)を入れて、B列に下記の計算式を入れる。

```
=countifs('集計シート'!$D:$D,">=" & A1,'集計シート'!$D:$D,"<" &EOMONTH(A1,0))
```

EOMONTH()で月末日を算出して期間内の集計をしている。

## 雑記

そのうち各記事のview数とかも取得するようにしようかな。
systemdで初期処理の同期をとる方法。

先日、systemdを使っていて、

* 「あるサービス(Ａ)のある処理(Ｂ)が正常終了してから、別のサービス(Ｃ)を起動させたい。」
* 「あるサービス(Ａ)のある処理(Ｂ)が異常終了したら、別のサービス(Ｃ)は起動させたくない。」

という状況になりました。

systemd.serviceは、[Unit]のAfterで起動順序を定義できます。
ですが、それはただ、`ExecStart`を実行する順序が定義されるものであるため、
ある処理(Ｂ)が特に時間のかかる処理だった場合は(Ｃ)の起動が(Ａ)を追い越してしまいます。

そこで、(Ａ)に対して、少し細工をすることにしました。

## 前提条件

Linux系OSのsystemdを使っていること。
私はubuntuで実施してますが他のOSでも同じように動くと思います。

## サービス(Ｃ)のsystemd.service
サービス(Ｃ)のsystemd.serviceの[Unit]定義を以下にします。

```C.service
[Unit]
After = A.service
Requires = A.service
```

## サービス(Ａ)のsystemd.service
サービス(Ａ)のsystemd.serviceの[Service]Typeをnotifyにします。
[マニュアル](https://www.freedesktop.org/software/systemd/man/systemd.service.html#Type=)

```A.service
[Service]
Type = notify
```
こうすることで、サービスＡのプログラムコードと連携できるようになります。
コードから通知を受けたタイミングで、起動処理が正常終了する、という意味になります。

## サービス(Ａ)に、sdnotifyを埋め込む。
今回はcppで書かれたサービスだったので、[ここ](https://stackoverflow.com/questions/38302883/c-undefined-reference-to-sd-notify)を参考に、notifyの処理を埋め込みます。
埋め込む場所は、同期を取りたい処理が正常終了するタイミングです。

```
#include <systemd/sd-daemon.h>

main(){
  //
  // 処理(Ｂ)
  //
  sd_notify(0, "READY=1");
  //
  // main処理
  //
}
```

[マニュアル](https://www.freedesktop.org/software/systemd/man/sd_notify.html)

## イニシャライズ処理をplotしてみる。

```bash
systemd-analyze plot > foo.svg
```

点線部分がsystemdによる`ExecStart`から、`Type=notify`されるまでの時間がplotされたものです。
処理(B)を実施している時間が赤くなりました。

![Screenshot from 2018-04-16 21-03-36.png](https://qiita-image-store.s3.amazonaws.com/0/52547/43aaa522-c50e-7985-26c5-34e8d3c56d8c.png)

※サービス名は公開できないので隠しています。


## 各言語のsdnotifyはこちら

検証はしていませんが、go,pythonのsdnotifyです。

https://github.com/coreos/go-systemd/blob/master/daemon/sdnotify.go
https://github.com/bb4242/sdnotify
Datastoreのスケジュールバックアップを新方式へ移行


Cloud Datastore Admin バックアップが2019/2/28に廃止となってしまうので新方式に移行してみました。

[Cloud Datastore : フルマネージドのエクスポートとインポート機能を正式リリース](https://cloudplatform-jp.googleblog.com/2018/03/fully-managed-export-and-import-with-Cloud-Datastore-now-generally-available.html)

[エクスポートのスケジューリング](https://cloud.google.com/datastore/docs/schedule-export?hl=ja)を参考にして進めていきます。

## バックアップ用GCSバケット作成

```bash
gsutil mb -p [PROJECT_NAME] -c [STORAGE_CLASS] -l [BUCKET_LOCATION] gs://[BUCKET_NAME]/
```

Cloud Storage バケットと Cloud Datastore で同じロケーションを使用する必要があります。
[Datastoreのロケーションの確認方法](https://cloud.google.com/datastore/docs/locations?hl=ja#location-chosen)

## 権限をApp Engineのデフォルトサービスアカウントに割り当てる

### Cloud Datastore Import Export Admin

```bash
gcloud projects add-iam-policy-binding YOUR_PROJECT_ID \
--member serviceAccount:YOUR_PROJECT_ID@appspot.gserviceaccount.com \
--role roles/datastore.importExportAdmin
```

### Cloud Storage バケットの書き込み権限

```bash
gsutil iam ch serviceAccount:YOUR_PROJECT_ID@appspot.gserviceaccount.com:objectCreator \
gs://BUCKET_NAME
```

## アプリケーションファイル

[Application files](https://cloud.google.com/datastore/docs/schedule-export?hl=en#application_files)

基本は参考URLのままですが、 `cron.yaml` を修正しました。
※これを書いている時点では、日本語ドキュメントがベータ版のままで `cloud_datastore_admin.py` のコードが古いため英語ページからコードをコピーしました。

* `kind` パラメータを追加しエクスポート対象のKindを指定する
* `schedule` を時間指定にする
* `timezone` を日本時間にする

```cron.yaml
cron:
  - description: "Daily Cloud Datastore Export"
    url: "/cloud-datastore-export?namespace_id=&\
    	kind=Kind1&\
    	kind=Kind2&\
    	output_url_prefix=gs://BUCKET_NAME[/NAMESPACE_PATH]"
    target: cloud-datastore-admin
    schedule: 'every day 00:00'
    timezone: Asia/Tokyo
```

## デプロイ

```bash
gcloud app deploy app.yaml cron.yaml --project YOUR_PROJECT_ID
```

## テスト

1. [Cron ジョブ](https://console.cloud.google.com/appengine/taskqueues/cron)ページを開いて、Daily Cloud Datastore Exportジョブの[今すぐ実行] をクリックする
2. ジョブが完了するのを確認したら、[Cloud Storage ブラウザ](https://console.cloud.google.com/storage/browser)を開いて、作成したバケットにエクスポートがあるのを確認する

## インポート

`default` namespaceに、 `Kind1` , `Kind2` Kindをインポートする場合

```bash
gcloud datastore import gs://[BUCKET_NAME]/[PATH]/[FILE].overall_export_metadata --namespaces='(default)' --kinds='Kind1','Kind2' --project=YOUR_PROJECT_ID
```

エクスポート時と同様にCloud Storage バケットと Cloud Datastore で同じロケーションを使用する必要がありました。
UITextViewの文字制限

# はじめに
UITextViewを入力ボックスとした時に，文字列制限が欲しい場合があるのではないでしょうか？:sunny:
参考になるかもしれないので，置いときます．
コピペどうぞ:sunny:

# コード
```swift

class UIViewController: UITextViewDelegate {

    @IBOutlet weak var textField: UITextView!

    override func viewDidLoad() {
        textField.delegate = self
    }

    func textViewDidChange(_ textView: UITextView) {
        let beforeStr: String = textField.text // 文字列をあらかじめ取得しておく
        if textField.text.count > 10000 { // 10000字を超えた時
            // 以下，範囲指定する
            let zero = beforeStr.startIndex
            let start = beforeStr.index(zero, offsetBy: 0)
            let end = beforeStr.index(zero, offsetBy: 10000)
            textField.text = String(beforeStr[start...end])
        }
    }
}
```

# 終わりに
もっとこうしたほうがいいなどありましたらご指摘ください．:rolling_eyes:
ありがとうございました．

# 参考文献
Swift 4 iPhoneアプリ開発入門ノート
(win)Pythonの開発環境(IDE)としてSublimeText3を使う。

##はじめに
Pythonは始めたばかり
IDLEの最低限すぎる見た目と一切補完やデバッグのない仕様に絶望して、なんかいいものないかと探した所SublimeText3が見た目かっこよくていいなと感じた次第
自分用メモなので分からなかったところだけ追記

##環境
- Windows10 Home 64bit バージョン1709
- Python 3.6.4
- Sublime Text 3 Build 3143


##Sublime Text 3のインストール
詳しく書かれている方がいらっしゃったので割愛。

[Sublime Text 3のインストールと初期設定](https://qiita.com/lunatea/items/53f4adcc6ea3f316e781)

2018/04/15現在の最新ビルドは3143。
パッケージ(アドイン的なモノ？)を色々とインストールすることになるが、最低限として

- Package Control …パッケージマネージャ
- ChineseLocalizations　…日本語化
- Japanize　…日本語化2
- IMESupport　…IMEの補正
- ConvertToUTF8　…シフトJISなどへの対応策

以上のパッケージをインストールした。

##SublimeText3内のPython環境の設定

参考:[Windowsに、Sublime Text3でPython開発環境を構築](https://torina.top/detail/155/)

###設定した内容

- Tubキーを自動で半角スペース4つに変換する

適当なpythonファイルを開いてから、基本設定>基本設定―シンタックス指定
Python-sublime-settingsというタブが開くので、中身を以下のように書き換え
```
    {
        "tab_size": 4,
        "translate_tabs_to_spaces": true
    }
```

- python36のビルド設定を新規追加する

PackageControlからSUblimeREPLをインストールする
その後、ツール>ビルドシステム>ビルドシステム追加…を選択
タブが開くので、以下のように書き換え

```
    {
        "cmd": ["c:/自分のpythonが入っているパス/python.exe", "-u", "$file"],
        "selector": "source.python",
        "file_regex": "file \"(...*?)\", line ([0-9]+)",
        "env": {"LANG": "ja_JP.UTF-8"},
        
    	"windows":
    	{
    		"encoding": "cp932",
    	}
    }
```
Ctrl+Sで保存する。Python36などとしておくと分かりやすい。

[Pythonのインストールパスを調べる方法](http://com4tis.net/python-install-path/)
何を設定しているかは以下のサイトが参考になった。
[Sublime Text 3のBuild Systemについて](https://qiita.com/lunatea/items/2bd07ae58e657d625868)

- Python3のコーディング規約をチェックしてくれるチェッカーを導入する

Python Flake8 Lintというパッケージをインストールした。
コレを入れておくと記述を間違っていたときに赤丸で警告してくれるらしい。

[Sublime TextをPython開発に使いやすいようにカスタマイズ](http://blog.serverworks.co.jp/tech/2016/10/19/sublime-text/)

##終わりに

ひとまずPython3で前より便利にコーディング出来るようになった気がするので、このへんにしておく。
また何か必要になったら/便利そうなのを見つけたら追記したい。
twitter4jを使い、Twitterの画像取得

ほとんど、参考サイトの丸写しですが、メモ

##srcフォルダ内に以下を用意
- twitter4j.properties
- GetTwitterImage.java

##コード
###twitter4j.properties
```
#
debug=false
oauth.consumerKey= ***
oauth.consumerSecret= ***
oauth.accessToken= ***
oauth.accessTokenSecret= ***
```
https://apps.twitter.com/ でapiのトークンを取得。


###GetTwitterImage.java
```java
/**
 * 参考：http://kikutaro777.hatenablog.com/entry/2014/01/26/110350
 * Wordで定めたTwitterIDもしくはタグの画像をTWEET_NUMの数だけローカルに保存する。
 */

package oppai_image_get;

import java.io.FileOutputStream;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.nio.channels.Channels;
import java.nio.channels.ReadableByteChannel;
import java.text.DateFormat;
import java.text.SimpleDateFormat;

import twitter4j.*;

public class GetTwitterImage {

    //取得件数
    static final int TWEET_NUM = 20;
    
    //保存対象の画像拡張子
    static final String TARGET_EXTENSION = ".jpg";
    
    //検索クエリ
    static final String Word = "aragaki_fun"; //WordでIDかタグで指定。
    static final String MY_QUERY = "from:" + Word;
    
    public static void main( String[] args ) throws TwitterException, MalformedURLException, IOException
    {
        Twitter twitter = new TwitterFactory().getInstance();
        
        //検索実行
        Query query = new Query(MY_QUERY);
        query.setCount(TWEET_NUM);
        QueryResult result = twitter.search(query);
        
        //検索結果からmedia entity情報をチェックして保存
        for(Status sts : result.getTweets()){
            MediaEntity[] arrMedia = sts.getMediaEntities();
            for(MediaEntity media : arrMedia){
                //ファボ数でフィルタとかも良さそう
                //if(sts.getFavoriteCount() > 5)
                
                //とりあえず拡張子だけでフィルタ
                if(media.getMediaURL().endsWith(TARGET_EXTENSION)){
                    URL website = new URL(media.getMediaURL());
                    ReadableByteChannel rbc = Channels.newChannel(website.openStream());
                    //保存ファイル名にStatusが持つ作成日を付与
                    DateFormat df = new SimpleDateFormat("yyyyMMddHHmmssSSS");
                    FileOutputStream fos = 
                        new FileOutputStream("ImageFromTwitter" + df.format(sts.getCreatedAt()) + TARGET_EXTENSION);
                    fos.getChannel().transferFrom(rbc, 0, Long.MAX_VALUE);
                }
            }
        }
        System.out.println("出力完了！");
    }

}
```

##実行結果
![スクリーンショット 2018-04-16 20.37.16.png](https://qiita-image-store.s3.amazonaws.com/0/185846/6ddf6d79-9972-eaa1-413a-6c6625f90e50.png)

新垣結衣さんの画像が無事取れました。

##参考
http://kikutaro777.hatenablog.com/entry/2014/01/26/110350
http://java-beginner.com/practice-search-twitter/
http://nekonokotatsu.hatenablog.com/entry/2015/01/27/222653
https://qiita.com/yokoh9/items/760e432ebd39040d5a0f
Swift：カラーコードをRGBの値に変換してくれるCommand Line Tool作ってみた

#これなぁに
今まではCUIの簡易プログラムを作るといえばC言語やRuby、Pythonを使ったり、Javascriptで書いてnode.jsで動かすなんてことをしていました。
しかし、SwiftでCommand Line Toolというのが使えるというのを知り、試しに`#FF34A3`などのカラーコードを`(r, g, b) = (255, 52, 163)`と変換してくれるプログラムを作ってみました。

#Command Line Toolの作り方
`File` -> `New` -> `Project...` -> `macOS` -> `Command Line Tool`でできます。 

#ソースコード
```swift:main.swift
import Foundation

let input = FileHandle.standardInput

func HEXtoRGB(_ hex: String) -> (r: Int, g: Int, b: Int) {
	let v = hex.map { String($0) } + Array(repeating: "0", count: max(6 - hex.count, 0))
	let r = Int(v[0] + v[1], radix: 16) ?? 0
	let g = Int(v[2] + v[3], radix: 16) ?? 0
	let b = Int(v[4] + v[5], radix: 16) ?? 0
	return (r, g, b)
}

while true {
	Swift.print("Input HEX:")
	var hex = String(data: input.availableData, encoding: String.Encoding.utf8) ?? "000000"
	hex = hex.replacingOccurrences(of: "\n", with: "")
	if hex == "Q" || hex == "q" {
		Swift.print()
		exit(0)
	}
	let rgb = HEXtoRGB(hex)
	Swift.print("RGB: \(rgb.r), \(rgb.g), \(rgb.b)\n")
}
```

#実行例
```plaintext:
Input HEX:
ff34a3
RGB: 255, 52, 163

Input HEX:
3520f0
RGB: 0, 82, 15

Input HEX:
Q

Program ended with exit code: 0
```

#ポイント
Xcodeのデバッグエリアを使って標準入力を行うために、`FileHandle.standardInput`を使いました。
`.availableData`でreturnキーを押した際の最新の入力を取得できるようです。

カラーコードの変換部分については[この記事](https://qiita.com/Kyomesuke3/items/eae6216b13c651254f64)を参照してください。
Chrome 66でUnity WebGLビルドの音が鳴らない状況を緩和する

# 何が起きているのか

Chromeのバージョン66から、ビデオ・オーディオの自動再生のポリシーが変更されました。
現状はユーザーがクリックかタップでオーディオのサスペンド状態を解除しないといけなくなりました。

Autoplay Policy Changes
https://developers.google.com/web/updates/2017/09/autoplay-policy-changes#webaudio

Chrome On The Dev Branch (version 66) May Block Audio For Unity WebGL
https://forum.unity.com/threads/chrome-on-the-dev-branch-version-66-may-block-audio-for-unity-webgl.517758/

で、これに現状Unityが対応してないので完全に音が鳴りません。

※4/17追記
しかも、この自動再生の可否は**ユーザーごとに**変化するため、デバッグ時に気が付かないことがあります。
Chrome 66ではMEI(Media Engagement Index)という仕組みによって内部で動画・音声が再生されるサイト上での挙動が記録され、ユーザーごとにスコアリングされます。
この数値をもとに、自動再生を許可するかしないか判定する仕組みです。

参考：Safari, Chromeの自動再生ポリシー変更のまとめ
https://qiita.com/ktknest/items/e81b3a4caac540098fc8

なお66は今ベータですが、4/17米国時間で正式リリースされます。やばい。

~~forumは超キレている人がいたりして荒れてます...~~

# 回避（緩和）方法

WebGLビルド用のjsファイルをいじるとある程度緩和できます。

### 修正対象ファイル
[Unityインストール位置]\Editor\Data\PlaybackEngines\WebGLSupport\BuildTools\lib\Audio.js

### 修正前

```javascript

JS_Sound_Init: function()
{
	try {
		window.AudioContext = window.AudioContext||window.webkitAudioContext;
		WEBAudio.audioContext = new AudioContext();
		WEBAudio.audioWebEnabled = 1;
	}
	catch(e) {
		alert('Web Audio API is not supported in this browser');
	}
},
```

### 修正後

```javascript
JS_Sound_Init: function()
{
	try {
		window.AudioContext = window.AudioContext||window.webkitAudioContext;
		WEBAudio.audioContext = new AudioContext();
		WEBAudio.audioWebEnabled = 1;
		var wakeupWebAudio = function() {
			if (WEBAudio.audioContext.state === "suspended") {
				WEBAudio.audioContext.resume();
			}
			document.removeEventListener("click", wakeupWebAudio);
			document.removeEventListener("touchend", wakeupWebAudio);
			document.removeEventListener("keydown", wakeupWebAudio);
		};
		document.addEventListener("click", wakeupWebAudio);
		document.addEventListener("touchend", wakeupWebAudio);
		document.addEventListener("keydown", wakeupWebAudio);
	}
	catch(e) {
		alert('Web Audio API is not supported in this browser');
	}
},

```

※4/17修正: [wilfrem](https://qiita.com/wilfrem)さんのコメントのご指摘で修正しました

編集が終わたたら、普通にWebGLビルドします。
この対処を行ったとしてもページを開いた直後はやっぱり音は出ないので、一回どこかをクリックかタップもしくはキーを入力してもらう必要があります。（つらい..


# Unity issue tracker立ってます

エンジン側で根本解決してもらうためにも、issue trackerのチケットが余ってる人は突っ込んでくださいませ。

https://issuetracker.unity3d.com/issues/chrome66-no-longer-playing-integrated-audio
ArduinoとProcessingでシリアル通信をする簡易例

#背景
Arduinoでとったセンサの値をProcessingで可視化したい場合が結構あります。
そこで、備忘録としてまとめておきます。

#実行環境
> PC: MacBook Pro, macOS High Sierra
> Arduino: Uno
> Processing: version 3.3.6

#例
今回はセンサを使ってしまうと、記事の読者がすぐに試すことができない可能性があるため、Arduino側で生成した乱数をProcessing側で取得して折れ線グラフとしてプロットするようなものにしました。

![plot.png](https://qiita-image-store.s3.amazonaws.com/0/67153/f828f30f-7bbd-e654-401d-691d2cd601bc.png)


##Arduino側のソースコード
```c:RandomValue
int randomValue1 = 0;
int randomValue2 = 0;
int randomValue3 = 0;

void setup() {
  Serial.begin(9600);
  randomSeed(analogRead(0));
}

void loop() {
  randomValue1 = random(20);
  randomValue2 = random(20);
  randomValue3 = random(20);
  Serial.print(randomValue1);
  Serial.print(",");
  Serial.print(randomValue2);
  Serial.print(",");
  Serial.println(randomValue3);
  delay(100);
}
```

##Processing側のソースコード
```java:RandomValueGraph
import processing.serial.*;
Serial port;

boolean DEBUG = false;
int[][] values = new int[3][100];
color[] colors = {color(244, 67, 54), color(67, 160, 71), color(25, 118, 210)};

void setup() {
  size(800, 500);
  frameRate(50);
  String[] ports = Serial.list();
  if (DEBUG) {
    for (int i = 0; i < ports.length; i++) {
      println(i + ": " + ports[i]);
    }
  } else {
    port = new Serial(this, ports[適切なポートの配列番号], 9600);
  }
}

void draw() {
  background(color(255, 255, 255));
  for (int i = 0; i < 3; i++) {
    stroke(colors[i]);
    for (int j = 0; j < 99; j++) {
      line(8 * j, 250 + values[i][j], 8 * (j + 1), 250 + values[i][j + 1]);
    }
  }
}
  
void serialEvent(Serial p) {
  if (p.available() > 0) {
    try {
      String input = p.readStringUntil('\n');
      if (input != null) {
        input = trim(input);
        String [] value = split(input, ',');
        println(value[0] +","+ value[1] +","+ value[2]);
        for (int i = 0; i < 3; i++) {
          values[i] = append(subset(values[i], 1), int(value[i]));
        }
      }
    } catch (RuntimeException e) {
    }
  }
}
```

#ちょっと説明
Processing側のソースのDEBUG変数をtrueにするとシリアルポート一覧がコンソールに出力されます。ポート番号を適切に切り替えてDEBUG変数をfalseにすると、シリアル通信ができます。
コミットした内容を他のブランチで読み込む(cherry-pick)



cherry-pickを使う

```
git cherry-pick [コミットNo]
```

cherry-pickは特定のコミットのみ取り込むことが可能

```
error: commit commitNumber is a merge but no -m option was given.
fatal: cherry-pick failed
```

このエラーが出た場合は

```
git cherry-pick -m 1 [コミットNo]
```

あとはconflictが起きた箇所を解消すればokです。
【Linux】【Cent OS】/tmpと/var/tmp以下のファイルを放っておくと勝手に削除される話

# 概要
Linux系OSの一部では、/tmpや/var/tmp以下のファイルが一定時間経過すると削除される設定がされていることがあります。実際に、/tmpをテンポラリー用途じゃないファイル配置場所として使用していたら、ファイルが消えて焦りました。。。
そこで、この設定の確認方法と無効化の方法を記事にしてみました。
ちなみに、Red Hat Enterpriseで、この現象が発生するのを確認しました。その他、Cent OSの6と7でも発生するみたいですね。

ただし、LinuxのFHS(Filesystem Hierarchy Standard)では、そもそも/tmpは一時的なファイル配置場所にしか使っていけないことになっています。だからこそ、削除されるように設定されていたりします。そのため、この規約に従えば、設定を変更するのではなく、そもそも削除されて困るようなファイルを長時間置かないことが正しいアプローチとなります。
とはいえ、そうは言ってはいられない事情もあると思うので、記事にしました。


以下の通り、Systemdかcron(tmpwatch)のどちらかの仕組みでファイルの定期削除がされるようです。どちらで設定されているか順番に確認してみてください。
(OSによっては下記以外の仕組みで設定されていることもあるかもしれません。)

## 1. Systemdの設定
Linuxの起動管理・システム管理のSystemdに削除設定がされていないか確認してみます。

## 確認方法
/usr/lib/tmpfiles.d/tmp.confを確認して、以下のような記述がないか確認します。

```/usr/lib/tmpfiles.d/tmp.conf
# Clear tmp directories separately, to make them easier to override
v /tmp 1777 root root 10d
v /var/tmp 1777 root root 30d
```

## 無効化方法
上記ファイルをコピーして、/etc/tmpfiles.dに作成して、削除の例外設定を追記します。
/usr/lib以下のファイルを直接書き換えることは非推奨のため、このようにします。/etc/tmpfiles.d/での設定は、/usr/lib/tmpfiles.d/以下の設定より優先されます。

```
$ cp -a /usr/lib/tmpfiles.d/tmp.conf /etc/tmpfiles.d/

```

```/etc/tmpfiles.d/tmp.conf
# 下記を追記(xで例外指定となる)
x /tmp/*
x /var/tmp/*
```

# 2. cron.daily(tmpwatch)の設定
こちらはcronの設定です。古いCent OSなどはこちらのようです。

## 確認・無効化方法
/etc/cron.daily/tmpwatch内で、下記のように削除する処理を記載している箇所がないか確認します。`tmpwatch`が該当ディレクトリ内のファイル定期削除を行っています。削除設定を無効化する場合は、下記の処理をコメントアウトします。

```/etc/cron.daily/tmpwatch
/usr/sbin/tmpwatch 240 /tmp
/usr/sbin/tmpwatch 240 /var/tmp
```

# 最後に
Linux系OSでは、ここで紹介したケース以外にも、ファイルの定期削除やシャットダウン時のファイル削除設定がされている場合があります。大切なファイルを失わないためにも、OS導入時に最初に確認しておきたいですね。

# 参考
[CentOS 7 : /var/run 直下に作ったディレクトリが消えないようにする](http://server.etutsplus.com/centos-7-tmpfiles-d-deleted-outdate-files/)

[お前らもさっさとハマって泣くべきCentOS7の落とし穴4つ](https://qiita.com/suemoc/items/e29285e8e67263298f35)

[/tmp/ディレクトリ下のファイルはいつ削除される？](http://www.itmedia.co.jp/help/tips/linux/l0609.html)
[ネタばれ] 長テーブルのうなぎ屋 (paizaランク B 相当)

https://paiza.jp/learning/long-table

境界線の処理をどうするかの問題だよなこれ

```java
import java.io.InputStream;
import java.util.Scanner;

class UnagiNew {

	public static void main(String[] args) {
		System.out.println(exec(System.in));
	}

	public static int exec(InputStream is) {
		try (Scanner sc = new Scanner(is);) {
			// 座席数
			int n = sc.nextInt();
			boolean[] bools = new boolean[n];
			// グループ数
			int m = sc.nextInt();
			for (int i = 0; i < m; i++) {
				// 人数
				int a = sc.nextInt();
				// 開始位置
				int b = sc.nextInt();
				// チェック
				boolean check = false;
				for (int j = b; j < a + b; j++)
					if (bools[j % bools.length] && (check = true))
						break;
				if (check)
					continue;
				for (int j = b; j < a + b; j++)
					bools[j % bools.length] = true;
			}
			int ret = 0;
			for (boolean b : bools)
				if (b)
					ret++;
			return ret;
		}
	}
}
```

関連:
https://qiita.com/krppppp/items/a75205c9dcb4165ca2b4

## 最新の技術を利用し、可読性無視で記載を修正した場合

```java
import java.util.Arrays;
import java.util.Scanner;
import java.util.stream.IntStream;


public class App {
    public static void main(String[] args) throws Exception {
        try (Scanner sc = new Scanner(System.in);) {
            int[] c = new int[sc.nextInt()];// 座席数
            IntStream.range(0, sc.nextInt() /* 入力数 */).forEach(i->{
                int a = sc.nextInt(),b = sc.nextInt(); // a=人数,　b=開始位置
                if (IntStream.range(b, a+b).anyMatch(j->c[j % c.length]==1)) return;
                IntStream.range(b, a+b).forEach(j->c[j % c.length]=1);
            });
            System.out.println(Arrays.stream(c).filter(v->v==1).count());
        }
    }
}
```

stream に置換するとここまで短くなるがもっとショートに成る案を募集してみる。