OmniAICreator/Qiita-1.07M huggingface dataset:
canvasを画面比に応じて可変にする(canvasでお絵かきアプリ)

# 背景
canvasを画面サイズに応じて可変させたい。
純粋にそのまま実行すると**javascriptにて操作するときにcssで書いた値は有効にならず、「幅300px 高さ150px」という認識で動く**のです…

# 結論
回避策としては下記…

``` javascript

window.onresize =//<- resize時も対応
window.onload  = function() {
var cnv=document.getElementsByClassName('cnv')[0];
var ctx=cnv.getContext('2d');
cnv.setAttribute('width',cnv.clientWidth);  //<- sizeを教えてあげる
cnv.setAttribute('height',cnv.clientHeight);//<- sizeを教えてあげる

var p=false;
cnv.addEventListener('mousemove', (e)=>{
  console.log(e.which,cnv);
  if(e.which==1){
    if(!p){
      ctx.beginPath();
      ctx.strokeStyle="#fff";
      ctx.moveTo(e.x, e.y);
      p=true;
    }else{
      ctx.lineTo(e.x, e.y);
      ctx.stroke();
    }
  }else{
    p=false;
  }
});
};
```

属性として書き込んであればそれをもとに動くようです。

# 追加
表記の機能を利用して簡単なお絵描きキャンバスを実装したので、ここに共有させていただきます…
消しゴム・色選択・ペンサイズ変更は実装済みです。

<p data-height="265" data-theme-id="0" data-slug-hash="JvgGmj" data-default-tab="js,result" data-user="hashito" data-embed-version="2" data-pen-title="canvas" class="codepen">See the Pen <a href="https://codepen.io/hashito/pen/JvgGmj/">canvas</a> by hashito (<a href="https://codepen.io/hashito">@hashito</a>) on <a href="https://codepen.io">CodePen</a>.</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>
コードでAutoLayoutを指定するときのtranslatesAutoresizingMaskIntoConstraintsの振る舞い

# **translatesAutoresizingMaskIntoConstraintsはデフォルトがtrueである**
つまり、コードで生成したビューは`translatesAutoresizingMaskIntoConstraints = false`とキチンと書いてあげないとオートレイアウトが適用されない。
UIViewのレイアウトはデフォルトでは`frame`に従うように振る舞う。
コードで書いたり、Storyboardで書いたりしているとゴッチャになって無駄にハマることがあるのでキチンと覚えておく。
第7話 四色定理(トーラス)

