OmniAICreator/Qiita-1.07M huggingface dataset:
日本語等幅フォントをコンソール端末用に最適化させるフォント Illusion を作りました

コンソール端末と JIS X 0208 をこよなく愛する前世紀生まれのオールドタイプのための、日本語等幅フォントを Unicode の East Asian Width に対応させる補助フォント「**Illusion**」を作りました。

* リポジトリは [https://github.com/tomonic-x/Illusion](https://github.com/tomonic-x/Illusion) です。
* ダウンロードは [releases](https://github.com/tomonic-x/Illusion/releases) からどうぞ。

# 解消したい問題

* 通常の Unicode 環境で半角扱いの Ambiguous や Neutral が全角で、被ったりズレたりする。
* Unicode の罫線素片やブロック要素が不足したり、縦の罫線が行間で切れたりする。

CJK 用の文字幅などで Ambiguous を全角扱いにすると、Text User Interface なコマンドやアプリとの相性が悪くなります。出来るなら、普段の日本語等幅フォントを使いながら、場面によって半角と全角どちらも使い分けたい。そして罫線を補って、日本語混じりのコーディング環境をより快適にしたい！

そうした欲求と衝動で生まれたフォントです。


# 特徴

* 主な英数文字は Roboto Mono をベースに半角幅に調整。
* Unicode の East Asian Width の扱いに応じたバリエーションを実装。
* 通常の日本語等幅フォントとの併用を想定。
* アスキーコード、JIS X 0208 の Ambiguous な記号類、コンソール端末用の 罫線素片とブロック要素を収録。

![Illusion screenshot](https://github.com/tomonic-x/Illusion/raw/master/img/screenshot.png)

スクリーンショットは MacType のヒンティング無しで描画したものです。

罫線素片とブロック要素は、敢えて微妙な角丸と立体交差的に装飾しています。

## 好みの日本語フォントとの組み合わせ

好みの日本語等幅フォントと組み合わせて使えるよう、 日本語の平仮名・片仮名・漢字は含めていません。

ブラウザの CSS の `font-family` や、Windows のレジストリの `FontLink` など、フォールバックの仕組みを活用して、合成フォントなしに組み合わせられます。

## 三種類のバリエーション

| 曖昧 | 中立 | Font Family          | 主な使い分け                       |
|:----:|:----:|:---------------------|:-----------------------------------|
| 半角 | 半角 | Illusion N (Narrow)  | 国際的なコンソール環境との互換重視 |
| 全角 | 半角 | Illusion W (Wide)    | Shift_JIS や EUC-JP との互換重視   |
| 全角 | 全角 | Illusion Z (Zenkaku) | 多くの日本語等幅フォントと同様の幅 |

詳細については [リポジトリの README.md](https://github.com/tomonic-x/Illusion) をご覧ください。

以下、各サンプルのスクリーンショットです。

### Illusion N (Narrow)

![Illusion N with Yu Gothic](https://github.com/tomonic-x/Illusion/raw/master/img/screenshot-n.png)

### Illusion W (Wide)

![Illusion W with Meiryo](https://github.com/tomonic-x/Illusion/raw/master/img/screenshot-w.png)

### Illusion Z (Zenkaku)

![Illusion Z with BIZ UDGothic](https://github.com/tomonic-x/Illusion/raw/master/img/screenshot-z.png)

# README に書いていないこと

紹介だけでは Qiita っぽくないので、一つ技術的な背景を書きます。

## TTC (TrueType Collection) 形式ということ

三種類のバリエーションに標準・斜体・太字・太字斜体を組み合わせると 12個の .ttf ファイルになるのを共通化させて、ウェイト違いの2個の .ttc にまとめました。

各フォントで共有の glyf テーブルにするために、FontForge では一旦仮に Unicode の私用領域にマップして、ビルド処理でバリエーションに応じた cmap テーブルの .ttf を中間生成して .ttc にしています。

グリフ名で管理する方法では、AGL (Adobe Glyph List) と Unicode の対応や、グリフ名と .ttc 内の各フォントでの Unicode との対応で、混乱したり煩雑だっりしていたので、仮にマップした Unicode で管理しています。

このおかげで、ビルド処理用のスクリプトもシンプルになりました。

- - -
 
tmux や vim で左右に画面分割したら悲惨な目に遭うとか、pstree がきちんと描画されないとか、でも Ambiguous が全角の方が良いときもあるよ！　……とか。コンソール端末と JIS X 0208 の間の課題を、幾らか吸収することが出来れば幸いです。

ご意見・ご感想などありましたら、お手柔らかにお願いします。
Windows Subsystem for Linux (WSL)でROS

# はじめに
Windows Subsystem for Linux (WSL)のUbuntu18.04にROS melodic入れてみた。
いろいろトラップあったのでメモ。
2019/06/01現在で、うまくいった方法が書かれてた場所を示す。

# 環境
Windows10
proxy
WSL
Ubuntu18.04
Xming

# インストール時の参照先とコメント
[Installation/Ubuntu - ROS Wiki](http://wiki.ros.org/Installation/Ubuntu)
基本的には、ここを参照。
desktop-fulを入れてみる。

[WSLのUbuntu 18.04にROSをインストールする - Symfoware](https://symfoware.blog.fc2.com/blog-entry-2311.html)
上記方法だと、WSLだとエラーがでる部分あるので、ここを参照。
パッケージ管理の仕組みがわかっていないと理解できなさそうな解決策。

[VirtualBoxでROSを動かしてみる - Qiita](https://qiita.com/oh_rusty_nail/items/b19f474b0d88eecddc1e)
proxy経由だとエラーがでるので、ここを参照。
`sudo -E rosdep init`
この`-E`が重要。sudoに環境変数を渡してんのかな。

[WSL(Windows Subsystem for Linux)でROSを動かす - naonaorange's blog](https://naonaorange.hatenablog.com/entry/2018/11/05/200715)
Xいれるのは、ここを参照。
Xもよくわからん。WSLでうまいことやってくれてるとうれしけど、そういうもんでもないんかな。

[Bash on Ubuntu on Windows + XmingによるGUI - Qiita](https://qiita.com/makky0620/items/e31edc90f22340d791ff)
Xいれるのは、ここも参照。
`sudo apt-get install x11-apps`の最後のs大事。

# 動作確認時の参照先とコメント
[WSL(Windows Subsystem for Linux)でROSを動かす - naonaorange's blog](https://naonaorange.hatenablog.com/entry/2018/11/05/200715)
turtlesimとrvizを動かしてみた。良い感じ。

# おわりに
最終的に良い感じに入れられた。よかった。
Windowsでできるって、それなりにおどろき。
PythonでHTTPを操作する : requests

# はじめに
本記事では、requestsライブラリを使用してHTTPを処理します。

# 実装
```Python:example.py
import requests

url = 'http://www.webscrapingfordatascience.com/basichttp/'
r = requests.get(url)
print(r.text)
```

- 最初にrequestsモジュールをインポートする。
- 続いて、http://www.webscrapingfordatascience.com/basichttp/ のコンテンツの取得に取りかかる。このWebページにアクセスしてみると「Hello from the web!」という文字列がページに表示される。この文字列を、Pythonを使って抽出したい。
- この例では、```requests.get```メソッドを使用して、urlに対する「HTTP GET」リクエストを実行している。
- ```requests.get```メソッドは、requests.ResponseというPythonオブジェクトを返す。このオブジェクトには、取得したHTTPレスポンスに関する多くの情報が格納されている。
- r.textにはHTTPレスポンスのコンテンツ本体がテキスト形式で格納される。

# 結果
```
Hello from the web!
```
何も問題がなければ、以下の行が表示されます。
Amazon Lightsail へ移行してみた (MySQL観点)

#導入
　去年Webページ構築用にAWSで作った無料アカウント期間が終わるので、どうしようか考えた結果、そのままEC2インスタンスを残すのではなく、月額3.5ドルから160ドルまで選べる[Lightsail](https://aws.amazon.com/jp/lightsail/)へ引っ越すことにしました。[マンガ](https://aws.amazon.com/jp/campaigns/manga/vol1-3/)に描かれている通り、確かに速い！

###以下はインスタンス作成画面の抜粋
　移行前から *LAMP(PHP 7)* を利用していたので、こちらを選択しインスタンスを作成。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/428575/b7254329-3376-8fa3-c683-b6003b427817.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/428575/e8b53c33-5a63-0212-7e2f-5041010260c7.png)

#LightsailにおけるMySQL
　MySQLもすぐさま使える状況になっています。とりあえず、元環境から**mysqldump**を使ってDBレベルで情報を引っこ抜き、Lightsail環境へ突っ込んでみます。ちなみに、元環境のバージョンは *5.6.43*、Lightsail環境は *5.7.25* でした。（Lightsail環境のLinux/Unix OSは *Ubuntu 16.04.6 LTS* でした。）

　Webページの挙動は概ね問題無し。ただ、１点気になることがあり、
　どうも、表の名前の大文字小文字が無視される様になっています。

[MySQL 5.7 Reference Manual - 9.2.2 Identifier Case Sensitivity](https://dev.mysql.com/doc/refman/5.7/en/identifier-case-sensitivity.html)
> On Unix, the default value of lower_case_table_names is 0.
> On Windows, the default value is 1. On macOS, the default value is 2. 

にもかかわらず、実際は以下の通りでした。

```ruby:mysql
mysql> show variables where variable_name='lower_case_table_names';
+------------------------+-------+
| Variable_name          | Value |
+------------------------+-------+
| lower_case_table_names | 1     |
+------------------------+-------+
1 row in set (0.02 sec)
```

不思議に思いながら、設定変更してMySQLを再起動しようとしたところで、ハタと気づきます。
**/etc/init.d** に mysqld が居ないぞ？

更に、普段通りDBへ xmlファイルをロードしようとした際に以下のエラーが出力され、

> ERROR 1290 (HY000) at line 1: The MySQL server is running with the --secure-file-priv option so it cannot execute this statement

LOAD XML INFILE構文の"INFILE"の手前に"LOCAL"を差し込むと解決したところで、
こう考える様になりました。さてはお前クライアントだな？

おそらく、Lightsail用に汎用MySQLサーバーが別にあるのでしょう。
だから lower_case_table_names も 1 にしているんだろーなー、と納得するようにしました。
Python氏によるデータのビジュアライズ 

#ずっと避けてきたmatplotlibを勉強する
何故か、面倒だという理由から避けてきましたが、オライリーの本を買ったので、これを機に勉強する。

今回買った本はこちら、「Python for Data Analysis 2nd Edition」
この本の第9章を眺めていこうと思います。

本書では、十分なスペースがないとのことですが、使いこなしていくための下地を作来るのが目的とのこと。

データ分析という意味合いが強いですが、普段の業務にも多岐に渡って活躍してくれると信じています。

#matplotlib
Pythonには組み込みのビジュアライゼーションライブラリがあるらしい（使ったことないです）今回は、本に沿って、matplotlibを使っていきます。

環境は　CentOS7 Jupyter-notebookにて

# 1. 最も単純なパターン

描写される部分が　plot とよばれるらしいです。

```python

import numpy as np
import pandas as ps
import matplotlib.pyplot as plt
%matplotlib inline

data = np.arange(10)
data

plt.plot(data)

```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/128504/4c3344b9-9671-209e-d283-891a296abdf5.png)

うーん。なんか動いたけどよくわからないなぁ。
一次元のデータなのに2次元で表示された。

y=x　の１次関数ぽい

# 2. sub plot
plot は Figureオブジェクトの中に含まれているとのこと。そのため

ax1 = fig.add_subplot(2, 2, 1)
とすることでplotに図を追加することができる。
2*2の場所を作成して、その1つめということとのこと。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/128504/dc656b73-2ae4-dc7c-1362-f2b823a82ea4.png)

```
fig = plt.figure()
ax1 = fig.add_subplot(2, 2, 1)
ax2 = fig.add_subplot(2, 2, 2)
ax3 = fig.add_subplot(2, 2, 3)
ax4 = fig.add_subplot(2, 2, 4)
ax3.plot(np.random.randn(50).cumsum(), 'k--')
ax1.hist(np.random.randn(100), bins=20, color='k', alpha=0.3, 'ko--')
```

cusumはcumulative sumなので累積。
最後のk--はスタイルオプションと言って、描画のオプションを決める事ができる。

k--は黒色の破線。 --の部分が破線*-というように線のスタイルを決めることができる。
細かいオプションは、公式サイトを見てねという感じだった。

ko--は黒で、データのポイントを●で表示して、破線。

https://matplotlib.org/api/_as_gen/matplotlib.pyplot.hist.html?highlight=hist#matplotlib.pyplot.hist

ヒストグラムのbinsはどれだけ、標本を分割するかという値。

# ラベリング
今までだと、ラベルや、メモリは自動生成だった。
ある程度データがみえてきたらラベリングしたほうが見やすい。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/128504/e846d14a-5177-28c8-dac4-a40df97220f3.png)

```python
fig = plt.figure()
ax = fig.add_subplot(1, 1, 1)
ax.plot(np.random.randn(1000).cumsum(),label='one',)
ax.set_xticks([0, 250, 500, 750, 1000])
ax.set_xticklabels(['one', 'two', 'three', 'four', 'five'],rotation=30, fontsize='small')
ax.set_xlabel('Stages')
ax.legend(loc='best')
```

ticksってこと目盛りなので、そのメモリをｘ軸に対して設定して、そのラベルが１から５というように設定できる。
rotationはラベルをどれだけ傾けるかということとのこと。

legend　伝説的な凡例を入れるにはこれを使う。

昔Excelでやってたなー。。こんなこと。

#と思ったら

pandas氏にはもうそんな機能が備わっていた。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/128504/6655fe41-38d1-21fe-072b-851bb2d39dda.png)


```python
df = pd.DataFrame(np.random.randn(10, 4).cumsum(0),
columns=['A', 'B', 'C', 'D'],
index=np.arange(0, 100, 10))

df.plot()
```

ぐぬぬ。

#ひとまず
本は最後に、ネットでググって良いリソースをもとにいっぱい勉強してね！って書いてありました。

道は長そうです。
中国で利用できないアプリ・Webサービス等【2019年5月】

2019年5月に上海に行ったのですが、その時に仕事（iOSアプリ開発）で利用しているアプリやWebサービス、Webサイトがいくつか使えなかったので報告します。ネット環境は現地のISPを利用しました。

## アクセスできなかったサービス：

- Google関連サービス（e.g., Firebase, Crashlytics/Fabric, Google Data Studio, Big Query, YouTubeなど）
- Twitter 
- Facebook / Messanger / Instagram
- Dropbox
- Discord 
- LINE 
- Yahoo Japan検索（サーチエンジンがGoogleのため）
- Wikipedia
- Vimeo
- Nikkei.com

## アクセスできたサービス：

- Apple関連サービス（e.g., App Store, App Store Connect, iCloud, Messages, FaceTimeなど）
- Microsoft関連サービス（e.g., Bing, Skype, GitHub, など）
- Slack 
- StackOverflow
- Qiita
- Asana
- Zeplin
- Everhour
- Esa
- HelpShift
- Yahoo Japan（検索以外）
- SmartNews
- note.mu

かなり役立ったのがBing検索で、翻訳などもこれでできました。ただcn.bing.comへのアクセスはhttp経由となり、ブラウザには「not secure」と表示されていました。

またSlackやGitHub、StackOverflowやQiitaなどは問題なく使えたので、これは大きかったです。その他にもAsanaやZeplinなどのコラボレーションツールも使えたので助かりました。

一番困ったのはFirebaseが使えない事ですが、これだけは中国とGoogleの仲を考えるとどうしようもないです。ちなみにFirebaseを組み込んでいるアプリでも起動することはできます。Firebaseからデータを取得したり送信したりはできないのですが、それ以外の部分の開発はできました。
GitLab CI を使って GitHub の Private Repository を無料で CI する

題記の手順をチュートリアル形式にした記事を書きました。詳細は、リンク先のブログをご参照下さい。

※ 小生が扱うことのある ROS を扱っている場合でも、重宝します。

![GitLab CI 構成図](https://cdn-ak.f.st-hatena.com/images/fotolife/M/MoriKen254/20190601/20190601154613.png)

### 目次
- [① 背景編](http://www.moriken254.com/entry/2019/06/01/161006)
- [② ミラーリング編](http://www.moriken254.com/entry/2019/06/01/172507)
- [③ SSH 編](http://www.moriken254.com/entry/2019/06/01/223717)

### 概要
#### [① 背景編](http://www.moriken254.com/entry/2019/06/01/161006)　→　詳細は「[こちらのリンク](http://www.moriken254.com/entry/2019/06/01/161006)」
  - 無料版 Travis CI では GitHub の Private Repository を CI できないから、GitLab CI 使おう、と思った、という背景のお話。
  - ![Travis CI 無料では Private Repository CI 不可](https://cdn-ak.f.st-hatena.com/images/fotolife/M/MoriKen254/20190601/20190601154043.png)
  - 詳細なチュートリアルについては右のリンクを参照下さい。　→　[① 背景編](http://www.moriken254.com/entry/2019/06/01/161006)

#### [② ミラーリング編](http://www.moriken254.com/entry/2019/06/01/172507)　→　詳細は「[こちらのリンク](http://www.moriken254.com/entry/2019/06/01/172507)」
 - GitHub の Private Repository を一旦 GitLab CI にミラーリングしないといけないので、その設定周りのお話。
 - ![ミラーリング](https://cdn-ak.f.st-hatena.com/images/fotolife/M/MoriKen254/20190601/20190601164118.png)
 - ![ミラーリング設定](https://cdn-ak.f.st-hatena.com/images/fotolife/M/MoriKen254/20190601/20190601164835.png)
 - 詳細なチュートリアルについては右のリンクを参照下さい。　→　[② ミラーリング編](http://www.moriken254.com/entry/2019/06/01/172507)


#### [③ SSH 編](http://www.moriken254.com/entry/2019/06/01/223717)　→　詳細は「[こちらのリンク](http://www.moriken254.com/entry/2019/06/01/223717)」
  - Private Repository を CI するとき、依存する Repository も Private だったりすることってよくあるよね。そうなると素の設定じゃクローンできないよね？だから SSH の設定必要だよね？というところから、その設定周りをしていくお話。
  - ![SSH overview](https://cdn-ak.f.st-hatena.com/images/fotolife/M/MoriKen254/20190601/20190601225508.png)
  - ![SSH setting](https://cdn-ak.f.st-hatena.com/images/fotolife/M/MoriKen254/20190601/20190601212246.png)
  - 詳細なチュートリアルについては右のリンクを参照下さい。　→　[③ SSH 編](http://www.moriken254.com/entry/2019/06/01/223717)
matplotlib 3次元極座標系での曲面グラフ

3次元極座標系での曲面$r = r(\theta, \phi)$をプロットする。ここでは球面調和関数をプロットしてみた。

```python
import numpy as np
from mpl_toolkits.mplot3d import Axes3D
import matplotlib.pyplot as plt

_phi = np.linspace(0, 2*np.pi, 100)
_theta = np.linspace(0, np.pi, 100)
phi, theta = np.meshgrid(_phi, _theta)

r = np.abs((5*np.cos(theta)**2 - 1)*np.sin(theta)*np.cos(phi)) 
x = r*np.cos(phi)*np.sin(theta)
y = r*np.sin(phi)*np.sin(theta)
z = r*np.cos(theta)

fig = plt.figure()
ax = fig.add_subplot(111,projection="3d")
ax.plot_surface(x, y, z)

plt.show()
```

![figure.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/271560/331adebb-26dc-e888-d6a8-ff2713c8fe35.png)
Windows VScode で使うターミナル（シェル）をWSLのbashに設定する。

# windows VScode で使うターミナル（シェル）の設定

すこし分かりにくかった。
以下、手順を示す。

- VScode を開く
- File -> Preferences -> Settings
- `integrated terminal` で検索
- `Terminal>Integrated>Env:Windows` を探す
- `Edit in settings.json` をクリック
- wsl の bashを使う場合は、以下のように設定する

```json:settings.json
{
    "workbench.colorTheme": "Monokai",
    "terminal.integrated.shell.windows": "C:\\Windows\\System32\\wsl.exe"
}
```
angular-twitter-client

#はじめに
　angularはtwitterのクライアントをサクサク作れるんだろうなと思って、gitを探したが、なかなかない。
　ようやく動いた１つのgitと、気にくわない所のいろいろ

#動いたgit
 [twitter-angular-client](https://github.com/sitepoint-editors/twitter-angular-client)が動いたのだが、ちょっと違うなあという感じである。
　
　まるで、readmeに書かれていないのだが、まず。今ではangular v7になっているので、次の手順が必要
 [あとで調べたら[ここ](https://www.sitepoint.com/building-twitter-app-using-angular/)に書いてあった]

```
 git clone https://github.com/sitepoint-editors/twitter-angular-client
 cd twitter-angular-client
 npm install
 ng update
```
 まあ、もちろん、nodeも@angular/cliはインストールしてある前提ですけどね。

#動かすまで
　普通は、これで[ng s -o]で動くと思うが、動かない。そうそう、問題はOauthですよ、そこがどうなっているかが問題なのですが。
　server.jsというのがある。これがくせ者である。
　ここに、

```
const client = new Twitter({
  consumer_key: 'CONSUMER_KEY',
  consumer_secret: 'CONSUMER_SECRET',
  access_token: 'ACCESS_TOKEN',
  access_token_secret: 'ACCESS_TOKEN_SECRET'
});
```
 というOauthの定義があって、これに自分のconsumer_key等を４つ設定して
`node server.js`
で動かしてから、ng sでhttp://localhost:4200で見ると、おー！homelineがでとる！
ということになった。

#気に入らない所
　まあ、これで作り続けるというのは、ちょっと変だなあ・・ということでtwitter-node-clientとかを、angularに入れられないかなあ・・とか考えているのだが、なかなかうまくいかない。
　angular.jsonのscripts[]に追加すれば、javascriptをangularのコンポーネントから呼び出せるのだが、twitter-node-clientがrequireを連発していて、なんだか動かない。

　まあ、このデザインもいまいちなので、なんかうまくいったらまた、
[simple-twitter](https://github.com/hideume/simple-twc)みたいに公開したいなあと思っている。
Cannot find module './algs' などモジュールが見つからないエラー

これまでWindowsローカルで動いていたファイルをAWSCloud9に移行したら動かなくなった。
エラーは以下の表示。

```
module.js:457
throw err;
^

Error: Cannot find module './algs'
    at Function.Module._resolveFilename (module.js:455:15)
    at Function.Module._load (module.js:403:25)
    at Module.require (module.js:483:17)
    at require (internal/module.js:20:19)
    at Object.<anonymous> (C:<file path>\node_modules\sshpk\lib\key.js:6:12)
    at Module._compile (module.js:556:32)
    at Object.Module._extensions..js (module.js:565:10)
    at Module.load (module.js:473:32)
    at tryModuleLoad (module.js:432:12)
    at Function.Module._load (module.js:424:3)
```

`./algs`なんて使ってないし、なんじゃこりゃ。。。
って思ってたら非常に単純で、
`at Object.<anonymous> (C:<file path>\node_modules\sshpk\lib\key.js:6:12)`
ここが味噌でした。

```
npm install sshpk
```
で無事解決。読解力の問題ですね。。。
footerの位置をページの最下部に固定する【学習メモ】

自分専用の勉強メモです。
編集中

##内容
HTML、CSSでページを作成する際、メインのコンテンツが少ない場合footer部分が上の方にきてしまう。それを防ぐためにjs(今回はjQuery)でfooterを固定させてみる。

*window.innerHeight*で画面全体の高さを取得し、*$ftr.offset().top*はfooterまでの高さ、*$ftr.outerHeight()*でfooter自身の高さを取得する。
もし、*$ftr.offset().top*と*$ftr.outerHeight()*の合計よりもwindow.innerHeight(画面全体の高さ)の方が大きい場合は、styleでwindow.innerHeightから$ftr.outerHeightを引いた高さ分を付け加えることによりfooterが下に固定される。
##コード
```javascript:footer.js
$(function(){
     var $ftr = $('#footer');
     if( window.innerHeight > $ftr.offset().top + $ftr.outerHeight() ){
          $ftr.attr({'style': 'position:fixed; top:' + (window.innerHeight - $ftr.outerHeight()) + 'px;' });
     }
```
随時更新
Warning: PATH set to RVM ruby but GEM_HOME and/or GEM_PATH not set, see の解決方法（AWS Cloud9）

AWS Cloud9環境で以下のエラーが出るときの解決方法
同じエラーで2回スタックしたので備忘録的に。。。

```
Warning: PATH set to RVM ruby but GEM_HOME and/or GEM_PATH not set, see:
    https://github.com/rvm/rvm/issues/3212
```

`~/.bashrc`ファイルに以下の行を追加する。

```
export PATH=$PATH':/path/to/add'
export GEM_HOME=$HOME/.gem
export GEM_PATH=$HOME/.gem
```
ターミナルで`vi ~/.bashrc`と打ち込めば編集画面が開くので、
最終行あたりに追加すればいい。

参考
https://unix.stackexchange.com/questions/203376/how-to-set-ruby-gem-home-and-gem-path
[rails]form_forのfile_field使用時のアイコンをAwesomeアイコンに変える

# form_forでfile_field使用時のアイコンの変え方

Railsの勉強を初めて３週間ですが、少しずつアウトプットをしていきたいと思います。

今回はform_forでfile_fieldを使用した時にでてくる、以下のボタンとメッセージをAwesomeアイコンに変更する方法について記載します。
[出てくるボタンとメッセージ]
- 「ファイルを選択」ボタン
- 「選択されていません」メッセージ

　※Awesomeについては、調べたらすぐに出ると思います。
## 結果
[form_for]の記述

```ruby
= form_for(@hoge) do |f|
  = f.text_area :text
  %label.label
    = fa_icon'image'
    = f.file_field :upload_file, class: "hoge"
  = f.submit "send"
```

[css]の記述

```
.label{
  cursor: pointer;
  font-size:1.5em;
 }
.hoge{
  display: none;
} 
```

## 手順

####初期状態
```ruby
 = form_for(@hoge) do |f|
  = f.text_area :text
  = f.file_field :upload_file, class: "hoge"
   # file_fieldを指定すると、ファイルを選択ボタンとメッセージがでてきます。
  = f.submit "send"
```

####[追記1]
file_fieldのクラスにdisplay:noneを記述する。

```
.hoge{
  display: none;
} 
```

出力結果：display:noneと記述すると、ボタンとメッセージが一旦表示されなくなります。

####[追記2]
form_forにコードを追記し、Awesomeアイコンを追加する。

```ruby
 = form_for(@hoge) do |f|
   = f.text_area :text
   = fa_icon'image' # ←を追加。
   = f.file_field :upload_file, class: "hoge"
   = f.submit "send"
```

出力結果：Awesomeアイコンが表示されます。（ボタンとメッセージは消えたまま。）
　　　　 アイコンは出ますが、クリックも何もできない状態です。
　　　　

####[追記3]
form_forにlabelを追記する。
[form_for]

```ruby
 = form_for(@hoge) do |f|
   = f.text_area :text
   %label.label # ←を追加
     = fa_icon'image'
     = f.file_field :upload_file, class: "hoge"
   = f.submit "send"
```

出力結果：見た目は変わりませんが、アイコンをクリックするとファイルが選択できるようになります。

####[追記4]（完了）
labelにcssを追記し、アイコンを装飾する。

```
.label{
  cursor: pointer;
  font-size:1.5em;
}
```

出力結果：アイコンにカーソルを当てるとポインタになり、またアイコンのサイズが大きくなります。クリックするとファイルが選択できるようになります。


以上です！！
sizeof PHP vs C

株式会社オズビジョンのユッコ (@terra_yucco) です。
今日はびっくりしたことを 1 つだけ。

# TL;DR

`sizeof` は `count` のエイリアス

※いや、今日はこの後もそんなに長くない

## PHP の sizeof は配列の要素数

基本的に入社時に見たコードがそれだったのか、自分はずっと `count()` を使っていました。
しかし、ある人のコードで `sizeof()` を見かけ、アレ？となった次第。

- [PHP マニュアル > 関数リファレンス > 変数・データ型関連 > 配列 > 配列 関数 > sizeof](https://www.php.net/manual/ja/function.sizeof.php)

>この関数は次の関数のエイリアスです。 count().

潔すぎて変な声でました。

## C 言語の sizeof は占有メモリの byte 数

前職は C 言語だったのですが、この仕様で結構バグだしたなあと遠い目を。

[2019-06-02] 早速バグだしてました。paiza.IO で実行確認したものに貼り替えておきます。
[2019-06-03] 再度ご指摘を頂いたので [Wandbox](https://wandbox.org/permlink/Zd2MmIelwTNN1Zfa) にて実行確認。

```c
#include <stdio.h>

int main(void) {
    
    char c = 'a';
    printf("%zu\n", sizeof(c)); /* => 1 */

    char str[4];
    str[0] = 'a';
    str[1] = 'b';
    str[2] = 0x00;
    printf("%zu\n", sizeof(str)); /* => 4 */

    char str2[] = "Hello!";
    printf("%zu\n", sizeof(str2)); /* => 7 */
    printf("%zu\n", sizeof(*str2)); /* => 1 */

    int num = 5;
    printf("%zu\n", sizeof(num)); /* => 4 (系依存) */
}
```

## Conclusion

C と PHP は同名同機能の関数も多いのですが、こういうように偶に違いがあってそこで迷います。
違いを理解した上で、それぞれの言語でベストなやり方を見つけていきたいなと感じました。

※久々に C を書いたら文字列を `'` でくくってしまって怒られた…。
PoCとかで使えるモックとなるWebサイトを作る

私自身は一度もWebのフロントエンジニアとしてはアサインがされたことがないのだが、「PoCではこんな感じのものでOKをもらって、こんなイメージのプロダクトを作りたいです」と言うのにモックアップ的なサイトを作ることもある。

## モックのWEBサイトをpythonで作るにはflaskが便利
- モックのレベルなので、MVCとかがわからなくてもなんとかなる
- 本質的にな価値（例えば革新的な機械学習の応用例などを実装、例として示す）
- 可能ならばこのユースケースから使い勝手の要点となる箇所を洗い出す（精度なのか、速度なのか、UI/UXなのか）

## 問題設定

問題を定義してそのソリューション（ソリューションの精度以外の品質はそんなに問わない）を与える。この基本的なフレームワークが基本的なPoCの基礎となり、実際にプロダクションにしたときの具体的なイメージの示唆を与えることを目的とする

### 仮設定：例えば、Togetterで投稿記事の日時順にバズったやつを過去に遡る仕組みがない
- 試しに作ってみよう

### WorkerとPre-fork
- アクセスが来たらプロセスを増やすか、事前にプロセスを立ち上げているかの違い
- 事前にpandasや機械学習の推論ロジックなどCPU使用率が高い処理をやらせようとすると、pre-forkなどしか実質選択肢がない

### gunicorn

- flaskなどをgunicornというものでラップアップするとPre-forkになっていて機械学習や重い処理ｔ相性がよく便利
- APIサーバを作るときの一定のベストプラクティスになっている 
- APIサーバとしては単独で提供することがあるが、普通にWebサーバとしてラップするのにも使える

### バッチでオンメモリの内容を更新する
- 1日3回、togetterの人気を知るためにDBを更新する
- このときオンメモリでごちゃごちゃやっているので（そうでないと早いパフォーマンスがでない）、 gunicornを非同期に1日に3回再起動する


### 実際にできたもの

<img width="895" alt="スクリーンショット 2019-06-01 21.51.49.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/87692/5f3e73da-d954-6f57-7ffa-28b3fd60c860.png">


[gifアニメ](https://www.dropbox.com/s/b44t1rlwj3v5o3d/image_preview.gif?raw=1)


### できることと、ユースケースのシェア

- 日付、月、週の粒度で過去の投稿日時順に一年以上、遡れる
- タグを選択するとそのキーワードで人気だった指定された粒度でのTOP10のコンテンツを返す
- (たとえばTwitterアカウントでログインしたら直近のツイートから、相性の良い記事を探すなども原理的にはできる)


### 実際に触れるサイト（運用が面倒なので止めるかも）

http://124.219.129.108/

### ソースコード

https://github.com/GINK03/togetter-backlog


### 起動法
依存が複雑でdebugがしにくいのでwrapperでまとめまくりました

```
$ sudo pip3 install -r requirements.txt
$ sudo python3 Wrapper.py
```

もしくはDockerで固めたものもある（一度停止すると辞書ファイルが消えるのでおすすめしない）

```
$ docker-compose build && docker-compose up
```

### PoCの判断基準
以上のモックアップをもってして、エンドユーザの定性的、定量的な評価を組み合わて、使い物になりそうか、ならなそうかを判断する。
（余談ではあるが、このモックアップは使っていて楽しいので割と良かったのでは）
OpenAI Gymをインストールする時にエラー

#OpenAI Gym インストール
OpenAI Gym のライブラリをインストールする時にエラーが出ましたが，一応解消しましたので共有しておきます．

## 状態
[このqiitaの記事](https://qiita.com/ishizakiiii/items/75bc2176a1e0b65bdd16)通りのインストールを行いました．

##Failed building wheel for atari-py
このエラーが出ました．
とりあえずもう一度cmakeをインストールしてみたら直りました．

参考になれば．
UWP Tips - 試験的にアプリを配布する

#概要
UWPのサンプルアプリを作成する中でつまづいたことを書き留めておく備忘録。
タイトルに書いている通り、作ったUWPアプリをお客さんに試験的に入れてもらうときの話。
というか、これ、いつもアプリを作っては忘れてしまって検索している気がする（笑）。


#準備
1. アプリができたら、プロジェクトメニュー → ストア → アプリパッケージの作成を選択
![AppPackage作成1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/146789/8776c02e-1c27-db4c-2b4e-1fd46b23e286.png)


2. 以下のようなウィザード形式のダイアログが表示されます。ここでは、「サイドロード用のパッケージを作成します」を選択して、「次へ」をクリック
![AppPackage作成2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/146789/a2fdf5ee-291d-b286-6699-5580d70ade46.png)


3. 以下のような画面が表示されるので、適宜入力し、「作成」をクリック
![AppPackage作成3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/146789/a07bc11f-7bb2-6f09-4fc0-37380bce3600.png)

4. 出力ペインに、進行状況が表示されます。
![AppPackage作成3.5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/146789/bdc3bfd1-05b6-784d-6eee-8cca659c4f0c.png)

5. 完了すると、以下のような画面が表示されるので、「閉じる」をクリック
![AppPackage作成4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/146789/cc2f2361-004e-a7aa-f500-c47958dc41f6.png)


6. プロジェクトのフォルダ内にある、AppPackagesフォルダ配下に、アプリパッケージが出来上がっています。
![AppPackage作成5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/146789/f3fac433-ec83-c703-9ae1-d9327fe3be36.png)


7. 上記フォルダ内の「Add-AppDevPackage.ps1」をPower Shellで実行します。スクリプトからの質問に回答して進めていきます。
![AppPackage作成6.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/146789/872b10f3-0c2f-844a-aeaa-118048e8cc5d.png)

8. 証明書のインストール確認が表示されるので、「Y」を入力
![AppPackage作成7.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/146789/9f7419c9-4feb-d75d-fc88-1da5791b8c8e.png)

9. インストールが完了すると、以下のような画面が表示されます。Enterキーを押すとインストールは終了です。
![AppPackage作成8.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/146789/c5fe1bcd-1405-ab3f-639b-13123df6021e.png)

10. スタートメニューを確認すると、インストールされていることがわかります。


#まとめ
端的に言うと、ストアを通さず、試験的にお客さん等にUWPアプリを使ってもらいたいときは、
アプリパッケージを生成・配布し、中のPower Shellスクリプトを実行すればよいということですね。

・・・・・・また忘れるんだろうな・・・そしてこのページを見返そう（笑）。
最近流行りのojichatをslackbotにした

# 最近流行りのojichatをslackbotにした話

最近シェル芸botの猛威によってTLがおじさんだらけになってしまった。:older_man_tone2:
うちのslackにもおじさんで賑やかにしたいな～と思ったので作ってみた。

greymd/ojichat
https://github.com/greymd/ojichat

## 処理の流れ

1. OutGoing WebHooks使って特定の投稿をとる。
2. Slack側から特定のサーバにリクエスト送る。
3. サーバで受け取って名前取り出す！
4. 取り出した名前をIncomingWebHooksで指定されたURLにJSON形式でリクエスト送る!
5. おじさんしゃべる！

## Outgoing WebHooks
指定した文字の投稿があった際に、Slackから外部のサーバにPOST送るやつ。
それぞれの設定項目があるので入れていく。
Channel　　　　　#general
TriggerWord(s)　　ojisan
URL(s)　　　　　　http://X.X.X.X:8080

今回はこれくらいしか設定入れてません。
URL(s)にはリクエストを受け取りたいサーバのipアドレス指定してください。

これでojisanキーワードが投稿されたら上記URLにPOSTされます。

## Incoming WebHooks
外部からSlackにメッセージを送信するやつ。これでおじさんメッセージ送ります
Outgoing WebHooksと同様設定項目を入れていきます
Post to Channel　#general
Customize Name　おじさん

他にもアイコンなども変えることができます。
項目のWebhook URLにあるURLに対してJSON形式でリクエストを送ることで
Slackの指定したチャンネルにメッセージを送ることができます。
  
## 受信サーバ
最近Goしか書いていないので、Go製Webアプリケーションフレームワークのgin/gonic使いました。
https://github.com/gin-gonic/gin

もうここまで来たらほぼ完成じゃんと思って、
ウキウキで受け取ったデータがこれ...

```
token=vFlRfdwGp9Nk5koVtSrbMxxx&
team_id=T63EC9xxx&
team_domain=xxx-network-club&
service_id=652176051511&
channel_id=CJSJ7TXXX&
channel_name=general&
timestamp=1559196598.002400&
user_id=U643K5XXX&
user_name=minatoo&
text=ojisan&
trigger_word=ojisan"
```
なんの形式やねんこれ....
調べたら
`application/x-www-form-urlencoded: キーと値は、その間に '=' がある形でキーと値の組になり、 '&' で区切られてエンコードされます。`
https://developer.mozilla.org/ja/docs/Web/HTTP/Methods/POST

てことでJSON形式にコンバートする処理をガキみたいなコードで実装した。
https://github.com/mntky/convA2J/blob/master/pkg/conv.go

これで自由にデータを扱える...!!

### 受信サーバのコード

```
package main

import (
	"fmt"
	"os/exec"
	"encoding/json"

	"github.com/gin-gonic/gin"
	"github.com/mntky/convA2J/pkg"
)


type ConvData struct {
	Token           string
    Team_id         string
    Team_domain     string
    Service_id      string
    Channel_id      string
    Channel_name	string
    Timestamp       string
    User_id         string
    User_name       string
}

func main() {
	g := gin.Default()
    g.POST("/", func(c *gin.Context) {
            buf := make([]byte, 2048)
            n, _ := c.Request.Body.Read(buf)
            b := string(buf[0:n])

            decode(b)
    })
    g.Run(":8080")
}

func decode(data string) {
	var convdata *ConvData = &ConvData{}
    resp := conv.Convert(data)
    err := json.Unmarshal([]byte(resp), convdata)
    if err != nil {
            fmt.Println(err)
    }

    fmt.Println(convdata.User_name)
	out, err := exec.Command("sh", "./send.sh", convdata.User_name).Output()
	if err != nil {
		fmt.Println(err)
	}
	fmt.Println(string(out))
}
```

取り出した名前はexecで send.shに引数渡して実行させてます。

```
curl incomingwebhookの指定URL -X POST -H "Content-Type: application/json" -d '{"username":"おぢさん", "text":"'$(ojichat $1)'"}'
```

## まとめ
これで完成です。
最後に動かした例を...
![キャプチャ (2).PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/266629/e8771af2-e122-95b3-4477-86c5c8371a7e.png)

相変わらずのキモさで疲れが飛びました。
なお自分以外誰もojisan打ってくれないので二度と出番がなさそうです。

ぜひみなさんのチャンネルにもいかがでしょうか？
初めての技術ブログ

# はじめに

はじめまして。初心者パイソニスタたけまるです。ちなみにPythonどころかプログラミング自体初心者です。現在仕事の合間にプログラミングを勉強，アウトプットのために技術ブログやっちゃおう，というノリです。ブログ内容は日々の勉強内容を書いていきますので，PV目的ではなく，完全に自分用ですが，ご了承ください。

# 勉強したい言語

・**Python** ： 本ブログの主役のpython。webサービスを立ち上げたい(未定)。
・**HTML，CSS，Javascript** ： webページをつくるにはいるでしょう。
・**Swift** ： iphoneアプリ制作したい
・**Ruby** : pythonが神ってきたらRubyにも手を出したい。

今の所こんなところです笑

# 目指す目標

プログラミングで食べていけるようになりたいです。そのためには日々の勉強を怠らないことが大事。8月末には，pythonである程度のことができるようになっておくことが，とりあえずの目標。

# 終わりに

学んだことを随時アップしていきます。完全に自分用の文章スタイルなのでわかりにくいかもですが，全くの初心者がみたら学べるところはもしかしたらあるかもしれません。
【AtCoder】ABC085C - Otoshidama

# これは何？
AtCoderという競技プログラミングサイトの練習問題についての私の解答です。
入門者用の練習問題なのでそれほど難しくはないはずなんですが、自力では解けなかったので記録として載せます。

問題はこちら。
https://atcoder.jp/contests/abs/tasks/abc085_c

# 解答
```ruby
n, y = gets.chomp.split.map(&:to_i)
 
not_found = true
# repeated_permutation(3)でも要件は満たすが、組み合わせ爆発でタイムアウトになってしまう
(0..n).to_a.repeated_permutation(2) do |a1, a2|
  a3 = n - a1 - a2
  next if a3 < 0
  next if (a1 + a2 + a3) != n
  
  sum = a1 * 10_000 + a2 * 5_000 + a3 * 1_000
  if sum == y then
    puts "#{a1} #{a2} #{a3}"
    not_found = false
    break
  end
end
 
if not_found then
  puts '-1 -1 -1'
end
```
`repeated_permutation` は重複順列を出力するメソッドで、レシーバの配列の要素から引数の個数の値を取り出す全てのパターンを出力してくれます。
ブロックを渡せば、順列をブロック引数として受け取って任意の処理を書けるのでそうしています。

コードのコメントにあるように当初は`repeated_permutation(3)` でやってみていたのですが、これではパターンが多すぎて、入力値のnが大きい場合はタイムアウトになってしまいました。

```ruby
(0..2000).to_a.repeated_permutation(3).size
# => 8012006001
```
nが最大値の2000だった場合、なんと80億件以上です。そりゃ遅いはずです。

しかし、後述の参考サイトを見て`repeated_permutation(2)` でもできるとわかったので、それで試してみたらうまくいきました。

```ruby
(0..2000).to_a.repeated_permutation(2).size
# => 4004001
```
`repeated_permutation(2)` にしたら約400万件になりました。多いといえば多いですが、これくらいなら現実的な時間で処理可能なようです。性能が劇的に改善され、nが2000の場合でもタイムアウトせずにクリアできました。

正直、自力で思いつけなかったのは悔しいです。精進します。

# 参考（というか答え）
https://qiita.com/drken/items/fd4e5e3630d0f5859067#%E7%AC%AC-8-%E5%95%8F--abc-085-c---otoshidama-300-%E7%82%B9
Cloud9の開発環境のデータベースをPostgreSQLに変更する方法

Cloud9の開発環境のデータベースをPostgreSQLに変更する方法をご紹介します。

前提として、すでにMysqlやSqliteでアプリケーションを開発しており、Postgresqlに乗り換えることを想定しています。

少し実情を話しますと、僕の通っているプログラミングスクールでは、導入コストの低さから開発環境はMysql、本番環境はPostgresqlを利用するカリキュラムでした。

しかし、環境ごとにデータベースが違うと不整合が起きてしまうことを体験したので、今回の試みをすることとなりました。

[【Rails】データベースの型の変更・置き換え（Postgresql）](https://qiita.com/YukiWebTech/items/13d50523bad1c0e991f3)

それでは、コマンド中心に全てのステップを紹介します。

# PostgreSQLをインストール

```
sudo yum install postgresql postgresql-server postgresql-devel postgresql-contrib
```

# PostgreSQLを初期化
```
sudo service postgresql initdb
```

# PostgreSQLのを起動

```
sudo service postgresql start
```

# Gemfileを編集

↓変更前

```ruby
gem 'mysql2'
```

↓変更後

```ruby
gem 'pg'
```

# database.ymlの編集

mysqlとpostgresqlは`adapter, encoding, username`がそれぞれ違うので要注意です。

↓変更前

```
default: &default
  adapter: mysql2
  encoding: utf8
  pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
  username: root
  password:
  host: localhost
```

↓変更後


```
default: &default
  adapter: postgresql
  encoding: unicode
  pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
  username: postgres
  password:
  host: localhost
```

# データベース作成

```
rails db:create
```

# マイグレーション適用

```
rails db:migrate
```
これでバッチリマイグレーションが適用できれば完了です。

お疲れ様でした！

# 参考
[cloud9上でrailsのデータベースをsqliteからpostgresqlにする方法はありますか？](https://teratail.com/questions/121880)
[PostgreSQL　セットアップからＤＢの作成＆削除まで](https://www.infoscoop.org/blogjp/2014/08/08/postgresql-setup-ddl/)
通信接続が切れても再度接続待ちに戻るSocket通信をPythonで

# はじめに
PythonでSocket通信するための情報はまあまあ見つかるけど、Clientからの接続が切れたとき、再度接続待ちに戻るような動作させる方法は、見つからなかった。今回、tryを使って試してみた。ちなみに、Serverがデータを送る設定。

# Socket通信
こんな感じ。

## Server
Serverかつ送信側。
`bind()`, `listen()`で接続の設定して、`accept()`で接続待ち。
`sendall()`を`try`してだめだったら`accept()`に戻る。

```python:server.py
# -*- coding:utf-8 -*-
# tcp/ip socket server
import socket
import time

with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
    # initialize socket
    s.bind(('127.0.0.1', 50007))
    s.listen(1)
    print("listen")

    while True:
        # wait for a connection
        conn, addr = s.accept()
        print("accept")

        while True:
            # get timestamp
            timestamp = "{}".format(time.perf_counter())
            data = timestamp.encode()

            # send
            try:
                conn.sendall(data)
                print("send data")
                ## sleep
                time.sleep(1)
            except:
                print("connection failed")
                break
```

## Client
Clientかつ受信側。
`connect()`で接続先を設定。
`recv()`で受信。

```python:client.py
# -*- coding:utf-8 -*-
# tcp/ip socket client
import socket

with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
    # initialize socket
    s.connect(('127.0.0.1', 50007))

    while True:
        # receive data
        data = s.recv(1024)
        timestamp = float(data.decode())
        print(timestamp)
```

## 実行結果
サーバー側はこんな感じ。

```
$ python .\server.py
listen
accept
send data
send data
send data
connection failed # ここで、クライアントをとめて接続きれた
accept # 再度クライアントを立ち上げた
send data
send data
send data
```

# おわりに
とりあえず、動いた。よかった。
localhostでしかやってないけども。
exceptは、もうちょいちゃんとエラーによって対応変えたほうがいいのかも。
Serverが受信側の場合、どうしたらいいかよくわからん。

# 参考
[pythonでsocket通信を勉強しよう - Qiita](https://qiita.com/__init__/items/5c89fa5b37b8c5ed32a4)
Railsで基本情報技術者試験の過去問題サイトを作る（６：SlackBOT編）

# はじめに
ゆる〜く学ぶ。みんなのWeb勉強コミュニティー。　「にゅ〜ぶる会」を運用中です。
https://newburu.github.io/

そこで、何か教育用のコンテンツが欲しいなぁ〜と思い立ち、今回の企画をスタートしました！

Railsで基本情報技術者試験の過去問題サイトを作ります！

# 最終目標
- 問題・回答の登録は、Scaffoldで簡易でOK
- APIを用意して、ランダムに問題を抽出する機能を追加する
- TwitterBOT、LINEBOT、SlackBOTが出来たら良いな

# 履歴
１：構築編
　　https://qiita.com/newburu/items/ed59f47ac645b19620f6
２：日本語化(i18n)編
　　https://qiita.com/newburu/items/4f12fdb61bf6cd601545
３：親子関係、登録編
　　https://qiita.com/newburu/items/f2a20289be5ec1fc1b77
４：親子関係、参照編
　　https://qiita.com/newburu/items/51b11bd02691efc2cc0d
５：API編
　　https://qiita.com/newburu/items/89f9f847a2648bdd006c
６：SlackBOT編
　　本ページ
７：Herokuデプロイ〜自動化編
　　https://qiita.com/newburu/items/0a8bb02e1e8c8fe737c7

# 今回やる事
- 登録された問題からランダムで問題を呟くSlackBOTを作ります

# SlackBOTを作ります

## 1. SlackにBOTを追加します。
BOTのトークンが必要になりますので、
以下のURLからBOTを追加し、トークンをメモしておいて下さい。
https://api.slack.com/bot-users

## 2. ランダムで問題を取得するメソッドを追加します。
まずは、モデルに必要なメソッドを追加しましょう。
※もちろん、selfをつけてクラスメソッドですね！

```ruby:app/models/question.rb
  def self.random()
    Question.all.sample
  end
```

うん、これは、一度全レコードを取得しちゃうので、メモリ圧迫するし遅いからダメですね。。。

```ruby:app/models/question.rb
  def self.random()
    Question.find( Question.pluck(:id).sample )
  end
```

というわけで、先にIDをランダムに決めてから取得する方法に変更します。

## 3. Slackに呟くタスクを追加します。

SlackAPI用のGem([slack-api](https://github.com/aki017/slack-ruby-gem))があるので追加します。

```ruby:./Gemfile
gem 'slack-api'
```

まずは、rails gでタスクを新規作成します。

```terminal
rails g task slack_bot
```

作成されたファイルに処理を追加します。

```ruby:lib/tasks/slack_bot.rake
require 'slack'

Slack.configure do |config|
  config.token = ENV["SLACK_API_TOKEN"]  # BOTのトークンは公開できない為、環境変数で設定します。
end

namespace :slack_bot do
  desc 'ランダムに問題をSlackに書き込む'
  task :random_question => :environment do
  task :random_question => :environment do
    question = Question.random
    source = "出典：#{question.category1}年度 #{question.category2} 基本情報技術者試験 午前 問#{question.category3}"
    msg = "【問題】\n#{question.msg}\n\nア　#{question.answers[0].msg}\nイ　#{question.answers[1].msg}\nウ　#{question.answers[2].msg}\nエ　#{question.answers[3].msg}\n\n#{source}"

    # text:出力テキスト、channel:出力先のチャンネル名、username:表示ユーザ名
    Slack.chat_postMessage(text: msg, channel: 'times_にゅーぶる', username: 'FE問題_出題BOT')
  end
end
```

## 4. 確認しましょう
まずは、rakeタスクとして登録されているか確認しましょう。

```terminal
$ rake -vT

〜　略　〜
rake slack_bot:random_question          # ランダムに問題をSlackに書き込む
〜　略　〜
```

では、実行！

```terminal
$ rake slack_bot:random_question
```

Slackを確認し、こんな感じの表示されればOKです！
<img width="478" alt="Slackを確認" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/118481/d44259da-a176-92b5-df71-31e80bd6f6b4.png">
※事前にブラウザから、問題を登録しておく必要があります。




# 今回はここまで
ありがとうございました！
次回は、このSlackBOTを定期的に実行する環境を作りましょう！
YOLOv3を動かしてみる

## まずYOLOv３とは

物体認識モデルの一つ
他のモデルとの比較や性能、構造については

[一般物体認識手法の把握](https://note.mu/seishin55/n/n542b2b682721)
[検出アルゴリズムの紹介](https://tech-blog.abeja.asia/entry/object-detection-summary)
[YOLPv3論文日本語訳](https://qiita.com/mdo4nt6n/items/7cd5f106adc775e5d92b)
を読んでまずYOLOの概観を知る

**[YOLOv3のスクラッチコード](https://blog.paperspace.com/how-to-implement-a-yolo-object-detector-in-pytorch/)

## 実装してみる

#### 開発環境
MacBook Pro(13-inch, 2017)
macOS Mojave 10.14.5
python 3.7.1

#### 環境構築
pipenvで仮装環境を構築

仮装環境をつくりたいディレクトリに移動

```
$cd test_yolov3
```
仮装環境の構築

```
$pipenv install --Python 3.7.1
```
環境に入る+次回以降はpipfile に入ってるPackageInstall（必要ならUpdata）
http://pynote.hatenablog.com/entry/pipenv-usage

```
$ pipenv shell
(test_yolo) bash-3.2$
(test_yolo) bash-3.2$　pipenv install
```
必要なパッケージのインストール
*ここでMatplotlibのインストールでエラーが出たので、[参考1](https://qiita.com/Kodaira_/items/1a3b801c7a5a41c9ce49),[参考2](http://starpentagon.net/analytics/yolo_v3_on_mac/)
を元にmatplotlibrcのpathを調べて
vimでmatplotlibrcを編集

```
$python -c "import matplotlib;print(matplotlib.matplotlib_fname())"
$cd ~~~~~~~~~~~~~~~~~~/matplotlibrc
$vi matplotlibrc
```
`
backend : macosx-> backend : macosx
`
に変更。

その上で再度

```

$ pipenv install opencv-contrib-python
$ pipenv install numpy
$ pipenv install matplotlib-python
```


#### YOLOv3の設定 
本家以外に色々あってややこしい。。。
1. [公式サイトのコードで認識](https://pjreddie.com/darknet/yolo/)

```
git clone https://github.com/pjreddie/darknet
$ cd darknet
$ make
$ wget https://pjreddie.com/media/files/yolov3.weights
$ ./darknet detect cfg/yolov3.cfg yolov3.weights data/dog.jpg
```
[YOLOv3とりあえず一枚画像で試す](https://qiita.com/hiroyuki_mrp/items/ae70eba771449fc6f283)

DATAの自作
- https://qiita.com/watakandhi/items/7981f05e6cfc1b69737c
- https://nmxi.hateblo.jp/entry/2019/02/28/104546
- https://demura.net/misc/14458.html
- https://qiita.com/tk-tkhs/items/eb74ea516cadfaa202a0


2. 次に不要なコードが省かれた
[Pytorch仕様のYOLOv3](https://github.com/ayooshkathuria/pytorch-yolo-v3)
を使うことに
これはCOCOデータセットの学習済みモデル。後にオリジナルのデータセットを学習させることも可能

```
(test_yolo) $ git clone https://github.com/ayooshkathuria/pytorch-yolo-v3.git
(test_yolo) $ cd pytorch-yolo-v3
(test_yolo) $ wget https://pjreddie.com/media/files/yolov3.weights
```

**Mac wget -> curl https://pjreddie.com/media/files/yolov3.weights -0
とするといいそうです（私はbrew install wgetしました）

#### 認識テスト
- あらかじめ用意した画像データ
imgsフォルダに認識させたい画像いれる。
detフォルダに認識後の画像が入る。

```
$ python detect.py --images imgs --det det
```

- 動画認識のデモ

```
$python video_demo.py --video sample.mp4
```

- リアルタイムで内蔵カメラで撮影した画像の認識

```
$python cam_demo.py
```
### YOLOv３の編集について
> どのgithubコードをメインにするかによって実行コマンドが違う。
公式のDarknetをcloneした場合、画像の書き出しや座標出力をimage.cファイルの編集により可能となるそう。
ただし、コンパイル$makeが毎度必要
https://pycarnival.com/yolo_python_opencv/

> GPU使うにはmakefileを編集すればいい
これも変更したらコンパイル$makeが毎度必要

####　参考にさせて頂いた資料

- https://qiita.com/daiarg/items/03c55c82fdc6e623bf07

- https://qiita.com/Kodaira_/items/1a3b801c7a5a41c9ce49
[Android] WebViewのLocalStorageをオンにする

# やりたいこと
AndroidのWebViewはデフォルトでは、ローカルストレージをWeb側から使用しようとするとエラーになる為、解消したい

# 実装
```MainActivity.kt
class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        main_web_view.settings.javaScriptEnabled = true // JavaSrciptの有効化
        main_web_view.settings.domStorageEnabled = true // ローカルストレージ有効化

        main_web_view.loadUrl("url")
    }
}
```

```activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context=".MainActivity">

    <WebView
            android:id="@+id/main_web_view"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintLeft_toLeftOf="parent"
            app:layout_constraintRight_toRightOf="parent"
            app:layout_constraintTop_toTopOf="parent"/>

</android.support.constraint.ConstraintLayout>
```
freemakerのメモ

JAVA系はfreemarkerはよく使うテンプレートエンジンです。

#freemarkerとは
>Apache FreeMarker™ is a template engine: a Java library to generate text output (HTML web pages, e-mails, configuration files, source code, etc.) based on templates and changing data.

https://freemarker.apache.org/


#freemarker変数定義、存在チェック

##変数定義例

freemarkerではnull付与するとエラーになります。
変数定義にエラーが回避するために、初期値を設定したほうがよいです。

```error.ftl
<#-- 新変数名 = "固定時文字" の形で初期値設定できます。-->
<#assign userName = "山田">

<#-- 新変数名 = 変数名!初期値 の形で初期値設定できます。-->
<#assign userName = loginUserName!"（記入していない）">

<#-- 新変数名 =  変数名! の形で初期値設定しないが、エラー回避-->
<#assign userName = loginUserName!>

<#-- 新変数名 =  変数名　初期値がないとエラー-->
<#assign userName = loginUserName">
```


##存在チェック例

```sample.ftl


<#--変数定義あり、データは空白でない-->
<#assign content = "123" />
<#if content?has_content>
   サンプルデータ(content)：${content}
<#else>
   サンプルデータ(content)：(空白)
</#if>

<#--変数定義あり、データは空白-->
<#assign emptyContent = "" />
<#if emptyContent?has_content>
   サンプルデータ(emptyContent )：${emptyContent }
<#else>
   サンプルデータ(emptyContent )：(空白)
</#if>


<#--変数定義なし、「?has_content」で存在判断-->
<#if notExistData?has_content>
   サンプルデータ(notExistData)：${notExistData}
<#else>
   サンプルデータ(notExistData)：(定義していない)
</#if>

<#--変数定義なし、「??」で存在判断-->
<#if notExistData?has_content>
   サンプルデータ(notExistData)：${notExistData}
<#else>
   サンプルデータ(notExistData)：(定義していない)
</#if>

```

結果：

>    サンプルデータ(content)：123
   サンプルデータ(emptyContent )：(空白)
   サンプルデータ(notExistData)：(定義していない)
   サンプルデータ(notExistData)：(定義していない)

#異常処理（recover）
<#attempt>
  普通処理
<#recover>
  普通処理にエラーがある場合、ここのコードを実行
</#attempt>

例：

```recover.ftl
<#-- 異常なしの場合　-->
<#attempt>
  正常処理: ${1+1}
<#recover>
  異常処理：異常ありました。
</#attempt>

<#-- 異常ありの場合　-->
<#attempt>
  正常処理: ${nodata}
<#recover>
  異常処理：異常ありました。
</#attempt>
```

出力：

>  正常処理: 2
  異常処理：異常ありました。


#オンラインデモサイト
https://try.freemarker.apache.org/

以上
AWS Cloud9のEC2上にmysql2のgemを導入する

#1.目的
フレームワークにRailsを用いて、Rubyのポートフォリオを製作するにあたり、DBにMySQLを使用しようと環境設定を行おうと試みたが、エラーが発生し、導入が進まなかったので、解決した手順を残す。

ただし投稿当時は、初学者のため原因の詳細は今後追記する事とする。

##1.1 環境
mysql2のgemのバージョンは0.5.２である

これらをAWS Cloud9 EC2へインストールしておくこと。
Ruby：2.6.3
Rails：5.2.3
MySQL：5.7.25

#2.手順
##2.1 順番にライブラリをインストール
```
$　sudo yum install mysql57-devel
```
```
$　sudo yum -y install ruby-devel
```
```
$　sudo yum groupinstall "Development Tools"
```
##2.2 gemのインストール
```
$　gem install mysql2
```
##2.3 gemの確認
リストを表示して、mysql2が確認できること。

```
$　gem list
```
##2.4 Gemfileの変更（プロジェクトを管理する場合）
Gemfileに以下を記述し、保存する。

```
gem 'mysql2'
```
##2.5 Gemfileに従ったインストール（プロジェクトを管理する場合）
```
$ bundle install
```

gem listにてmysql2があれば、とりあえずクリアと言う事で一件落着...
#参考
mysql2ではlibmysqlclinetを使用していることがどうやら関係している模様。

https://qiita.com/toshihirock/items/4dee1365b925021d4490
DIalogFrgamentを画面いっぱいに表示する

# やりたいこと
DialogFragmentはデフォルトだと画面いっぱいに表示されない為、画面いっぱいに表示する

# 実装
```MainActivity.kt
class MainActivity {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
    }

    override fun onStart() {
        super.onStart()
        StampDialogFragment().show(supportFragmentManager, StampDialogFragment::class.java.simpleName)
    }
}
```

```FullWindowDialogFragment.kt
class FullWindowDialogFragment : DialogFragment() {

    override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
        val dialog = Dialog(requireActivity())
        dialog.setContentView(R.layout.view_full_window_custom) // custom layout
        dialog.window?.setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT))    // 必要なさそうだが、これがないと全画面にならない
        dialog.window?.setLayout(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT)
        return dialog
    }

}
```

```view_full_window_custom.xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="@android:color/black">

    <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Full Window Custom View"
            android:textColor="@android:color/white"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintLeft_toLeftOf="parent"
            app:layout_constraintRight_toRightOf="parent"
            app:layout_constraintTop_toTopOf="parent"/>

</android.support.constraint.ConstraintLayout>
```

layoutが真っ黒の為、背景が黒い画面が全体に表示される
<img width="300" alt="スクリーンショット 2019-06-01 20.39.34.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/199764/32896709-cbc0-03df-e8c0-9b702fe20b98.png">

# CustomViewにする

```FullWindowDialogFragment.kt
class FullWindowDialogFragment : DialogFragment() {

    override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
        val dialog = Dialog(requireActivity())
        dialog.setContentView(FullWindowCustomView(requireContext())) // custom layout
        dialog.window?.setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT))    // 必要なさそうだが、これがないと前画面にならない
        dialog.window?.setLayout(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT)
        return dialog
    }

    // custom view
    private class FullWindowCustomView(context: Context) : FrameLayout(context) {
        init {
            View.inflate(context, R.layout.view_full_window_custom, this)
        }
    }
}
```
axiosのmaxContentLengthの脆弱性について（2019/05/31）

# 先に結論
axiosを使ってる人は脆弱性があるのでv0.18.1以降に上げましょう
axiosを使っていない人は関係ないのでブラウザバックして大丈夫です。

axiosはJavaScriptのメジャーな通信系のライブラリです。
xhrで実装されているため、レガシーなブラウザやマルチブラウザに対応しています。
https://github.com/axios/axios

# GitHub上でセキュリティアラートが・・・

GitHub上でセキュリティアラートが上がっていました。（2019/05/30確認時点）
![スクリーンショット 2019-05-30 20.08.56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/55077/3d1e5af9-e1f6-7334-b89e-8b5d6aec69c2.png)

# どうゆう脆弱性？

<img width="1475" alt="スクリーンショット 2019-06-01 20.24.34.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/55077/035a6034-a537-9364-9490-097030210d54.png">

>Axios up to and including 0.18.0 allows attackers to cause a denial of service (application crash) by continuing to accepting content after maxContentLength is exceeded.

maxContentLengthを超えた場合でも通信処理が行われていて、アプリケーションに負荷をかけ続けるという脆弱性のようです。

詳細は修正のプルリクの例を見たほうがわかりやすいです。
https://github.com/axios/axios/pull/1485

この例だと、100%を超えても通信処理が呼ばれ続けています。

```
  ticks parent  name
  61777   81.0%  /lib/x86_64-linux-gnu/libc-2.23.so
  61542   99.6%    LazyCompile: *Buffer.concat buffer.js:423:25
  61437   99.8%      Function: ~handleStreamData /home/resure/something/node_modules/axios/lib/adapters/http.js:165:52
  61437  100.0%        Function: ~emitOne events.js:114:17
  61437  100.0%          Function: ~emit events.js:156:44
  61437  100.0%            Function: ~addChunk _stream_readable.js:261:18
```

# axios側の対策

`#1485`の対応で`stream.destroy()`関数を呼び出して通信処理を破棄しています。
Destroy stream on exceeding maxContentLength
https://github.com/axios/axios/pull/1485/files
（というかこのプルリク自体は2018/4月からあるのでaxiosチームも認知はしてたんですね・・・）

この脆弱性の対応のために、axiosはv0.19に上がりました。（2019/05/31）
~~`#1485`の対応はv0.19に入ってるのでバージョンを上げれば大丈夫のはずです。~~
追記`#1485`の対応だけ分離してv0.18.1が出来ていたので、v0.19に一気に上げるよりもこちらを使ったほうが無難そうです。
https://github.com/axios/axios/releases
[初心者向け]ちょっと便利なLinuxターミナル ショートカット６個

Linuxを触りだして数ヶ月、ターミナルのショートカットがおぼえれず。。
上級者のかっこいいターミナルさばきに憧れてに覚えておきたいショートカットを一覧にしました。

|ショートカット|説明|
|---|---|
|ctrl+l|画面のクリア|
|ctrl+r|過去コマンドサーチ|
|ctrl+a|先頭に移動|
|ctrl+e|行末に移動|
|ctrl+u|先頭〜カーソルまで削除|
|ctrl+k|カーソル〜行末まで削除|
【each文の入れ子の挙動】eachの中にeachの中にeach

#eachの中にeachを入れるとどういう挙動をするのだろうか。やってみました

なんでeachの中にeachを入れてみたくなったのかというと

<img width="986" alt="スクリーンショット 2019-05-29 21.06.57.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/346005/40c9cf0a-1e84-a30e-85cd-d215bb51b54b.png">

こんな感じで階層のカテゴリ機能を作成する過程で必要と思いました。

## ・・・というのも

<img width="711" alt="スクリーンショット 2019-06-01 20.07.45.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/346005/84e838ad-d3e8-caad-7af3-42e6490311bd.png">

中身がこんな感じでえらいことになっていて
カテゴリの数は全部で400近く・・・

流石に手書きはありえんなと思い
eachでdbから引っ張ってきた要素文回せばいけそう！？

という考えに至った。

<img width="774" alt="スクリーンショット 2019-06-01 20.11.34.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/346005/3f52f63d-6b05-0e73-69b5-61102992a354.png">

こんな感じで中でぐるぐる同じ繰り返しが行われるので
安直な考えでeachの中にeachを回して見ようと思った。

# 【結論】eachの入れ子ってできたっけ？どんな挙動するんだっけ
実験のコードはこちらです↓

```ruby:test.rb
parents = [1,2,3]
childs = [10,11,12]
babys = [20,21,23]

parents.each do |parent|
  puts "親#{parent}"
  childs.each do |child|
    puts "子#{child}"
    babys.each do |baby|
      puts "孫#{baby}"
    end
  end
end

```
結果はこちら↓
<img width="45" alt="スクリーンショット 2019-06-01 20.20.36.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/346005/35c6d992-03c0-d511-8af7-fc9de385325f.png">

です。

# 最後に・・・

まだhtmlの方は作り上げてないので
この挙動で本当にいけるのか？という感じですが
今のところこれくらいしかアイデアがないので書きながら探っていきます。

こうしたらいいよ！
こうしたらうまくいくよ！楽チンだよ！
先輩方の知恵があれば教えていただきたいです。

最後まで読んでいただきありがとうございました!
deviseのアンインストール

gemでdeviseをインストールしたけど、やっぱりアンインストール、削除したい時に。

## 1.テーブルの削除

```ruby:ターミナル
$ rake db:rollback
```
マイグレーションをロールバックし、データベースから作成済みのテーブルを削除する。
その後マイグレーションファイルとスキーマファイルを確認し、バージョンの整合性が取れているか確認すること。
もしずれがあれば合わせておかないとマイグレーションでエラーが起きるようになる。

## 2.configファイルの削除

```ruby:ターミナル
$ rails destroy devise:install

=> Running via Spring preloader in process 56238
      remove  config/initializers/devise.rb
      remove  config/locales/devise.en.yml
```
## 3.gemアンインストール

```ruby:ターミナル
$ bundle exec gem uninstall devise
=> Successfully uninstalled devise-4.6.2
```

## 4.残ったdevise関係のファイル・記述を手動で削除
devise_for **(routes.rb)**
gem 'devise' **(gemfile)**
before_action :authenticate_user! **(controllers)**
user_signed_in? **(controllers, views)**
current_user **(controllers, views)**
user_session **(controllers, views)**
devise.rb **(config/initializers)**
devise.en.yml **(config/locales)**
view/deviseのファイル
等など。他にもあるかもしれません。

これでエラーが出なければおそらく問題ないはず。

## もしこの後に　rails g ~ ができなくなったら

```ruby:ターミナル
$ bundle exec spring stop
```
これで直ると思います。


### 参考
・たれみみマンデー
　[Devise取り消す作業](http://taremimi.hatenablog.jp/entry/2018/02/16/120343)
・joppot
　[ruby on railsのbundleのGemfileでインストールしたgemを削除する](https://joppot.info/2014/07/08/1673)