OmniAICreator/Qiita-1.07M huggingface dataset:
開発中のgdb拡張「Exgdb」について/開発予定の機能・届いている要望一覧

## Exgdbとは

SecHack365というハッカソンイベントで、gdb拡張・gdbプラグイン開発を行うことになりました。
動的解析の効率化や、Exploitの効率化を目的としています。
リポジトリは[こちら](https://github.com/miyagaw61/exgdb)になります。
こんな機能も欲しいなどの要望等がありましたら、この記事のコメントか、 [Twitter](https://github.com/miyagaw61) のリプ/DMか、SecHack365同期の方はTypetalk/Backlogで待ってます。

## コードのリファクタリング

現状コードが汚すぎるので、綺麗にします。

## コマンド名をわかりやすくする

コマンドの名前が今は適当なので、わかりやすい名前に変えます。
基本、短いコマンドで済ましたい人は自分でaliasをかけてくださいというスタイルでいく予定です。
以下の追加予定機能/要望に出てくるコマンド名は、現状のコマンド名です。

## aliasを簡単にかけられるようにする

現状は、aliasだけを書く設定ファイルでも用意しようかなと考えています。

## `cc`や`jj`などの自動ステップコマンドで`SIGINT`受信

これまだ、止めたい時に止められないんですよね。
シグナル待機スレッドを作るかシグナルハンドラを登録するかで`SIGINT`(`Ctrl+C`)は受信できるようにしたいです。
pythonのsigtrapとかはどうなんだろう。
Ctrl+C用のパイプを使う？？

## `grep`コマンドがうまく動作しないことがある

たまにgrep漏れがあるんですよね。

## 情報をより多く取得できるようにする

どのような情報が欲しいか、要望をください！
現状は、以下の要望が届いています！

### ・ヒープのUnlinkについての情報

Pwngdbではこの機能があったので、それを良い感じに再現したいです。

### ・ヒープのアリーナ情報

要望がありました。

### ・GOTテーブル

## 脆弱性の自動発見/攻撃方法の自動解析

どのような脆弱性を自動で発見/攻撃方法の自動解析をして欲しいか、要望をください！
現状は、以下のような要望が届いています！

### ・自明なBOF

要望のところに書いていますが、これは僕がとりあえず「まずは自明なBOFからかなあ」と思って作ってみたいなぁと思っている要素です。

### ・Unlink Attack

ある程度のヒープの情報が集まったら、何を用意してどこをどうすればUnlink Attackできるか解析できたら便利ですね。

## 関数や変数、構造体等のラベリング

IDAやradareのように、自分で関数や変数、構造体などをリネームできる機能を追加したいと思っています。
ASLRで毎回アドレスが変わるからオフセットなどで推測。

## パッチ機能

gdbから簡単にパッチを当てられたら便利じゃないですか？

## 与える入力値の保存

現在では、Pythonを書くことで毎回与える入力値を固定させるのがデファクトスタンダードですが、それだとgdbとPythonを行き来するオーバーヘッドが大きくなってしまいます。
なので、gdb側で毎回与える入力値を保存しておくことで、同じ手順を踏んで解析することを容易にします。

## OSやコンテナ、エミュレータ、ハイパーバイザ等の動的解析の更なる効率化（カーネルエクスプロイトの効率化など）

ここらへんは自分はまだよくわかってないので、色々と要望やアドバイスなどをお待ちしております...

## エディタとの連携

エディタとgdbを連携させます。
gdbでの解析結果を参考にエクスプロイトコードを書き、そのコードを回した結果をgdbで解析し、その結果を参考にエクスプロイトコードを書き換え...というように、gdbとPythonを行き来することが多くオーバーヘッドが大きいので、共通プラットフォーム上で一つのフローでエクスプロイトコードを開発できるようにします。

## エディタ感覚でデータ書き換え

エディタ感覚でレジスタ値やスタックの中身などを書き換えることができるようにします。
言い換えると、バイナリエディタを内蔵しているような感じにします。

## マルウェア解析用の機能

マルウェア解析を効率化する機能を追加したいです。

## 機械学習

機械学習無しでは、既知の脆弱性は見つけられても、未知の脆弱性は見つけられません。
現状私は機械学習何もわからないので、実装は難しいかもです...

## grepの更なるグルーピング

gdbに適した便利オプションを追加する（stackgrepみたいな）

## システムコールへ飛ぶ

intの直前のraxへの代入値を解析してブレークポイントを仕掛けてcontinueなど）

## /proc以下を良い感じに見る

vmmap的なもの

## ROP（ガジェット）の探索

rp++のラッパーみたいになるのかな？
、という要望を頂きました。

## AA

AAみたいにわかりやすく可視化・gdbの`add symbol なんたら`コマンドでシンボルを追加できる

## その他動的解析やpwnを効率化する機能を募集しています！

この記事のコメントか、 [Twitter](https://github.com/miyagaw61) のリプ/DMまで！
どんな要望でも構いませんので、気軽に、宜しくお願いいたします！

## r2apiを使う

gdbからr2apiに投げて解析した結果をgdbが受け取る
r2pipeとかでggると出てくる

## その他gdbに関するメモ

gdbに関することはできるだけ知っておきたいので、gdbに関することはメモっておきます。

### ・`-S -gdb tcp::4444`をqemuに付けるとgdbで`gdb target remote`できる

聞いただけなのでどうとも言えませんが、gdbserverを起動してアタッチするとユーザランドしか解析できなかったらしいのでこっちのが良さそうです。

### ・gdbの`add symbol なんたら`コマンドでシンボルを追加できる

らしい

## その他gdb以外についてのメモ

### シンボリック実行

シンボリック実行とやらが使えるらしい？
聞いたことあるだけで全然何か知らないので、調べてみます。

### 最適化問題

どうやら、pwnは最適化問題に落とし込めるらしい？？
よくわからないので、調べてみます。

## 今後の進め方

・nrun.cを読む
・armシミュレータを読んでaarch64と比較
・gdbをaarch64向けにビルドしてaarch64の実行ファイルを動かす
・gdbをgdbで解析
・プラグインをどのように実現しているかという部分も読みたい．
・gdb本体のプラグイン実現部分を改造して，さらに進んだプラグインを実装したりすることも考えたい

## その他要望

・`@exit`（.finiを追加する関数？）、`.iniセクション`（mainに行く前に実行される初期化機構）、`.fini`（.iniの逆）などを見たい
・glibc-malloc以外のmallocにも対応
・iiをAT&Tにも対応
Laravelのインストールと設定

#Laravelのインストールと設定について
Laravelを新しいプロジェクトを作ったらLaravelのバージョンによって若干異なる部分があったのでまとめておこうと思います。

##環境
ubuntu 16.04
php 7.2
composer 1.0.0
Laravel 5.3 5.6
Laravel5.3と5.6の違いで苦労したのでそこについて書きます。

##インストールと設定
おそらく以下のコマンドで最新版のLaravelのプロジェクトを作成することができるかと思います。
`composer create-project laravel/laravel project-name --prefer-dist`

そのままproject-name/publicにアクセスしても500番のエラーになってしまうので、権限の変更でstorageとbootstrap/cacheの権限を変更する必要があります。
`chmod -R 775 public storage bootstrap/cache`
また、ファイルの所有者を変更します。
`chown -R www-data:www-data storage bootstrap/cache`

Laravel5.3だとこれでLaravelのページが表示されるかと思いますが、5.6だと500番エラーで表示されませんでした。
そこで、以下のコマンドを実行中に~~project-name/public~~localhost:8000へアクセスすると表示されました。
`php artisan serve`

Laravelはバージョンによって結構設定が変わるみたいですので気をつけてください。
python からRを使用。for 文内のRの記述に変数を使用する方法

以下の一文が無いことではまりました。
r.assign("i",i)

成功例
r = pyper.R(use_pandas = True)
for i in conti_var_names:
    df_one_row = df[i]
    r.assign("data",df_one_row)
    r.assign("i",i)
    print(r("shapiro.test(data[,i])"))

失敗例
r = pyper.R(use_pandas = True)
for i in conti_var_names:
    df_one_row = df[i]
    r.assign("data",df_one_row)
    print(r("shapiro.test(data[,i])"))

参考サイト
https://futabooo.hatenablog.com/entry/20110910/1315634652
[時系列index編] pythonで時系列データをぽちぽち　~東京電力の過去実績データを対象に~

今回のテーマは，時系列index
---
です．今回，実際のデータには手を加えませんが，大事な大事な前処理ってやつの１つかもしれませんね．おろそかにするとあとで苦労するので頑張ってやりましょう．

はじめましての方のために，一応前回記事へのリンクを貼っておきます．
[https://qiita.com/KogeTakahiro/items/2207bf138af8e474ce04](https://qiita.com/KogeTakahiro/items/2207bf138af8e474ce04)

この記事のモチベーションとかが書いてあります．読んでくださるとより理解が深まるかもしれません．

### 時系列indexとは，<b>時間軸<i>t</b>のことです．
---
のことです．<b>日付とかそういうもの</b>のことを指します．そもそも時系列indexという表現が一般的な表現かどうかはわかりません．

では，今回のデータではどうなっているのでしょう？

さて，早速データを見ていきましょう．2017年の一年間のデータを用います．
[データダウンロードはここからどうぞ](http://www.tepco.co.jp/forecast/html/images/juyo-2017.csv)
注：PC上で保存する際は，３行目から下のみを保存してください
（データのダウンロードに関する記事は，そのうち別で書きますね）

### 時系列indexっていろんな形で格納されている．
---
``` python3
import pandas as pd

data = pd.read_csv('path_to_data/file_name.csv') #かっこの中は置き換えてください
data.head(5) #データの頭５行のみを表示
```
実行結果

|| DATE | TIME | DEMAND(10GW) |
|:--|:--|:--|:--|
| 0 | 2017/1/1 | 0:00 | 2783 |
| 1 | 2017/1/1 | 1:00 | 2634 |
| 2 | 2017/1/1 | 2:00 | 2520 |
| 3 | 2017/1/1 | 3:00 | 2438 |
| 4 | 2017/1/1 | 4:00 | 2389 |
（便宜上，一番右のカラム名を英語表記に変更してあります．）
見たところ，<b>日付と時間が別に記録されている</b>ようです．しかし，これでは時間軸<i>t</i>が１つに統一されておらず，今後使いづらいので１つにしておきます．

```python3
#DATEとTIMEを文字列でくっつけて，datetimeという行を作る．
data['datetime'] = data.apply(lambda x: str(x['DATE'])+' '+str(x['TIME']),axis=1)

#datetimeの行を，
data['datetime'] = pd.to_datetime(data['datetime'], format='%Y/%m/%d %H:%M')
```
実行結果


|| DATE | TIME | DEMAND(10GW) | datetime |
|:--|:--|:--|:--|:--|
| 0 | 2017/1/1 | 0:00 | 2783 | 2017-01-01 00:00:00 |
| 1 | 2017/1/1 | 1:00 | 2634 | 2017-01-01 01:00:00 |
| 2 | 2017/1/1 | 2:00 | 2520 | 2017-01-01 02:00:00 |
| 3 | 2017/1/1 | 3:00 | 2438 | 2017-01-01 03:00:00 |
| 4 | 2017/1/1 | 4:00 | 2389 | 2017-01-01 04:00:00 |


~書き途中です．以後追記していきます~
[はじめに]　pythonで時系列データをぽちぽち　~東京電力の過去実績データを対象に~

pythonで時系列データをぽちぽち vol.0
---
こんばんは．ひさびさに時系列データをいじることにしました．
一連の分析の流れをシリーズにして，まとめようと思います．
もしかするとお役に立てる部分があるかも．

### こんな人に読んで欲しい
---
* 時系列データ分析に興味がある人
* python,pandasで時系列データをいじろうとしてる人
* データはあるがなにしていいかわからない人
* 東京電力の電力使用実績に興味のある人

pandasでの時系列データの操作方法については，多くの素敵な記事があります．どれも参考にすべきものばかりです．でも，手元にあるデータを前に，<b>なにからはじめていいかわからないから，なにを読めばいいかすらわからない</b>人がいると思うんです．（僕がそうだったように）

### 目的：時系列データをいじる方法を，一連の流の中で説明すること
---
そこで，一連の流れで説明すれば，イメージも湧くんじゃないかなって思いました．今回は，[東京電力の過去の電力実績データ](http://www.tepco.co.jp/forecast/html/download-j.html)を使ってやっていきます．時系列データの操作云々だけじゃなく，電力実績ってどんな風になってるのかもわかる記事にしたいと思います．


### 時系列データのイケてるところって，やっぱり予測できるとこ
---
だと思うんですよ．あくまで僕の主観ですが...いかにも，データ分析っぽいカッコいいとこ！！！だなって．
ただ，<b>予測って先の先のそのまた先の話</b>な部分があります．段階としては，大きく分けて
* 前処理
* 集計
* 分析（モデル化）
* 予測（汎化性能も加味したモデル化）
なので，このシリーズでは，１つ１つこうやって切って説明して，最後に予測手法の一例でも説明できれば嬉しいかなと思います．

では，ひとまず今日はここら辺で

今日のBGM：Norah Jones - [Come Away with Me](https://youtu.be/Do1GKZsDoNY)

追記：次回までの準備
---
Pythonのinstallやデータのダウンロード（．csvファイルでの保存）は，各自お願いしたいです．
openbsd growfs

##家族が増えて　小さなお家が住みにくくなったら　ddとgrowfsとをつかって
##大きなお家（ハードディスク）に引っ越しましょう:hugging:


話を単純化するために　８０GBのハードディスクにopenbsdをいれてるのですが
##cat /etc/fstab
##05e6829d8a4741b1.a / ffs rw,wxallowed 1 1
であり　swap さえつくってません（メモリ１０GB故です）

さて最初に
OpenBSD を入れた80 GB のハードディスク　と　160 GB のハードディスク　とを
archlinux につけて ddで　８０GB　を160 GB のハードディスクにコピーします

しかしこの段階では160 GB のうちの80 GB しか使われていません

これでは残念です

従って Open BSD のgrowfsを使います

160 GB のハードディスクをつけて起動します

1) boot bsd.rd で起動します

そして　shell へ

2)まず　openbsdの縄張りを拡大します
fdisk -e sd0 します。
edit 3 し、いっぱいまで広げます
![4.jpg](https://qiita-image-store.s3.amazonaws.com/0/211097/6327317e-5328-749c-23c7-351c5379fb11.jpeg)


￼
3)disklabel -E sd0 です
バウンダリをディスク全体にするため
ｂ
*
です。

それから　aの縄張りを拡大します」　
ｃの次にaして　領域aを最大サイズに変更します
![7.jpg](https://qiita-image-store.s3.amazonaws.com/0/211097/8d572dbe-7561-8ea2-3321-29a1dd9e440b.jpeg)






4)fsck_ffs -fy /dev/rsd0a

￼5)growfs /dev/rsd0a

6)fsck_ffs -fy /dev/rsd0a

7)halt -p

諸賢には　以上でOKだと　思います
だらだら　書いたのは以下です
## please see the photos of the next URL :poop:
## http://openbsd-akita.blogspot.jp/2018/04/growfs.html
これは　冗長で　俳句の歯切れ良さがないですね

##2.5inch sas 73GBX3で使ってますが　間もなく４台で運用します。速さ優先でraid0です。
１００円ショップでかった木製お皿立てを改造してつかってます。
![0.jpg](https://qiita-image-store.s3.amazonaws.com/0/211097/4d11e241-22ef-e2e3-1b4f-51fafbc6f708.jpeg)



------------
##linuxでは　ddのあと　gpartedで簡単に領域拡張はできるのですが　
openbsdには　いまのところ　こんな便利なツールはないですね:cry:

## 日立のサーバー　HA8000では
boot bsd.rd をしようとしても　USB　keyboard からの入力を受け付けてくれず
ハードディスクのopenbsdが立ち上がります。
よって　この場合は　install63.fs をUSBメモリに焼いたもので行います。
以下は　概観だけですけど、　前節を参照すればわかるでしょう。
1. boot by USB memory
2. Upgrade to sd0
3. ctrl+C after fsck
4. cp /mnt/sbin/growfs ./
5. umount /mnt
6. fdisk -e sd0
7. disklabel -E sd0
8. fsck_ffs -fy /dev/rsd0a
9. growfs /dev/rsd0a
10. fsck_ffs -fy /dev/rsd0a
Mac用 Unityセッティング for android <Gear VR & Cardboard VR>

UnityでAndroidのビルドエラーが多発したので解決法です。
追加でGearVR/Cardboard(GoogleVR)用にビルドする際の注意事項を入れておきます。
他のサイト、qiita内でも説明されていますが、自分用の備忘録

# 1. Unity,jdk,android sdkのバージョンの確認
jdk,android sdkのバージョンによってunityのbuildエラーが起きることがある
よくあるエラー
Unable to list target platforms. Please make sure the android sdk path is correct.
>[UnityのAndroidビルドができなくなった時の対処 - Qiita]
(https://qiita.com/niusounds/items/bcbeee622b2114b4016e)
>[Unityを使ったAndroid向け課金ゲームアプリの開発環境を準備する - Qiita]
(https://qiita.com/cayto_pr/items/27945404518560337e3d#_reference-f2fa14faf8ee3235f5ee)

現在自分で安定して使えているバージョン(mac)

 + Unity:2017.3　
 + jdk  :jdk1.8 (Java SE Development Kit 8)
 + sdk  :[tools_r25.2.5-macosx.zip](http://dl-ssl.google.com/android/repository/tools_r25.2.5-macosx.zip)
 win用:[tools_r25.2.5-windows.zip](http://dl-ssl.google.com/android/repository/tools_r25.2.5-windows.zip)

### 基本的な手順
1. Unity(Android Buildも忘れずに),Android Studio,jdkのインストール
2. android sdk : [tools_r25.2.5-macosx.zip](http://dl-ssl.google.com/android/repository/tools_r25.2.5-macosx.zip)をandroid studioのtoolに差し替える。
3. android studioのConfigure/SDK Managerで必要なAndroidのAPIをインストール
4. unityのPreferences/External toolsでjdk,sdkの場所を指定

## googleVR
Cardboardはデフォルトで存在しません。GoogleVRのアセットを入れます
>https://developers.google.com/vr/develop/unity/download

## GearVR
以下のサイトがすごく良くまとまっているので参考
特に「Gear VRアプリをビルドするには」の欄をよく読みましょう
oculus署名が必要です。
> [Unity＋Gear VR開発メモ](https://framesynthesis.jp/tech/unity/gearvr/)

# 2. Edit/Project Settings/Playerの設定
PlayerSettingsでandroidのバージョンなどの設定をめんどくさがってbuildエラーが起きたので注意

## 2.1 com.company_name.product_name
Bundle Identifyの設定
PlayerSettings/Other Settings/IdentificationのPackage Nameを変更する必要がある
> [[Unity]Android向けにビルドする]
(https://qiita.com/neku/items/c35b1de07eac18151f4e)


## 2.2 androidのバージョン
Minimam API LevelやTarget API levelが指定する。
特にgoogleVRは5.6以上推奨です。その際SDKでAPIがインストールされているか確認しましょう。

## 2.3 XR settings
Virtual Reality Supportedをオン
GoogleVRのアセットが入っていれば、Cardboadの設定があるはずです。
GearVRはOculusに設定

ここまででGearVR/Cardboardのビルドはできるはずです。ビルドして確かめてみましょう
Texture Compressionですが、GearVRの場合ASTCが推奨されているサイトが多いです。
ただ、GoogleVR(私の場合はHTV32)だとASTCだとアプリが強制停止してしまったのでETC2を使用しています。
また、Quality Settingは触れていませんが、アンチエイリアスや影、光など調整が必要な部分はあると思います。

# 3. その他のエラーについて
私が引っかかってしまったエラー集です。

## Texture Compression
先ほども触れましたが、Texture Compressionはどれがいいのか悩み中です（そもそもどれがどんな性質かもよくわかってない）。

## 5/11 clustering jobs
VRに限った話ではなく、NavMeshを入れるとかかるエラーです。URL参照。
>[Unityで5/11 Clustering 1jobsから動かなくなった時の解決法](http://saitetutan.hatenablog.jp/entry/2016/07/09/162258)

## Unet関係
NetworkIdentityが結構厄介です。NetConnectorを継承してNetworkManagerを作り、それとは別にUnetを管理するものがあると良いです。というかなんとなくできたけど、何がダメで何がOKなのかもよくわかっていません。Unet使っている方がいれば教えて欲しいです。なおPhotonもよくわからん。

## Cameraはできるだけ少なく
当たり前だけどVRな分Cameraの処理がえげつない。Camera増やしてたらいつの間にかFPSがとんでもないことになっていたのでなるべく減らしましょう。FPSの低さがそのまま酔いに繋がってしまわないように。

# 終わりに
長くなりましたが、細かいエラーで失敗してしまわない用の備忘録です。
VRアプリは重くなりやすく、Qualityなど色々と注意を向ける部分が多いので細かい調整が不可欠です。読まれた方で、Qualityやtextureなど細かい設定、「自分はこういう設定にしている」等ありましたら、教えていただけると嬉しいです。
HyperLedger Fabric v1.1でchaincodeを実行する

#０．前回
[前回の投稿](https://qiita.com/yukike/private/093b9277296886746f91 "vagrantを使って、HyperLedger Fabric v1.1の環境を簡単構築")でHyperLedger Fabricの起動まで行いましたので今回は動作確認のためgo言語のサンプルソースを使ってchaincodeの実行を行いたいと思います。

#１．chaincodeとは
端的にいうと、イーサリアムでいうスマートコントラクトのことであり、HyperLedger Fabricではchaincodeと呼んでいます。HyperLedger Fabricでもブロックチェーン上にプログラムを実行することができます。HyperLedger Fabricを使用したブロックチェーンの開発となれば大半がchaincodeの開発になると思います。

#２．dockerのCLIイメージへログインする
前回の投稿に沿ってHyperLedger Fabricを起動した場合、イメージ名が`cli`であるイメージが起動されているはずです。コマンド実行によりチェーンコードを実行するためのイメージですが、chaincodeのインストール、インスタンス化についても使用します。以下のコマンドでイメージの中へログインします。

```
#「cli」の部分にdockerのイメージ名を入れる
sudo docker exec -it cli bash
```

#３．ソース格納用のディレクトリを作成する
ログインしたら、イメージ内部にソース格納用のディレクトリを作成します。作成したらログアウトしておきます。

```
mkdir -p /opt/gopath/src/github.com/sample
exit
```

#４．dockerへファイルをコピー
以下のコマンドでdockerのcliイメージへファイルをコピーします。ここではサンプルソースであるchaincode_example02.goを使用します。

```
cd /home/vagrant/fabric-samples/chaincode/chaincode_example02/go
sudo docker cp chaincode_example02.go cli:/opt/gopath/src/github.com/sample/chaincode_example02.go
```

#５．ファイルのインストール
chaincodeを`sample`という名前でインストールします。更新をする場合は、`-v 1.0`がバージョン情報になっていますので、バージョンを上げて実行してください。

```
sudo docker exec -e "CORE_PEER_LOCALMSPID=Org1MSP" -e "CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp" cli peer chaincode install -n sample -v 1.0 -p github.com/sample
```

#６．インスタンス化
chaincodeをインスタンス化します。サンプルソースは簡単な送金アプリになっていて、`-c '{"Args":["init","a","5000","b","5000"]}'`で初期の設定を行っています。`a`,`b`が名称、`5000`が金額になります。

```
sudo docker exec -e "CORE_PEER_LOCALMSPID=Org1MSP" -e "CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp" cli peer chaincode instantiate -o orderer.example.com:7050 -C mychannel -n sample -v 1.0 -c '{"Args":["init","a","5000","b","5000"]}' -P "OR ('Org1MSP.member','Org2MSP.member')"
```

#７．送金処理
これでchaincodeを実行できる状態になりました。サンプルのソースの機能で送金機能がありますので実行してみます。ここでは「a」から「b」へ100を送金します。

```
sudo docker exec -e "CORE_PEER_LOCALMSPID=Org1MSP" -e "CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp" cli peer chaincode invoke -o orderer.example.com:7050 -C mychannel -n sample -v 1.0 -c '{"Args":["invoke","a","b","100"]}' 
```

#８．残高確認
以下のコマンドで残高を確認します。aの残高は4900、bの残高は5100と出力されるはずです。

```
#「a」の場合
sudo docker exec cli peer chaincode query -C mychannel -n sample -c '{"Args":["query","a"]}'
---------結果---------
Query Result: 4900
#「b」の場合
sudo docker exec cli peer chaincode query -C mychannel -n sample -c '{"Args":["query","b"]}'
---------結果---------
Query Result: 5100
```
Docker for Windowsをインストール後 could not read CA certificateエラーが出た時の解決方法

# 問題
Docker for Windowsをインストール後、`docker images`を実行したところ、エラー発生

`
could not read CA certificate "C:\\Users\\...\\.docker\\machine\\machines\\default\\ca.pem": open C:\Users\...\.docker\machine\machines\default\ca.pem: The system cannot find the path specified.
`

# 原因
おそらく、Docker Toolboxを利用していたことのあるPCにDocker for WindowsをインストールしたことでDocker Toolboxの設定が残ってしまった。

# 発生経緯と手順
* Windows 10 Home だったため、Docker Toolboxをインストールし利用していた
* Windows 10 Pro にアップグレード
* Docker Toolboxをアンインストール
* Docker for Windowsをインストール
* インストール後、確認のため`docker images`を実行したところエラー発生

# 解決方法
以下をPowershellで実行

~~~
[Environment]::SetEnvironmentVariable("DOCKER_CERT_PATH", $null, "User")
[Environment]::SetEnvironmentVariable("DOCKER_HOST", $null, "User")
[Environment]::SetEnvironmentVariable("DOCKER_MACHINE_NAME", $null, "User")
[Environment]::SetEnvironmentVariable("DOCKER_TLS_VERIFY", $null, "User")
[Environment]::SetEnvironmentVariable("DOCKER_TOOLBOX_INSTALL_PATH", $null, "User")
~~~

# 解決するのに使用したissues(詳細はリンク先参照)
https://github.com/docker/for-win/issues/1746
[ffmpeg,dvdauthor]MacでCLIでmovをDVDに焼くためのVIDEO_TSを作成する

# 背景

GUI使うのも（ツール探すのも）面倒臭くて特に何かしらの調整も必要ないけど、
さっくり動画ファイル（.mov）をDVDに焼きたかった。

## 環境

- macOS High Sierra 10.13.3
- Homebrew 1.6.2
- FFmpeg 3.0.1
- dvdauthor 3.0.1

### 行程

以下をターミナルで実行。Homebrewでffmpegとdvdauthorは入ります。

```sh
# install ffmpeg & dvdauthor
brew install ffmpeg
brew install dvdauthor

# create VIDEO_TS & AUDIO_TS
ffmpeg -i in.mov -target ntsc-dvd out.mpg
dvdauthor -o dvd -t out.mpg
ls dvd # --> AUDIO_TS     VIDEO_TS
```


あとはmacのディスクユーティリティで
``ファイル > 新規イメージ > フォルダからのイメージを作成``を選択し、
先ほど作成したVIDEO_TSを選択し、`.cdr`を作成したら
ファインダーで作成した`.cdr`を右クリックして接続したDVDに書き込めば良いだけです。

![スクリーンショット 0030-05-04 0.47.11.png](https://qiita-image-store.s3.amazonaws.com/0/36105/8e74f510-2a5d-5f76-de06-4816ea0d4275.png)

---

## 参考

- FFmpeg
  - https://www.ffmpeg.org/
- dvdauthor
  - http://dvdauthor.sourceforge.net/
[Sinatra]APIサーバーを作ろう

#RubyでAPIサーバーを作ろう!!

##クロスドメイン制約をどうにかしなくてはいけません。
そのために以下のコードを書きます。

```ruby:app.rb
before do
content_type :json
headers 'Access-Control-Allow-Origin' => '*',
'Access-Control-Allow-Methods' => ['OPTIONS', 'GET', 'POST']
```
オーバーフロー/アンダーフローについてまとめてみた


# はじめに

オーバーフロー、アンダーフローは意味が曖昧なまま使われているので、
一般的にどのような定義になっているのかまとめて見ました。

注意：
「うちは社内方言でこうだ」と言うのを否定するものではありません。

# 種類

一般的な定義の有無は対象が整数なのか浮動小数点数なのか、
はたまたバッファなのかによって異なるようです。

いかに示す通り、整数のアンダーフローのみ一般的な定義はありません。

|            |オーバーフロー  |アンダーフロー  |
|:-:         |:-:             |:-:             |
|整数        |*YES*           |NO              |
|浮動小数点数|*YES*           |*YES*           |
|バッファ    |*YES*           |*YES*           |

# 整数

## オーバーフロー

そのビット幅で表現できる範囲の最大値を上回った場合、下限を下回った場合がオーバーフローです。
Wikipedia : https://en.wikipedia.org/wiki/Integer_overflow

8bitの符号なし整数に入る値の範囲は0～255ですが、これを超えた場合が以下の例です。

```c
#include<stdio.h>
#include<stdint.h>

void main(void)
{
    uint8_t a = 255;
    printf("a:%d\n", a);

    a++;
    printf("a:%d\n", a);
}
```

結果：
このようにa++の結果、aは256にはならず0になります。

```
a:255
a:0
```

下限を下回った場合も *オーバーフロー* です。
以下の例は上記と同様ですが、今度は下限値0から更にデクリメントしています。

```c
    uint8_t b = 0;
    printf("b:%d\n", b);

    b--;
    printf("b:%d\n", b);
```

結果：

```
b:0
b:255
```

## アンダーフロー

整数の場合、一般的な定義は特に無いようです。

# 浮動小数点数

MSDNの記事が良い感じにまとまっています。
https://msdn.microsoft.com/ja-jp/library/hd7199ke.aspx

## オーバーフロー

整数型と同じように、浮動小数点数型にも表現できる最大数があります。
詳しくは上記のMSDNのページをご覧ください。

## アンダーフロー

こちらは整数型にはない要素です。

値が限りなく0に近づいて表現しきれなくなると、浮動小数点数で表現しきれなくなります。
Wikipedia : https://en.wikipedia.org/wiki/Arithmetic_underflow

しかし、用途によっては単に0と扱ってしまえば良かったりもします。

# バッファ

## オーバーフロー

Wikipedia : https://en.wikipedia.org/wiki/Buffer_overflow

確保している領域からはみ出してアクセスしてしまう事です。
PCなどのリッチな環境だとMMUで止めてくれたりしますが、
組み込み系の場合、特にスタックオーバーフローすると被害が甚大です。

ありがちな例：

```c
    uint8_t  buf[4];

    /* Correct condition is "i < 4" */
    for(i = 0; i <= 4; i++){
        buf[i] = i;
    }
```

## アンダーフロー

バッファアンダーランの別名です。
オンラインの動画配信サービスで再生が止まるのは
再生用バッファの枯渇(=アンダーラン)によるものです。

# ソース

一応、Githubに上げておきました。
https://github.com/YankeeDeltaBravo225/Overflow_sample

バッファオーバーフローのやつは環境によっては
セグメント違反が起きるかもしれないので要注意です。
PowerShellでサーバーの死活監視

監視対象に定期的にPingを打って反応なければメールを送信するスクリプトです。
イベントログにも記録します。





```powershell:Check-DeadOrAlive.ps1

# 監視対象
[String[]]$addressAp = @('ホスト1','ホスト2',...)

# 間隔
$interleave=180

# イベントログソース
$eventLogSource = "DeadOrAlive"


# メール送信
function Send-Mail( $Subject, $Body ) {
	$MailSv = "メールサーバー"
	$Port = 587
	$Encode = "UTF8"
	$address = "メールアドレス"

	$pwd = "パスワード" | ConvertTo-SecureString -AsPlainText -Force
	$cred = New-Object System.Management.Automation.PSCredential $address,$pwd

	Send-MailMessage `
	    -To $address `
	    -From $address `
	    -SmtpServer $MailSv `
	    -Credential $cred `
	    -Encoding "UTF8" `
	    -Port $Port `
	    -Subject $Subject `
	    -Body $Body 
}

# イベントログソース作成
if ([System.Diagnostics.EventLog]::SourceExists($eventLogSource) -eq $false){
    New-EventLog -LogName Application -Source $eventLogSource
}
 

$dead_or_alive = @{}
for($i = 0; $i -lt $addressAp.Count; $i++) {
	$dead_or_alive.Add($addressAp[$i],'alive')
}

# ping 
while(1){
	for($i = 0; $i -lt $addressAp.Count; $i++) {
		# Pingを実行します。
		$pingAlive = @(Test-Connection -ComputerName $addressAp[$i] -Quiet)

		if ($pingAlive -eq $True) {
			$message = "Check-DeadOrAlive SUCCESS:" + $addressAp[$i]
			echo $message
			Write-EventLog -LogName Application -Source $eventLogSource -EventId 1 -Message $message
			$dead_or_alive[$addressAp[$i]] = 'alive'
		} else {
			if($dead_or_alive[$addressAp[$i]] -eq 'alive'){
				# ログを記録する
				$message = "Check-DeadOrAlive ERROR:" + $addressAp[$i]
				echo $message
				Write-EventLog -LogName Application -Source $eventLogSource -EventId 1 -Message $message
				# メールを送信する
				$subject = $addressAp[$i] + " IS DEAD"
				[String]$date = Get-Date
				$body = $date + "`r`n" + $subject + "`r`nfrom ad.vanpool.lan"
				Send-Mail $subject $body
				$dead_or_alive[$addressAp[$i]] = 'dead'
			}
		}
	}


	# 待機
	Start-Sleep -s $interleave
}

# 終了
Write-EventLog -LogName Application -Source $eventLogSource -EventId 1 -Message "Check-DeadOrAlive: Terminated"

```
Acronis True Image 2017によるWindows 7システムバックアップ

#環境
- Windows 7 Professional 64bit
- Intel Corei7-3770K
- 16GB RAM
- Acronis True Image 2017

#1.Window AIKのインストール
- https://www.microsoft.com/ja-jp/download/details.aspx?id=5753 よりWindows 7用のAIKダウンロード
- ダウンロードしたISOファイルをDVDなどに書き込む
- 書き込みしたDVDからWindows AIKをインストール

#2.Windows PEベースのAcronis True Imageブータブルメディア作成
- Acronis True Image 2017を起動
- 左メニュー>ツール>ブータブルメディアビルダ>Acronisプラグインを含むWINPEベースのメディアを作成
<br>※通常のブータブルメディア(Acronisブータブルレスキューメディア)で作成すると、うまくドライバ関係を読み込めていないせいか、BIOS>CDブート>Acronisの選択肢3つ選ぶ画面が出てくる>画面真っ暗だったのでWindows(7だけ?)はWinPEベースで作成してほうがよいです。

#3.システムバックアップ
- 作成したブータブルメディアをDVDドイラブに挿入した状態で再起動or起動
- Acronisのx86, x64, OSブートの3つ選択肢が出てくるのでAcronisを選択
- Acronisが起動してくるので、ディスクのバックアップでシステムドライブを選択
- バックアップの完了画面が出てくるまで待機
- 完了画面が出てきたら終了

#おまけ(ディスクイメージのリストア)
元のディスクにリストアする場合は、Acronis起動画面から復元を選び戻せば良い。

バックアップしたディスクイメージを別のディスクにリストアする際は、OSの読み込み先を修正しないと正しく読み込めないため下記手順にてリストア(別ディスクにリストアした後の手順)。
- Windows 7のインストールメディアをドライブに挿入した状態で起動
- Windowsのインストーラが立ち上がるので、最初の画面を「次へ」を押す
- 次の画面に移ったら、「コンピュータの修復」を押す
- スタートアップの修復

これで、OSが立ち上がってくると思います。
PCM5102AとAK4495SEQの周波数別インパルス応答

# 概要

インパルスデータを同時にI2S入力させ、周波数別に観測。

# 実験環境

|DAC|ProductName|
|:--|:--|
|PCM5102a|[HanoHat-PCM5102a](http://www.friendlyarm.com/index.php?route=product/product&product_id=169)|
|AK4495SEQ|NanoHat-AK4495SEQ(自作)|

※いずれも、Normal Delay, SharpRollOffFilter 相当です。

SBC: NanoPi-NEO PLUS2
OS : [Ubuntu 16.04 MCLK出力改造版](https://qiita.com/blue-7/items/d643cc9e441ca594a01e)

![image.png](https://qiita-image-store.s3.amazonaws.com/0/187531/db1dc17c-344d-ad8e-90d2-e636799657db.png)

# 観測結果

オシロスコープへは、RCA→BNCで直接入力。
1ch(黄色)側：AK4495SEQ
2ch(水色)側：PCM5102a

終端抵抗は無し。オシロの入力抵抗 1MΩ のみ。

## 44.1kHz

![image.png](https://qiita-image-store.s3.amazonaws.com/0/187531/959e56ca-5df7-0fa5-4790-57241af48c1f.png)

![image.png](https://qiita-image-store.s3.amazonaws.com/0/187531/6735948b-dfe0-7305-2140-a9d41e800a9c.png)

## 96kHz

![image.png](https://qiita-image-store.s3.amazonaws.com/0/187531/21e209fc-1e0f-afd0-f1df-c23d11efbfee.png)

![image.png](https://qiita-image-store.s3.amazonaws.com/0/187531/7ae87e17-ae55-89d6-105c-199268244534.png)

## 192kHz

![image.png](https://qiita-image-store.s3.amazonaws.com/0/187531/bb0f8381-bf60-efff-d5fc-1fa3f689fe84.png)

![image.png](https://qiita-image-store.s3.amazonaws.com/0/187531/63ff8b4d-d218-1ed8-5e71-5e2477e6ba85.png)


## 384kHz

![image.png](https://qiita-image-store.s3.amazonaws.com/0/187531/84f1fd94-b1f8-80ef-5ffd-b6069fee4579.png)

## 768kHz

![image.png](https://qiita-image-store.s3.amazonaws.com/0/187531/fa1fbade-eca1-5170-1f23-91f1f90b2d49.png)

PCM5102aは384kHzまでなので、出ていません。

# 結論

- AKのほうが遅延が大きい。ただし、384kHzにおいては反転。
- いずれも、384kHz以上は十分なアナログフィルタがあるとみなし、SincInterpolationを実施していない。
- いずれも、192kHzは荒れ気味。
- PCM5102aのこの波形は、チップ固有なのか、ボード固有かは不明です。
AutoHotkey で Thinkpad の PageUp/Down のキー押し間違いを防止する

# 最近の ThinkPad のキー配置は特殊です。

最近の ThinkPad のキー配置です。

![ThinkPadX280](https://pc.watch.impress.co.jp/img/pcw/docs/1012/609/13.jpg)

昔の Thinkpad が、7段(7列)キーボードのときは、普通のデスクトップキーボードと似た配置だったために、デスクトップとThinkPadを併用するときに、頭の切り替えなどがあまり必要なくかなり使いやすかった感覚がありましたが、今の ThinkPad のキーボード配置は微妙です。

PageUp / PageDown / Home / End を独立させて押しやすくしている努力はわかるのですが、他のノートPCとも互換性がなくて、複数PC を使いこなす時にいろいろ困る感じがします。

特に PageUp/PageDown が変な場所にあり、押し間違いも多いようです。

なので AutoHotkey でPageUp/PageDown を無効化したり、あるいは押し間違えてもよいように 左キー/右キー と一致させてみます。

# PageUp / PageDown キーを無効化する。

ahkファイルを作成して、AutoHotkeyインストールされているところで、ahkファイルを起動すると、機能が実現します。


```PageUpPageDownCancel.ahk
PgUp::
PgDn::
^PgUp::
^PgDn::
+PgUp::
+PgDn::
!PgUp::
!PgDn::
#PgUp::
#PgDn::
```

このようにすれば PageUp/PageDown と Ctrl / Shift / Alt / Win キーの同時押しも全て防止して PageUp/PageDown キーが事実上つかえなくなります。

Ctrl + Shift + PageUp / PageDown の同時押しなども同じような記述で防止できると思うのですが、そもそも、そのようなキーの押し方で特殊な動きをすることが通常ないと思うので定義していません。


# PageUp / PageDown キーを 左キー / 右キー に変換する

次は変換の方法です。

```
PgUp::Send {Left} 
PgDn::Send {Right} 
^PgUp::Send ^{Left} 
^PgDn::Send ^{Right} 
+PgUp::Send +{Left} 
+PgDn::Send +{Right} 
!PgUp::Send !{Left} 
!PgDn::Send !{Right} 
#PgUp::Send #{Left} 
#PgDn::Send #{Right} 

```

このようにすると、PageUp / PageDown キーを左右の矢印キーと同じ機能をもたせることができます。

# PageUp / PageDown キーを押したくなったときはどうすればいいのか

自分の記事ですが、次の記事をみていただき、右Ctrlキーと、矢印キーで、Home / End / PageUp / PageDown と同じ機能を実現させると、右手だけで、カーソルやブラウザのスクロールができて便利なのではないでしょうか。

Win10 AutoHotKeyで、右Ctrl+矢印キーでPageUp/PageDown/Home/Endする - Qiita
https://qiita.com/standard-software/items/6e4ad65da23041c075de


他社のノートPCでよく使われている 左下のFnキー + 矢印キー との組み合わせで、Home / End / PageUp / PageDown の各キーを実現させる方法は、左下のFnキー + 矢印キー で、ThinkPad がどんなキーコードを返してくるのかを調査できなかったので不明です。

昔の ThinkPad のように、再生系のキーコードが送られるのなら、AutoHotkeyで変換ができますが、そもそも、キーコードが送られないかもしれません。


# 参考

> ThinkPad X260のPgUp(Page Up),PgDn(Page Down)キーを変更・無効化する方法
> https://look-around-the-world.com/post-3671-3671.html<br>

こちらのページの方もやはりPageUp/PageDownの押し間違いがいやだったようで、他のソフトを使って改善したようです。


> Windows 7のLenovo ThinkPadで、無変換とFn+上下左右カーソルキーの割当を変更 - つれづれ日記
> https://diary.sshida.com/20110108-1-Windows%207%E3%81%AELenovo%20ThinkPad%E3%81%A7%E3%80%81%E7%84%A1%E5%A4%89%E6%8F%9B<br>

こちらのページの方は昔のThinkPadのFnキー+矢印キーの同時押しのMediaPlayerキーが納得いかなかったみたい。確かにあれは変だった。


> ThinkPad X201sのFn + 矢印キーにHomeとEndを割り当て｜KONさんのブログ
> http://kaizoukonpa.blog87.fc2.com/blog-entry-24.html

これは、昔のThinkPad キーボード。Fn+矢印キーの同時押しは昔からカスタマイズネタだった。
WindowsにDjangoの環境を作る

Windows Subsystem for LinuxにUbuntuをインストーしてPython3とDjangoをインストールしてWEBアプリを動作させるまでの手順です。

DjangoのWebアプリは本番環境ではDBにMariaDBを使用するので、ここでもインストールします。


# 環境
Windows10 バージョン1709
Ubuntu16.4
Python3
Django2.0

# Windows Subsystem for LinuxとUbuntuのインストール
こちらのページを参照させていただきました。
[Windows Subsystem for LinuxからUbuntuをアンインストール](https://qiita.com/akabei/items/1e2931cdfd8c0b206990)

バージョン情報はこちら

```bash
NAME="Ubuntu"
VERSION="16.04.3 LTS (Xenial Xerus)"
ID=ubuntu
ID_LIKE=debian
PRETTY_NAME="Ubuntu 16.04.3 LTS"
VERSION_ID="16.04"
HOME_URL="http://www.ubuntu.com/"
SUPPORT_URL="http://help.ubuntu.com/"
BUG_REPORT_URL="http://bugs.launchpad.net/ubuntu/"
VERSION_CODENAME=xenial
UBUNTU_CODENAME=xenial
```

バージョンの確認方法はこちらのページに。
[Ubuntuのバージョン確認](https://qiita.com/glires/items/a2a07565207509af0e83)

sudoのパスワード入力を解除する方法はこちら。
[sudo のパスワードを入力なしで使うには](https://qiita.com/RyodoTanaka/items/e9b15d579d17651650b7)

# 開発ツールのインストール
Pythonモジュールのインストールでgccが必要だったりするので開発ツールパッケージをインストールしておきます。

```bash
$ sudo apt install build-essential
```
結構時間かかる・・・



# Python3のインストール

最初からPython 3.5.2が入っていました。

```bash
$ python3 --version
Python 3.5.2
```

以前にはPython3って入っていなかったような・・・Ubuntuがアップデートされたりしたのかな？

# venv環境作成

venvの環境を作ろうとするとエラーになります。

```bash
$ python3 -m venv venv
The virtual environment was not created successfully because ensurepip is not
available.  On Debian/Ubuntu systems, you need to install the python3-venv
package using the following command.

    apt-get install python3-venv

You may need to use sudo with that command.  After installing the python3-venv
package, recreate your virtual environment.

Failing command: ['/mnt/c/prj/sao/venv/bin/python3', '-Im', 'ensurepip', '--upgrade', '--default-pip']
```

以前自分がメモしたページ
[wslでpythonのvenv環境が作れない](https://qiita.com/tatamyiwathy/items/c673c19202eea260f37e)

これでvenv環境が作成されpipコマンドもインストール出来ました。


# Pythonパッケージのインストール

```bash
$ pip3 install -r requirements.txt
```

エラーで止まりました

```bash
    x86_64-linux-gnu-gcc -pthread -DNDEBUG -g -fwrapv -O2 -Wall -Wstrict-prototypes -g -fstack-protector-strong -Wformat
 -Werror=format-security -Wdate-time -D_FORTIFY_SOURCE=2 -fPIC -DHAVE_SASL -DHAVE_TLS -DHAVE_LIBLDAP_R -DHAVE_LIBLDAP_R
-DLDAPMODULE_VERSION=3.0.0 -DLDAPMODULE_AUTHOR=python-ldap project -DLDAPMODULE_LICENSE=Python style -IModules -I/usr/in
clude/python3.5m -c Modules/LDAPObject.c -o build/temp.linux-x86_64-3.5/Modules/LDAPObject.o
    In file included from Modules/LDAPObject.c:8:0:
    Modules/constants.h:7:18: fatal error: lber.h: No such file or directory
    compilation terminated.
    error: command 'x86_64-linux-gnu-gcc' failed with exit status 1
```

*lber.h*がないよって言ってますね。どうやら*python_ldap*パッケージで必要なようです。
こちらに答えがありました。このページではpython-devをインストールしてますがpython3-devをインストールする必要があります。

[I can't install python-ldap](https://stackoverflow.com/questions/4768446/i-cant-install-python-ldap)

```bash
$ sudo apt install libsasl2-dev python3-dev libldap2-dev libssl-dev
```

# MariaDBのインストール

```bash
$ sudo apt install mariadb-server
$ sudo mysql_secure_installation
$ sudo service mysql start
```

# そのほかパッケージインストール

```bash
sudo apt install libcairo2-dev
```

# 終わり
以上でWSLのUbuntuにDjangoの環境構築は終了です。
portの空きを確認してふさがっていたらkillする

## コマンド
3000番が空いているかどうか確認したいとき

```sh
$ lsof -i:3000

COMMAND   PID     USER   FD   TYPE            DEVICE SIZE/OFF NODE NAME
ruby    10657 mom0tomo   19u  IPv4 0x8cd63e6cdb026c9      0t0  TCP localhost:cgms (LISTEN)


// 殺す
$ kill 10657
```

## どんな時に使うか
`rails s`で起動したサーバをエラーが出た際、 `^C`で落とそうとしても、なかなか停止してくれないときがある。
このとき不意にターミナルを閉じたりするとゾンビ化してしまう。

お目当のポートがふさがっていないか確認して、ふさがっていたら殺す。

## 参考
[Linuxでプロセスが何のポート使っているかを調べる](https://qiita.com/sonoshou/items/cc2b740147ba1b8da1f3)
PythonのgspreadでGoogleスプレッドシートを読み書きしようとしたらInsufficient Permissionと言われた場合の対処法

# 症状

- [[Python] Google SpreadSheetをAPI経由で読み書きする - YoheiM .NET](https://www.yoheim.net/blog.php?q=20160205)
- [SCUEL開発者ブログ](http://scuel-developer.hatenablog.jp/)

あたりを参考に、Googleスプレッドシートをpythonからいじろうとしたらハマった。

- macOS High Sierra 10.13.4
- python 3.6
- gspread 3.0.0
- oauth2client 4.1.2

ソースコードは[SCUEL開発者ブログ](http://scuel-developer.hatenablog.jp/)のほぼそのままなので割愛。

```:エラーメッセージ
Traceback (most recent call last):
  File "/Users/****/testspread.py", line 22, in <module>
    wks = gc.open("idcard").sheet1
  File "/Users/****/myenv/lib/python3.6/site-packages/gspread/client.py", line 122,in open
    self.list_spreadsheet_files()
  File "/Users/****/myenv/lib/python3.6/site-packages/gspread/client.py", line 96, in list_spreadsheet_files
    res = self.request('get', url, params=params).json()
  File "/Users/****/myenv/lib/python3.6/site-packages/gspread/client.py", line 79, in request
    raise APIError(response)
gspread.exceptions.APIError: {
 "error": {
  "errors": [
   {
    "domain": "global",
    "reason": "insufficientPermissions",
    "message": "Insufficient Permission"
   }
  ],
  "code": 403,
  "message": "Insufficient Permission"
 }
}
```

**Insufficient Permission** なので認証が通っていない？？

- Google Drive APIを有効化
- サービスアカウントを作成して、編集権限を追加
- APIアクセスのJSONファイルをダウンロード
- 操作したいスプレッドシートに、共有編集者として作成したサービスアカウントを追加

はちゃんとやったはず。

# 検索

gspread Insufficient Permission python
でググったら
ここが見つかって
[insufficient permission · Issue #532 · burnash/gspread · GitHub](https://github.com/burnash/gspread/issues/532)
ここにたどり着いた。
[python - gspread authentication throwing insufficient permission - Stack Overflow](https://stackoverflow.com/questions/49258566/gspread-authentication-throwing-insufficient-permission/49295205#49295205)

# 解決

Google Drive API のほかに、**Google Sheets API** を有効にし、

```python:before
scope = ['https://spreadsheets.google.com/feeds']
```

を

```python:after
scope = ['https://spreadsheets.google.com/feeds',
         'https://www.googleapis.com/auth/drive']
```

にしたら動いた。

# その後

公式リファレンス見たら書いてあったというオチ
[gspread API Reference — gspread 3.0.0 documentation](https://gspread.readthedocs.io/en/latest/#gspread.Client.create)

<img width="655" alt="Note" src="https://qiita-image-store.s3.amazonaws.com/0/70022/2da52989-4d8e-fd27-c733-e5e434251dc7.png">

ドキュメントは良く読みましょう！
JavaScriptでShift_JISの固定長APIを読み込む

Ajaxで取得したShift_JISのレスポンスを、固定長でスライスして読み込む方法。
とてもマイナーな要件で情報がない。
SJISでしかも固定長とは時代遅れも甚だしいが、日本の片隅に人知れず苦労している人がいるかもしれないのでシェアする。

ちなみに、Shift_JISのデータをAjaxで取得して丸ごとString化するだけであれば、もっと簡単で以下のようなことをやる必要はない。
そちらはググれば他にたくさん記事があるので割愛。

# 概要

やり方は知ってしまえば簡単。
ArrayBufferの形でHTTPレスポンスを取得して、固定長でバイナリデータをスライスした後、ライブラリでバイナリデータをテキスト化する。

# ライブラリ

ライブラリは[encoding.js](https://github.com/polygonplanet/encoding.js)を使用。
こういったユーティリティーを作ってくださる方は本当にありがたい。

# サンプルコード

以下の例では "http://localhost:8000/sample.txt" に配置されたSJISのテキストを固定長で区切ってログ出力する。
ES2015形式。エラー処理などは無視した必要最低限のコードとなる。

```JavaScript
class Response {
    constructor(data) {
        this.data = data;
        this.readOffset = 0;
    }

    read(size) {
        const data = this.data.slice(this.readOffset, this.readOffset + size);

        const sjisData = new Uint8Array(data);
        // SJISのデータをEncodingライブラリでUnicodeのデータに変換する
        const unicodeData = Encoding.convert(sjisData, 'UNICODE', 'SJIS');
        // UnicodeのデータをEncodingライブラリでStringにする
        const text = Encoding.codeToString(unicodeData);

        this.readOffset += size;

        return text;
    }
}

class SJISReaderSample {

    readSJISData() {
        this.getData('http://localhost:8000/sample.txt', this.parseResponse)
    }

    parseResponse(responseData) {
        const response = new Response(responseData);

        const name = response.read(4); // 4バイト読み込みString化
        const age = response.read(6); // 6バイト読み込みString化

        console.log(`${name} は ${age} 歳`)
    }

    getData(url, onComplete) {
        const connection = new XMLHttpRequest();
        connection.responseType = 'arraybuffer'; // ☆arraybufferの形でデータを受け取ることで、固定長でデータをスライスできる

        connection.onreadystatechange = () => {
            if (connection.readyState === 4 && connection.status === 200) {
                onComplete(connection.response);
            }
        };

        connection.open('GET', url);
        connection.send();
    }
}

new SJISReaderSample().readSJISData();

```
Reinforcement LearningのUdemyコンテンツをやっていく(1)

##Reinforcement LearningのUdemyコンテンツの勉強を始めました。
個人的に、機械学習を利用したセキュリティのソリューションを作りたくて、Pythonを使った強化学習の勉強を開始したいと思います。
教科書は、以下のものを使います。

「Advanced AI: Deep Reinforcement Learning in Python」
https://www.udemy.com/deep-reinforcement-learning-in-python/

何かあれば、マサカリ、質問など投げていただけたらと思います。

##Introduction and Outline
深層学習と強化学習の組み合わせ→ALphaGo、自動運転自動車、人間を超えたテレビゲームの試合
７０年代から開発されてたけど、最近すごいらしい
深層強化学習！！
強化学習は教師あり学習、教師なし学習とは違うよ
技術的には、エージェントがデータと相互作用するんだけど、逐次的で、もっと相互作用的だよ。
教師あり学習や教師なし学習を退屈なものにするよ

多大な潜在能力があって、多大なリスクがあるよ
経済の安定性や、我々の存在そのものに多大なリスクがあるお（ターミネーター！？）
AIは人間みたいには考えないよ

OpenAI使うみたい

基礎をやっていったら、OpenAI Gym環境をやっていくよ
Open AI Gymって、シンプルな標準的UIを全ての環境で準備しているので、UIを勉強するだけだよ

Cart-Pole
カートに乗ったポールを可能な限りバランスしていくゲーム
Mountain Car
車を山のてっぺんまでおしあげる必要があるんだけど、直接登る力はなくて、反動を使う必要がある

Boston Dynamicsのロボットが例として出てた

##テクニック
前のコース：Marcov Decision Process
Dynamic Programming
Monte Carlo
Temporal Difference Learning
の三つが重要らしい

RBFネットワークが強化学習では使われるらしい
Deep Q-Learning

##どこでコードをゲットするか
以下のリポジトリでコードをゲットできます。

https://github.com/lazyprogrammer/machine_learning_examples

OpenAI Gymをインストールするには以下のようにします

```
sudo pip install gym
```

pipがインストールされてなかったので、以下のサイトを参考にインストール

http://uxmilk.jp/12691

注意事項としては、「ちゃんとコードしようね！」ということが挙げられていました。講義の中で実行されているコードを自分でもちゃんと実行してみること、そして最後には、何も見ずに自分でもコードして実行できるようにすること。
なんとなく通して見て、何も覚えてないということはないようにすること

成功するためのガイドラインも示されていました
1,Q&Aを活用することーこれは、Udemyコンテンツを買った人しか使えないですね
2,前提科目を知っておくこと
３、学んだことを全て実際に実装してみることー重要
　
ということで、次回に続きます
[WIP]Vgrantのboxをパッケージ化する方法

# Vgrantのboxをパッケージ化する目的

個人用に使うとして、設定状態をパッケージ化しておけば使いまわすことができ１から設定する必要がないから

# パッケージ化の手順

### 1. Vagrantfile のあるディレクトリに移動
### 2. ```vagrant package``` でパッケージ化する
### 3. ```package.box``` というファイルが作成される
### 4. ```vagrant box add { box名 (例)my_box } package.box``` でボックス名を登録
### 5. ```vagrant box list``` でボックスのリストを確認

# 追加したboxの使い方

### 1. プロジェクトディレクトリを作成し、移動
### 2. ```vagrant init (例)my_box``` でVagrantfileの作成（初期化）
### 3. ```vagrant up``` でvagrant起動
### 4. ```vagrant ssh``` で仮想マシンに接続
### 5. ```httpd -v``` でWEBサーバーの状態を確認
### 6. ```chkconfig``` でApacheの自動起動設定状態を確認

# boxの削除

### ```vagrant box remove { box名 (例)my_box }``` でboxの削除
### ```rm -rf [プロジェクトディレクトリ]``` でプロジェクトディレクトリを完全に削除

# 参考
https://hajipro.com/vagrant/vagrant-package
オフラインリアルタイムどう書くF07の実装例(Go)

オフラインリアルタイムどう書くF07のGoによる実装例

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

順当な実装を Go で書いてみた。

```go:実装
package f07

func neibours(x int) []int {
	r := make([]int, 0)
	for _, d := range []int{-6, 6, -1, 1} {
		c := d + x
		if 0 <= c && c < 29 {
			r = append(r, c)
		}
	}
	return r
}

func byteDiff(a, b byte) int {
	d := int(a) - int(b)
	if d < 0 {
		return -d
	}
	return d
}

func solve(src string) string {
	b := []byte(src)
	q := []int{2}
	for 0 < len(q) {
		pos := q[0]
		h := b[pos]
		b[pos] = '*'
		for _, i := range neibours(pos) {
			diff := byteDiff(h, b[i])
			if diff < 2 && '0' <= b[i] && b[i] <= '9' {
				q = append(q, i)
			}
		}
		q = q[1:]
	}
	return string(b)
}
```


```go:テスト
package f07

import (
	"testing"
)

func Test(t *testing.T) {
	var tests = []struct {
		name  string
		input string
		want  string
	}{
		{"0", "12345/29496/19485/09594/82457", "*****/*9*9*/*9*8*/*9*9*/82**7"},
		{"1", "12345/11011/65432/71999/65432", "*****/*****/*****/*1999/*****"},
		{"2", "11111/11111/11111/11111/11111", "*****/*****/*****/*****/*****"},
		{"3", "88011/79992/69992/69993/55443", "*****/*****/*****/*****/*****"},
		// 中略
		{"44", "10180/11677/22208/34867/28064", "***80/**677/***08/**867/*8064"},
		{"45", "34503/83687/42707/02558/12933", "***03/8**87/4**07/**558/**933"},
	}
	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)
		}
	}
}
```

`for _, x:=range 略` と書くべきところを間違えて `for x:=range 略` と書いて、10分以上ロスした。弱い。

`math.Abs` の引数が `float64` だったので使うのが嫌になって、 `byteDiff` を書いた。`math.IntAbs` なんかがあっても良さそうなもんだと思ったけど、なさそう。

`neibours` の 29 がややマジカルだけど、5×(5+1)-1 ということ。

書く前はだいぶ慣れてきたかと思っていたけど、`for`文の書き方がわかっていないようではまだまだである。
[Android] AppWidgetProviderで複数のクリックイベントを扱う

# はじめに
ウィジェットのクリックイベントの処理は特殊で，ブロードキャストを行うことで実装します．この記事では複数のクリックイベントを扱う際の注意点と，Oreoからの暗黙的なブロードキャストの制限についての対策を書いていきます．

※ ウィジェットのクリックイベントの処理方法をある程度知っていることが前提の記事です

# PendingIntentの作成
ここで注意すべきことは次の3つです．  

- ```Intent```を明示的にする
- ```requestCode```を一意にする
- ブロードキャスト受け取り時の処理分岐を可能にする

以下のコードで```Intent```と```requestCode```の作成をします．

```kotlin
private enum class ClickType {
     TYPE1, TYPE2, TYPE3
}

private fun createIntentAndRequestCode(context: Context, appWidgetId: Int, type: ClickType): Pair<Intent, Int>{
    val intent = Intent(context, WidgetCounter::class.java).apply {
        putExtra(APP_WIDGET_ID, appWidgetId)
        putExtra(CLICK_TYPE, type)
    }
    val requestCode = appWidgetId * ClickType.values().size + type.ordinal
    return Pair(intent, requestCode)
}

private const val CLICK_TYPE = "clickType"
private const val APP_WIDGET_ID = "appWidgetId"
```

その後，```PendingIntent.getBroadcast()```でブロードキャストする```PendingIntent```を生成し，```RemoteViews.setOnClickPendingIntent()```でクリックが発生した時の処理をセットします．

```kotlin
val (intent, code) = createIntentAndRequestCode(context, appWidgetId, ClickType.TYPE1)
// viewsはウィジェット本体(RemoteViews)
views.setOnClickPendingIntent(R.id.layout_id, // クリックイベントを設定するviewのID
    PendingIntent.getBroadcast(context, code, intent, PendingIntent.FLAG_UPDATE_CURRENT))
```


## Intentを明示的にする
Oreoから暗黙的なブロードキャストに制限がかかるため，自身(```AppWidgetProvider```)に対して明示的なブロードキャストする必要があります．```Intent(context, WidgetCounter::class.java)```の様にクラスを直接指定します．

## requestCodeを一意にする
ブロードキャストする```PendingIntent```には一意な```requestCode```を割り当てる必要があります．ウィジェットの一意なIDである```appWidgetId```を利用することで，一意な```requestCode```を生成することが出来ます．

```kotlin
val requestCode = appWidgetId * ClickType.values().size + type.ordinal
```
後述する```ClickType```が異なれば```appWidgetId```が同じでも```requestCode```が区別出来るようにするため，```ClickType```ごとに```type.ordinal```で値をずらしています．

## ブロードキャスト受け取り時の処理分岐を可能にする
処理分岐のために```enum class```である```ClickType```を定義します．```Int```の定数を複数定義して，その値によって処理を分岐させても良いのですが，```enum class```の方が便利なのでこちらを利用しました．```Intent```に```putExtra(CLICK_TYPE, type)```で```ClickType```を渡して，ブロードキャスト受け取り時に分岐が出来るようにします．

# onReceiveでイベント処理
```onReceive``` では，クリックイベント以外のブロードキャストも受け取ってしまう点に注意します．ウィジェットの更新を行う```ACTION_APPWIDGET_UPDATE```などの```Intent```も受け取り，スーパークラスで処理されるため，フィルタリングをする必要があります．

```kotlin
override fun onReceive(context: Context, intent: Intent) {
    super.onReceive(context, intent) // ACTION_APPWIDGET_UPDATEなどのIntentが処理される
    if (!intent.hasExtra(APP_WIDGET_ID) || !intent.hasExtra(CLICK_TYPE)) return

    val appWidgetId = intent.getIntExtra(APP_WIDGET_ID, 0)
    when (intent.getSerializableExtra(CLICK_TYPE) as ClickType) {
        ClickType.TYPE1 -> {
            // 処理1
        }
        ClickType.TYPE2 -> {
            // 処理2
        }
        ClickType.TYPE3 -> {
            // 処理3
        }
    }
}
```

# おわりに
明示的なブロードキャストという不思議なことをしていますが，これでOreoでも動くようになります．同じ```requestCode```を利用したために，処理分岐が出来ないというミスで数時間無駄にしてしまったので，同様の原因で詰まっている人の助けになればいいなと思います．
FinalIK(VRIK)+Animationでアバター制御

#やりたかったこと
研究室の教授がVRIK導入してくれたのでその使い方を勉強+Unityで汎用的な人型アバターの制御をやりたい
~~Animator触るのがめんどい、Blenderやだ~~

#VRIKについて
[FinalIK](https://assetstore.unity.com/packages/tools/animation/final-ik-14290)という有料アセットの一部。FinalIKは、簡単に言うと始点と終点を決めれば、その間のオブジェクトの位置角度を良い感じに整えてくれるアセット。
VRIK本来の使い方は、VRChatとかで人型アバターを扱いやすくするためのものなんだけど、その時の手順が

1.ヘッドセットとコントローラのオブジェクトをVRIKにアタッチ
2.VRIKがその位置に合わせて首から下のものを自動で制御

なので、1でつけるオブジェクトを別のものにすればアニメーション的な制御が楽にできるんじゃね?と考えた。

#前提
VRIKが導入してある
Animation使える

#やってみた
使用するモデルはunityちゃん。
Unityちゃんの親オブジェクトにVRIKコンポーネントを追加する
頭、腰と四肢にあたるオブジェクト(合計6つ)をVRIKにアタッチ。
完全にオブジェクト追従して欲しいので全てのRotation、PositionともにWeightを1にする。

↓こんな感じ
![スクリーンショット (100).png](https://qiita-image-store.s3.amazonaws.com/0/254776/bd32f416-35ad-fc2b-a494-06e00decf120.png)

Unityちゃんを座らせたかったので、こんな感じに各オブジェクトを設置。

![スクリーンショット (101).png](https://qiita-image-store.s3.amazonaws.com/0/254776/be74d107-3de9-107a-128f-e864ab542e72.png)

さあどうなる
![スクリーンショット (102).png](https://qiita-image-store.s3.amazonaws.com/0/254776/e28be287-67b5-2d97-ba7b-1b39556c87bf.png)

失敗、グロい。
パッと見て、角度がおかしいので、良い感じに各オブジェクトの向きを調整
![スクリーンショット (104).png](https://qiita-image-store.s3.amazonaws.com/0/254776/99f3d609-2ebf-9de2-300b-3896c37f3c81.png)

それでも失敗。
手は良いとして、足の曲がる方向が逆になってるので、これを制限しないとダメ。
FinalIKに入っているRotationLimitを使って可動域を変える必要がある。

色々使った結果一番簡単な、一平面だけの制限を与えるRotationLimitHingeを使う。ただ、座標系がEditor上の表示と違うのか、それとも俺が理解できてないのか不明だけどうまく設定できない。結局この↓設定でいくことに

右足
![スクリーンショット (105).png](https://qiita-image-store.s3.amazonaws.com/0/254776/87437b58-ce13-35f2-dd11-063db77d1b1e.png)

左足
![スクリーンショット (106).png](https://qiita-image-store.s3.amazonaws.com/0/254776/2b430423-2c98-b04b-f5df-a4cd5049f3f7.png)


腕を組みながら座っているようにAnimationを組んで、再生を押す
![スクリーンショット (107).png](https://qiita-image-store.s3.amazonaws.com/0/254776/6707f763-d331-99d0-28c3-2934ff629cf6.png)

それっぽくなった
で、それぞれのオブジェクトをAnimationで操作
![スクリーンショット (108).png](https://qiita-image-store.s3.amazonaws.com/0/254776/e8cd6460-558b-4833-0912-29a9ed3cd5e7.png)

動かしてみる
![ダウンロード.gif](https://qiita-image-store.s3.amazonaws.com/0/254776/3f06d6d4-0195-c1aa-0d5f-0d49857072bc.gif)
それっぽくなった


#他にも使ってみる
汎用的な使い方を目指していたので、他のアバターに使ってみた
![スクリーンショット (109).png](https://qiita-image-store.s3.amazonaws.com/0/254776/45d30354-7e53-b238-f224-316c80c05bc8.png)

…向きが違って失敗

標準のUnityちゃんに合わせて作成したので、VRMフォーマットのニコニコ立体ちゃんには使えなかった。というかFBX系のフォーマットが違いすぎるのは問題だなぁ…RobotKyleに使ってみた結果も似た感じに。

↓な感じみたいに、それぞれのオブジェクトの子に追従するものを付け加えればなんとなく補正はできるけど、アバターごとにするのはめんどう
![スクリーンショット (110).png](https://qiita-image-store.s3.amazonaws.com/0/254776/58fc97fe-3a1f-d897-9099-18e0dfda04ee.png)

#感想
いちいち再生しないと動きが確かめられないのが面倒。
VRMを基準に作れば大丈夫そうだけど、HumanoidBornが既に設定されているならAnimatorを触った方が楽っぽい。
でも、FinalIK(VRIK)+Animationの発想は違うものに使えそう。
DockerでSQLServerを触ってみる

#この記事について
Dockerを使って、SQLServer2017を実行する環境を作るためのメモを記載する。
あと、MacではSQLServer Management Studioを使うことができないので、「SQL Operation Studio」のインストール／接続／使い方なども残しておく。

#SQLServerをDockerで起動する
##イメージ取得(pull)
DockerHubのpullコマンドを参照して、イメージを取得する
[DockerHub - SQLServer](https://hub.docker.com/r/microsoft/mssql-server-linux/)

```:pullコマンド
docker pull microsoft/mssql-server-linux
```

##Docker上で起動
実際に起動させてみる。runコマンドもDockerHubに載っているので、参考にする。

```:起動
sudo docker run -e ACCEPT_EULA=Y -e SA_PASSWORD=P@ssw0rd! -p 1433:1433 --name sql1  -d microsoft/mssql-server-linux
```

```:実行されていることを確認
docker ps

CONTAINER ID        IMAGE                          COMMAND                  CREATED              STATUS              PORTS                    NAMES
a9b510df47f9        microsoft/mssql-server-linux   "/opt/mssql/bin/sqls…"   About a minute ago   Up About a minute   0.0.0.0:1433->1433/tcp   sql1
```

##実行されたコンテナの中に入る
execコマンドを使い、実行されたコンテナの中に入る。
(sql1は、実行したコンテナのNAMES)

```:コマンド
docker exec -it sql1 "bash"
```

##ローカル接続
sqlcmdコマンドを使用して、SQLServerに接続する。

```:コマンド
/opt/mssql-tools/bin/sqlcmd -S localhost -U SA -P P@ssw0rd!
```

##データベースを作成する
SQLServerに接続したら、データベースを作成する。
作成したら、そのDBに入る。
これさえ出来れば、あとは自由にテーブルを作成して操作できる。

```sql:SQL
CREATE DATABASE TestDB
GO

USE TestDB
GO
```

#SQL Operations Studioを使ってみる
MacだとManagement Studioが使えないので、その代わりとしてSQL Operations Studioを使う。
オブジェクトブラウザがあった方が、やっぱり便利だし。
（個人的にはコマンドラインから操作する方が好きだけど。オブジェクトブラウザだと、不意に誤った操作をしちゃいそうで...）

##インストール
インストールは↓から。
[SQL Operations Studio (プレビュー) のダウンロードおよびインストール](https://docs.microsoft.com/ja-jp/sql/sql-operations-studio/download?view=sql-server-2017#get-sql-operations-studio-preview-for-windows)

##接続してみる
Docker上でプロセスを起動した状態で、↓を入力すれば接続することができる。

<img width="489" alt="スクリーンショット 2018-05-03 22.04.47.png" src="https://qiita-image-store.s3.amazonaws.com/0/217445/1dfff9f5-771f-9434-6537-ec7f6f04eb91.png">



#参考
[SQL Operations Studio (プレビュー) のダウンロードおよびインストール](https://docs.microsoft.com/ja-jp/sql/sql-operations-studio/download?view=sql-server-2017)
[Docker を使用して SQL Server 2017 コンテナー イメージを実行する](https://docs.microsoft.com/ja-jp/sql/linux/quickstart-install-connect-docker?view=sql-server-linux-2017)
[DockerHub - SQLServer](https://hub.docker.com/r/microsoft/mssql-server-linux/)
[docker execコマンドの使い方（実例付）CE対応](http://www.memotansu.jp/2016/10/docker/591/)

##過去の自分の記事
[Dockerの超基礎的な知識メモ](https://qiita.com/kazuho39/items/24d309983c2d4a7b401f)
denite.nvimに移行しておく

ある程度環境整えてからunite.vimがobsoluteになってるので[denite.nvim](https://github.com/Shougo/denite.nvim)移行するといいよという話やら、[neovim](https://neovim.io/)がいいっすよみたいな話やらあったので、とりあえずdeniteだけは移行したほうがいいのかな？ということでパッと移行しました。windowsでneovimの恩恵受けたくても…うーん。

## 何が違うの？

- 新しい
- python使うらしい

## 設定

### まずPython使えるの？

ついこないだPython最新版突っ込んだし大丈夫でしょー。

```vim
:echo has("python3")
0
```

えぇー…

### 問題は何？

Vimのビルドの問題があるらしい、ということで検索…Pythonのバージョンの問題らしいので`:version`でチェック…Python3.5が必要で…あぁ3.6はダメなのね。ならPythonは3.5を入れ直せば…あっこれx64とx86の問題出てくるなきっと。
転がってるVimのバージョンを吟味した結果、kaoriya版のビルドしただろうファイルだけコピーしてしまうのが一番簡単そうだったのでコピーして済ませました。

## 本題

vim8.0でもちゃんと動くらしいしとりあえずplug-vimに書いてしまえばなんとかなるんでしょ？

```vim:vimrc
	Plug 'Shougo/denite.nvim'
```

## コンフィグはこんなに簡単！

deniteに入ってからのキーバインドなど細かい部分でUniteと違うのでuniteの設定はuniteに入るキーマップ`<C-u>`だけを残して削除、インサートモードで立ち上がるのがどうにも好きになれなかったのでその設定だけでうまく付き合っていけそうです。

```vim:vimrc
noremap <C-u> :Denite -mode=normal buffer file_mru file<CR>
noremap <Leader>f :Denite -mode=normal file<CR>
noremap <Leader>r :Denite -mode=normal file_mru<CR>
noremap <Leader>b :Denite -mode=normal buffer<CR>
```

せっかくなのでリーダーキー使って個別に開けるようにしました。
あとは誰かがdenite経由でQiitaに書き込みできるようにすれば…作れ？えぇー？
UnityでVisual Studioのインテリセンス（自動補完/候補）が出ない

#◆Unity(C#)で制作中、VS上で起こる現象
Unity側で新しくC#ファイルを生成した場合、
VSのソリューションに組み込まれず[インテリセンス](https://ja.wikipedia.org/wiki/%E3%82%A4%E3%83%B3%E3%83%86%E3%83%AA%E3%82%BB%E3%83%B3%E3%82%B9)が表示されなかったり、
そもそも自作クラス等が参照できなかったりします。
何度か「これどうやって直すんだっけ・・・」となったので備忘録がてらシェアします。

#◆直す方法
まずはソリューションエクスプローラーを表示してください。
デフォルトだと表示されてるかも。
![000.png](https://qiita-image-store.s3.amazonaws.com/0/254812/4b927688-498a-378a-64a7-656dc299e5e1.png)

-----------------------
このように追加したtest.csの隣に三角がついていません。
![001.png](https://qiita-image-store.s3.amazonaws.com/0/254812/f9ef5471-a49a-03b4-1b0c-d9b005c8ecfe.png)

-----------------------
ブラウザの更新ボタンみたいなコレをクリック、更新しましょう。
![002.PNG](https://qiita-image-store.s3.amazonaws.com/0/254812/8d44e3b9-1258-3aad-eb5c-4019422780ab.png)


以上です。一瞬でしたね。

環境
Unity 2017.2.0f3
VS2017 15.4.4
今日のQiitaエラー　error

今日、過去記事を直していたら、初めて見るエラーが出たので採取した。

![qiitaerror.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/51423/23ba5d12-8034-4b06-dbfd-8b92343ba285.png)

Qiitaの仕様で残念なのは、過去記事の誤植などを訂正していると、　
新しい記事を書けなくなること。　

Qiitaって、たくさん入出力する人を試験対象にすればいいのにしていないらしい。　

記事では、こんなテストをするなという記事が出ていても、　
Qiita自体がそんなテストしかしていないのかなった感じる。　

Qiitaのシステム担当は忙しくてQiitaの記事読めないのかもしれない。　

＜この記事は個人の過去の経験に基づく個人の感想です。現在所属する組織、業務とは関係がありません。＞
# 文書履歴(document history)
ver. 0.01 初稿 　20180503
ver. 0.02 ありがとう追記　20230513
## 最後までおよみいただきありがとうございました。
いいね　💚、フォローをお願いします。
####  Thank you very much for reading to the last sentence.
Please press the like icon 💚　and follow me for your happy life.