この記事は[仮面ライダービルドの数式](https://qiita.com/izmktr/items/e26a624e79bce3edccc9)の第7話です。

```math
\max_{G:torus} χ(G) =7
```

第四話で見た式とほぼ同じです…が、Gを示すものがplanerからtorusに変化しています。
つまり、「トーラスの表面の地図を塗り分けるには、最大7色必要になる」という意味になります。

トーラスとは浮き輪やドーナツのような形をした物体です。
つまり、浮き輪の表面に地図を書いたら4色では足りず、7色必要になります。

浮き輪の形をしたものにはゲーム世界の地図があります。
世界の端に達した時、ループするものがそれです。
東の端を更に東に進むと西の端から出て、北の端を更に北に進むと、南の端から出るものです。
ドラゴンクエスト3は世界地図がゲームの地図でしたが、
北極から更に北に進むと南極付近に出る、というのは違和感を覚えた人がいるかもしれません。
上と下、左と右が繋がった世界はトーラスと呼ばれます。

トーラスの最大の特徴は世界をふたつに分けない円がかけることです。
平面では円を書いても外と中で完全に別れます。
これは球体の表面でも同様です。
ですが、浮き輪の場合は赤道のように線を引いても、反対側から回り込めるので世界を二分できません。
この性質が7色必要な理由でもあります。

なお、世界をふたつに分ける円が書けるか否かで世界の形を特定するのが、
難題と呼ばれたポアンカレ予想です。
このポアンカレ予想を巡ってもかなりのドラマがあります。
python3でfizzbuzz

今月のニュースでこんなのがありました。
[PythonがJavaを抜く - PYPLプログラミング言語ランキング](https://news.mynavi.jp/article/20180515-630398/)

やっぱりpythonですよね。
とりあえずfizzbuzz問題を書いてみました。

```fizzbuzz.py
def fizzbuzz(i):
    return 'Fizz' * (i % 3 == 0) + 'Buzz' * (i % 5 == 0) or str(i)

    # if i % 15 == 0:
    #     return "FizzBuzz"
    # elif i % 3 == 0:
    #     return "Fizz"
    # elif i % 5 == 0:
    #     return "Buzz"
    # else:
    #     return str(i)

if __name__ == '__main__':
    
    outputs = [fizzbuzz(i) for i in range(1,101)]
    print(outputs)
```

出力

```
['1', '2', 'Fizz', '4', 'Buzz', 'Fizz', '7', '8', 'Fizz', 'Buzz', '11', 'Fizz', '13', '14', 'FizzBuzz', '16', '17', 'Fizz', '19', 'Buzz', 'Fizz', '22', '23', 'Fizz', 'Buzz', '26', 'Fizz', '28', '29', 'FizzBuzz', '31', '32', 'Fizz', '34', 'Buzz', 'Fizz', '37', '38', 'Fizz', 'Buzz', '41', 'Fizz', '43', '44', 'FizzBuzz', '46', '47', 'Fizz', '49', 'Buzz', 'Fizz', '52', '53', 'Fizz', 'Buzz', '56', 'Fizz', '58', '59', 'FizzBuzz', '61', '62', 'Fizz', '64', 'Buzz', 'Fizz', '67', '68', 'Fizz', 'Buzz', '71', 'Fizz', '73', '74', 'FizzBuzz', '76', '77', 'Fizz', '79', 'Buzz', 'Fizz', '82', '83', 'Fizz', 'Buzz', '86', 'Fizz', '88', '89', 'FizzBuzz', '91', '92', 'Fizz', '94', 'Buzz', 'Fizz', '97', '98', 'Fizz', 'Buzz']
```

こう書けるのが良いですよね。

```
return 'Fizz' * (i % 3 == 0) + 'Buzz' * (i % 5 == 0) or str(i)

outputs = [fizzbuzz(i) for i in range(1,101)]
```
WindowsでLinuxコマンド(というかLinux)を使う方法

Windows10でLinuxコマンドを使う方法は色々あると思いますが、現時点で一番簡易だと思われる方法を一つ体系的にまとめようかと思って記事を書きました。
ここでは、**Windows Subsystem for Linux**(旧Bash on Windows)を使います。
※Windows10 2017 Fall Creators Update以降を適用済みのものとします。
初稿時点ではWindowsPowershellでssh系のコマンドが使えなかったのでタイトルにLinuxコマンドを使う方法と書いてますが厳密にはLinuxを使う方法です。

# Windowsw版Ubuntuのインストール
ざっくりとした手順としては以下のようになります。
1.Microsoft Storeを開く
2.Ubuntuを見つけてインストール
3.おまじないを唱えてPCを再起動
最後に再起動を行うので、なるべく他の作業はすべて終わらせた状態で始めましょう。


### 1.Microsoft Storeを開く
Microsoft Storeにアクセスしましょう。
よく分からない人はキーボードの左下あたりの白い四角っぽいキー(Windowsキー)を押して、
「store」と入力したあとEnterキーを押しましょう。
<img width="587" alt="menu.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/260152/87849622-35c1-38f6-4856-61a027c7c562.png">

### 2.Ubuntuを見つけてインストール
Microsoft Store を開いたら、右上の検索窓から「ubuntu」と入力しEnter。
<img width="765" alt="store.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/260152/116b69c2-dcdb-9cda-c9e7-f183db2eea2f.png">

そうすると一番上に「C:¥> Linux on Windwos? 本当です。」
などと表示されるのですぐ下の「アプリを入手する」ボタンをクリック。
<img width="765" alt="store2.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/260152/e42b284c-2a82-3aa5-4940-0c6ee34469b8.png">

その後左端に表示されているUbuntuをクリックすることでインストールページに移るので、
<img width="774" alt="store3.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/260152/ccca90c3-920d-a83a-d715-0bb036307567.png">

Ubuntuアイコン横の「入手」をクリックしてしばらく待ちましょう。

このUbuntuアプリをインストールことで、Linuxコマンドが使えるようになります。
<img width="765" alt="store4.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/260152/26026864-58eb-86cf-8667-8a9fd9ab62b2.png">

>※2018年12月6日現在（実装はもっと前からですが）では「Ubuntu 18.04 LTS」も選べるようになっています。
　ただただLinuxコマンドを使う目的ならばただの「Ubuntu」で十分です。

入手後に「起動」ボタンが現れますが、クリックしてもこのままではInstall Failed!となるはずなので
おまじないを唱えましょうヾ(⌒(ﾉ'ω')ﾉ。

### 3.おまじないを唱えてPCを再起動
さぁこのままではせっかくインストールしたUbuntuも使えないのでおまじないを唱えましょう。
※プログラミングでよく言うおまじないであって本当に何か呪文を唱えるわけではありません

おまじないを唱えるためにPowershellというものを使います。
Windowdsキーを押して、「Powershell」と入力すると画面の左下あたりの一覧にWindows Powershellと出てくると思います。
**それを右クリックして、出てきたメニューから「管理者として実行」を選んで下さい。**
その後警告文が出ますが「はい」を選んで大丈夫です。
このウインドウで、
`Enable-WindowsOptionalFeature -Online -FeatureName Microsoft-Windows-Subsystem-Linux`
と入力してEnterを押しましょう。打ち間違いの無いようにコピペしてください。
<img width="674" alt="ps2.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/260152/258a3a8b-0ca5-f71c-498a-1c1c6578e0e7.png">

Enable-WindowsOptionalFeatureが黄色、-Online -FeatureNameが灰色、Microsoft-Windows-Subsystem-Linuxが白色になれば恐ら
く成功です。

後はしばらく待てば再起動を求められるので、PCを再起動しましょう。

これで先ほど起動できなかったUbuntuが起動できるようになります！
再起動し終わったらスタートメニューからUbuntuが起動できるはずです( ´ ∀ `)


##あとがき
>1hぐらいでどぁーっと書いたので誤字・脱字・誤り等ありましたらご報告下さい。
この記事の一番の目的は実はWindowsでLinuxコマンドを使うというよりはWindowsでSSHコマンドを使う、
という方が正しいかもしれません。
というのも学内環境にSSHで入る方法をUNIX準拠で書いている人が居たのでWindows Subsystem for Linux環境でSSHコマンドの実行ができるようにする方法が分れば上記の記事がWindows民にとっても有用なものになるんではないかと。
そんなモチベーションから解説記事を書いてみた次第です。
というかWSL使えれば基本的にUNIXでできることが、仮想環境作るよりかなりストレスフリーにできるよねっていう。

書いた当初は上記のようなモチベーションでしたが、今はお手軽Linux導入説明書になればなぁと思っています。（特にPC初心者の人）
故にUbuntuとLinuxてどう違うの？とかいう話は触れていませんが...

ちなみにおまじないの部分は Microsoft Store のアプリの説明欄に書いてあるし手間もそんなに無いと思うんですが、ネットで探すと設定画面ごにゃごにゃする方法ばっかり出てくるの何故なんでしょう(´・ω・`)？
Markdown+UMLが書きたいならBoostnoteがおすすめです！


# Markdown+UMLが簡単にできるエディタの紹介です。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/30329/f4699214-4b6d-6567-c36f-26fc73cd020a.png)

> 開発者の為のノートアプリ
Markdownノートにはライブプレビュー機能があり, 即座に内容の確認ができます. また, シーケンスやフローチャート, Latexなどもサポートしています.
コードスニペット機能では, Javascript, Python, HTML, CSS等100以上の言語でシンタックスハイライトを付けることが出来, 複数のコードスニペットを同じスニペットに保存することができます.
引用: https://boostnote.io/ja/

無料で利用でき最近のQiitaの記事やメモ、仕様検討まで、開発以外のログ取りはすべてBoostnoteを利用させてもらっています。

## 最近しったMarkdown+UMLについて

実は、boostnoteでUMLが書けるということを知りました。
UMLが書きたいな−。boostnoteで書けないのかなとぐぐったら普通に書けました。

Markdown+URLという言葉はこちらから引用させていただきました。
[Markdownテキストでシーケンス図とフローチャートを描く](https://qiita.com/ka215/items/a709665cb34c505ccf1f)

## boostnoteが標準でサポートしているUMLの書き方は３つ

- plantuml
- flowchart
- Sequence

[Diagram support · BoostIO/Boostnote Wiki · GitHub](https://github.com/BoostIO/Boostnote/wiki/Diagram-support)

Qiitaで閉じタグをエスケープする方法が見つからず\\```については先頭の\を取ってください。

### plantuml

![image.png](https://qiita-image-store.s3.amazonaws.com/0/30329/ed5bb5ef-44a8-196b-a27c-91b756a3744c.png)

`@startuml` と`@enduml`で囲むとplantuml表記ができます。

```
@startuml
actor actor
agent agent
artifact artifact
boundary boundary
card card
cloud cloud
component component
control control
database database
entity entity
file file
folder folder
frame frame
interface  interface
node node
package package
queue queue
stack stack
rectangle rectangle
storage storage 
@enduml
```


### flowchart

![image.png](https://qiita-image-store.s3.amazonaws.com/0/30329/085b9d86-9825-85f4-cf72-fc37d92e197e.png)

```
flowchart
st=>start: Start:>http://www.google.com[blank]
e=>end:>http://www.google.com
op1=>operation: My Operation
sub1=>subroutine: My Subroutine
cond=>condition: Yes
or No?:>http://www.google.com
io=>inputoutput: catch something...

st->op1->cond
cond(yes)->io->e
cond(no)->sub1(right)->op1
\```
```

### sequence

![image.png](https://qiita-image-store.s3.amazonaws.com/0/30329/9ba4df9e-d97f-c0ac-2e30-f2c9f70fb786.png)

```
```sequence
Title: Here is a title
A->B: Normal line
B-->C: Dashed line
C->>D: Open arrow
D-->>A: Dashed open arrow
\```
```

### 日本語にも対応しています。

なので、結構自由に書けます。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/30329/9344cf61-625f-45e2-161e-e1414d273f8b.png)

```
```sequence
Title: 100%よりも70%からはじめる
はじめる->できたもの:70%の完成度を目指す
できたもの->試行錯誤:課題を見つける
試行錯誤->失敗:いろいろ失敗する
失敗->試行錯誤:挑戦を繰り返す
失敗->解決:一つずつ前に進む
解決->できたもの:OneUp!
\```
```

UMLは`sequence`しかまだ利用したことがまだないですが、業務フローを確認することが多いのでそのときに日本語でささっと書けるのでとてもいいエディタだと思います。
C# Script の #load で相対パスを指定した際の基準ディレクトリ

# 発端

C# Scriptファイル，csx で以下のように書いた場合，どこのフォルダを基準に Hoge.csx が読み込まれるのかネットを検索してもなかなか情報が出てこなかったので実験結果を書いておきます。

```csharp
// Foo.csx
#load "./Hoge.csx"
```
# 結果

基準ディレクトリは`#load`を書いたスクリプトファイルのディレクトリ。csi 実行時のカレントディレクトリではない。

# 実験記録

用意した環境。

```
/ <- カレントディレクトリ
/dir
  /Foo.csx
  /Hoge.csx # Print("Parent is dir."); と記述
/Hoge.csx   # Print("Parent is root."); と記述
```

実行したコマンドと結果。

```
$ csi /version
2.6.0.62309
$ csi ./dir/Foo.csx
"Parent is dir."
```
clearfixについて復習

# clearfixについて復習

## floatプロパティについて
floatを使用すると親要素の高さがなくなってしまう。  

```html
<div id="wrapper">
  <div id="contents">コンテンツ</div>
</div>
```
```css
#wrapper {
  padding: 10px;
  background-color: gray;
}
#contents {
  float: left;
  width: 100%;
  height: 80px;
  background-color: cyan;
}
```

![clearfix復習_親要素の高さがない.PNG](https://qiita-image-store.s3.amazonaws.com/0/136617/648a725b-08c5-b64b-f3f1-c031faa6687c.png)

上記を回避するためには、clearプロパティを使う必要がある。
やり方として、float要素の後にclearプロパティを指定した空の要素を用意すればいい。

```html
<div id="wrapper">
  <div id="contents">コンテンツ</div>
  <div class="clear"></div>
</div>
```
```css
#wrapper {
  padding: 10px;
  background-color: gray;
}
#contents {
  float: left;
  width: 100%;
  height: 80px;
  background-color: cyan;
}
.clear {
  clear: both;
}
```

![clearfix復習_clearfix.PNG](https://qiita-image-store.s3.amazonaws.com/0/136617/a39b008a-5aab-fd81-2316-0fff739e98ec.png)

じゃあこれを:afterを使って clearプロパティの空要素を用意すればいいんじゃない？
というのが **clearfix**

```html
<div id="wrapper" class="clearfix">
  <div id="contents">コンテンツ</div>
</div>
```
```css
#wrapper {
  padding: 10px;
  background-color: gray;
}
#contents {
  float: left;
  width: 100%;
  height: 80px;
  background-color: cyan;
}
.clearfix:after {
  content: "";
  clear: both;
  display: block;
}
```
![clearfix復習_clearfix.PNG](https://qiita-image-store.s3.amazonaws.com/0/136617/a39b008a-5aab-fd81-2316-0fff739e98ec.png)
Windowsでシンボリックリンクを作成する

####Windowsでシンボリックリンクを作成したときのメモ

Point
管理者権限でコマンドプロンプトを開きます。

- シンボリックリンクの作成

```cmd.prompt
C:\WINDOWS\system32>mklink /D C:\nginx C:\nginx-1.14.0
```

- 作成したシンボリックリンクの削除 

```cmd.prompt
del C:\nginx
```
YAMLでCloudFormation Templateを書く

# CloudFormation Template
VSCodeとYAML schemaを使って、簡単かつ高速でTemplateを書くことができます。
IntelliSense、AutoComplete、~~Validate~~もやってくれますの、超ハッピー:grin:

## 事前準備
* Visual Studio Code: [Download](https://code.visualstudio.com/Download)

## VSCodeの設定
* [Ctrl + Shift + X] > [YAML入力] > [YAML Support by Red Hat]
    * インストール完了 > 読込ボタンクリック
* Settings (Ctrl + Comma) > 下記設定を追加

```json
"yaml.schemas": {
    "https://raw.githubusercontent.com/awslabs/goformation/master/schema/cloudformation.schema.json": [
        "cf.yaml",
        "cf.yml"
    ]
},
"yaml.validate": false
```

## 使用方法
* `*cf.yaml`、`*cf.yml`のファイルは対象になる、[Ctrl + Space]でIntelliSense超楽
* 注意点：Resources sectionは任意のLogicIdを入力してから、IntelliSenseが効く
* 注意点：IntelliSense効くのは最後の行のみ

## YAMLスキーマについて
他も色々ありますので、興味ある方は下記サイトをご覧ください。
[http://schemastore.org/json/](http://schemastore.org/json/)

## validateについて
組み込み関数(Fn::xxx)はうまく動作しないため、validateを無効にします。
validateは`aws-cli`を使ってやるしかいない。。。
React Native for Webの0.7が出て、導入しやすくなった

2018/05/18に、React Native for Webの0.7.0がリリースされました。
https://github.com/necolas/react-native-web/releases/tag/0.7.0
（その直後、軽微な修正によるアップデートがちょこちょこ出ています）

これからReact Native for Web（以下、RN Web）を使い始める人にとっては、地味にありがたいアップデートのようです。

# Babelプラグインが不要になった

これまでRN Webを使うためには、RN Web用のBabelプラグイン（babel-plugin-react-native-web）を使う必要がありました。これについては[以前の記事](https://qiita.com/nacam403/items/7c48f1163646887b11fb#rn-web%E3%81%8C%E5%8B%95%E3%81%8F%E4%BB%95%E7%B5%84%E3%81%BF)も参照ください。

ところが0.7.0のリリースノートによると「Babel plugin is legacy.」とのことで、Babelプラグインは必須ではなくなりました。[公式ドキュメントのInstallの節](https://github.com/necolas/react-native-web/blob/master/website/guides/getting-started.md#install)においても、`yarn add --dev babel-plugin-react-native-web`という手順が削除されています。

とはいえ、JavaScriptコードに書くimportの行において、fromをreact-nativeからreact-native-webに変換する必要があることは変わりません。よってBabelプラグインの代わりに、以下の様にWebpackの設定として`alias`を書く必要があります（このあたりは公式ドキュメントにも書いてあります）。

```webpack.config.js
module.exports = {
  // （前略）もろもろの設定

  resolve: {
    alias: {
      'react-native': 'react-native-web'
    }
  }
}
```

なお既にBableプラグインを使っているなら、今まで通り使い続けても構いません。

# flowとの併用がしやすくなった

これまでにRN Webを使いつつ、flowで型チェックをしようと人ならしばしば経験したであろうエラーが解消しました。

今までは、RNとRN Webをインストールしたプロジェクトに対し、何気なくflowもインストールして実行してみると、以下の様なエラーが大量に出ることがありました。

```
Error: node_modules/react-native/Libraries/Animated/src/nodes/AnimatedModulo.js:0
AnimatedModulo. Duplicate module provider
current provider. See: node_modules/react-native-web/dist/vendor/Animated/nodes/AnimatedModulo.js:0
```

RNとRN Webとで同名のモジュールが検出されているようで（？）、何やらflowに怒られまくります。[^1]
RN Webのバージョンを0.7.xに上げると、このエラーが解消します。

[^1]: 当時途方に暮れた私は、とりあえずの回避策として.flowconfigの`[ignore]`のところに`.*/node_modules/react-native-web/.*`と書いて、エラーを黙らせていました。

どうやらエラーの原因は`@providesModule`というflow独自のJsDocタグに関係していたようで、以下のコミットにおいて削除されていました。
https://github.com/necolas/react-native-web/commit/18933724d65c146fbcf6d21bff00beced48843e4
見たところRNの方も、2018/04/25に削除されていました。
https://github.com/facebook/react-native/commit/d5e9e55fa38c574bce6c04cbcaf6b144b87fa17f
今までは両者のソースコードに`@providesModule`が含まれていたことから、別々のパッケージに含まれているモジュールにも関わらず、flowによって同一視・重複扱いされたのではないでしょうか。ともあれ直った！

# Getting startedのドキュメントが結構改訂された

先述のBabelプラグインに関することでだけでなく、公式ドキュメントの[Getting started](https://github.com/necolas/react-native-web/blob/master/website/guides/getting-started.md)があちこち改訂されており、どうやってRN Webを使い始めるかが分かりやすくなっている印象があります。

既にRN Webを使っている人も、一度見直してはいかがでしょうか。
特に、これからRN Webのバージョンを上げようとするなら、思わぬトラブルを回避するためにも目を通した方がよいでしょう。
Windows上でのUnixライクな環境構築メモ

## 1. msys2のインストール
　http://www.msys2.org

## 2. mingw64.iniの設定
以下をアンコメントする（Windowsのシンボリックリンクを使う、windowsのPATHを引き継ぐ）

```mingw64.ini
MSYS=winsymlinks:nativestrict
MSYS2_PATH_TYPE=inherit
```
## 3. $HOME/binにPATHを通す
.bash_profileの以下をアンコメントする。

```~/.bash_profile
if [ -d "${HOME}/bin" ] ; then
  PATH="${HOME}/bin:${PATH}"
fi
```

## 4. ls, grepの色付け
.bashrcの以下をアンコメントする

```~/.bashrc
alias grep='grep --color'
alias ls='ls -hF --color=tty'
```

## 5. パッケージのインストール
msys2 mingw64を起動して、以下のコマンドを実行

```bash
$ pacman -S base-devel mingw-w64-x86_64-toolchain VCS compression editors sys-utils winpty mingw-w64-x86_64-ag expect busybox pass mingw-w64-x86_64-python3-pip fzy
```

## 6. vimの設定
```~/.vimrc
syntax on
set nocompatible              " be iMproved, required
filetype off                  " required
set laststatus=2
set statusline=%F%r%h%=
set number
set fileencodings=utf-8,iso-2022-jp,euc-jp,sjis
set fileformats=unix,dos,mac
set cursorline
set nowrap
set mouse=a
set ttymouse=xterm2
set t_Co=256
set backspace=indent,eol,start
let g:vim_markdown_folding_disabled=1
let g:vim_markdown_toc_autofit = 1

call plug#begin('$HOME/.vim/plugged')
Plug 'flazz/vim-colorschemes'
Plug 'itchyny/landscape.vim'
Plug 'plasticboy/vim-markdown'
Plug 'godlygeek/tabular'
Plug 'kannokanno/previm' | Plug 'tyru/open-browser.vim'
Plug 'rking/ag.vim'
Plug 'yegappan/mru' 
Plug 'b4b4r07/vim-shellutils'
Plug 'nathanaelkane/vim-indent-guides'
Plug 'majutsushi/tagbar'
Plug 'thinca/vim-quickrun'
Plug 'vim-airline/vim-airline'
Plug 'vim-airline/vim-airline-themes'
Plug 'scrooloose/syntastic'
Plug 'vim-scripts/autodate.vim'
Plug 'vim-scripts/scratch-utility'
Plug 'mhinz/vim-signify'
call plug#end()

colorscheme wombat
let g:lightline = {
      \ 'colorscheme': 'wombat',
      \ }

let g:changelog_username="hogehoge <hoge@hoge.com>"
let g:changelog_timeformat="%Y-%m-%d"

let g:scratchBackupFile=$HOME . "/.scratch"
set shortmess+=I

let g:netrw_nogx = 1 " disable netrw's gx mapping.
nmap gx <Plug>(openbrowser-smart-search)
vmap gx <Plug>(openbrowser-smart-search)
```

## 7. vimのpluginインストール
```bash
$ curl -fLo ~/.vim/autoload/plug.vim --create-dirs https://raw.githubusercontent.com/junegunn/vim-plug/master/plug.vim
$ vim +":PlugInstall" 
```

## 8. pdftk serverのインストール
 https://www.pdflabs.com/tools/pdftk-server/

## TBD
- pass -cを使えるようにする
- batsをインストールして使えるようにする
- openbrowserでchromeを使えるようにする
- ~/.bash_aliases (openとか)
- ~/.bash_functions
RでLSIを使った次元削減

特徴量が多くなった場合に、LSIを使って次元削減する方法。

ライブラリのインポート(fpcはRのクラスタリング用のパッケージ)
https://cran.r-project.org/web/packages/fpc/fpc.pdf

```
library("fpc")
```

特異値分解(SVD)を行う

```
s <- svd(doc_mat?)
str(s)
```
特徴量を50次元に削減

```
d50 <- t(s$u[,1:50]) %*% doc_mat 
dist_mat <- dist(t(d50), method="euclidean", diag=FALSE, p=2)
```

dist_matは目的に合わせて色々使ってください
例)次元削減した文章行列を用いてDBSCANを行う

```
db <- dbscan(dist_mat,eps = 1.7, MinPts=5)
```

参考したURLだけどどうやら消された様子...
http://qiita.com/HirofumiYashima/items/076563794ca2912eef4d
[C#]ML.NETを使ってタイタニック号の生存者予測をしてみた

##内容
最近公開された[ML.NET](https://www.microsoft.com/net/learn/apps/machine-learning-and-ai/ml-dotnet)を使って、機械学習ではおなじみのタイタニック号の生存者予測をしてみました。

参考：https://qiita.com/github129/items/2ed5895f1a900f27038f
参考：https://docs.microsoft.com/ja-jp/dotnet/machine-learning/tutorials/sentiment-analysis
参考：https://www.youtube.com/watch?v=OhCysVU5RDA

##環境
* Visual Studio Community 2017 Version15.7.2（**Version15.6以上必須**）
* .NET FrameWork 4.6.1（.NET Standard 2.0必須）

##コード
GitHubにあげています
https://github.com/koshian2/Titanic-MLnet

##概要
データは[Kaggle](https://www.kaggle.com/c/titanic/data)から。事前に891人分のデータをID順で6:2:2で訓練、交差検証、テストに分割しています。[TrainTestDatasetSplitter](https://docs.microsoft.com/en-us/dotnet/api/microsoft.ml.transforms.traintestdatasetsplitter?view=ml-dotnet)を使えばパイプライン上で分割できそうな気はするけど、使い方がよくわかりませんでした。

訓練データの前処理は年齢（Age）が不明のデータを落としたのと、性別（Sex）と乗船港（Embarked）をOneHotベクトルにしただけです。

アルゴリズムはランダムフォレスト（[FastForestBinaryClassifier](https://docs.microsoft.com/ja-jp/dotnet/api/microsoft.ml.trainers.fastforestbinaryclassifier?view=ml-dotnet)）を使っています。

交差検証を行い、NumTreesとNumLeavesの2つのハイパーパラメーターについてグリッドサーチをしています。グリッドサーチのクラスあるのかもしれないけど、ML.NETでのハイパーパラメーターのチューニングのやり方がよくわからなかったので、自分で実装しました。ハイパーパラメーターを変更する際、pipelineから一度削除しないと変更が反映されないみたいです。

ハイパーパラメーターをチューニングしたあと、テストデータにフィットさせると次のような結果になりました。

```
### Result ###
- Selected Classifier
NumTree=4, NumLeaves=32
- Trian Sets
Accuracy=83.45%, Precision=83.78%, Recall=72.94%, F1score=77.99%
- Cross Validation Sets
Accuracy=80.28%, Precision=86.67%, Recall=63.93%, F1score=73.58%
- Test Sets
Accuracy=86.58%, Precision=86.79%, Recall=77.97%, F1score=82.14%
```

テストデータで精度は86.58%、F1Scoreが82.14%と、訓練データとテストデータともに8割近いのでそこそこ良さそう。グリッドサーチも含めて2分ぐらいで終わりました。

##FAQ
自分がハマったところのまとめ

**Q:NuGetからダウンロードできない**
A:[.NET Standard2.0](https://docs.microsoft.com/ja-jp/dotnet/standard/net-standard)(≠.NET Framework)、Visual Studio15.6以上が必要。VSのバージョンはVisual Studio Installerから更新する。プロジェクトを右クリック→プロパティ→ターゲットフレームワークを「.NET Framework 4.6.1」以上にする。

**Q:TextLoaderで「Type not implemented or supported」と怒られる**
A:データの型をintで定義しているから。floatかstringにすると直る。

**Q:TrainのところでDLLがないと怒られる**
A1:DLLが64ビットなので、64ビット環境必須。構成マネージャーから64ビットにすること。
参考：https://msdn.microsoft.com/ja-jp/library/ms185328.aspx

A2:ソリューションエクスプローラー→参照→packages.configをPackageReferenceに移行するを選択→そのままOK
参考：https://blog.nuget.org/20180409/migrate-packages-config-to-package-reference.html
参考：https://github.com/dotnet/machinelearning/issues/93

##わからなかったところ
* 新しいカラムってどうやって作るの？  
→例えばCabinのカラムから、最初の一文字を取って船室の位置を見る変数を作るにはどうやるの？
* MissingValueSubstitutorで欠損値を平均値に置き換えるとかできそうだけどどうやるの？
* TrainTestDatasetSplitterで、Sklearnでいうところのtrain_test_split的なことができそうだけどどう使うの？
* ハイパーパラメーターのチューニングってどうやるの？グリッドサーチ用のクラスってあるの？

##感想
久しぶりにC#の投稿。まだプレビュー版でドキュメントがほとんどないような状態だけど、結構使いやすかったです。特に前処理から訓練まで1つのパイプラインでできるというのがすごい（Pythonだと前処理にpandasなどでワンクッション入る）。

チュートリアルの[回帰問題](https://docs.microsoft.com/ja-jp/dotnet/machine-learning/tutorials/taxi-fare)で重回帰でもSVMでもなく、いきなり勾配ブーストを使ってるのが面白かったです。Microsoftといえば[LightGBM](https://github.com/Microsoft/LightGBM)という素晴らしいライブラリがあり、これがML.NETに組み込まれたという話は聞きませんが、勾配ブーストを重視してるのかもしれません。ロードマップによると、そのうちTensorFlowも対応になってディープラーニングできるらしいので、MSの期待の新星かもしれません。今後に期待しましょう。あとAPIドキュメント書いて（切実）
Rで教師あり機械学習(ニューラルネットワーク)


### 必要なライブラリやデータのインポート

```
#ニューラルネットワーク
library(nnet)

#DBSCAN結果
load("/path/to/dbscan/data") #dbscan_result
#教師となる正解データ
load("/path/to/train/data") #train_matrix
#予測したいテストデータ
load("/path/to/test/data") #test_matrix
```
正解データには、正解クラスタとSVM用の正誤を付加したものを用意する。
※あとでデータの載せる
※DBSCANのやり方とSVMのやり方も載せる

### それぞれのクラスタについてモデルを作る

```
#データフレームに変換
train_matrix <- as.data.frame(train_matrix)
#クラスタのレベル分け
level <- levels(factor(dbscan_result$cluster))

#クラスタ毎に出力
for (i in level[-1]){
 print(i)
 
 #クラスタの出現場所に1,それ以外に0を付与
 train_matrix$svm_tf <- ifelse(train_matrix$cls == i, 1, 0)
 #用済みなのでclsの列を削除
 train_matrix <- train_matrix[-2] 

 #ニューラルネットワーク実行
 nnet_model <- nnet(factor(svm_tf)~., size=3, data=train_matrix)
 
 #結果
 print(predict(nnet_model, test, type="class"))
}

```
※結果のデータと解説載せる
Twilioの Signature検証 ( Twilio::Security::RequestValidator ) でエラーになるときに調べるべきこと


TwilioをRailsで利用しているときに、ローカル環境ではWebhookのSignature検証が正しく通るのに、サーバに上げたら通らなくなって四苦八苦したので、原因と解決方法を残しておきます。


TwilioのAPIを利用する場合、取得した電話に電話がかかってくると、自分のサーバにWebhookが飛んできます。
それを処理して電話に対しての対応、例えばメッセージを読むとか、電話を切るとか、そういうことができます。
その時、本当にTwilioのサーバからWebhookが飛んできたのか、ということを検証するために、Webhookのヘッダにある Signature を検証します。
下記がそのドキュメントです。
https://www.twilio.com/docs/usage/security

今回、 **この検証の動作がローカル環境では通ったのに、サーバに上げると通らなくなった** という問題が発生しました。

# この記事の内容
1. TwilioのSignature検証のサンプルコード
2. 検証が通らなかった原因
3. 解決方法
4. おまけ

# 1. TwilioのSignature検証のサンプルコード（エラー時）

今回は、Railsで下記のようなメソッドを作りました。（RailsのController内で動作します）
[TwilioのGem](https://github.com/twilio/twilio-ruby) が必要です。

```.rb
def validate_twilio
  validator = Twilio::Security::RequestValidator.new(ENV['TWILIO_AUTH_TOKEN'])
  return request.post? && !signature.blank? && validator.validate(request.url, request.request_parameters, signature)
end
```

このメソッドが `true` を返せば、検証は成功です。

上記コード、ローカル環境でテストするときには通ります。
ちなみに、ローカル環境でTwilioのテストを行うときは、 `ngrok` を使ってグローバルにローカル環境を開放してあげましょう。

```
# install
npm i -g ngrok
# 実行
ngrok http 3000 # <= railsを起動しているポート番号
```

上記でターミナルが開き、グローバルのURLが取得できるので、それをTwilioの電話番号に設定します。「


# 2. 検証が通らなかった原因
サーバに上げると、上記コードでは通りませんでした。
その原因は、 **LoadBalancer** にありました。

私のインフラ構成では、 `Elastic Load Balancer` により、 `https` の処理を `LoadBalancer` にしてもらい、 `VPC` の中では `http` で `LoadBalancer` と `EC2 Instance` を通信させていました。
このため、サーバ上では、 URLが `https` => `http` に変換されていました。

なんということでしょう…ローカル環境では（ `https` であっても）問題なく動いたコードが、動かなくなります。

もう一度上記のコードの一部を見てみましょう。

```
validator.validate(request.url, request.request_parameters, signature)
```

この `validate` メソッドの第一引数は、 `URL` です。
そのため、検証で使うURLは `Twilio` が送ったと思っている `https` のURLでないといけません。
でも、 `request.url` では、 `http` に変換されています。

これが原因でした。

これは、マジで気づかないやつ。

# 3. 解決方法
`URL` を `https` に変換してやれば、ちゃんと動きます。

```
def validate_twilio
  validator = Twilio::Security::RequestValidator.new(ENV['TWILIO_AUTH_TOKEN'])
  return request.post? && !signature.blank? && validator.validate(url, request.request_parameters, signature)
end

def url
  if Rails.env.test? || Rails.env.development?
    request.url
  else
    request.url.gsub(/^http/, 'https')
  end
end  
```

これで解決！！

# 4. おまけ

おまけとして、TwilioのSignatureを作るコードを残しておきます。
上記以外でも、TwilioのSignature検証で困ったときに役に立つこと必見です。

```.rb
key = ENV['TWILIO_AUTH_TOKEN']
params = request.request_parameters
additional_string = params.keys.sort.reduce('') { |aac, elm| aac + "#{elm}#{params[elm]}" }
data = request.url + additional_string
digest = OpenSSL::Digest.new('sha1')
hmac = OpenSSL::HMAC.digest(digest, key, data)
calculated_signature = Base64.strict_encode64(hmac)

p calculated_signature
```

上記コードで、TwilioのSignatureが作れるので、困ったときには利用してみてください。
Flutterで複数の選択肢から1つを選択するダイアログの作り方

`SimpleDialog` を使えば実現できます。
https://docs.flutter.io/flutter/material/SimpleDialog-class.html


<img src="https://qiita-image-store.s3.amazonaws.com/0/18273/455e7da4-e160-b601-bf59-f5fc5ee15fc1.png" width="300px">

コードはこんな感じです。awaitで選択結果の取得が直列にかけるのがいいですね。

```dart
    switch (await showDialog<String>(
        context: context,
        builder: (BuildContext context) {
          return new SimpleDialog(
            title: const Text('選択してください'),
            children: <Widget>[
              new SimpleDialogOption(
                onPressed: () {
                  Navigator.pop(context, "hoge");
                },
                child: const Text('ほげ'),
              ),
              new SimpleDialogOption(
                onPressed: () {
                  Navigator.pop(context, "fuga");
                },
                child: const Text('ふが'),
              ),
            ],
          );
        })) {
      case "hoge":
        print("hoge");
        // ほげが選択された
        break;
      case "fuga":
        print("fuga");
        // ふがが選択された
        break;
    }
```
RでTweetをクラスタリング(DBSCAN)

RでTweetをリプライの内容によってクラスタリング(DBSCAN)する。
特徴量は形容詞のTF-IDFを利用。

必要なライブラリをインポート

```
#DBSCAN
library("fpc")
#形態素解析
library(RMeCab)
#データベース
library(RSQLite)
```

データベース接続

```
dbd <- dbDriver("SQLite")
dbname <- "/path/to/database.db"
dbcon <- dbConnect(dbd, dbname)
```

データベースから特定のツイートに対するリプライが10以上のものを取ってくる

```
tweet_list <- dbGetQuery(dbcon, "select to_tweet_id 
  from reply_table group by to_tweet_id having count(to_tweet_id)>=10")
```

```
for(i in 1:length(tweet_list[[1]])){
 print(tweet_list[[1]][i])
 #tweet_idを指定してリプライを取得
 sql <- paste("select text from reply where to_tweet_id = ", tweet_list[[1]][i], sqp = "") 
 #リプライをベクトルとして格納
 vec <- dbGetQuery(dbcon, sql) 
 #ノイズを取り除く
 vec <- gsub("\\n","",vec) 
 vec <- gsub("\\\"","",vec)
 vec <- gsub("\\\\n","",vec)
 vec <- gsub(",","",vec)
 print(vec)
 #データをテキストファイルに出力して保存
 file <- paste("/path/to/a/folder/to/store/data", tweet_list[[1]][i], ".txt", sqp = "")
 write(vec, file)
}
```

TF*IDF*NORMで規格化しつつ文書行列を作成

```
doc_mat <- docMatrix("/path/to/a/folder/to/store/data", pos=c("形容詞"), weight="tf*idf*norm")
```

DF取り除いて積集合

```
df <- docMatrix("/path/to/a/folder/to/store/data", pos=c("形容詞"), weight="df")
df <- df[row.names(df) !="[[LESS-THAN-1]]",]
df <- df[row.names(df) !="[[TOTAL-TOKENS]]",]

#DFが3以上のものを取り出す
df_min3 <- df[rowSums(df) >= 3, ]
doc_t <- t(doc_mat)
doc_s <- subset(doc_t, 1==1, rownames(df_min3))
```

DBSCANを行う

```
dist_mat <- dist(doc_mat, method="euclidean", diag=FALSE, p=2)
db <- dbscan(dist_mat,eps = 1.8, MinPts=4)
db
db$cluster
```

グラフ結果出力

```
plotcluster(dist_mat, c)
```
Mac上のgitで日本語を含むファイルが何故かUntrackedになる場合

# 原因

Mac上では濁点や半濁点を含む日本語（例として「ガ」）は、元の文字+濁点/半濁点(「カ」+「゛」)のように分割して扱われています。(UnicodeのNFD)

参考: [WikipediaのUnicode正規化](https://ja.wikipedia.org/wiki/Unicode%E6%AD%A3%E8%A6%8F%E5%8C%96)

そのため、WindowsやLinux等の1文字に結合して扱われている(UnicodeのNFC)環境からコミットしたファイルで問題が出る場合があります。

# 解決法

gitの設定として下記を指定します。

```
core.precomposeunicode=true
```

こちらの設定をすることにより、分割されている文字を結合するようになります。

なお、Macのgit 1.8.5以降はデフォルト設定が上記となっているようなので、事象が発生するとすればそれより古いバージョンを使っている or 明示的に変更している状態だと思われます。
VS codeのinclude pathの設定をちゃんとする

# 状況

使い捨てのC++コードを書いているのですが、それでEigenをインクルードしようとした時、
ファイルが見つからないと言った感じのことを言われて、Intellisenseの補完が効きませんでした。

今回に限ればそんなにEigenから呼び出さないので、適当にググったりコンパイル時のエラーメッセージをみたりとかで調整してもいいのですが、せっかくなのでできるようにしたいと思います。

# 環境

Ubuntu 16.04
Visual studio code 1.23.1

# やり方

まず、プログラムのソースコードを含むフォルダを開きます。

![vscode_opening_folder.png](https://qiita-image-store.s3.amazonaws.com/0/258019/99a09cd1-0e3d-a5c5-9fc6-92130861d206.png)

Eigenをインクルードしているところを見てみます。

![vscode_no_include.png](https://qiita-image-store.s3.amazonaws.com/0/258019/35a34277-6728-f745-9c15-b9f907dbbb66.png)

問題があることを示す緑色の波線が引かれています。これにカーソルを合わせます。

![vscode_clicking_hint.png](https://qiita-image-store.s3.amazonaws.com/0/258019/d9bef9f4-efe8-1816-d485-a112d335498a.png)

左上に電球のアイコンが出てきますので、これをクリックします。

![vscode_clicked_hint.png](https://qiita-image-store.s3.amazonaws.com/0/258019/71a68528-972d-48c5-a085-31b82cf26870.png)

設定にPathを設定するかどうかのリストが出てきました。他でTensorflowで遊んでいますので、そのPathも見つけてくれているようです。

ここまで出来るなら勝手に`/usr/include/eigen3`から引っ張ってきて補完してくれてもいいのに・・・

とりあえず一番上の`/usr/include/eigen3`をIncludePathに追加する項目をクリックします。

![vscode_after_setup_includepath.png](https://qiita-image-store.s3.amazonaws.com/0/258019/8aa65185-d1fd-e054-c459-3bec1e66e48b.png)

すると、`.vscode`フォルダ以下に`c_cpp_properties.json`というファイルができて、
`"includePath"`に`"/usr/include/eigen3"`が設定されていることがわかります。

これでもう一度cppファイルを開き、コーディングしてみます。

![vscode_after_enable_eigen.png](https://qiita-image-store.s3.amazonaws.com/0/258019/aae3a241-692d-4a8e-299e-65ab68ec7284.png)

無事、補完が有効に働いているようです。

ちなみにフォルダを開いてやらないと補完してくれませんでした。

# その他

`.vscode`フォルダには他に`.settings.json`ファイルがあり、このフォルダ以下でのみ有効な設定をエディタの設定に追加することができます。
インデントのスペース数とかを調整できます。

なんとなく、Visual Studioでプロジェクトのプロパティから設定していくよりはなんか自動的にできて簡単かなとは思いました。

まあネット上には他にもいっぱいこの情報を載せているところも多いでしょうが、僕の記憶を定着させる目的もあり、書いておくことにしました。
Googleフォームをカスタマイズして導入、Ajax処理を行う

## はじめに
Googleフォーム、簡単にアンケート等作成できて便利ですよね
実はこれ、デザインをカスタマイズして自アプリ・サイトに導入することもできます
下記の記事をみていただくとどのように導入できるかがわかるかと思います

[Googleフォームを自在にカスタマイズする](https://qiita.com/sota6412/items/fa077cbf820faca30598)

しかしながらこちらの場合お問い合わせ送信後にGoogleの送信完了ページに遷移してしまい、本アプリから一度離れてしまいます。
SPAを中心としたアプリ・サイトを実装をする場合、画面遷移せず、本アプリ中で完結するように作りたいことも出てくるかと思います。そのためカスタマイズしたGoogleフォームでAjax処理できないかと思い調べてみました。

## まずAjaxなしで書いてみる

作成したGoogleフォームのhtmlソースからaction,およびクエリパラメータのキーとなるnameを抜き出します


### 作成したGoogleフォーム
![スクリーンショット 2018-05-26 21.45.59.png](https://qiita-image-store.s3.amazonaws.com/0/168201/1c7ad4c6-02ee-bc4c-6275-7ae101118845.png "スクリーンショット 2018-05-26 21.45.59.png")

### Googleフォームのhtmlソース
![スクリーンショット 2018-05-26 21.46.13 2.png](https://qiita-image-store.s3.amazonaws.com/0/168201/65a1523d-e47b-d582-82a7-e1b2577fe22a.png "スクリーンショット 2018-05-26 21.46.13 2.png")

これらのactionのURLとキー名を同じようにして、自分のアプリ・サイト中でデザインをカスタマイズしたフォームを作成すれば・・・

```html

<form action="https://docs.google.com/forms/hoge/formResponse">
	<dir>
		<label for="email">お名前</label>
		<input id="name" type="text" name="entry.123456789" required="required">
	</dir>
	...
</form>
```

無事カスタマイズしたGoogleフォームから内容を送信できました

![screencapture-docs-google-forms-d-e-1FAIpQLSc2QD1VjvsRMb9c94Gm0yChnZxJziGsBg6xtXR0w03kEpYQww-formResponse-2018-05-26-21_33_59.png](https://qiita-image-store.s3.amazonaws.com/0/168201/9323b762-67ff-43c1-61b2-fdfa6d3fb64e.png "screencapture-docs-google-forms-d-e-1FAIpQLSc2QD1VjvsRMb9c94Gm0yChnZxJziGsBg6xtXR0w03kEpYQww-formResponse-2018-05-26-21_33_59.png")

が！こんなとこに遷移したくねえ！！


## Ajax処理

やりかたはこちらを参考にしました　

- [How to Post Google Forms Data via jQuery and Ajax to Spreadsheets
](https://stackoverflow.com/questions/29267773/how-to-post-google-forms-data-via-jquery-and-ajax-to-spreadsheets)
- [CRUD AJAX CON GOOGLE FORMS Y GOOGLE SPREADSHEETS](https://www.youtube.com/watch?v=4itq6SRY21g)

今回はjQueryの$ajaxを使用しています
具体的にはポイントは以下です

- dataTypeをxmlにする
- CORSエラーが出るが、機能する

```js
$.ajax({
  url: "https://docs.google.com/forms/hoge/formResponse",
  data: {"entry.123456789": name},
  type: "POST",
  dataType: "xml",
  statusCode: {
    0: function() {
      //Success message
    },
    200: function() {
      //Success Message
    }
  }
})
```

以下のCORSのエラーが出てきてしまいますが、実際にはフォーム送信は機能しています。エラーは回避できないようです。

```
Failed to load https://docs.google.com/forms/hoge/formResponse: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.
```

ちなみにこれを回避するため `dataType: jsonp` としたら以下のようなMIMEに関するエラーが発生し、機能しなくなります。

```
Refused to execute script from 'https://docs.google.com/forms/hoge' because its MIME type ('text/html') is not executable, and strict MIME type checking is enabled.
```


## 終わりに
みなさん疑問に思ってるかもしれません。なぜレガシー気味のjQueryを使用したのかと。
本当はaxiosで実装したかったんですが、うまく反映されませんでした。。。！

axios等でできたよー！って方いましたらぜひ教えていただけるとありがたいです！！
pandas で DynamoDB からエクスポートしたデータを読み込む

# pandas で DynamoDB からエクスポートしたデータを読み込む

個人的にAWSで運営しているサービスのデータを取り込んで統計を取りたくなったので作業手順のメモを残します。

## DynamoDB からエクスポートしたデータを眺める

DynamoDBのデータは AWS Data Pipeline で S3 にエクスポートし、ダウンロードします。

```
{"userId":{"s":"Google-ABwppHFW〜"},"mapAttr":{"m":{}}}
{"userId":{"s":"Google-ABwppHFD〜"},"mapAttr":{"m":{"accessCount":{"n":"2"},"lastAccess":{"s":"2018-01-21T09:29:01.847Z"}}}}
{"userId":{"s":"Google-ABwppHEs〜"},"mapAttr":{"m":{"data1":{"n":"1772977"},"accessCount":{"n":"2"},"lastAccess":{"s":"2018-02-13T08:32:22.318Z"},"data2":{"m":{"data3":{"n":"2"}}}}}}
{"userId":{"s":"amzn1.ask.account.AFQ〜"},"mapAttr":{"m":{"data1":{"n":"2685460"},"accessCount":{"n":"8"},"lastAccess":{"s":"2018-04-17T00:38:09.553Z"},"data2":{"m":{"data4":{"n":"38000"}}}}}}
...
```

データは一部抜粋&加工。userIdをキーとして、mapAttrにオブジェクトを持つ形式です。
DynamoDBからエクスポートしたデータは1行ごとのJSONを繋げたテキストファイル(JSON Lines)になります。

## pandas で読み込む

pandas には read_json で JSON を直接読み込む事ができますが、今回のような複雑な入れ子のJSONは読み込めません。
[pandas.io.json.json_normalize](https://pandas.pydata.org/pandas-docs/stable/generated/pandas.io.json.json_normalize.html) を使用すると入れ子のキーを列に展開して dataframe に読み込む事ができます。

ただし、json_normalize は JSON Lines のファイルから直接読み込む事はできませんので、自前で1行ずつパースしてリストとして json_normalize に食わせます。

```python
# coding: UTF-8
import json
import pandas as pd
from pandas.io.json import json_normalize

pd.set_option("display.max_colwidth", 1024)

with open('data') as f:
    lines = f.readlines()
    json_lines = map(lambda l: json.loads(l), lines)
    df = pd.io.json.json_normalize(list(json_lines))
    print(df.head(10))
```

```
  userId.s          mapAttr.m.accessCount.n mapAttr.m.accessCount.lastAccess.s mapAttr.m.data1.n mapAttr.m.data2.m.data3.n ...
0 Google-ABwppHFW〜                     NaN                                NaN               NaN                       NaN ...
1 Google-ABwppHFD〜                       2           2018-01-21T09:29:01.847Z               NaN                       NaN ...
2 Google-ABwppHEs〜                       2           2018-02-13T08:32:22.318Z           1772977                         2 ...
...
```

色々加工が必要かと思っていたのですがあっさり読み込めてしまいました。
DockerでPostgreSQLを立ち上げる

# 前提
Dockerはすでにつかえるということが前提となっています

# 手順

1. プロセスの立ち上げ`$ docker run --name some-postgres -e POSTGRES_PASSWORD=mysecretpassword -d postgres`
2. postgresqlが立ち上がっているかどうかの確認`$ docker run -it --rm --link some-postgres:postgres postgres psql -h postgres -U postgres`
3. ファイルを任意の場所に作成し、以下を書き込む

```
# stack.yml
Example stack.yml for postgres:

# Use postgres/example user/password credentials
version: '3.1'

services:

  db:
    image: postgres
    restart: always
    environment:
      POSTGRES_PASSWORD: example

  adminer:
    image: adminer
    restart: always
    ports:
      - 8080:8080
```

4. `$ docker-compose -f stack.yml up`
5. localhost:8080でブラウザ確認

ユーザー名とパスワードを入力する画面が出てくる
それぞれ下記のものを入力する

```
ユーザー名 postgres
パスワード example
```
BitbucketのOAuthでリポジトリクローンする

## 背景
Infrastructure as Codeにおいて、プライベートリポジトリからソースコードを引っ張ってきて、ビルドあるいはデプロイしたいということはよくある（と思っている）。
しかし、コードの中や環境変数に、リポジトリのユーザ名・パスワードなどのアカウント情報を書いておくのは、あまりスマートではない。

本稿では、BitbucketのOAuthを使って、Dockerコンテナ内にコードをデプロイする方法について記述する。

## BitbucketのOAuth設定
まずはBitbucketのOAuthを設定し、Credentialを用いてBitbucketにAPIアクセスできるようにする。

1. Bitbucketのユーザ設定画面から、「設定」->「OAuth」->「コンシューマーキーを追加」をクリックする
![oauth_setting.png](https://qiita-image-store.s3.amazonaws.com/0/69645/f333477c-a075-77f9-100e-58f01dc010cc.png)

2. 「Name」と「コールバックURL」を入力し、権限の「リポジトリ」「読み取り」にチェックを入れ設定を保存する。「コールバックURL」は使わないので何でもOK
![スクリーンショット 2018-05-26 20.31.12.png](https://qiita-image-store.s3.amazonaws.com/0/69645/acc05a26-f56b-8d86-0fcc-3e8985c1a7e0.png)
![スクリーンショット 2018-05-26 20.47.40.png](https://qiita-image-store.s3.amazonaws.com/0/69645/de791c80-0a97-d35b-ddd9-d74c9deb0758.png)

3.今作成したコンシューマーキーの鍵・シークレットをメモしておく。これでOAuthの準備は完了
![スクリーンショット 2018-05-26 20.19.4523.png](https://qiita-image-store.s3.amazonaws.com/0/69645/2c914fab-5560-22fe-6a8c-49da4166f86f.png)

## アクセストークンの取得
[公式](https://confluence.atlassian.com/bitbucket/oauth-on-bitbucket-cloud-238027431.html)を参考にする。
アクセストークンの取得は下記コマンドで可能。
https://bitbucket.org/site/oauth2/access_token を叩いて、認証に成功するとJSONが帰ってくるので、jqコマンドで解析しaccess_tokenを取得する。
jqコマンドのインストールが必要。

```sh

# 上記の鍵とシークレットを設定する
$ BB_OAUTH_KEY=****
$ BB_OAUTH_SECRET=****

# API叩いて帰ってきたJSONからjqコマンドで`access_token`を取得する。
$ curl https://bitbucket.org/site/oauth2/access_token \
    -d grant_type=client_credentials \
    -u ${BB_OAUTH_KEY}:${BB_OAUTH_SECRET} \
  | jq -r '.access_token'
```

## Dockerfileからイメージの作成

イメージをビルドする際に、ホストマシンから変数を渡すことで、Dockerfile内にクレデンシャル情報を残さないようにできる。また、上のコマンドを使ってアクセストークンを取得し、リポジトリのクローンを行う。

### Dockerfile

```Dockerfile
# ベースイメージは何でもOK
FROM python:3.6.4-alpine3.7

# build時の変数
ARG BB_OAUTH_KEY
ARG BB_OAUTH_SECRET

RUN apk update
RUN apk add curl
RUN apk add jq
RUN apk add git

# USER_NAME, REPOSITORY_NAME は適宜書き換えてください
RUN git clone https://x-token-auth:`curl https://bitbucket.org/site/oauth2/access_token -d grant_type=client_credentials -u ${BB_OAUTH_KEY}:${BB_OAUTH_SECRET} \
 | jq -r '.access_token'`@bitbucket.org/USER_NAME/REPOSITORY_NAME
```

### ビルドコマンド
```sh

$ docker build -f ./Dockerfile --build-arg BB_OAUTH_KEY="****" BB_OAUTH_SECRET="****" .
```

これでビルドは完了。
環境変数を毎回書くのが面倒という時は、`--build-arg`を指定せずにホストマシンの環境変数からでも取得してくれる。
12cSQL受験備忘録

# 【前置き】
12cSQLを受けてきたので備忘録として残します。

・なぜ受けようと思ったのか？

必死こいてWEB系へ転向しようとしてますが、どこに行ってもDBとの関係は切り離せないわけです。実務経験があると言ってもEXCELでUIを作ってそこからSQL（SRUD）書いてAccessからデータ持ってきたり、テーブル作ったりとしたりとそんなもんです。外部インターネット使えないので持って行けませんでしたが！で、実問題oracleは触った事があっても分業化されたSESではメインで触った事がないこともあり、復習も兼ねて12cSQLを受けようと思った一週間でした。

・なぜ12cSQLなのか？

実はoracleという資格だけが欲しい場合、12cSQLではなくSQL基礎1という試験でも大丈夫です。何が違うかというと難易度と有効期限が違い12cSQLは75問65%、SQL基礎1は40問70%となってます。SQL基礎1は学習コスパがいいもののこれからがっつりエンジニアになろうものが簡単な方受けても・・・というくだらないプライド（）で難しい方を受けましたという話。

・OSSDBでないのはなぜなのか？

完全に失念、無能をさらした瞬間。
OSSDBの存在は知っていたが、SQL知識を復習したいという目的だったので12cSQLにしちゃいました。しかし何を隠そうOSSDBではDBA＋SQLの知識が得られさらにメインDBはposgreである。これから受託系に行かない限りoracleを触ることは少ないだろうし、web系なら間違いなくposgreの方が触るやんアホやんワイ・・・ってなりました。これからDB系受けに行こうって人は自分のキャリアパスを考えてから受講してくださいね！って事がいいたい事です。

# 【本題】
さて、実際取ろうと思ってやった事を軽くまとめます。

本人スペック：oracle実務経験は薄いがaccessでテーブル作成SQLを書いた事があり、専門用語的な奴は把握してないが概念はわかる程度
参考書：【オラクル認定資格試験対策書】ORACLE MASTER Bronze[12c SQL基礎](試験番号:1Z0-061)完全詳解+精選問題集(オラクルマスタースタディガイド) 通称：白本
参考サイト：ping-t
勉強期間：一週間
理解度合い：白本9割、ping-t合格点程度

結果：合格（ギリギリ）

反省点：期間が短かったとはいえ白本は出来てる状態でいったがギリギリでした。oracle実務バリバリでって方は白本のみで余裕だとは思いますが、試験では白本では見ないような問題もあったので、不安感ある方は黒本とpingも9割行ける位やりこみましょう。私の場合時間が押されすぎててpingがっつり出来なかったので問題傾向すべてキャッチ出来てない感じでした。生きた心地しませんでしたね。

# 【後書き】
来月より新しい現場に移動する事になりました。距離も片道1時間オーバーですし24時間シフト（）とかもあるし、客先に完全に左右されてしまい転職活動がくっそしにくくなります。SESでなければ現場の近くに引越しして時間を捻出することも可能なんでしょうがリスク高すぎます、だからSESは・・・！ウォンテッドリーで気軽に訪問って事も出来なさそう・・・って事で8月か9月くらいから環境さえあれば勝手にいろいろやっちゃう私と一緒にお仕事して下さるweb系企業様お探ししてますっ！
Ajax（jQuery）での通信中にローディング画像を表示する

# やりたいこと
Ajaxでサーバーと通信する際、くるくるのローディング画像を表示したい。

## 概要
- `beforeSend` を使用する。これを使うことでajaxのリクエスト前に処理を実行させることができます。
 - `removeClass`, `addClass`を用いてローディング画像の表示、非表示を実行します。
 - 画像はこちらから拝借いたしました。https://www.benricho.org/loading_images/transparent01.html
- php側は受け取った値をそのまま出力するだけのものとします。
 - ローディング画像を表示するために、`sleep()`で1秒ほど遅延させています。

```html:index.html
<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="utf-8">
  <title>Ajax Test</title>
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
</head>
<body>
<style type="text/css">
body {
  margin-top: 100px;
  text-align: center;
}
.hide {
  display: none;
}
.loading {
  position: fixed;
  top: 0;
  right: 0;
  bottom: 0;
  left: 0;
  background: rgba(0,0,0,.5);
  background-image: url(../img/712-88.gif);
  background-repeat: no-repeat;
  background-attachment: fixed;
  background-position: center center;
  background-size: 150px 150px;
}
</style>

  <form method="post" accept-charset="utf-8">
    <p>NAME: <input type="text" name="name" id="name"></p>
  </form>

  <button id="button1">POST</button>
  <div class="msg"></div>
  <div class="loading hide"></div>

  <script type="text/javascript">

    $(function() {
      $('#button1').on('click', function(){
        $.ajax({
          url: 'send.php',
          type: 'POST',
          data: {
            name: $('#name').val()
          },

          //リクエストが完了するまで実行される
          beforeSend: function(){
            $('.loading').removeClass('hide');
          }

        }).done(function(data){
          $('.loading').addClass('hide');          
          $('.msg').append('<p>NAME: ' + data + '</p>');

        }).fail(function(XMLHttpRequest, textStatus, errorThrown){
          console.log("failed...");
          console.log("XMLHttpRequest : " + XMLHttpRequest.status);
          console.log("textStatus     : " + textStatus);
          console.log("errorThrown    : " + errorThrown.message);
        });
      });
    });

  </script>
</body>
</html>
```

```php:send.php
<?php
  sleep(1);

  header('Content-type: text/plain; charset=utf-8');
  if(isset($_POST['name'])) {
    $name = $_POST['name'];
    $msg = nl2br($name);
    echo $msg;
  } else {
    echo "FAILED.";
  }
```
##実行結果
![ajax_test.gif](https://qiita-image-store.s3.amazonaws.com/0/239966/9f5c24fe-706c-fa29-97d3-4cea2af1a282.gif)

## Special Thanks
- [jQuery samples - Ajax時にローディングを表示](http://blog.webcreativepark.net/2015/12/21-204123.html)
- [【ajax】通信エラーとなった原因（エラーログ）を取得する]
(http://ysklog.net/jquery/ajax/4501.html)
Railsチュートリアル

# rootのエラー

[![Screenshot from Gyazo](https://gyazo.com/c7d54d01ecc3617054d555919408c3f9/raw)](https://gyazo.com/c7d54d01ecc3617054d555919408c3f9)


こちらになります。
signupのrootがないと怒られたんですが、
signupと直接入力すると動きます

何か考えられる原因はありますでしょうか

```Rails.application.routes.draw do
  root 'static_pages#home'
  get  '/help',    to: 'static_pages#help'
  get  '/about',   to: 'static_pages#about'
  get  '/contact', to: 'static_pages#contact'
  get  '/signup',  to: 'users#new'
  post '/signup',  to: 'users#create'
  resources :users
end```
上記のroutesではエラーが出なかったんですが
下のコードではエラーが出ました。

```Rails.application.routes.draw do
  root   'static_pages#home'
  get    '/help',    to: 'static_pages#help'
  get    '/about',   to: 'static_pages#about'
  get    '/contact', to: 'static_pages#contact'
  get    '/signup',  to: 'users#new'
  get    '/login',   to: 'sessions#new'
  post   '/login',   to: 'sessions#create'
  delete '/logout',  to: 'sessions#destroy'
  resources :users
end```

ではエラーが出ました。
ちなみに両方ともチュートリアルのコピペです。
UiPathで避けて通れないDataTableをおさらい

UiPathで定型作業を自動化する際、どうやっても使う事になるのがDataTable。
.NETで業務アプリケーションを作るプログラマーにとっては定番なのですが、
RPAの世界ではそうじゃない人の方が大多数と思います。

UiPath Academyの「レッスン9 - Excelとデータテーブル」でも学べるのですが、
早い段階から知っておいた方が良い知識なので、UiPathで必要な範囲に絞っておさらいしてみます。

#DataTable（データテーブル）とは何か
Excelシートと同じ、行と列の表形式データを入れる"入れ物"です。
Excelシートと違うのは、行番号は1でなく0から始まる事と、
列もA, B, C, ...ではなく列名（↓の例だと"ロボID"等）、もしくは行と同様に0, 1, 2, ...です。
![DataTable.png](https://qiita-image-store.s3.amazonaws.com/0/255097/b5c53311-ca74-6443-5e95-c9b9141f11b9.png)

UiPathでは大抵の場合、↓のような使い方になります。
・Read RangeアクティビティでExcelシートを読み込む
・Data ScrapingでWebサイトから表形式データを取り込む
と、UiPathがデータをDataTableに詰めて返してくれるので、後はFor Each Rowアクティビティで
データを１行ずつ処理して、最後にWrite RangeでデータをExcelに書き込む、という流れ。
![Usage.png](https://qiita-image-store.s3.amazonaws.com/0/255097/2b409b24-1af0-15db-ba41-3262e6eaf046.png)

#DataTableデータの持ち方
Excelシートを読み込む場合、UiPathから返されるDataTableのデータの持ち方は
Read Rangeアクティビティの"AddHeaders"のオン（デフォルト）／オフで変わってきます。
![AddHeader.png](https://qiita-image-store.s3.amazonaws.com/0/255097/999d1c58-d41c-161a-5ee1-afc7ff4d836c.png)
例えば↓のExcelシートでロボID "BP-302"が入っているのはA4セルですが、
![Excel.png](https://qiita-image-store.s3.amazonaws.com/0/255097/8c3107b7-a3d1-ff85-c629-e6d0c9196ca1.png)
読み込んだ結果のDataTableの中身とデータのアクセスの仕方は↓のように全然違います。
![compare.png](https://qiita-image-store.s3.amazonaws.com/0/255097/ccfa43ae-64b5-ff9d-72b9-b5283db77d35.png)
　※dtRobotはDataTableの変数名ね。
**AddHeadersオンの場合（Data Scrapingで取ってくる場合もコレ）**
　１行目がヘッダ列情報として使われ、データに入ってきません。
　DataTableは行番号が0から始まるのと合わせると、Excelの行番号と２つズレる事になります。
　データは列の名前でアクセスできます。わかりやすい。
**AddHeadersオフの場合**
　１行目からデータとして入ってきますが、列名が無いためデータは列番号でアクセスする事になります。

※行番号のズレも注意ですが、セル指定の順番もExcelと逆な事に注意が必要です。
　Excelは"A4"のように列→行の順、DataTableはdtRobot(2)("ロボID")のように行→列の順。
#For Each RowとDataRow
DataRowについても知っておきましょう。
↓の通り、DataRowとはDataTableのそれぞれの行を指します。
1DataRow = １行なので、行番号はありません。
![DataRow.png](https://qiita-image-store.s3.amazonaws.com/0/255097/59e15eec-806a-3be9-4217-22cd432f86fb.png)
UiPathから返されたDataTableを上から１行ずつ処理する場合、For Each Rowアクティビティを使います。
Foreachの後に、勝手に"row"変数がセットされますが、これがDataTableから取り出したDataRowです。
row.Items(列名)で、指定した列名のデータを取り出す事ができます。
![foreach.png](https://qiita-image-store.s3.amazonaws.com/0/255097/01b65595-ed97-93d7-1bee-ba0c8b25abcb.png)
このワークフローを実行すると、Output窓に
デッカード
マクレーン
パワージョー
・・・
といったように、Excelから読み込んだ"ロボ名"列のデータがリストアップされます。

---
今回はここまで。
DataTableのもうちょっと踏み込んだ使い方、例えばソートとかフィルタとかは
[UiPathでよく使う.NETコード集](https://qiita.com/UmegayaRollcake/items/2a4573b4fb664fa923a9)
で説明してますので、参考にして下さい。
ReentrantLockで順序性を保証するロック

個人用メモ。
Javaの排他制御について調べていたところ、以下の記事を見つけました。
[Javaのsynchronizedは順序を保証しない。](http://d.hatena.ne.jp/megascus/20141209/1418100367)
記事中で言及されているように、`synchronized`によるロックは、複数同時にロックした場合の解放順序を保証しません。
理解していないと、ひょんなところでドはまりしそうです（しました）。
当方の対処としては、ロック機構を`synchronized`から`java.util.concurrent.locks.ReentrantLock`に置き換えました。
## ReentrantLockを使う
```java
// コンストラクタはfair=trueで指定する
// lockインスタンスは排他制御するスレッド間で使いまわす
ReentrantLock lock = new ReentrantLock(true);
try {
    lock.lock();
    // 排他制御中の処理
} finally {
    lock.unlock();
}
```

## ロックの取得と解放を自動化する
そのまま使用しても目的は果たせるのですが。`synchronized`と違い明示的なロック解放が必要な分、うっかり漏れると、深刻な状況になりかねません。
そこで、ReentrantLockのラッパーを作成し、ロックとアンロックをペアで使用することを強制しました。

```java:FairLock.java
public class FairLock {
    private ReentrantLock lock = new ReentrantLock(true);

    public void withSync(FairSyncTask task) {
        try {
            lock.lock();
            task.act();
        } finally {
            lock.unlock();
        }
    }

    public interface FairSyncTask {
        void act();
    }
}
```

```java:使用例
// synchronizedで書いていた例
private final Object syncObj = new Object();

public void actWithUnfair() {
    synchronized(syncObj) {
        // 排他制御中の処理
    }
}

// ReentrantLockのラッパーで置き換えた例
private final FairLock fairLock = new FairLock();

public void actWithFair() {
    fairLock.withSync(() -> {
        // 排他制御中の処理
    });
}
```
## まとめ
知っていればなんてことないのでしょうが。
この記事が誰かの助けになれば幸いです。
VBAでTitleの列番号を入手する関数を作成する

仕事でVBAを操作する機会がたくさんあったのでメモ。

Function Title(WS as Worksheet, TitleName as string)

set WS = WS
Dim TitleRow

TitleRow = 1 'titleの列
For i = 1 to Cells(TitleRow, Columns.Count).End(xlToLeft).Column

 if TitleName = cells(TitleRow, i)
  exit for
 end if

 Title = i

end
unicornでMaterialize関連が読み込めないエラー【File to import not found or unreadable】


#前説

グローバルIPをURLに打ち込むと、自分のアプリが出るらしい・・・
しかし！！！

#エラーがでた

403エラー

とりあえず困った時はnginxかunicornのエラーを見ればいい。

log/nginx.error.logには

```ruby:nginx.error.rb
 *20 directory index of "/home/masaya/madeit2/public/" is forbidden
```

こいつです。

```/etc/nginx/nginx.conf
user  nginx;
worker_processes  1;
```

nginx -> [username]に変更

nginxを再起動

```:Terminal
$ sudo service nginx reload
```

nginx.error.rb曰く、403は消えた

##またエラーがでた

```:unicorn.log
ActionView::Template::Error (Invalid CSS after "...t "./matelpage"": expected selector or at-rule, was "@import "materi..."):
```

やったこと①

```
config.assets.css_compressor = :sass
config.assets.enabled = true
config.assets.compile = true
```

```
$ rake assets:precompile
```

```
Sass::SyntaxError: Invalid CSS after "...t "./matelpage"": expected selector or at-rule, was "@import "materi..."
```

文法エラーでしたので/assets/stylesheet/application.scssのミスを修正すると直るかと思われます。


#またまたエラーがでた

<img width="583" alt="スクリーンショット 2018-05-26 20.06.12.png" src="https://qiita-image-store.s3.amazonaws.com/0/253129/3fe9d823-69fe-8b11-f505-ab879d473685.png">

次はunicorn。

```ruby:unicorn.rb
ActionView::Template::Error (File to import not found or unreadable: materialize/components/color-variables.)
```

```application.scss
@import "./matelpage"
```

```JavaScript:application.js
//= require jquery
//= require jquery_ujs
//= require turbolinks
//= require_tree .
//= require materialize
//= require jquery
//= require jquery.turbolinks
//= require jquery_ujs
//= require jquery.infinitescroll
//= require turbolinks
//= require_tree .
```
materialize/components/color-variablesを読み込めていないそうです。

##やったこと①

直感で以下のコードを追加

```application.scss
@import "materialize";
```

変化なし

##やったこと②

gemを確認+bundle install+nginxとunicornを再起動

```:Gemfile
gem 'materialize-sass'
```

変化なし

##やったこと③

"materialize/components/color-variables"を消しまくる。

```application.scss
- @import "materialize/components/color-variables";
```

```matelpage.scss	
- @import "materialize/components/color-variables";
```

デプロイに成功した！

参考文献
https://github.com/mkhairi/materialize-sass/blob/master/README.md