OmniAICreator/Qiita-1.07M huggingface dataset:
Missingを能動的に取得する

VBAの`Missing`を自力で作成する方法のメモです。

# `Missing`とは？

`Variant`型に格納できる特殊な値の一つで、省略可能な`Variant`型引数が省略されたことを示す値です。

ローカルウィンドウ上などでは、以下のように値に「参照不可」と表示されるのが特徴です。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/142842/13cf8780-562d-70a0-da9c-6b727de65f57.png)


## 参考

`Missing`以外の`Variant`のみに格納できる特殊な値は以下のようなものが存在します。

### Empty

数値として扱うと0、文字列として扱うと空文字列になる値。
Variant型変数の初期値として使われる。

[IsEmpty 関数](https://docs.microsoft.com/ja-jp/office/vba/language/reference/user-interface-help/isempty-function "IsEmpty 関数 (Visual Basic for Applications) | Microsoft Docs")や[VarType 関数](https://docs.microsoft.com/ja-jp/office/vba/language/reference/user-interface-help/vartype-function "VarType 関数 (Visual Basic for Applications) | Microsoft Docs")で判定でき、Emptyキーワードで取得できる。

### Null

無効な値。
データベースや、一部のオブジェクトで値が設定されていないことを示すのに使われる。
[IsNull 関数](https://docs.microsoft.com/ja-jp/office/vba/language/reference/user-interface-help/isnull-function "IsNull 関数 (Visual Basic for Applications) | Microsoft Docs")や[VarType 関数](https://docs.microsoft.com/ja-jp/office/vba/language/reference/user-interface-help/vartype-function "VarType 関数 (Visual Basic for Applications) | Microsoft Docs")で判定でき、Nullキーワードで取得できる。

データベースを扱うAccessのタイプライブラリには、簡単に扱うための関数なども定義されている。

### エラー値

なんらかのエラーを示す値。
Excelのワークシート関数のエラーなどは、この値で表現される。

> 参考
[VBAでセルのエラーの種類を判定する（CVErr + XlCVError 列挙型） - Qiita](https://qiita.com/nukie_53/items/6c2d9d4699149bebe863 "VBAでセルのエラーの種類を判定する（CVErr + XlCVError 列挙型） - Qiita")


内部に持つ数値により複数の種類があり、Missingもエラー値の一種となる。

[IsError 関数](https://docs.microsoft.com/ja-jp/office/vba/language/reference/user-interface-help/iserror-function "IsError 関数 (Visual Basic for Applications) | Microsoft Docs")や[VarType 関数](https://docs.microsoft.com/ja-jp/office/vba/language/reference/user-interface-help/vartype-function "VarType 関数 (Visual Basic for Applications) | Microsoft Docs")で判定でき、[CVErr 関数](https://docs.microsoft.com/ja-jp/office/vba/language/reference/user-interface-help/cverr-function "CVErr 関数 (Visual Basic for Applications) | Microsoft Docs")で取得できる。

### Decimal

高精度な数値型。
[VarType 関数](https://docs.microsoft.com/ja-jp/office/vba/language/reference/user-interface-help/vartype-function "VarType 関数 (Visual Basic for Applications) | Microsoft Docs")で判定でき、CDec関数で取得できる。

# 作成方法

[Array 関数](https://docs.microsoft.com/ja-jp/office/vba/language/reference/user-interface-help/array-function "Array 関数 (Visual Basic for Applications) | Microsoft Docs")の引数を省略すれば、そのインデックスの値が`Missing`となるため、そこから取得できます。


```vb
'Get "Missing" value
Public Property Get Missing() As Variant
    Static cacheMissing As Variant '高速化のためキャッシュする
    If VBA.IsEmpty(cacheMissing) Then _
        Let cacheMissing = VBA.Array(, Empty)(0)
    Let Missing = cacheMissing
End Property
```

普通にArray 関数を呼び出すと、`Option Base`の影響を受けるため、`VBA.Array`とライブラリ名を指定して`0`始まりと明示しています。

# 役に立つ場面

……正直あまりないですが、ExcelのRangeの`Resize`プロパティなど、引数省略時の動作が特殊なものを呼ぶときに知っていると便利なこともあるかもしれません。

# 関連

[VBA.IsMissingの致命的な問題 - Qiita](https://qiita.com/nukie_53/items/9bfbe89ac491e99f9665 "VBA.IsMissingの致命的な問題 - Qiita")
GitHubのContributionで草が生えない。メールアドレスが間違っていたのが原因だった

# 前書き
GitHubのコミット記録がまったくContributionに反映されていなかった。

[公式情報](https://help.github.com/articles/why-are-my-contributions-not-showing-up-on-my-profile)と自分のコミット履歴を照らし合わせて確認したところ、

原因は「commitしたgitユーザのメールアドレスとGitHubのアカウントのメールアドレスが一致していない」ことにあった。

# ダミーのメルアドを使っていた場合はrebaseが必要

commitしたユーザのメールアドレスがまだGitHubのアカウントに紐づいていない場合は紐付ける設定をすればOK。

メールアドレスは複数設定でき、紐付けてやれば過去に遡ってContributionに反映される。

厄介なのが、なんらかの理由で無効なメールアドレスでcommitされていた場合。

この場合はメール認証ができずアカウントとの紐付けができないため、過去のコミットの改竄をするしかない。

# というわけでrebase

過去のコミットを書き換えることになるので要注意。

実施する場合はブランチを切るなどしていつでも戻れるようにしておくこと。

```
$ git filter-branch --env-filter 'GIT_AUTHOR_EMAIL="<メールアドレス>"'　<コミットのハッシュ>..HEAD HEAD
$ git push --force
```

# 参考情報

Github invalid author email commits, no contribution activity
https://stackoverflow.com/questions/39631983/github-invalid-author-email-commits-no-contribution-activity

2種類の方法が紹介されているが、もう片方の方法を使用するとコミット時刻が書き換えられてしまうので、今回の記事で紹介した方法を使うのがベターである。
【Python】prompt-toolkitでfuzzy complete(あいまいな補完)を実装する

## 動作環境

```
> python --version
Python 3.7.1

> pipenv graph
prompt-toolkit==2.0.8
  - six [required: >=1.9.0, installed: 1.12.0]
  - wcwidth [required: Any, installed: 0.1.7]
```

## 基本的な補完機能(WordCompleter)

![wordcompleter.gif](https://qiita-image-store.s3.amazonaws.com/0/116551/76365e7d-a1cf-b701-4541-dbbdcd6b2b6b.gif)

単語の補完には、`prompt_toolkit.completion.WordCompleter`が使える

```python
from prompt_toolkit import prompt
from prompt_toolkit.completion import WordCompleter

# 単語の候補
my_completer = WordCompleter(
    ["apple", "goole", "japan", "hoge", "hello world", "good morning"]
)

while 1:
    # hisotoryで履歴を追加
    user_input = prompt(">", completer=my_completer)
    print(user_input)
```

## あいまいな補完(FuzzyWordCompleter)

![fuzzywordcompleter.gif](https://qiita-image-store.s3.amazonaws.com/0/116551/1b31a2aa-0869-82ce-fb40-16ff6cf10ce4.gif)

[prompt_toolkit 2.0.8](https://github.com/prompt-toolkit/python-prompt-toolkit/commit/fc53fe9befbfdb86f6de0a2f4de14affb5d449b3) から、あいまい検索(fuzzy find)でのauto_completeができるようになった

`FuzzyWordCompleter`は`WordCompleter`をラップしたものであるため、`WordCompleter`と同じように使える

```python
from prompt_toolkit import prompt
from prompt_toolkit.completion import FuzzyWordCompleter

# 単語の候補
my_completer = FuzzyWordCompleter(
    ["apple", "goole", "japan", "hoge", "hello world", "good morning"]
)

while 1:
    # hisotoryで履歴を追加
    user_input = prompt("> ", completer=my_completer)
    print(user_input)
```


## 参考文献

- [python-prompt-toolkitを使ってお手軽自動補完 - Steel Dragon 14106](http://raimon49.github.io/2017/05/29/auto-suggest-by-python-prompt-toolkit.html)
- https://github.com/prompt-toolkit/python-prompt-toolkit/blob/81c30157422989957c8a56b333b17ba35ab1a223/prompt_toolkit/completion/fuzzy_completer.py#L142-L168
Tech系YouTube チャンネルまとめ

# TL;DR
私が暇つぶしがてら見ているTech系YouTube チャンネルの紹介
 

## [sentdex](https://www.youtube.com/user/sentdex)
- おそらくPython関連の動画を最も多く投稿しているチャンネル
- トピックは多岐に渡る（機械学習、Web開発、Pythonの基礎など）
- 最近はDeep Learning関連のチュートリアルが多い
- 基本的なスタイルは「From Scrachで何かを作る」
- チュートリアルのオリジナリティが高い（[Python plays Grand Theft Auto](https://www.youtube.com/watch?v=ks4MPfMq8aQ&list=PLQVvvaa0QuDeETZEOy4VdocT7TOjfSA8a) とか）


## [Siraj Raval](https://www.youtube.com/channel/UCWN3xxRkmTPmbKwht9FuE5A)
- 最新の論文や、AIの活用事例を良い感じに噛み砕いて説明してくれるチャンネル
- 情報の鮮度も高い
- チャンネルを運営しているSirajさんの**「AIをもっと普及させたい」**という熱意が半端ない
- 以前はLIVEコーディングなんかもしていた（最近はあまり見ない）
- ここ最近は凄まじい頻度で動画を投稿している（週２〜３本）
- [SirajさんのLinkedIn](https://www.linkedin.com/in/sirajraval/)


## [PyData](https://www.youtube.com/user/PyDataTV)
- 世界各地で実施されているPyDataのカンファレンス内での発表を配信しているチャンネル
- 動画のタイプは以下の2種
    - プレゼン：３０〜５０分
    - チュートリアル：１時間を超えるものが多い
- データサイエンスや人工知能を勉強している方は必見
- 色々な英語のアクセントに触れることができる
- プレゼン資料作りの参考になる


## [Traversy Media](https://www.youtube.com/user/TechGuyWeb)
- 主なトピックは Web開発（かなりフロントエンド寄り）
- スタイルは上述の`sentdex`さんと似ていて「From Scratchで何かを作る」
- 作成するものは比較的シンプルな者が多いので、初学者の方でも理解しやすいと思う
- たまに技術以外の話もしてくれる（例えばこの動画：[The Importance Of Passion & Hard Work](https://www.youtube.com/watch?v=rZg2N4gFUc0&t=28s)）
- Crash Course系の動画は結構重たい（１時間を超えるものがほとんど）。それ以外は３０分前後のものが多い
- Udemyでも活動している（[Brad Traversy](https://www.udemy.com/user/brad-traversy/)）
- 手軽に取り組めるチュートリアルが多いので、Web系以外の方でも、「知見を広めたい」 or 「手を動かして何か作りたい」という衝動に駆られた際に、このチャンネルを覗いてみるといいかも

## [freeCodeCamp](https://www.youtube.com/channel/UC8butISFwT-Wl7EV0hUK0BQ/featured)
- 1時間を超えるCrash Course系の動画が多い
- CS50（Harvard大学の有名なComputer Scienceの講義）なんかも投稿されている

## [Life of Luba](https://www.youtube.com/channel/UCgzKCeDYLRzPhQ64R6AKyBQ)
- チャンネル運営者Lubaさんの経歴（[LinkedIn](https://www.linkedin.com/in/yudasinal/?locale=en_US)）
    - ベラルーシ出身
    - Waterlooに通っていた
    - 初めはChemical Engineering（化学工学）を専攻していた
    - しかし、Computer Science（CS）の魅力に気づき、独学でプログラミングを学習
    - ドイツに留学してCSのコースを専攻
    - 現在は Airbnb の Backend Engineer
- Lubaさんの実体験に基づく話が多く説得力がある（米国への移住、プログラミング学習など）
- 「自分も頑張らねば」という気持ちにさせてくれるチャンネル



# 最後に
以下に挙げる作業を行うことで、記憶に定着する確率が上がります。ただ見ているだけだと、全く記憶に残りません。せっかく見るなら、少しでも収穫があった方が良いですよね？

- 動画のまとめや所感を発表 or 投稿してみる
- 重要だと感じた事柄はメモしておく
- 実際に手を動かしコーディングする
- 学んだ知識・知識を転用して、何かやってみる
エディタ比較

人気と言われる4つのエディタの比較。Visual Studio Codeの一強。

<blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr">Google トレンドで「Atom, Brackets, Visual Studio Code, Sublime Text - すべての国、2016/12/28～2019/01/28」の 人気度の動向 を見る - <a href="https://t.co/E9aG0aVOEj">https://t.co/E9aG0aVOEj</a></p>&mdash; kannkyo (@kannkyoshi) <a href="https://twitter.com/kannkyoshi/status/1089895960564555776?ref_src=twsrc%5Etfw">2019年1月28日</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
pandasの行を列にする

multi indexのcolumn版をやる。

[便利なmulti indexの記事](https://qiita.com/ryskchy/items/59028f1a3ed1d433b1a8)

<img width="243" alt="image.png" src="https://qiita-image-store.s3.amazonaws.com/0/53186/1ef30073-87de-53a6-a6fc-73dd43e01d35.png">

を

<img width="283" alt="image.png" src="https://qiita-image-store.s3.amazonaws.com/0/53186/d507be1b-adf0-001b-58d7-5b46f731222b.png">


こうしたい
つまりclassをtop levelの列にしたい!

## 以下のようにすればいい
```
df = pd.DataFrame({
    'class' : ['A', 'A', 'A', 'A', 'A', 'B', 'B', 'B', 'B', 'B'],
    'number' : [1,2,3,4,5,1,2,3,4,5],
    'math' : [90, 20, 50, 30, 57, 67, 89, 79, 45, 23],
    'english' : [40, 21, 68, 89, 90, 87, 89, 54, 21, 23]
})

pipod_df = df.set_index(['number','class']).unstack(level=-1).swaplevel(0,1,axis=1).sort_index(axis=1, level=0)
```

## 解説

- set_index: listを引数に取ることでmulti index化(行名をtupleで取る)
- unstack: 行を列へ (-1を指定してclassを列に)
- swaplevel: 列を入れ替える((math, english)⇔class)
- sort_index: 行を入れ替える


# 列を指定

```
pipod_df.loc[:, 'A']
```

<img width="185" alt="image.png" src="https://qiita-image-store.s3.amazonaws.com/0/53186/33e9e513-bda0-658b-cf1f-b94bccb38fef.png">
Tomcatのスレッド名

# 背景
Tomcatのアクセスログ、Log4Jなどのロガーでリクエスト毎のスレッド名を出力していましたが、諸々設定を変更したところスレッド名のフォーマットが変わってしまいました。

# スレッド名
Tomcatのアクセスログであれば「%I」、Log4J系なら「%t」を指定することでスレッド名を出力することができます。イメージ的には以下のような感じ。

```
http-nio-127.0.0.1-8080-exec-1
```
こんな感じでサーバのIPアドレスとポートが出力されていたのですが、以下のようになってしまいました。

```
http-nio-8080-exec-1
```
わたくしの現場ではサーバが数台あり、そのアプリのログをfluentdを使って１ファイルにまとめていましたが、IPアドレスが出力されなくなってしまったので、ログの各行がどのサーバのログがわけわかめになってしまいました。

# 分かったこと
どうやらserver.xmlのConnectorタグのaddress属性を消したのが原因でした。address属性は未設定の場合、localhostのIPでlistenするようなので任意属性のようです。
なので、Tomcatにおけるスレッド名のフォーマットは以下だと推測されます。

```
http-nio-[Connectorタグのaddress属性]-[Connectorタグのport属性]-exec-1
```

おわり。
AndroidTVのKey制御

AndroidTVを触る機会があったので、備忘録としてKey制御周りについて記載しようと思います。
#フォーカスがViewを重ねたことによって迷子になった場合
下記の図のように、何かのトリガーによって全体にViewを重ねた際に、フォーカスが下のボタンに当たったままになってしまい、重ねたViewのボタンの制御ができなくなってしまいます。
![レイアウト.png](https://qiita-image-store.s3.amazonaws.com/0/163140/58479285-bd79-f358-ca75-01f0a3d1d0c2.png)

そういった場合は、全体にViewを重ねるタイミングで重ねたViewのボタンへのフォーカスを当てる処理を追加してあげることで解決することができます。

```java
        Button belowViewButton = (Button)view.findViewById(R.id.belowViewButton);
        belowViewButton.setOnClickListener(new View.OnClickListener() {
            public void onClick(View view) {
                // トップのViewを表示
                topView.show();

                // トップのViewに表示しているボタンへフォーカスを当てる
                topViewButton.setFocusable(true);
                topViewButton.requestFocus();
            }
        });
```

#Fragment内でKeyEventを取得する場合
Fragment内でKeyEventを取得する場合はフォーカスが当たっているオブジェクトに対してOnKeyListenerを定義して上げる必要があるのですが、AndroidTVの場合キーの操作によってフォーカスが移り変わっていってしまうため、OnKeyListenerが定義されていないオブジェクトにフォーカスが当たっている場合はKeyEventが取得できなくなってしまいます。

Activity内ならフォーカス関係なくKeyEventを取得することできるためActivity→Fragmentの流れでKeyEventを通知して上げることで解決できます。
#どうしてもFragment内だけでKeyEventの処理を済ませたい場合
下記のように、フォーカスが当たる予定の全てのオブジェクトに対してOnKeyListenerを定義することになります。

```java
   	@Override
	public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
	    super.onCreateView(inflater, container, savedInstanceState);
	    View view = inflater.inflate(R.layout.fragment_main, container, false);
	    
	    Button button1 = (Button)view.findViewById(R.id.button1);
	    // button1へKeyEventを設定
	    setKeyEvent(button1);
	    
	    Button button2 = (Button)view.findViewById(R.id.button2);
	    // button2へKeyEventを設定
	    setKeyEvent(button2);
	    
	    return view;
	}
	
	private void setKeyEvent(Button button) {
	    button.setOnKeyListener(new View.OnKeyListener() {
	        @Override
	        public boolean onKey(View v, int keyCode, KeyEvent event) {
	            // ACTION_DOWNとACTION_UPの両方が取れるのでACTION_DOWNのみ受け付けるように
	            if (event.getAction() != KeyEvent.ACTION_DOWN) return false;
	            switch (keyCode) {
	                case KeyEvent.KEYCODE_BACK:
	                    // バックキーが押されたときの処理
	                    return true;
	
	                case KeyEvent.KEYCODE_DPAD_CENTER:
	                    // D-padのCenterボタンが押されたときの処理
	                    return true;
	
	                case KeyEvent.KEYCODE_DPAD_UP:
	                    // D-padのUpボタンが押されたときの処理
	                    return true;
	
	                case KeyEvent.KEYCODE_DPAD_DOWN:
	                    // D-padのDownボタンが押されたときの処理
	                    return true;
	
	                case KeyEvent.KEYCODE_DPAD_LEFT:
	                    // D-padのLeftボタンが押されたときの処理
	                    return true;
	
	                case KeyEvent.KEYCODE_DPAD_RIGHT:
	                    // D-padのRightボタンが押されたときの処理
	                    return true;
	            }
	            return false;
	        }
	    });
	}
```
CentOS7にOAuth.ioのオープンソース「oauthd」をインストールする

# 1. はじめに
[oauthd](https://github.com/oauth-io/oauthd)はnode.jsをベースにしたソリューションで、独自のスタンドアロンの完全に無料のWeb Background API Serverをセットアップして実行することができます。

今回はCentOS7にこちらをインストールします。
いろいろとインストールする準備があるので、それぞれは各リンクを参考に。

# 2. nodebrewからNodeJsのインストール
👉[CentOS7 nodebrewからNode.jsをインストール](http://sh-yoshida.hatenablog.com/entry/2016/02/17/124742)

# 3. Redisのインストール
👉[Redis Quick Start](https://redis.io/topics/quickstart) ← 最新版のインストール
👉[CentOS7にRedisのインストールとsystemdサービス化まで](https://yomon.hatenablog.com/entry/2016/02/20/162648) ← 手順はこちらを参考に

# 4. grunt-cliのインストール
oauthdに依存関係があるNPMパッケージに次のコマンドを実行することで、グローバルでインストールする必要があります。

```
$ (sudo) npm install -g grunt-cli
```

# 5. 前提条件が整ったらoauthdをインストール
```
$ （sudo）npm install -g oauthd
```
# 6. サーバ設定
👉[CentOS7にOAuth.ioのオープンソースをサーバ公開する](https://qiita.com/blue_islands/items/4f6ec1050ef49d8f4371)

# 7. 使用方法
使用方法はAPIから直接oauthdサーバに接続するか、またはSDKを利用することができます。

クライアントサイドSDK

- JavaScript
- iOS
- Phonegap
- Android

サーバーサイドSDK

- Nodejs
- PHP
- Go

[oauthd apis](https://github.com/oauth-io/oauthd/wiki/API)と[oauthd-sdks](https://github.com/oauth-io/oauthd/wiki/Server-and-client-side-SDKs)について、詳しくはこちらから。
Nuxt.js + Herokuで、簡単SPA(Single Page Application)

参考サイトの手順通りにやっていけば、簡単なSPAが出来たので、ブックマーク的な手順メモ

完成したサイトは、こちら
https://ango-maker.herokuapp.com/

#プロジェクト作成
```terminal:プロジェクト作成
npx create-nuxt-app <project-name>
```

```terminal:起動
cd ango
npm run build
npm start
```

ブラウザで、
http://localhost:3000/
にアクセス
<img width="933" alt="スクリーンショット 2019-01-27 21.01.13.png" src="https://qiita-image-store.s3.amazonaws.com/0/118481/eb184fe6-519e-7505-0a69-126d12bae5de.png">

```terminal:開発モードで起動？
npm run dev
```
こっちであれば、ファイル更新を自動で検知してくれる模様
※開発モードって指定だからかな


#GoogleAnalyticeを設定
ここの手順通りにやるだけで可能
 https://github.com/nuxt-community/analytics-module

便利だなぁ〜これ

#GoogleAdsenseを設定
これも、便利な機能が！
 https://github.com/nuxt-community/google-adsense-module

#FontAwesomeをNuxt.jsで使う
 https://yinm.info/20181008/

#Herokuにデプロイ
公式サイトの通りにデプロイ
　https://ja.nuxtjs.org/faq/heroku-deployment/

#Bootstrapの色を変える
 https://qiita.com/Cheekyfunkymonkey/items/09a28c947a59bb9a9026
ブロックチェーンサミットに行ってきた　beyond PoC by Microsoft & HashHub & Neutrino

#Blockchain
2018/12に開催されたブロックチェーンサミットに行ってきました。
その内容と、個人的にググったブロックチェーン技術についてまとめました。

ビジネスサイドの方、なんだかんだ今まであんまりブロックチェーンは調べなかったという人向けです。
ごりごりの開発者の方、普段からブロックチェーン技術に興味を持っている方はあまり面白くないと思います。。。汗

前半戦はググったことのまとめと参照したURL乗せていて、後半はイベントの内容とそれにまつわるリンクです。

ブロックチェーンビジネスサミットに参加してきた！｜chokunari @Chokunary｜note（ノート） https://note.mu/chokunari/n/na3fd1bdce545

僕も全然詳しくないので、なるべくわかりやすく書いたつもりです。
勉強するきっかけになれば幸いです。
Rails Association １対多,１対１について。

#Rails Association (関連付け）とは
モデル同士に関係性を持たせる事。モデル同士を関連付けすることで、
関連付けられたモデルから変数を呼び出す事ができ、コードをシンプルに、簡単にできる。
例えば、ユーザ（User)と投稿（Post)というモデルがある場合に、PostはUserがいないと作成されないため、この２つには切り離せない関係性がある時など。
##１対多 （belongs_to  と  has_many)
１対多の関連性がある場合、関連付けたいモデルに、belogs_to または　has_manyを加える。
下記のUser（ユーザー）とPost（投稿）では、ユーザーは複数の投稿を持つ事ができる(has_many)。投稿は特定のユーザーに属している(belongs_to)。

```Ruby:UserモデルとPostモデル
class User < ApplicationRecord
    has_many :posts
end

class Post < ApplicationRecord
    belongs_to :user
end
```
###has_manyの例
ユーザーに関連付けている投稿（つまりユーザーが投稿したもの）をすべて取得しようとすると↓

```Ruby:Association「なし」
class User < ApplicationRecord
  def posts
    return Post.where(user_id: self.id)
  end
end
```

```Ruby:Association「あり」
class User < ApplicationRecord
  has_many :posts
end
```

###belongs_toの例
投稿に関連付けているユーザー（つまり投稿したユーザー）を取得しようとすると↓

```Ruby:Association「なし」
class Post < ApplicationRecord
  def user
    return User.find_by(id: self.user_id)
  end
end
```

```Ruby:Association「あり」
class Post < ApplicationRecord
  belongs_to :user
end
```
このように「あり」の方が「なし」より、シンプルで分かりやすくなる

##１対１（belongs_to と has_one)
１対１の関連性がある場合、関連付けたいモデルに、belogs_to または　has_oneを加える。
例えばあるシステムでは１人のUserは１つのAccount　しか持てない決まりだった場合、
ユーザーは１つのアカウントを持っている（has_one)、アカウントは特定のユーザーに属している(belongs_to)という関連付けができる。
###belongs_toとhas_oneのどちらを選ぶか？
2つのモデル（UserとAccount）の間に1対1の関係を作りたいのであれば、いずれか一方のモデルにbelongs_toを追加し、もう一方のモデルにhas_oneを追加する必要がある。どちらの関連付けをどちらのモデルに置けばいいか迷った場合、「ユーザーがアカウントを持っている」とみなす方が、「アカウントがユーザーを持っている」と考えるよりも自然。つまり、この場合の正しい関係は以下のようになる。

```Ruby:UserモデルとAccountモデル
class User < ApplicationRecord
  has_one :account
end

class Account 
  belongs_to :user
end
```
sklearnのrandom forestでサンプルごとのfeature importanceを計算する

sklearnのrandom forestではfeature_importances_というattributeが用意されていますが、これはあくまで分類器そのものの話でサンプルごとにその判断根拠を提示してくれるわけではありません。

あるサンプルが森を通って判断される際に、どの特徴量が何回使われるかを計算してみました。

```python
from sklearn.ensemble import RandomForestRegressor
import pandas as pd
import numpy as np

df = pd.DataFrame({'A':np.random.uniform(0,1,10000),
                  'B':np.random.uniform(0,1,10000),
                  'C':np.random.uniform(0,1,10000),
                  })

X_train = df
Y_train = df['A']+df['B']+np.random.uniform(0,1,10000)

rf = RandomForestRegressor()
rf.fit(X_train, Y_train)

def feature_importance_for_one_sample(rfregressor, X):
    estimators = rfregressor.estimators_
    
    feature_count = {}
    
    for estimator in estimators:
        features = estimator.tree_.feature
        
        indicator = estimator.decision_path(X)
        node_index = indicator.indices
        
        for feature in features[node_index]:
            feature_count[feature] = feature_count.get(feature, 0) + 1
    
    # -2はリーフノードなので削除
    del feature_count[-2]
    
    return feature_count

feature_importance_for_one_sample(rf, X_train.iloc[[0]])
>>>{0: 48, 1: 52, 2: 25}

```

まぁなにやらそれっぽい値が出てきました。使えるかどうかは？
なお、Xは1つのサンプルですが、DataFrameで入力しないとエラーになるのでご注意ください。



参考：
https://own-search-and-study.xyz/2016/12/25/scikit-learn%E3%81%A7%E5%AD%A6%E7%BF%92%E3%81%97%E3%81%9F%E6%B1%BA%E5%AE%9A%E6%9C%A8%E6%A7%8B%E9%80%A0%E3%81%AE%E5%8F%96%E5%BE%97%E6%96%B9%E6%B3%95%E3%81%BE%E3%81%A8%E3%82%81/
https://scikit-learn.org/stable/auto_examples/tree/plot_unveil_tree_structure.html#sphx-glr-auto-examples-tree-plot-unveil-tree-structure-py
https://docs.scipy.org/doc/scipy-0.18.1/reference/generated/scipy.sparse.csr_matrix.html
Vue.js（または Nuxt.js）でCSS in JavaScript

## 導入

（自分の周りでは）たまに聞くCSS in JavaScriptですが、Reactユーザーの方は、[styled-components](https://styled-components.com/)を使ってCSS in JavaScriptを行っているのでしょうか？
では、Vue.jsは？？

## CSS in JavaScript with Vue.js
![50833110-30b41180-138b-11e9-9ddd-20af6afc1747.png](https://qiita-image-store.s3.amazonaws.com/0/18699/3a685972-0995-6516-8e10-8ea41dfb12a3.png)

[egoist/styled-vue: Use dynamic styles in Vue single-file components.](https://github.com/egoist/styled-vue) :thumbsup:  
実際に自分で使ってみました。

```javascript
<template>
  <div><h1 class="title">hello there!</h1></div>
</template>

<script>
import { css } from 'styled-vue'
import { modularScale } from 'polished'

export default {
  style: css`
    .title {
      font-size: ${modularScale(2)};
      margin: 0;
      color: red;
      text-align: center;
    }
  `
}
</script>
```
ちゃんとスタイル効いてる！
<img width="937" alt="" src="https://qiita-image-store.s3.amazonaws.com/0/18699/a92b29e2-7ced-329c-1a3c-6e3a01e1e0bf.png">

## まとめ
ということでVue.jsでCSS in JavaScriptを実現できました。
といあえず紹介おわり。
Windows 10 Pro x64 で Apache2 を試してみる

#目的
Windows 10 Pro x64 に Apache2 をインストールしてみる
##ファイルのダウンロード
[Downloading Apache for Windows](https://httpd.apache.org/docs/current/platform/windows.html#down)より適当なサイトを選択してダウンロードする
httpd-2.4.38-win64-VC15.zip を解凍して c:\ 以下に配置する
VS2017をインストールしていない場合は[最新のサポートされる Visual C++ のダウンロード](https://support.microsoft.com/ja-jp/help/2977003/the-latest-supported-visual-c-downloads)より 
[Visual Studio 2017 用 Microsoft Visual C++ 再頒布可能パッケージ] 
をDLしてインストールする必要があるかもしれません
##httpd.conf を修正する
C:\Apache24\conf\httpd.conf を修正する
<pre>
 58行目　Listen 8090               <- 8090に修正
222行目　ServerName localhost:8090 <- コメントアウト＆localhost:8090に修正

httpd.conf のデフォルトでは以下の設定となっている
インストール先のフォルダを変更する場合（権限変更が必要かも？）
 37行目　ServerRoot "c:/Apache24"　　　　　# フォルダの変更
243行目　DocumentRoot "c:/Apache24/htdocs" # コンテンツの配置先の変更
243行目　<Directory "c:/Apache24/htdocs">  # 上記に合わせる
363行目　ScriptAlias /cgi-bin/ "c:/Apache24/cgi-bin/"　# 上記に合わせる
</pre>
修正後 以下で httpd.conf の確認を行う
\> C:\Apache24\bin\httpd -t
Syntax OK
##Windows のサービスとして登録する
以下はコンソールを管理者モードで起動して行う
<pre>
サービスとして登録
自動起動に設定されるので、変更する場合はサービス画面より変更する
> C:\Apache24\bin\httpd -k install
Installing the 'Apache2.4' service
The 'Apache2.4' service is successfully installed.
Testing httpd.conf....
Errors reported here must be corrected before the service can be started.

サービスから削除
> C:\Apache24\bin\httpd -k uninstall
Removing the 'Apache2.4' service
The 'Apache2.4' service has been removed successfully.

以下は通常の画面より実行可能
起動
\> C:\Apache24\bin\httpd -k start

終了
\> C:\Apache24\bin\httpd -k stop
</pre>
自分は C:\Apache24\bin\ApacheMonitor.exe のショートカットを貼り付けています
##参考にしたのは以下のサイト
[Apacheインストール](https://www.adminweb.jp/apache/install/)
[Windows版Apacheのconfigテスト](https://qiita.com/rsuzuki/items/22493421b57ee37646df)
[Uipath]ファイルを保存する時には保存先を指定する方法

ファイルの保存を自動化する際にパスの指定をしたかったのですが、アドレスバーに所定のパスを入力しようとしてもうまくいかずに困っていたところ、別の指定方法がありましたのでまとめます。

##最初にやろうとしたこと
最初はアドレスバー全体をセレクターにとって文字入力をしようとしたのですが、うまくいかずに、通常の動作と同じようにアドレスーバー内空白の部分をクリックしてから文字を入力しようとしました。しかし、空白の部分のセレクタはとれずにアドレスバー全体の下の階層はフォルダ名部分しかセレクターが取れないことがわかりました。
![キャプ.png](https://qiita-image-store.s3.amazonaws.com/0/347151/b3740947-8471-918b-d55e-047183180b51.png)
![キャプ3.png](https://qiita-image-store.s3.amazonaws.com/0/347151/c80a17b7-2e17-8126-82e7-f3380adae1e2.png)


##パスの指定はファイル名の入力欄でできる
パス指定はアドレスバーだけではなくファイル名の入力欄でもできます。
その際には`絶対パス¥ファイル名`で入力すれば絶対パスで指定した保存先に所定のファイル名で保存されます。
<img width="664" alt="スクリーンショット 2019-01-28 21.19.11.png" src="https://qiita-image-store.s3.amazonaws.com/0/347151/61764756-d8bf-2595-4844-4185f3820d44.png">

##入力文字列を変数化する
パスを文字列として文字列として代入してもいいですが、同じ絶対パスを何度も使用したり、ファイル名を入力ダイアログなどで毎回変更させる場合には変数化した方が可読性や保守性が上がります。
<img width="424" alt="スクリーンショット 2019-01-28 21.35.48.png" src="https://qiita-image-store.s3.amazonaws.com/0/347151/208e4aea-a2cb-69b7-f23e-4d8fda3bebaf.png">

ファイルの保存先の指定方法は以上になります。
【メモ】ActionTextを使う6ステップ

# 概要
* ActionTextを使う手順を箇条書き

# 環境
* Rails 6 beta 1

# 手順
* ActionTextインストール
* gemインストール
* modelに追加
* viewのformに追加
* controllerのparamsに追加
* viewの showに追加

## ActionTextインストール

```console
rails action_text:install
rails db:migrate
```

## gemインストール

```Genfile
gem 'image_processing', '~> 1.0'
```

```console
bundle install
```

## modelに追加
例えば `Item` モデルに `content` という名称で追加します。

```app/model/item.rb
class Item < ApplicationRecord
  has_rich_text :content
```

## viewのformに追加
`rich_text_area`を使います

```app/views/new.html.erb
form_with @item do |f|
  f.rich_text_area :content
```

## controllerのparamsに追加
例えばitem_paramsに `:content` を追加します。


```app/controllers/items_controller.rb
  def create
    @item = Item.new(item_params)
    @item.save!
  end

  def item_params
    params.require(:item).permit(:content)
  end
```

* viewの showに追加
`content` で呼び出すだけ。

```app/views/items/show.html.erb
@item.content
```

以上
『リファクタリング』を読んでみて

[リファクタリング](https://www.amazon.co.jp/dp/427405019X)を読んでみたので、感想と心に残った箇所を書き留めておく。

# 第１章：リファクタリング - 最初の例

最初に小さなプログラムに対して実際のリファクタリングの例がコードとともに挙げられていてすごい分かりやすいし、さくさく読み進められてとても良かった。４００ページ以上あるから、最初に時間かかっちゃうと多分読み終われないだろうから。

> リファクタリングを開始するとき、最初にすることは常に同じです。対象となるコードについてきちんとしたテスト郡を作り上げることです。

ユニットテストはクラス・関数の構造変えたりすると、結局ガッツリ手がはいりそうだから、そこまでのリファクタリングをする場合は、ITくらいの粒度のテストを書いたほうがいいのかな。どうだろう。

> コンパイラが理解できるコードは誰にでも書ける。優れたプログラマは、人間にとって分かりやすいコードを書く。

あぁ、うまく表現した言葉だな。後者を目指したい。
（バグは結構あるけど）コードが書ける ＜ バグの少ないコードが書ける ＜ バグの少ない分かりやすいコードを書ける
って感じかな。

あと、印象に残ったのは１次変数を極力取り除いていたところ。結果、読みやすいと思う、シンプルで。

# 第２章：リファクタリングの原則

> - リファクタリングはソフトウェアを理解しやすくする
> - リファクタリングはバグを見つけ出す
> - リファクタリングでより速くプログラミングできる

そのタイミングで直接ユーザに影響があるのは、２つ目くらいだけど、長い目で見てユーザーにもエンジニアにも確実に利益がある。

> リファクタリングには２つの価値がある。今できること、そして将来できるようになること。

レガシーシステムの一番の問題は、前者に着目しすぎて何も変えれずに、後者が疎かになって結果的にジリ貧になってしまうこと。

> リファクタリングを採用すると、力点の置き方が変わってきます。事前設計は行うのですが、そこで唯一無二の、完璧な解決策を見出す必要はありません。...解決策をコードとして作り込んでいくにつれて、やがて問題の本質がもう少し見えてきます。

結構、設計はふわっとしてまずは動くものを作ってみる。で、そこから構造をいじったり書き方を変えてみたりするリファクタリングを何回かしたほうが、最終的にシンプルで良いものができる気がする。

> 柔軟性を求めた解決策は複雑になりがちです。その結果できたソフトウェアは、予想していた変更に簡単に対処できるものの、通常は保守しにくくなります。

そうなのよ。将来考えてこんなものを入れています！っていうのは大概複雑で一見わかりにくかったりする。しかも結果使われませんでしたってなるとなんでそんな作りになってるのかもはやわからなくなっちゃうし。

> 柔軟な解決策を作り込む代わりに、「シンプルな解決策を柔軟なものにリファクタリングするのに、どの程度工数がかかるか」を考えていきます。ほとんどの場合、その答えは、「比較的簡単にできる」になります。そうしたいときは、シンプルな解決策を単に実装すればいいのです。

「将来に向けて柔軟にしました！」は、ちょっとこの基準で考えてみるといいかも。

# 第３章：コードの不吉な臭い

> - 重複したコード
> - 長過ぎるメソッド
> - 巨大なクラス
> - 長すぎるパラメータクラス
> - 変更の偏り
> - 変更の分散
> - スイッチ文
> - コメント

最後の「コメント」は、

> コメントの必要性を感じたときにはリファクタリングを行って、コメントを書かなくとも内容がわかるようなコードを目指すこと。

によって、解消しましょうねということ。

# 第６章：メソッドの構成

ここからは具体例を通じて、一つ一つのリファクタリングのパターンに名前をつけてある感じ。

> - メソッドの抽出　⇔　メソッドのインライン化
> - 説明変数の導入
> - メソッドオブジェクトによるメソッドの置き換え

このあとの章でも出てくるけど、対になっているプラクティスが出てくるのがよい。
要は状況に合わせてより読みやすくなる方を考えて選ぶ必要があるよということ。

# 第７章：オブジェクト間での特性の移動

> - メソッド・フィールドの移動
> - クラスの抽出　⇔　クラスのインライン化

> 私は、１０年以上もオブジェクトを生業としてきましたが、未だに、責務をはじめから正しいところに配置することができません。今ではそうした状況においても、リファクタリングを適用して、以前に決定したことを変えることができます。

やはり設計時にはすべて適切に責務を切り分けるのは難しいということ。機能も付け足されていくし、適宜見直してリファクタリングしていくのがよさそう。

> システムが発展していくにつれて、新たなクラスや責務の振り直しが必要になります。ある週ではそうではなくなります。それが問題ではなくて、それについてなにもしないことが問題なのです。

ぐさり。めっちゃ刺さる。そうだよね。

# 第８章：データの再編成

> - オブジェクトによるデータ値・配列の置き換え
> - クラス・サブクラスによるタイプコードの置き換え

# 第９章：条件記述の単純化

> - 条件記述の分解　⇔　条件記述の結合
> - 重複した条件記述の断片の統合
> - ガード節による入れ子条件記述の置き換え
> - ポリモーフィズムによる条件記述の置き換え

# 第１０章：メソッド呼び出しの単純化

> - メソッド名の変更
> - パラメータの追加　⇔　パラメータの削除
> - 問い合わせと更新の分離
> - オブジェクトそのものの受け渡し
> - パラメータオブジェクトの導入
> - Factory Methodによるコンストラクタの置き換え

# 第１１章：継承の取り扱い

> - フィールド・メソッド・コンストラクタの引き上げ　⇔　フィールド・メソッドの引き下げ
> - サブクラス・スーパークラス・インターフェースの抽出
> - Template Methodの形成

# 第１２章：大きなリファクタリング
### 手続き的な設計からオブジェクト指向への変換

まさに、いまいまリファクタリングでやりたいのはこれだな。MVCでクラスを使った書き方しているけど、複雑な処理が手続き的な形で記述されていて、すべてを読み込まないと仕様が理解出来ない。もっとオブジェクト指向の利点を活かして責務をいい感じに分けながら設計し直したいな。

# 全体を通じて

面白かった。普段これ自分も考えてるなーってものや、あっ全然このパターンは考えてことなかったやってもの。あとは、自分はこれはやりすぎなんじゃないかなーって思うものまでいろいろあったけど、様々なパターンをたくさん集めてまとめてあるっていうのはなかなか今後も参照できそうな本だなと思った。

あとは、自分たちのコードのリファクタリングの時に、ここでは○○のパターンを使ってこうリファクタリングして見ようみたいな会話ができれば結構スムーズにチームでリファクタリングが進みそう。
Let's encrypt の更新が突然うまくいかなくなったのを解決した

# 概要
WebサイトをSSL化するときに大変便利な Let's encrypt 。
私も、管理しているサイトで1年以上前（2017年）から利用しているのですが、今年（2019年）に入って、期限切れ予告メール[^1]が届くようになりました。

...あれ？
更新用のコマンドをcronに入れて定期実行しているから、予告すら届かないはずなのに。
実際、2018年中は一度も期限切れ予告は来ていなかったのに...

ともかく、問題を解決しなければ証明書の期限切れが起きてしまうので、調査・対応しました。

# 解決方法
先に、解決方法を示しておきます。

- rootユーザで実施しています。
- ポイントは --webroot -w -d の3つのオプションです。
- 残りのオプションはACME利用規約への同意と、期限切れ前でも実施できるようにするオプションです。

```console
# ./certbot-auto certonly --webroot -w /var/www/html -d dummy.example.com -n --agree-tos --force-renewal

（中略）
Waiting for verification...
Cleaning up challenges

IMPORTANT NOTES:
- Congratulations! Your certificate and chain have been saved at:
  /etc/letsencrypt/live/dummy.example.com/fullchain.pem
（後略）

```

無事、更新に成功しました。
「--webroot」というオプションをつけることで、Let's encrypt内蔵のWebサーバではなく、ApacheやNginxなどのWebサーバのほうを見に行くようになります。


念のため、DRY-RUN（実際に更新はかけずに、チェックのみ実行する機能）を実施して、今後の更新にも問題が発生しないことを確認しておきましょう。

```console
# ./certbot-auto renew --dry-run

（中略）
Congratulations, all renewals succeeded. The following certs have been renewed:
（後略）

```

問題なさそうです。めでたしめでたし。

# 何が起きていたか
次のようなエラーが発生していました。


```console
# ./certbot-auto renew --dry-run

（中略）
Waiting for verification...
Cleaning up challenges
（ここから実際は赤文字で表示）
Attempting to renew cert (dummy.example.com) from /etc/letsencrypt/renewal/dummy
.example.com.conf produced an unexpected error:Unable to find a virtual host li
stening on port 80 which is currently needed for Certbot to prove to the CA that
 you control your domain. Please add a virtual host for port 80.. Skipping.
All renewal attempts failed. The following certs could not be renewed:
 /etc/letsencrypt/live/dummy.example.com/fullchain.pem (failure)
（赤文字こここまで、さらに中略）
1 renew failure(s), 0 parse failure(s)

```

「80番ポートでVirtualHostを立ててよ」というメッセージですが、実際にはApacheが稼働していて80番ポートをリッスンしていますし、ブラウザからアクセスしても問題なく80番ポートで応答がある状態です。
なので、最初は原因調査に難儀しました。。。

# 参考
https://qiita.com/HeRo/items/f9eb8d8a08d4d5b63ee9
https://free-ssl.jp/command/


[^1]: 「Let's Encrypt certificate expiration notice for domain "dummy.example.com"」というような件名のメールです。
Vagrant + Fish + WSL

T.B.D

## Environment

```
$ cat /etc/lsb-release
DISTRIB_ID=Ubuntu
DISTRIB_RELEASE=16.04
DISTRIB_CODENAME=xenial
DISTRIB_DESCRIPTION="Ubuntu 16.04.5 LTS"

$ fish --version
fish, version 2.7.1
```

## Preparation

```
sudo apt install vagrant
```

install vbox <= 5.2 from [here](https://www.virtualbox.org/wiki/Download_Old_Builds_5_2)

check your environment
```
$ set -U
```

if you don't find below three universal variables, plese execute following cmds.

```
$ set -Ux VAGRANT_WSL_WINDOWS_ACCESS_USER_HOME_PATH <your path>
$ set -Ux VAGRANT_WSL_WINDOWS_ACCESS_USER <your name>
$ set -Ux VAGRANT_WSL_ENABLE_WINDOWS_ACCESS 1
```

Add the path of VBoxManage

```
$ set -Ux PATH $PATH /mnt/c/Program\ Files/Oracle/VirtualBox/
```

## Execute vagrant

```
vagrant box add ubuntu/xenial64
vagrant init ubuntu/xenial64
```

Edit VagrantFile

```
config.vm.provider "virtualbox" do |vb|
  vb.customize [ "modifyvm", :id, "--uartmode1", "disconnected" ]
end
```

```
vagrant up --provider virtualbox
```

## Appendix

If you get following the result, please check  if your VT-x is enabled in BIOS.

```
There was an error while executing `VBoxManage`, a CLI used by Vagrant
for controlling VirtualBox. The command and stderr is shown below.

Command: ["startvm", "66549888-8955-407b-a927-b512e4f2c1f0", "--type", "headless"]

Stderr: VBoxManage.exe: error: VT-x is not available (VERR_VMX_NO_VMX)
VBoxManage.exe: error: Details: code E_FAIL (0x80004005), component ConsoleWrap, interface IConsole
```

> You may need to check if Hyper-V is disabled from the control panel of Windows.
N予備校で得た知識を使ってAV-Conciergeを作ってみた

# はじめに
初めまして、普段は自分のブログで記事を書いていますが、今回はQiitaの方に初投稿させて頂きました。
初めて一人でWebサービスを作ってみたので、ご紹介（宣伝）させていただきたいと思います。

# 作ったもの
https://av-concierge.herokuapp.com
<blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr">Webアプリ作りました！ <a href="https://t.co/Jvb7UjaYYo">https://t.co/Jvb7UjaYYo</a> <a href="https://t.co/WVsa1elSTd">pic.twitter.com/WVsa1elSTd</a></p>&mdash; R.T (@Dr_RT) <a href="https://twitter.com/Dr_RT/status/1069879391126241280?ref_src=twsrc%5Etfw">2018年12月4日</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

お好みのジャンルを3つ答えると、オススメの作品を提案するサービスです。

# 参考にしたもの
[顔認識AI + LINEの新機能 でAVソムリエを作ってみた](https://qiita.com/mikan3rd/items/97cd0795cfcd4f548967)

[AIで似ているAV女優を紹介しているスケベAI「スケベ博士」を作りました。](https://qiita.com/kkdmgs110/items/ce0f47d053636ce14cae)

# きっかけ
きっかけは上記の記事を見て、実装方法まで詳しく書いていたので自分にも出来るかもと思ったことと、もう一つニコニコ生放送の普段見ている放送で、AVの話で盛り上がりこういうサービスあったらいいねというコメントを受け、実際に作って放送で報告したいというモチベーションで開発をはじめました。

# 機能
好みのジャンルを3つ選択すると、ジャンルにマッチした作品を3つ紹介します。
なるべく3つのジャンルがマッチしたものを紹介していますが、3つのジャンルにマッチしなかった場合はどれか一つのジャンルにマッチングした作品を紹介します。

紹介した作品はパッケージと作品名、ジャンルそしてサンプル動画があればその場で見ることができます。

# 工夫した点
* 必ず3つのジャンルに完全一致した作品を紹介できるよう、選択肢の内容を調整しています。
* スマホでも見やすいようにレスポンシブデザインに対応しています。
* DMMのAPIを使って必要なデータをPythonで取得しています。

# イマイチだった点
* 選択肢の内容を完全ランダムで出力していたら、結果が似たようなものしか出なかった。
* マッチングのアルゴリズムにレーベンシュタイン距離というものを使っていましたが、選んだジャンルの文字数に依存する場面が多く、短い文字数だと似通った結果になることが多かった。
* スマホからサンプル動画を見ようとすると、DMMのアプリのページに飛ばされてしまい直接見ることができない。

# 実装の概要
N予備校のプログラミングコースで学んだことを実践したいと思い、「プログラミング入門 Webアプリ」で学んだことをベースに実装しています。

* Node.js(サーバーサイド)
* Express(Webフレームワーク)
* mocha(テスティングフレームワーク)
* webpack(クライアントフレームワーク)
* jQuery(ライブラリ、DOMフレームワーク)
* Ajax(非同期通信)
* などなど...

大枠はこれらの技術で作ることができましたが、細かいところは調べながら作りました。
Pythonにも興味あったので、スクレイピングでAPIを叩いてデータを集めています。

# 反省
N予備校の「プログラミング入門 Webアプリ」コースを一通り学んだのですが、内容の理解が浅く、セッション管理が理解しきれていなくて、複数のPCからアクセスすると選択したジャンルをユーザ同士で共有し合うという状態になったりしていました。
フレームワークなどの技術も理解が浅いので、何がどこに役立っているのかもイマイチ分かっていないです。

しかし、理解が浅いことを理解したので、今後はこれらの技術について調査し、内容をまとめて理解を深めていきたいと思います。

# 今後
定期的なアップデートを目標に、どんどん機能改善・追加していきたいので、何かご意見・ご感想・ご要望等があれば気軽に問い合わせてくれると幸いです。
最終的にはアキネーターみたいにAIで、質問や選択肢の内容を変えていき、利用者の深層心理で求めている作品を提示していく方向に持っていければと考えております。
Seeeduino（Arduino互換ボード）で温湿度を取得する

#Seeeduino の初期設定と動作確認

初期設定とLチカはこちら
[Seeed Studio の Seeeduino（Arduino互換ボード）でLチカする](https://qiita.com/diskn/items/6c7b73c40a0eb6a0a437)

#温湿度を取得する

Grove - Temp and Humi Sensor(SHT31)
http://wiki.seeedstudio.com/Grove-TempAndHumi_Sensor-SHT31/

1. SHT31用の[ライブラリ](https://github.com/Seeed-Studio/Grove_SHT31_Temp_Humi_Sensor)をダウンロード

1. [スケッチ] - [ライブラリをインクルード] - [.ZIP形式のライブラリをインストール] を選択し、ダウンロードしたライブラリをインストール

1. [スケッチ] - [ライブラリをインクルード] - [Grove SHT31 Temp Humi Sensor]を選択

1. [ファイル] - [スケッチ例] - [Grove SHT31 Temp Humi Sensor]を開く

1. Seeeduino の I2Cコネクタへ SHT31 を接続する

1. Seeeduino をPC へ接続する

1. [スケッチ] - [マイコンボードに書き込む]を実行

1. [ツール] - [シリアルモニタ] を起動
![キャプチャ.PNG](https://qiita-image-store.s3.amazonaws.com/0/240467/2bad3789-eff5-e795-69df-bd6619b92721.png)
Mac環境でsedコマンドを使う時の注意点

MacとCentOS(Ubuntuも？)で`sed`コマンドの`-i`オプションの挙動が異なります。
どう違うかなどは以下の`man`コマンドで出力されるマニュアルを見てみましょう。

Macのsedコマンド

```
-i extension
             Edit files in-place, saving backups with the specified extension.  If a zero-length extension is
             given, no backup will be saved.  It is not recommended to give a zero-length extension when in-place
             editing files, as you risk corruption or partial content in situations where disk space is exhausted,
             etc.
```

CentOSのsedコマンド

```
-i[SUFFIX], --in-place[=SUFFIX]
              edit files in place (makes backup if extension supplied).  The default operation mode is to break symbolic and
              hard links.  This can be changed with --follow-symlinks and --copy.
```
ざっくり言うとMacの方はバックアップ用のファイルを作成することが推奨されているため、`-i`の後に何も記述しないとエラーになります。
よって、Macで`sed`コマンドを良い感じに使いたいなら、`brew install`しましょう。
そして、`.bashrc`にエイリアスを設定しましょう。

```
$ brew install gnu-sed
$ vim ~/.bashrc
alias sed='gsed'
$ source ~/.bashrc
```
これで、`-i`オプションの際にバックアップ用のファイルを指定しないで済みます。（＝エラーがなくなる）
gnuplotチートシート

# 標準入力から渡した値をプロットする

```sh
gnuplot -p -e "plot '< cat -' using 1:2 with lines"
```

from: https://stackoverflow.com/questions/4585770/gnuplot-stdin-how-to-plot-two-lines

## y=sin(x)

```sh
seq -w 0 0.01 6.28 |
awk '{print $1, sin($1)}' |
gnuplot -p -e "plot '< cat -' using 1:2 with lines"
```

<details><summary>y=sin(x) のグラフ</summary><div>

![image.png](https://qiita-image-store.s3.amazonaws.com/0/26038/0d8465b2-fcfa-7340-1e33-5efbab6de2fe.png)
</div></details>

## 反比例 y=1/x

```sh
seq 1 100 |
awk '{print $1, 1/$1}' |
gnuplot -p -e "plot '< cat -' using 1:2 with lines"
```

<details><summary>y=1/x のグラフ</summary><div>

![image.png](https://qiita-image-store.s3.amazonaws.com/0/26038/b7491e6b-3f69-266e-63b2-802b6d0a3096.png)
</div></details>

# 日付のフォーマットを指定する

```gnuplot
set xdata time
set timefmt '%Y%m%d%H%M%S'
```

参考: http://lowrank.net/gnuplot/datetime.html


# 線とか点とかのスタイルを指定する

http://www.proton.jp/main/apps/gnuplotadjust.html


# 凡例を非表示にする

```gnuplot
unset key
```


# PNGで出力する

```gnuplot
set terminal pngcairo size 2560,1800
set output './plot.png'
```


# 下付き文字などを無効にする

terminalの設定に`noenhanced`をつけると下付き文字などを表示する拡張テキストモードが無効化される。

例:

```gnuplot
set terminal svg size 640,480 font 'Verdana,10' noenhanced
```

http://blog.prhyzmica.com/?p=178


# 点でなく線で描画する

`with lines`をつけると線で描画してくれる。

```gnuplot
plot 'data.txt' using 1:2 title 'data 1' with lines
```

# xticsで時間軸を設定する

http://shuzo-kino.hateblo.jp/entry/2014/01/07/231418
AngularでbodyタグにCSSを当てる方法

#Angularにはbodyタグが使えない？
前につくったホームページをAngularで再構築してみようということで、
とりあえず、練習としてtopページのhtmlをapp.component.tsのtemplateにそのまま貼ってみた。CSSもstyleに指定して、いざ、表示！

あれ、なんか、スタイルがおかしい？
開発者ツールで見てみると、bodyタグのなかに、htmlタグが入れ子になっていることを確認できた。

#CSSを当てる方法
結論として、app.component.tsには、body以下のタグを書くこと！
html,head,bodyタグについては、src配下のindex.htmlに書くこと！
bodyタグのcssはindex.htmlに書くこと！

```index.html
<!DOCTYPE html>
<html lang="ja">
  <head>
    <meta charset="utf-8" />
    <title></title>
    <base href="/" />

    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <link rel="icon" type="image/x-icon" href="favicon.ico" />
    <link href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" rel="stylesheet">
    <link href="~@angular/material/prebuilt-themes/indigo-pink.css"/>
    <link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
    <style type="text/css">
      /* リセットCSS */
      * {
        margin: 0;
        padding: 0;
        box-sizing: border-box;
      }

      /* body */
      body {
        background: #ffffff;
        color: #5e5e5e;
        font: 400 87.5%/1.5em "Open Sans", sans-serif;
      }
    </style>
      <link href="https://fonts.googleapis.com/css?family=Roboto:300,400,500" rel="stylesheet">
</head>
  <body>
    <app-root></app-root>
  </body>
</html>

```
特定のユーザからのアクセスをブロックする（Django）

# はじめに
特定のユーザにアクセスを許可したくない場合があるかと思います。
対象のIPアドレスからアクセスがあった場合は侵入不可にするように設定します。

# DB作成

```python:model.py
class BlackIp(models.Model):
    ip_address = models.CharField(max_length=16)
    reason = models.CharField(max_length=1000)
```

# admin画面で表示されるようにする。
ReadDateTimeは管理画面で時刻を表示するため。

```python:admin.py
from .models import BlackIp

class ReadDateTime(admin.ModelAdmin):
    readonly_fields = ('created', 'updated')
admin.site.register(BlackIp, ReadDateTime)
```

# Viewにブロックするための関数を記述
DBへ毎回アクセスすると、速度面で遅くなる懸念があります。
そこで、`cache`を入れることにより、毎回のデータ読み込みを防ぎます。

```python:views.py
from .models import BlackIp
from django.core.exceptions import PermissionDenied
from django.core.cache import cache

    def is_black_ip(self, ip):
        # cacheからIPを抜き出す。
        black_ips = cache.get('black_ip_objs')

        # cacheにない場合、DBから情報を抜き取り格納する。
        if black_ips is None:
            black_ips = list(BlackIp.objects.all())
            cache.set('black_ip_objs', black_ips, 3600)

        black_ip_addresses = [black_ip.ip_address for black_ip in black_ips]
        return ip in black_ip_addresses

    def create(self, request, *args, **kwargs):
        ip = request.META.get('REMOTE_ADDR')
        # アクセスしてきたIPとDBに格納したIPを比較する。
        if self.is_black_ip(ip):
            raise PermissionDenied
SDKMAN!でAmazon Corretto JDKを入れる


[SDKMAN!のインストールページはこちら](https://sdkman.io/install)

```bash

# Amazon Corretto
sdk i java 8.0.202-amzn

# ついでに、Azul SystemsのOpenJDKの場合
sdk i java 8.0.201-zulu

# 確認
sdk list java
================================================================================
Available Java Versions
================================================================================
     13.ea.02-open       1.0.0-rc-11-grl                                        
     12.ea.26-open       1.0.0-rc-10-grl                                        
     11.0.2-zulu         1.0.0-rc-9-grl                                         
     11.0.2-open         1.0.0-rc-8-grl                                         
     11.0.1-zulufx                                                              
     10.0.2-zulu                                                                
     10.0.2-open                                                                
     9.0.7-zulu                                                                 
     9.0.4-open                                                                 
     8.0.202-amzn                                                               
 > * 8.0.201-zulu                                                               
     8.0.201-oracle                                                             
     8.0.192-zulufx                                                             
     7.0.201-zulu                                                               
     6.0.119-zulu                                                               

================================================================================
+ - local version
* - installed
> - currently in use
================================================================================

# どこに入っているのか？
# which javaとやるとシンボリックリンクが出てくる。フォルダを切り替えているだけっぽい。
# 設定した実体への↓シンボリックリンク
# /home/daijin/.sdkman/candidates/java/current

```

IntelliJ IDEAとかだと、プロジェクトごとにSDKの指定がありますが、SDKMANを使ってシンボリックリンクを指定すれば、アップデートごとに再設定する必要が無くなり便利です＾＾
Seeed Studio の Seeeduino（Arduino互換ボード）でLチカする

#Seeeduino V4.2 の購入

1,026円でした。（2018年9月時点）
個人的にはノーブランドより安心で、Groveコネクタ付きなのでSeeeduinoを選択しました。
（GroveコネクタはI2Cコネクタ×2、UART×1です）
ちなみに本家の Arduino Uno R3 は 3,240 円でした。 

スイッチサイエンス - Seeeduino v4.2
https://www.switch-science.com/catalog/2651/

スイッチサイエンス - Arduino Uno R3
https://www.switch-science.com/catalog/789/

Seeed WiKi Seeeduino v4.2
http://wiki.seeedstudio.com/Seeeduino_v4.2/

#Arduino IDE のインストール

Microsoft Store で Arduino IDE を検索し「入手」をクリックします。

Arduino IDEを設定する

Arduino IDEにシードボードを追加する方法
http://wiki.seeedstudio.com/Seeed_Arduino_Boards/

[ファイル] - [環境設定]を開く
「追加のボードマネージャのURL」へ以下のURLを追加する

```
https://raw.githubusercontent.com/Seeed-Studio/Seeed_Platform/master/package_seeeduino_boards_index.json
```

[ツール] - [ボード] - [ボードマネージャ] を開く
「Seeeduino AVR by Seeed Studio」をインストールする
![キャプチャ.PNG](https://qiita-image-store.s3.amazonaws.com/0/240467/e2ee7b9a-78ef-b906-cb29-9ff10929f445.png)

[ツール] - [ボード] - [Seeeduino V4(Atmega328P)] を選択

#Lチカさせる

[ファイル] - [スケッチ例] - [01.Basic] - [Blink] を選択

Seeeduino をPCへ接続する

[スケッチ] - [マイコンボードへ書き込み] を選択する

Seeeduino を接続したシリアルポートを選択する

青色LEDが点滅する
Objective-Cでカテゴリーを実装する際に hogehoge.ex.foo() のようにプロパティを噛ましたい

# はじめに

こちらは先日投稿した [SwiftでExtensionを実装する際に hogehoge.ex.foo() のようにプロパティを噛ましたい - Qiita](https://qiita.com/mitsuharu_e/items/da6bcdeb177dec0587ac) の Objective-C 版になります．

Objective-Cを使ってる（た）人なら，タイトルは ```[[hogehoge ex] foo]``` や ```[hogehoge.ex foo]``` なのでは？だと誤りと思いますが，最近Objective-Cを使うならメインをSwiftにしてだろうと思って，このようにしてます．Objective-Cだけを使う人は置き換えて見て下さい．


# カテゴリーを作る

UITableViewにカテゴリーを生やす例で紹介します．以下のクラス名などは任意で適当に付けています．

## カテゴリー用の変数を作る

まずカテゴリー用のクラス ```MyExtension``` を作成します．このクラスから生成した変数から，カテゴリーを作りたいインスタンスにアクセスします．

```Objective-C:MyExtension.h
@interface MyExtension : NSObject
@end
```

```Objective-C:MyExtension.m
@interface MyExtension ()

@property (nonatomic, weak) UITableView *tableView;
- (instancetype)initWithTableView:(UITableView *)tableview;

@end

@implementation MyExtension

- (instancetype)initWithTableView:(UITableView *)tableview{
    self = [super init];
    if (self) {
        self.tableView = tableview;
    }
    return self;
}
@end
```

## カテゴリー用の変数を生やす

作成したカテゴリー用のクラスを，カテゴリーを作成したいクラスに適用します．associate機能を使って，カテゴリーで変数を追加します．

```Objective-C:UITableView+.h
@interface UITableView (extension)

@property (nonatomic, retain) MyExtension* ex;

@end 
```

```Objective-C:UITableView+.m
#import <objc/runtime.h>
static void *MyExtensionKey = &MyExtensionKey;

@implementation UITableView (extension)

- (MyExtension*)ex{
    MyExtension *temp = objc_getAssociatedObject(self, MyExtensionKey);
    if (temp == nil){
        temp = [[TableViewExtension alloc] initWithTableView:self];
        [self setEx:temp];
    }
    return temp;
}

- (void)setEx:(MyExtension *)ex{
    objc_setAssociatedObject(self,
                             MyExtensionKey,
                             ex,
                             OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}

@end
```

## カテゴリーのメソッドを追加する

最初に作成した ```MyExtension``` にメソッドを追加しています．

```Objective-C:MyExtension.h
@interface MyExtension : NSObject

- (void)foo;

@end
```

```Objective-C:MyExtension.m
@implementation MyExtension

- (void)foo{
   UITableView *tableView = self.tableView;
   // 処理
}
@end
```

# まとめ

今更 Objective-C で新規開発する場面は少なくなったと思いますが，これで Objective-C でもカテゴリーで追加するメソッドを変数を噛ませて使用できます（あまり使用シーンはないと思いますが）．私は最近SwiftからObjective-Cの機能を使いたくて作ってみました（ [こちら](https://github.com/mitsuharu/MEOException) ）．この記事は実際のソースではどうなっているか気になる方はどうぞ．
etypingでDvorakJPを使う

#はじめに
![540px-KB_United_States_Dvorak.svg.png](https://qiita-image-store.s3.amazonaws.com/0/254147/a0c295ad-465f-2d1a-23a6-c2eb0ce68fd9.png)
（wikipediaの画像より）

Dvorakjpはdvorak配列を日本語向けに拡張したものです(下の記事が詳しい)
https://alpha.mixi.co.jp/entry/2012/10806/
しかし etyping等のタイピングサイトで使えないという弱点があります

ciを「き」に変換したり 
hnaを「ひゃ」に変換する事がサイト上で出来ないからです

なのでautotkey(キーの入力に対して処理を割り当てられる)を使って 
etypingでDvorakJPを使えるようにしました

#実装と説明
やりたいことは

1：か行をcで補う
2: 左下でan on en un inを打てるようにする
3: 左上でai ou eiを打てるようにする
4: yを使うものをhやnで代用する
pha → ぴゃ
rha → りゃ
nha → にゃ
zha → じゃ

gna → ぎゃ
cna → きゃ
hna → ひゃ
tna → ちゃ
bna → びゃ
mna → みゃ

1はcをkに置き換えれば出来て、23もそれらを置き換えれば出来ます
4も直前に打たれたキーによってh,nをyに置き換えれば出来ますが
nhaの時だけ注意が必要です
nnhaの時には「んや」ではなく「んは」と打たれるようにしたいからです
なのでnが2連続である場合にはhをyに置き換えないようにします

nmaeは直前のnが子音として残っていたらtを
なければfを代入しています
A_PriorKeyは直前に打たれたキーです

```
#MaxHotkeysPerInterval 200

#NoEnv  ; Recommended for performance and compatibility with future AutoHotkey releases.
SetWorkingDir %A_ScriptDir%  ; Ensures a consistent starting directory.
SetTitleMatchMode,2
#InstallKeybdHook
#UseHook


nmae = f

n::
	if( A_PriorKey ==  "%" || A_PriorKey == "q" || A_PriorKey == "j" || A_PriorKey == "k"|| A_PriorKey == "x" || nmae = "t")
	{
		nmae = f
		send,{n}
	}
	else if(A_PriorKey == "g" || A_PriorKey == "c"|| A_PriorKey == "h"|| A_PriorKey == "t"|| A_PriorKey == "b"|| A_PriorKey == "m")
	{
		nmae = f
		send,{y}
	}
	else
	{
		nmae = t
		send,{n}
	}
	return
a::
	nmae = f
	send,{a}
	return
o::
	nmae = f
	send,{o}
	return
e::
	nmae = f
	send,{e}
	return
u::
	nmae = f
	send,{u}
	return
i::
	nmae = fh
	send,{i}
	return
	
c::send,{k}
h::
	if(A_PriorKey == "p" || A_PriorKey == "r"|| A_PriorKey == "z")
		send,{y}
	else if(nmae = "t")
		send,{y}
	else
		send,{h}
	return
;::
	send,{a}{n}
	return
q::
	send,{o}{n}
	return
j::
	send,{e}{n}
	return
k::
	send,{u}{n}
	return
x::
	send,{i}{n}
	return
'::
	send,{a}{i}
	return
,::
	send,{o}{u}
	return
.::
	send,{e}{i}
	return

```
パスもクラス名も合ってるのにchromeでcssが反映されない

cssのパス、クラス名等間違えていないのに、chrome（クローム）において
cssの変更が反映されないときがあります。
そういうときは**デベロッパーツール**を開きながら**更新ボタンを右クリック**して
<font color='red'>__キャッシュの消去とハードの再読み込み__</font>を試してみてください
写真で見るとこうです。

<hr>まずページの上で右クリックして検証をクリックして
<img width="1440" alt="スクリーンショット 2019-01-28 20.45.51.png" src="https://qiita-image-store.s3.amazonaws.com/0/344311/ae4642ab-38e5-f51a-0734-d73486b52dc2.png">

<hr>
デベロッパーツールを開き、そのまま
<img width="1440" alt="スクリーンショット 2019-01-28 20.46.04.png" src="https://qiita-image-store.s3.amazonaws.com/0/344311/1fcd1c1d-91f2-2193-f9de-68b2d0db8724.png">

<hr>
読み込みボタンを右クリックするとキャッシュの消去とハードの再読み込みが出てくるのでクリック！
<img width="1440" alt="スクリーンショット 2019-01-28 20.46.18.png" src="https://qiita-image-store.s3.amazonaws.com/0/344311/8f01951b-6874-ede3-2665-26bb29d6eddb.png">
[terraform]俺でもわかるElatiCache Redis Clusterの作成を寺で実現するアレ

俺です。

3shards 9nodesなRedisはコレでOK

see: https://www.terraform.io/docs/providers/aws/r/elasticache_replication_group.html

```
resource "aws_elasticache_replication_group" "sample" {

..省略..

    cluster_mode {
        replicas_per_node_group = 2 # ←ココいじるとdestroy -> create
        num_node_groups         = 3 # ←ココいじるとonline resync
    }
}
```
Rspecでcsvアップロード機能のテストをする

# 背景

rspecでcsvファイルアップロード機能をテストすることがあった
絶対忘れるから残しておく

# やったこと

## CSVアップロード機能（controller）

こんな感じのcsvアップロード機能をテストしたい
``params[:csv_file]``は画面のフォームで指定したcsvファイル

```ruby:csv_upload_controller.rb
def create
  CSV.foreach(params[:csv_file].path, headers: true, encoding: 'SJIS') do |row|
    # 読み込み処理
  end
  
  respond_to do |format|
    format.html { render :index }
  end
end
```

## テストコード（specファイル）

controllerのspecファイルは以下の通り

```ruby:csv_upload_controller_spec.rb
describe 'POST #create' do
  # spec/fixtures/配下のテスト用csvファイルを指定
  # パスはfixturesからのパスでOK
  let(:csv_file) { 'test.csv' }

  it 'success' do
    post :create, params: {
      # let()で指定した変数を指定
      csv_file: fixture_file_upload(csv_file, 'text/csv')
    }
    # 今回はとりあえずレスポンスが正常だけ確認
    expect(response).to be_successful
  end
end
```

1. テスト用のcsvファイルを``spec/fixtures/``配下に格納する
2. ``let(:csv_file) { 'test.csv' }``でcsvファイルを指定する（ディレクトリを作成した場合は``{ 'user/test.csv' }``のようにfixturesからのパスを記載する）
3. paramsで``fixture_file_upload(csv_file, 'text/csv')``と書くことで指定したcsvファイルをパラメータに設定することができる

## 気をつけること

個人的な内容ですが・・・

* ファイル名はテスト内容がわかるようにする
* 無駄なファイルを大量生産しない（整理整頓）
* エラーパターンのファイルも作る
* 用途が異なる場合（controllerが異なるとか）の場合はディレクトリを作成して分類分けする

# 最後に

ファイルアップロード機能ってよくあるし、すごーく初歩的なことですが、結構覚えてないもんです
「テストファイル作るのかよ。めんどくさい！」と思わず、簡単に作れるよう工夫しましょー！