OmniAICreator/Qiita-1.07M huggingface dataset:
いわゆる「２バイト文字」を識別子に使用するのを推奨したいケース。

# 前段

Twitterでフォローしている方が

> データベースのテーブル名、カラム名、一部enumだけでなく画面のテンプレート名で日本語を使用している

と言う話をされていました。

解る解るー、と思って見ていたんですが、ぼくはこれに加えてもう一つ最重要視している**「日本語命名しても良い（むしろ推奨したい）と思うもの」**があります。



# ２バイト文字の使用について

JavaやC#では、識別子*（クラス名とか、メソッド名とか）*に、**「いわゆる２バイト文字」**を使う事が出来ます。

*※いわゆるなんちゃら～と書くのは面倒なので、以降は「日本語を使用できる」と言う表現を使います。*

日本語識別子を使うと言う事に対して、条件反射的に拒否反応を示す方も少なくないと思います。

ただ、落ち着いて考えてみると、（少なくとも最近の言語・開発環境に於いては）日本語識別子を使用する事による具体的な弊害と言うのはそんなに無いのかな、と思います。



## 日本語識別子を使用する事で考えられるデメリット

- IDEのインテリセンスが効かない（訳じゃないけど、使い難い）
- 若しかしたら一部のORマッパーとかが正しく動かない（かも？）

一番大きな要素が前者かなと思います。

インテリセンスって言うとMicrosoft用語ですかね、Eclipseで言うと何ですか、単にコード補完？
多くのIDEで ```[Ctrl] + [Space]``` で使えるあの機能です。

どうしてもあの機能だけはIME変換を想定していないので、日本語識別子を使っていると不便になります。

**※何か日本語識別子を使った事でこういうトラブルがあったよ！と言う人がいたら教えてください。**

## 日本語識別子を使用する事で考えられるメリット

- 単純に解り易い
- 英訳を調べたりする手間を省ける
- 無理に英単語にすると名前が長くなり過ぎるのを回避できる

特に、業務システム開発に於いては影響度大だと思います。

法律関係の用語とか、特定業務の専門用語とか、英単語化が不可能ではないにしてもかなり難しいと言う場合が多いと思います。


**難しい熟語をムリヤリ英語化した場合の弊害：**

法律用語や専門用語をムリヤリ英単語化しようとすると、幾つかの直訳英語を調べてみてそれをくっつけたりして、
だいたいそういう「調べないと出て来ないような単語」ってのは長くて読み難い事が多いし、
そもそも普通の人が普通は知らないような単語だったりして、ソースコードを読んだ人がその英単語を調べると言う手間が発生したりして。

とまぁ、とにかく余計なコストが多く、ハッキリ言って無駄なコストですよね。


**日本語識別子を毛嫌いしなくて良いのでは：**

一定以上難しい単語を要する場合は素直にローマ字表現とかを使うべきだと思いますし、
もっと言えば、前段に引用した通り、適用範囲を明確にしたうえで日本語識別子を使って良いと思います。

そもそも我々が書いているのはプログラムであって、ネイティブ英語文書ではないですしね。
*（勿論、構文が英語系の文法に親和性があるので、素直に英語表現に落とせるならそれが一番良いと思いますが、無理くり英語に当てはめる必要も無いよね、と言う話）*






# ぼくが日本語識別子を強く推奨する場所

で、前段に戻りますが。

ぼくが日本語識別の使用を推奨したいというのは、**テストプログラム**です。
*（テストクラス、テストメソッドの識別子）*


## テストメソッドに日本語識別子を使用するメリデメ

**メリット：**

メリットは前述の通りですが、とにかくテストの実行結果が解り易いと言う事が全てです。

自動テストをやっていると、エラーがあった時にどのテストでエラーになったのかが解り易い事が最も重要だと思います。
この時、テストメソッド名を日本語識別子にしていると非常に解り易くて便利です。


**デメリット：**

デメリットは特に無いように感じます。

日本語識別子を使用する上で**最大のデメリット**が、前述した通り**「IDEのコード補完が使い難い」**だと思いますが、**テストメソッドに於いてはこれは全く無関係**です。

何せ、テストメソッドの呼び出しを書かない*（普通はアノテーション・アトリビュートを目印にしてテストフレームワークがリフレクションで呼び出すので、呼び出しコードを書く事が無い）*のだから、コード補完も何も無いですよね。





**余談：**

前述の「一部のenum」と言うのが日本語識別子の許容対象になっているのは非常に上手いと思います。

通常、「列挙体名.列挙子名」と言う形で、グループを指定してからその中の要素を示す、と言うコードの字面になるので、IDEで補完が効かなくとも、もともと選択肢がかなり絞られるので、上下キー選択だけでもコーディングに支障が無い部分と言えます。

なので、IME云々と言う弊害がほぼ影響しないので、業務固有のコード定数や区分値等を定義した列挙体に対して、日本語識別子を使用すると言うのは賢いやり方だと思います。

それ以外の部分で、どの程度日本語識別子を許容するかと言うのは、各プロジェクトのアーキテクトが考える所かな、と言う気がします。
Amazon Polly を試す


テキストをMP3の音声データに。

```python
#!/usr/bin/env python                                                                                                                                                                                                                                                           
#-*- coding: utf-8 -*-                                                                                                                                                                                                                                                          

from boto3 import client

def main():
    """                                                                                                                                                                                                                                                                         
    """
    polly = client("polly")

    response = polly.synthesize_speech(Text="数字の中で、７だけが孤独なのよ。",
                                       OutputFormat="mp3",
                                       VoiceId="Mizuki")

    with open("sound.mp3", "wb") as fd:
        fd.write(response.get("AudioStream").read())


if __name__ == "__main__":
    """                                                                                                                                                                                                                                                                         
    """
    main()
```
Used Koa2 as Http Server in NodeJS

#1. New Add Server.js and index.html(You can put it on folder "dist")
```
const fs = require('fs');
const path = require('path');
const Koa = require('koa');
const logger = require('koa-logger');
const serve = require('koa-static');
const compress = require('koa-compress');
const Router = require('koa-router');

const app = new Koa();

// https://github.com/koajs/static
const SERVE_OPTIONS = {
    maxage: 30 * 24 * 60 * 60 * 1000
};

const distFolder = path.resolve(__dirname, 'dist');

const root = new Router();
root.get('*', async (ctx) => {
    ctx.type = 'html';
    ctx.body = fs.createReadStream(`${distFolder}/index.html`);
});

const router = new Router();
router.use('/', root.routes(), root.allowedMethods());

app.use(logger());
app.use(compress());
app.use(serve(buildFolder, SERVE_OPTIONS));
app.use(router.routes());
app.use(router.allowedMethods());
app.listen(80);
```

#2. Execute it :)
```
# node Server.js
```

#3. Browse
http://127.0.0.1
heroku コマンドでnot a directory

MacOSを EI CapitanからHigh Sierraにアップデートしたらherokuコマンドでエラーが出るようになってしまいました。

```
$  heroku config

 ▸    stat /Users/username/.local/share/heroku/client/bin/heroku: not a directory
 ▸    fork/exec /Users/username/.local/share/heroku/client/bin/heroku: not a directory
 ▸    stat /Users/username/.local/share/heroku/client/bin/heroku: not a directory
 ▸    fork/exec /Users/username/.local/share/heroku/client/bin/heroku: not a directory
```

調べて見たらどうやらCLIをuninstall & updateが必要みたいです。

解決策

```
$ rm -rf ~/.local/share/heroku/client 
$ heroku update
```

参考
https://devcenter.heroku.com/articles/heroku-cli#uninstalling-the-heroku-cli
https://github.com/heroku/cli/issues/427
cordova系コマンドで JSONおかしいとエラーが出たら


## 事象

`cordova platform add ios`とか `cordova platform add android` とか、 cordova 系のコマンド叩いた時に下記みたいなエラーに遭遇することが、まれによくある。

```
Error: Unexpected token } in JSON at position 5067
```

JSONがおかしいのは分かったよ
**どのJSONだよ！！！！１**

## 原因

`./plugins/fetch.json`
何かをどうにか間違えるらしく、中括弧が一個余計に付いてる。
![余計な中カッコ.png](https://qiita-image-store.s3.amazonaws.com/0/67742/1daea78b-7cf8-7f7c-e5bc-f9a8f1b040a5.png "余計な中カッコ.png")

## 対処

コレを消す。
![余計な中カッコなくなった.png](https://qiita-image-store.s3.amazonaws.com/0/67742/1f6fa90b-8a98-094f-8c38-ca042b02b02a.png "余計な中カッコなくなった.png")
Electron - Error: Unresolved node modules: fsevents

Node: 8.7.0
Yarn: 1.1.0

Today, I clean build the web project failed. And error message likes this.

```
electron-builder 19.40.0
Error: Unresolved node modules: fsevents
...
...
```

Then I roll back electron-builder version to 19.26.3. And it work well.

```
# yarn add electron-builder@19.26.3 --exact
```

Is electron-builder 19.40.0 bug?
Atom Editorの拡張子による言語選択をカスタマイズする

Atomはファイルの拡張子をみて、grammarを選択してくれるのだが、カスタマイズしたいことがある。
atomのソースコードを読んでやり方を調べたので、メモっておく。

# grammar選択の概要

atomの言語ハイライト機能は`grammar`と呼ばれている。(大抵は`language-hogehoge`というパッケージ名で提供されている)
`grammar`は内部的には`scopeName`で管理されているようで、
`grammar.fileTypes`という拡張子の`Array`に則って、どの`grammar`が選ばれるか決まる。

この部分には、ユーザー定義を追加できるようになっている。(`core.customFileTypes`)

[このあたりを参照](https://github.com/atom/atom/blob/1975e37e317d2502f9b53f37e1869578f878b4aa/src/grammar-registry.js#L69-L99)


# 適用したいgrammarのscopeNameを調べる

customFileTypesは、scopeNameから拡張子配列へのHashなので、scopeNameを調べる。
atomのプラグインはgithub上にソースコードが公開されていると思われるので、それをさがす。
grammarの属性の定義は grammars/*.cson にある。
当該csonの中身を見て scopeNameを調べる。


例えば、*.txtファイルに対して、markdownによるハイライトを適用したいとすると、
markdownというgrammarのscopeNameを知る必要がある。
atomに組み込みのmarkdown記法を実現しているパッケージは、`language-gfm`だ。(Github Flavored Markdownの略らしい。)
ソースコードは以下
https://github.com/atom/language-gfm

scopeNameはここ。
https://github.com/atom/language-gfm/blob/master/grammars/gfm.cson#L2

**`"source.gfm"`が求める文字列になる。**

# Atomの設定ファイル(config.cson) に記述する

atomの設定を開き(`Command`+`,`など)、`Open Config Folder`ボタンで、設定ディレクトリを開き、
`config.cson` を開く。

jsonとYaMLの合いの子のようなcson形式で書かれている。

ここに

```
"*":
  core:
    ...
    ...
    customFileTypes:
      先程調べたscopeName: [
        適用したい拡張子
      ]
```

という記述を追加する。

*.txtファイルに対して、markdownによるハイライトを適用したい、という先程の例の場合なら

```
"*":
  core:
    ...
    ...
    customFileTypes:
      "source.gfm": [
        "txt"
      ]
```

となる。
youtube-dl を使ってTwitterの動画を保存する方法

youtube-dl を使えばTwitterの動画をmp4ファイルに録画して保存することができる

- この記事はmacOS想定
- ffmpegさえ利用可能にすればWindowsやLinuxでも使えるのでは

# Homebrew のインストール
必須ではないが便利

```:macOS
/usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
```

# youtube-dl のインストール

```:macOS
brew install youtube-dl
```

## インストールできたかの確認
```:macOS
youtube-dl --version
```

```
YYYY.MM.DD
```


# 録画したファイルを置く専用フォルダを用意して移動
```:macOS
$ cd Desktop
$ mkdir video
$ cd video
```

# 録画したいTwitter動画のURLを取得
```
https://twitter.com/hoge/status/hogehogehogehogehogehoge
```


# 録画する
```
youtube-dl https://twitter.com/hoge/status/hogehogehogehogehogehoge
```
録画が終わると自動的に終了する

# 確認する
フォルダ内を覗くと
```hogehogehogehogehogehoge.mp4```
ができているはず

# 高度な操作
[youtube-dl/README.md at master · rg3/youtube-dl] (https://github.com/rg3/youtube-dl/blob/master/README.md#options)
にたくさんオプションが説明されている
windowsストアアプリのUbuntu（bow）

#insider programが不要になった
2017/10月25日時点で最新の更新”FallCreatorUpdate”の適用でストアアプリのubuntuが動くようになった。

前回のCreatorUpdateはビルド番号が15063だったが
今回16299に上がったことでインストール要件を満たしたみたい。

ストアでUbuntuで検索してやると

![sutoaubuntu.png](https://qiita-image-store.s3.amazonaws.com/0/208011/d2be54a4-70dc-89db-aa53-35f153af9815.png)

こんなのがいて、画像では”起動”になってる部分が”入手”になってるはず
クリックしてやればインストールされるのでお手軽。

ちなみにインストールされたUbuntuのルートディレクトリは

```
C:\Users\User\AppData\Local\Packages\CanonicalGroupLimited.UbuntuonWindows_79rhkp1fndgsc\LocalState\rootfs
```
みたいな感じになるみたい

CentOSは使ったことがあるけどUbuntuはないので、簡単に手に入るのはありがたい
これからいじっていこうっと
.pickle と .npz でlist・numpy行列を書き込みと読み出し

#listやnumpyのarrayを保存

Codeの中で計算したlistやnumpyのarrayを書き込みと読み出しする方法。備忘録。

#Code　(pickle)

まずはpickleから。

```Python
import pickle

sample_list = [1,3,5,7,9,2,4,6,8]

#.pickleに書き込み
with open('sample.pickle','wb') as f:
    pickle.dump(sample_list, f)

#.pickleから読み出し
with open('sample.pickle','rb') as f:
    new_list = pickle.load(f)

print(new_list)#[1, 3, 5, 7, 9, 2, 4, 6, 8]

#一致してるか確認
print(sample_list == new_list)#True
```

#Code　(npz)

numpyの行列

```Python
import numpy as np

a = np.array([1,2,3,4,5])
b = np.array([6,7,8,9,10])

#.npzに書き込み
np.savez('a_and_b.npz',x = a, y = b)

#.npzから読み出し
new_array = np.load('a_and_b.npz')

print(new_array['x'])#[1 2 3 4 5]
print(new_array['y'])#[ 6  7  8  9 10]

#一致してるか確認
print(a == new_array['x'])#[ True  True  True  True  True]
print(b == new_array['y'])#[ True  True  True  True  True]
```
MySQLのVARIABLESをコマンドから変更する

MySQLコマンドでVARIABLESを変更する方法を調べました。

## 環境
- MySQL5.7

## MySQLのVARIABLESとは
MySQLのVARIABLESとは以下のコマンドで表示されるシステム変数です。

```mysql
SHOW VARIABLES;
```

有名な変数としては、文字コードに関するものでしょうか

```mysql
mysql> SHOW VARIABLES like 'char%';
+--------------------------+------------------------------------------------------+
| Variable_name            | Value                                                |
+--------------------------+------------------------------------------------------+
| character_set_client     | utf8                                                 |
| character_set_connection | utf8                                                 |
| character_set_database   | utf8                                                 |
| character_set_filesystem | binary                                               |
| character_set_results    | utf8                                                 |
| character_set_server     | utf8                                                 |
| character_set_system     | utf8                                                 |
| character_sets_dir       | /usr/local/Cellar/mysql/5.7.19/share/mysql/charsets/ |
+--------------------------+------------------------------------------------------+
8 rows in set (0.01 sec)
```

## コマンドから変更するやり方
`SET`コマンドを利用することで変更可能です。例として,`character_set_database`を変更します。

```mysql
SET character_set_database=utf8mb4;
```


## VARIABLESを変更する方法として以下の方法がよく紹介されています
`.my.cnf`などに以下の用に記述することでも可能です。
というかこっちのほうが明示的で好ましいかも。

```mysql
[mysqld]
character-set-server=utf8mb4
```

## 参考
- https://dev.mysql.com/doc/refman/5.6/ja/show-variables.html
- https://dev.mysql.com/doc/refman/5.6/ja/set-statement.html
Kerasの学習過程をスマホで見る

**2017/12/18追記**
下のアイディアを、もっと扱いやすい形でHyperdash公式に取り込んでもらえました！（[PullRequest](https://github.com/hyperdashio/hyperdash-sdk-py/pull/113)）
まだドキュメントは無いようですが、以下の仕組みが理解できれば使えるものだと思います。また今度記事書こうと思います。

---

「ネットワークのトレーニング時間かかるし一日置いとくか」と放置していたら、最初の方でつまづいていたりすることがよくあります。次の日に気づくと悲惨です！
そこで、スマホアプリでリアルタイムに学習経過を見ることのできる便利なサービス[hyperdash](https://hyperdash.io/)を使いましょう。
インストールや基本的な動かし方は公式ページにあります。

この記事では少し応用してKerasのコールバックから、hyperdashのapiにつなげる方法を紹介します。
とは言っても、次の二つのファイルを用意するだけで終わりです。
実行は普段通り`python train.py`でOK!

```python:hyperdash_callback.py
from keras.callbacks import Callback

class Hyperdash(Callback):
    def __init__(self, exp):
        super(Hyperdash, self).__init__()
        self.exp = exp

    def on_epoch_end(self, epoch, logs=None):
        val_acc = logs.get('val_acc')
        val_loss = logs.get('val_loss')

        if val_acc is not None:
            self.exp.metric("val_acc", val_acc)
        if val_loss is not None:
            self.exp.metric("val_loss", val_loss)
```

```python:train.py
# 普段のimportに加えて以下の二つを追加
from hyperdash import Experiment
from hyperdash_callback import Hyperdash

def main():
    exp = Experiment("Experiment 1") # 宣言以降のログがスマホアプリに送られる

    # train dataやmodelを準備するコードをここに書く
    # ...

    hd_callback = Hyperdash(exp=exp)
    callbacks = [hd_callback] # Tensorboardなどのコールバックと併用できる
    history = model.fit(x_train, y_train, batch_size=32, verbose=1, epochs=50,
                        validation_split=0.1, shuffle=True,
                        callbacks=callbacks)

    exp.end() # 無事終了したことを示すためにコードの最後に置く

if __name__ == "__main__":
    main()

```

<img src="https://qiita-image-store.s3.amazonaws.com/0/98466/573a8f31-dfba-5e9a-8975-70bc23b1e0b4.png" width=50%>
便利！！（もう少し学習してる感のある画像にすればよかった）
競プロ等におけるpython3の標準入力

しょっちゅうわからなくなるのでチートシート作成。
必要を感じたら追加します。

---------------------------------------
入力：改行型int

```python
1
2
1
6
1
```

コード

```python
a = [int(input()) for i in range(5)]
```

※行数が不明な場合

```python
import sys
a = []
for l in sys.stdin:
    a.append(int(l))
```

print(a)

```python
[1, 2, 1, 6, 1]
```

---------------------------------------
入力：改行型文字列

```python
aa
ii
uu
ee
oo
```

コード

```python
a = [input() for i in range(5)]
```

print(a)

```python
[aa, ii, uu, ee, oo]
```

---------------------------------------
入力：連続文字int

```python
10 20 00
```

コード

```python
a = list(map(int,input().split()))
```

print(a)

```python
[10, 20, 0]
```

---------------------------------------
入力：連続文字列

```python
aa ii uu
```

コード

```python
a = input().split()
```

print(a)

```python
[10, 20, 0]
```

---------------------------------------
入力：複数行2数値

```python
1 2
3 4
5 6
7 8
9 0
```

コード     (2020/4/11 より良い方法をコメントにていただき変更しました。)

```python
xy = [map(int, input().split()) for _ in range(5)]
x, y = [list(i) for i in zip(*xy)]
```

print(x)
print(y)
print(x[1]+y[1])

```python
[1, 3, 5, 7, 9]
[2, 4, 6, 8, 0]
7
```

---------------------------------------
入力：複数行複合。リスト一つで処理。

```python
1 a
3 b
5 c
7 d
9 e
```

コード

```python
list = []
for i in range(5):
    a,b=input().split()
    list.append((int(a), b))
```

print(list[0][0]+list[1][0])
print(list[1][1])

```python
4
b
```

---------------------------------------

入力：行列

```python
1 2 3 4
5 6 7 8
1 1 1 1
```

コード

```python
a = [input().split() for l in range(3)]
```

print(a)

```python
[['1', '2', '3', '4'], ['5', '6', '7', '8'], ['1', '1', '1', '1']]
```

---------------------------------------
入力：単数値。桁ごとに分割したい。

```python
12345678
```

コード

```python
s = input()
a = [int(c) for c in s]
```

print(a[1])

```python
2
```

---------------------------------------


入力：複数行数値。ここから正方形の行列を作成

```python
123
456
789
```

コード

```python
import sys
a = [[int(c) for c in l.strip()] for l in sys.stdin]
```

print(a)
print(a[1][1])

```python
[[1, 2, 3], [4, 5, 6], [7, 8, 9]]
5
```

---------------------------------------
【Python】Tornadoの環境構築 / 2017年10月

#はじめに
私はある程度の環境構築を以前に済ましていたのでpipで入れましたが、Pythonをインストールするところからメモを残しておきたいと思います。

因みに「PythonのWebフレームワークはTornadoで下記条件のチャットアプリを作って」といただいたので本稿を作成しています。

①ユーザ同士でチャットが出来る部屋がある
②ユーザAとユーザBのチャットルームは他の人からは見れない
③ユーザ同士のチャット履歴はいつでも復元される(サーバ側に保存されている)
④ユーザ登録画面はあってもなくても
⑤チャットはリアルタイムで更新したい
・AWSのEC2とRDSを使ってインフラ構築
・EC2のOSはUbuntuまたはAmazon Linuxを使用
・RDSのDBMSにはMySQLを使用
・サーバ側はPythonで実装
・DBのORMにはsqlalchemyを使用
・マイグレーションにはalembicを使用
・コーディング規約はpycodestyle(pep8)に従う

Webクライアントであればハードル高くありませんが、バックもフロントも理解が深まりそうです！
上記条件のchatを少しずつ作っているのでそのうち投稿できたらいいなと思っています。

#Tornadoとは
>Tornadoは、Apache Licence 2.0に基づくオープンソースのノンブロッキングなWebサーバ&Webフレームワークです。TornadoはFriendFeedによって開発され、Facebookに吸収されたのちにオープンソース化されたフレームワークで、以下のような特徴があります。
* ノンブロッキングI/O
* リアルタイム性
* シンプルなテンプレート
* シングルスレッド、シングルプロセス

Djangoがフルスタック型のフレームワークなのに対して、Tornadoは自分で必要なコンポーネントを組み合わせていくフレームワークになります。
日本語情報は少ないのですが、多機能でドキュメントも充実しています。対照的に活用できれば大いに役立つことと思います。

#環境
MacbookPro Sierra 10.12.6
Python 3.6.3
tornado 4.5.2
homebrew
git

homebrewとgitは事前にインストール！


#pyenvをインストール
Pythonの複数バージョンをインストールする場合にpyenvを利用します。

```
$ brew install pyenv
```

#環境変数を設定
インストール後は ~/.bash_profile に書き込みます。

```
export PYENV_ROOT=$HOME/.pyenv
export PATH=$PYENV_ROOT/bin:$PATH
```

#pythonのインストール

$ pyenv install 3.6.3
$ pyenv install 2.7.13

上記のコマンドを実行するとそれぞれのバージョンのpythonがインストールされます。
pyenv global x.x.x、pyenv local x.x.xまたは、pyenv shell x.x.xでバージョンの切り替えができます。

globalとすると全体に、localにするとそのカレントディレクトリに、shellにすると今使用しているシェルのpythonのバージョンを変更できます。

#pyvenvで環境構築
「python3.6 -m venv」を実行してPythonの仮想環境を作成します。

```
$ cd ~
$ mkdir .virtualenvs
```

作成したらvenvを有効化します。
有効化したvenv内でpipで取得したパッケージが取得されます。

```
$ python3.6 -m venv .virtualenvs/tornado
$ source .virtualenvs/tornado/bin/activate
```

>因みにvenvを無効化する場合は、「deactivate」を実行

>```
$ deactivate
```

#Tornadoのインストール

pipを用いてインストール！

```
$ pip install tornado
```

公式サイトのドキュメントは下記のリンク
[Tornado Web Server — Tornado 4.4.2 documentation](http://www.tornadoweb.org/en/stable/)

ソースコード
公式ホームページに記載されているコードは下記の通りです。
実行すると「Hello, world」がブラウザに表示されます。

```
import tornado.ioloop
import tornado.web

class MainHandler(tornado.web.RequestHandler):
    def get(self):
        self.write("Hello, world")

def make_app():
    return tornado.web.Application([
        (r"/", MainHandler),
    ])

if __name__ == "__main__":
    app = make_app()
    app.listen(8888)
    tornado.ioloop.IOLoop.current().start()
```

上記のソースコードをserver.pyに保存します。

```
$ cd ~/.virtualenvs/tornado
$ mkdir workspace
$ vi server.py
```

そして、：wqで保存して抜け出します。

server.pyをpythonで実行

```
$ python server.py
```
ターミナルには何も表示されませんが、
ブラウザで[http://localhost:8888](http://localhost:8888)にアクセスすれば下記のように表示されます。

<img width="438" alt="スクリーンショット 2017-10-20 18.09.21.png" src="https://qiita-image-store.s3.amazonaws.com/0/200922/ab00277b-34c3-dc19-d2c6-f241ad63a66a.png">


因みにクライアントからアクセスするときは

```
$ wget -q -O - http://localhost:8888/
Hello World
```

になります。


#終わりに
Pythonで何かを表示したいときにGUIを組むほどでもないけどコンソールだけだとさみしい...
そんなときにはTornadoを使ってwebsocketでブラウザにデータを送り、ブラウザに表示すると良いよという記事があったので下記に貼っておきます。
[Tornadoを使ってブラウザをPythonの表示器代わりに使うメモ](https://qiita.com/Dr10_TakeHiro/items/4b6a6e7e3cea6e62252a)

お疲れ様でした！
nodebrewでrequired brew_dirというエラーになる

nodebrewでrequired brew_dirというエラーになる。
nodebrewのコマンドどれを使ってもこのエラー。

```
$ nodebrew list
required brew_dir at /Users/user_name/.nodebrew/current/bin/nodebrew line 39.
```

確認したら、nodebrewのパスが間違っていたので修正。

```
$ export NODEBREW_ROOT=$HOME/.nodebrew
```

これでちゃんと動くようになりました。

```
$ nodebrew
nodebrew 0.9.2

...
```
普通にScalaの環境を作って試したい

ただ、Scalaを試したいだけなのに、普通？のやり方が載ってない。
環境がVimとCentosなこともあるかもだけど、ここに調べて分かったことだけを載せる。

# 環境
Centos 7
Vim

# 必要環境
Scala
sbt
playframework

# 目標
Scalaでサーバを起動してHello Worldするまで。

# 環境構築

scalaenvのインストール

```bash
$ git clone git://github.com/mazgi/scalaenv.git ~/.scalaenv
$ echo 'export PATH="${HOME}/.scalaenv/bin:${PATH}"' >> ~/.bash_profile
$ echo 'eval "$(scalaenv init -)"' >> ~/.bash_profile
```

sbtのインストール

```bash
curl https://bintray.com/sbt/rpm/rpm | sudo tee /etc/yum.repos.d/bintray-sbt-rpm.repo
sudo yum install sbt
```

playフレームワークテンプレートのインストール

```bash
 sbt new playframework/play-scala-seed.g8

```

ひたすら待つ。

#起動

```
sbt run

```

ひたすら待つ。
http://localhost:9000 
アクセスすると、Welcome to Playが表示される。
目標達成。やったー。


これから。
意外と簡単だったけど、このやり方を見つけるのにいくつもページを回った。
あとは、vim-scalaを入れたい。
フレームワークは、giter8とActivatorの二つのやり方があるらしい。今回はgiter8を使ったみたいだけど、
どっちが普通？

参考
https://qiita.com/necojackarc/items/bc2f41d5a00926e9b0c5
SCSS　アンチパターン

# scss　アンチパターン
昨今、「デザインが多様化」しているので、「詳細度を高める記述は悪」とされる傾向なのかと推測しております。
そうなると、擬似クラス、擬似要素を使用した記述方法は、代替案か、関数型思考等が取り入れられるのが待ち遠しいところ。

まずは、不要に詳細度を高めるパターンに遭遇したので、今後自分がその記述をしないようにするために投稿致します。

## タグの入れ子

```scss
.content {   
  .content__wrap {
     .content__link {

     }
     .content__item {
      .content__list {

       }
     }
   }
 }
```

.content\_\_itemを適用するには、必ず.content\_\_wrapが必要になります。content\_\_wrapに記載されているプロパティがcontent__itemに影響していれば、modifier等で変更する必要があるかと思います。

もうこのように記述される方は、いないと思います。
## 要素セレクタの指定

```css
.item {


}
```

liタグでないタグにも適用したい、余白調整などのプロパティを少し変更したいといった場面で困ります。
.itemのmodifierを作成し、同じく .item--modifier li{}と記述するほかありません。
iOSでLINEのQRリーダーが#(hash)以降を勝手に削る対策

URLに#の入ったURLをiOSのLINEで読み込もとうしたところ、
なぜか#を含むそれ以降のURLが表示されなかった。
Androidだと読み込めるのになぜ...。

ということでhtaccessで無理やり対策。
QRで発行するURLは下記とします。
http://fromurl/test.php%23NANNTARAKANTARA

```bash
RewriteEngine on
RewriteRule test.php#(.*) http://gotourl/test.php#$1 [R,NE,L]
```

コレ以外にもやり方知っている方教えてください。
Linuxでサブディレクトリ別の容量を調べる

## はじめに
ディスク使用量が気づいたら残り12Gになっていたので、使用量の大きなところを特定して削除する必要があった。その際に闇雲に探しても時間の無駄なので、コマンドを利用して探すのが得策です。

## コマンド

引数|説明
---|---
**-s**, **--summarize**|引数で指定したものの総計のみ表示する。
**-h**, **--human-readable**|人が読み易い形式(e.g., 1K 234M 2G)で表示する。

```sh
# カレントディレクトリ以下でサブディレクトリ別の容量を表示
$ du -sh ./*/
```

## 参考
* [Man page of DU](https://linuxjm.osdn.jp/html/GNU_fileutils/man1/du.1.html)
joinコマンドの使い方

##ここに書いてあること
便利なコマンド`join`使いかたのまとめ
バイオシェル芸では遺伝子発現データの結合などで使う

##参考にした記事
こちらにほとんど書いてある。もしかしてシェル芸人...
[joinコマンドで覚えておくと便利な使い方8個](https://orebibou.com/2017/07/joinコマンドで覚えておくと便利な使い方8個/)
こちらも。
[joinコマンドが便利過ぎて生きるのが辛い]
(http://yut.hatenablog.com/entry/20120907/1346975281)

##使いかた
1列目が遺伝子名, 2列目に発現量（何かの値）
結合したい列で`sort`しておく

```shell-session
$ cat inu.txt
geneA	100
geneB	110
geneC	120
geneE	130
```

```shell-session
$ cat neko.txt
geneA	200
geneB	210
geneD	220
geneF	230
```

###inuとnekoで共通に発現している遺伝子
```
$ join -1 1 -2 1 inu.txt neko.txt
```
geneA 100 200
geneB 110 210

オプション`-1 1 -2 1` は結合キーとなる列を指定
（1番目のファイルの1列目と2番目のファイルの1列目）
2つのファイルのどちらにも値がある行だけが出力される

###全ての遺伝子の値

```
$ join -o '0,1.2,2.2' -a 1 -a 2 -e '-' inu.txt neko.txt
```
geneA 100 200
geneB 110 210
geneC 120 -
geneD - 220
geneE 130 -
geneF - 230

発現していない（値がない）遺伝子のところに-が入る
その他オプション
`-o 'num,num.num,....'`　表示する列を指定, 0は結合キーの列,n.nでn番目のファイルのn列目
`-a num` 指定したファイルの行は全部表示する
`-e 'string' `　値がないところを'string'で指定した文字で埋める

* 先日の[バイオシェル芸勉強会](https://bio-shell.connpass.com/event/66089/)のお題にあった

##その他
-  -e 'string'でデータのないフィールドに何か文字を入れたいときは、-o オプションと一緒でないと（つまり出力フィールドを指定してやらないと）何も出てこない
deviseで新規登録を行うと自動でアカウントが切り替わる問題

タイトルの通りです。
deviseの新規作成を他の画面からでも行えるような設定を行っています(デフォルトではログイン前でしか新規作成はできない)。

## 動作環境
Rails 5.0.4
devise 4.3.0

## 該当ソース
継承元のgemファイルのコントローラーです。

```registrations_controller.rb
class Devise::RegistrationsController < DeviseController
  prepend_before_action :require_no_authentication, only: [:new, :create, :cancel]
  prepend_before_action :authenticate_scope!, only: [:edit, :update, :destroy]
  prepend_before_action :set_minimum_password_length, only: [:new, :edit]

  # GET /resource/sign_up
  def new
    build_resource({})
    yield resource if block_given?
    respond_with resource
  end

  # POST /resource
  def create
    build_resource(sign_up_params)

    resource.save
    yield resource if block_given?
    if resource.persisted?
      if resource.active_for_authentication?
        set_flash_message! :notice, :signed_up
        sign_up(resource_name, resource)
        respond_with resource, location: after_sign_up_path_for(resource)
      else
        set_flash_message! :notice, :"signed_up_but_#{resource.inactive_message}"
        expire_data_after_sign_in!
        respond_with resource, location: after_inactive_sign_up_path_for(resource)
      end
    else
      clean_up_passwords resource
      set_minimum_password_length
      respond_with resource
    end
  end
・
・
・
```

原因はこいつ`sign_up(resource_name, resource)`
このメソッドで新しく作成されたアカウント(resource)でログインしなおしているようです。
なので、継承先(deviseの設定を行った際にできるregistrations_controller.rb)にcreateアクションを完コピしてあげます。

```app/controllers/users/registrations_controller.rb
class Users::RegistrationsController < Devise::RegistrationsController
  before_action :configure_sign_up_params, only: :create
  prepend_before_action :require_no_authentication, only: :cancel
  prepend_before_action :authenticate_scope!, only: %i[new create]
  prepend_before_action :set_minimum_password_length, only: :new
  before_action :back_link, only: :create
  # ↑ デフォルトの状態から、設定追加/変更しています

  # GET /resource/sign_up
  def new
    super
  end

  # ↓ ここにコピー
  # POST /resource
  def create
    build_resource(sign_up_params)
    resource.save
    yield resource if block_given?
    if resource.persisted?
      if resource.active_for_authentication?
        set_flash_message! :notice, :signed_up
        # sign_up(resource_name, resource)
        sign_up(resource_name, current_user) # current_user = 新規作成を行っているユーザー
        respond_with resource, location: after_sign_up_path_for(resource)
      else
        set_flash_message! :notice, :"signed_up_but_#{resource.inactive_message}"
        expire_data_after_sign_in!
        respond_with resource, location: after_inactive_sign_up_path_for(resource)
      end
    else
      clean_up_passwords resource
      set_minimum_password_length
      respond_with resource
    end
  end
```
`sign_up(resource_name, current_user) # current_user = 新規作成を行っているユーザー`
この一行を追加してください。
deviseの`sign_up`メソッドは実質`sign_in`と同じになっているようでした。

これで新規作成を行った際にアカウントが切り替わらなくなります。

## おわりに
deviseは意外と手強い
API Connect 開発者ポータルで開発者によるユーザー登録機能を無効にする方法

# はじめに

API Connectでは、APIの仕様等を公開する開発者ポータルを用意することができます。デフォルト設定で開発者ポータルを公開すると、開発者が自身でユーザー登録することが可能です。要件によっては、特定のユーザーのみポータル利用をさせたい場合があります。ここでは、ユーザー登録機能を無効にする方法を記述します。

# 前提条件

IBM API Connect v5.0.8.0, IBM DataPower Gateway v7.6.0.2 の組み合わせ(オンプレミス環境)で動作を確認しています。Cloud環境でも同様に稼働します。

# デフォルト設定の場合

デフォルト設定の場合、開発者ポータルにアクセスすると、画面右上のメニューに「Create an account」ボタンが表示されます。
![スクリーンショット 2017-10-25 11.07.24.png](https://qiita-image-store.s3.amazonaws.com/0/121209/6b132702-d760-c6f1-d212-4ba0ddef82d6.png)

「Create an account」をクリックすると、ユーザー登録画面が表示され、必要情報を入力することでユーザー登録を進めることができます。
![スクリーンショット 2017-10-25 11.07.55.png](https://qiita-image-store.s3.amazonaws.com/0/121209/5225cbd9-d2b6-a056-3713-470364bbab07.png)

以降では、この手順が実行できないようポータルを設定します。

# ユーザー登録機能を無効にする

API Managerにログインします。「ダッシュボード」から、開発者ポータルとして公開しているカタログを選択します。
「設定」タブを選択し、左メニューの「ポータル」を選択します。
「ユーザーの登録と招待」内の、「セルフサービス・オンボーディング」のトグルをoffにします。offにすると開発者は、招待がないとユーザー登録ができません。
![スクリーンショット 2017-10-25 11.28.20.png](https://qiita-image-store.s3.amazonaws.com/0/121209/391ae2ab-082d-5f3f-8af8-87a11f455f79.png)

開発者ポータルの画面では、以下のように「Create an account」が表示されません。
![スクリーンショット 2017-10-25 11.34.43.png](https://qiita-image-store.s3.amazonaws.com/0/121209/c928dea4-6130-2c94-a34d-947790b6c3bc.png)

# 開発者組織、開発者の登録

開発者によるユーザー登録を無効にした場合、API Managerで開発者組織を登録することになります。

API Managerにログインし、先ほどと同様、「ダッシュボード」から、開発者ポータルとして公開しているカタログを選択します。
「コミュニティー」タブを選択し、左メニューの「開発者組織」を選択します。
「追加」ボタンをクリックし、開発者組織を追加します。
![スクリーンショット 2017-10-25 13.12.40.png](https://qiita-image-store.s3.amazonaws.com/0/121209/b152316e-e320-823d-b66d-70995383b390.png)

必要項目を入力すると、開発者組織が作成されます。
![スクリーンショット 2017-10-25 13.27.25.png](https://qiita-image-store.s3.amazonaws.com/0/121209/a36e3c3b-fe95-2b52-b07f-c32140dea7bc.png)

入力したメールアドレスにアクティベーション用メールが送信されます。
![スクリーンショット 2017-10-25 13.26.24.png](https://qiita-image-store.s3.amazonaws.com/0/121209/b82d11cd-d761-ecdd-6b47-bcd795192b85.png)

メールリンクをクリックするとアクティベーションを行えます。
![スクリーンショット 2017-10-25 13.31.39.png](https://qiita-image-store.s3.amazonaws.com/0/121209/66801d15-5663-79dc-2b5c-bd64dd1f55ad.png)

アクティベーション完了後、開発者組織の所有者としてログインすると、組織を管理することが可能です。
![スクリーンショット 2017-10-25 13.40.55.png](https://qiita-image-store.s3.amazonaws.com/0/121209/cad85833-0e3e-572b-6f64-85fd2592e2c0.png)

ユーザーの追加、削除などができます。
![スクリーンショット 2017-10-25 13.43.41.png](https://qiita-image-store.s3.amazonaws.com/0/121209/da326eec-31da-ed2a-2dbe-18917eef3ac6.png)
vim のシンタックスハイライタを作るときに参考にしたサイト

* [vimで構文のハイライトを自作する - Qiita](https://qiita.com/kimurap/items/7058c9fe29f51932b196)
* [vimの構文ハイライトファイルを書いてみた 作成～コメントアウトをハイライトするまで - ケーズメモ](http://d.hatena.ne.jp/ksmemo/20090906/p2)
* [Creating your own syntax files | Vim Tips Wiki | FANDOM powered by Wikia](http://vim.wikia.com/wiki/Creating_your_own_syntax_files)
* 
* [syntax - Vim日本語ドキュメント](http://vim-jp.org/vimdoc-ja/syntax.html)
*
rbenvを使ったrailsワークフロー

備忘録として記載。

#前提
- rbenvはすでに入っている
- その他環境構築済み

rbenvのインストール/その他開発環境構築に関する内容は以下を参照にすると良さそう。

- <a href="https://qiita.com/emadurandal/items/e43c4896be1df60caef0#rails%E3%83%97%E3%83%AD%E3%82%B8%E3%82%A7%E3%82%AF%E3%83%88%E3%81%AE%E8%B5%B7%E5%8B%95" target=_blank>Rails開発環境の構築（複数バージョン共存可能）（Homebrew編）</a>
- <a href="https://qiita.com/egopro/items/aba12261c053eecd6d19" target=_blank>rbenv インストールから Bundler を使用した Rails のローカルインストールと起動まで</a>
- <a href="http://d.hatena.ne.jp/clmind/20111109/1320814435" target=_blank>rbenvでrailsの動作環境を構築</a>


#ワークフロー

主に以下の３つのパターンに分けられる。

- rubyのバージョン確認/ローカル設定
- railsのローカルインストール
- railsプロジェクト作成

##rubyのバージョン確認/ローカル設定

###知っておくと役に立つコマンド一覧
- `rbenv versions`ですでに入っているrubyのバージョンを確認。
- `rbenv install -l`でインストール可能なバージョンを確認。
- `rbenv install [version]`で指定したバージョンをインストール。

```
$ cd /path/to/project
$ rbenv local [version]
$ rbenv version #現在採用しているバージョン確認
```

##railsのローカルインストール

まずはじめにローカルのrubyにbundlerのみをインストールする

```
$ rbenv exec gem install bundler
$ rbenv rehash
```
次にrailsをインストールするためにgemfileを作成する

```
cat << EOS > Gemfile
source "http://rubygems.org"
gem "rails", "x.x.x" #<-指定しなければ最新版がインストールされる
EOS
```

`bundle install --path vendor/bundle`を実行。
railsを`vendor/bundle`いかにしまっておく。ruby環境内にgemを入れたくないので一時的に`vendor/bundle`にしまうよう命令しておく。

##Railsプロジェクト作成

`bundle exec rails new sample`で新たなプロジェクト作成

続いてrailsインストールに使った不要なファイルを削除する

```
rm -f Gemfile
rm -f Gemfile.lock
rm -rf .bundle
rm -rf vendor/bundle
```

ちなみにgitからクローンしてきたプロジェクトならばruby環境を合わせて`bundle install --path vendor/bundle`を行ってあげるだけで必要なgem環境を構築できる。
ansible1.9.6 | playbook実行時に インベントリファイルに 127.0.0.1 と localhost を両方書けない

# 問題

```inventory.txt
[example1]
localhost

[example2]
127.0.0.1
```

example1 を対象にした playbook を作り実行する

```:playbook.yml
---
- hosts: example1
  tasks:
  - debug: msg=TEST
```

## 結果

謎エラー。

```
$ ansible-playbook -i inventory playbook.yml

PLAY [example1] ***************************************************************

GATHERING FACTS ***************************************************************
ok: [localhost]

TASK: [debug msg=TEST] ********************************************************
FATAL: no hosts matched or all hosts have already failed -- aborting


PLAY RECAP ********************************************************************
localhost                  : ok=1    changed=0    unreachable=0    failed=0
```

![image.png](https://qiita-image-store.s3.amazonaws.com/0/89618/f84b9310-aee8-6dc0-e0b5-b36cdba532b6.png)



# 対応

両方 localhost にしてみる

```inventory.txt
[example1]
localhost

[example2]
localhost
```

## 結果

通る。

```
$ ansible-playbook -i inventory playbook.yml

PLAY [example1] ***************************************************************

GATHERING FACTS ***************************************************************
ok: [localhost]

TASK: [debug msg=TEST] ********************************************************
ok: [localhost] => {
    "msg": "TEST"
}

PLAY RECAP ********************************************************************
localhost                  : ok=2    changed=0    unreachable=0    failed=0
```

![image.png](https://qiita-image-store.s3.amazonaws.com/0/89618/6af1716b-be57-03a7-6096-fc4bb190e625.png)

# 備考

`ansible 2.4.0.0` では警告だけが出るように修正されていた。(中間のバージョンは確認していない)

```
$ ansible-playbook -i inventory playbook.yml

 [WARNING]: A duplicate localhost-like entry was found (127.0.0.1). First found localhost was localhost
```

# 環境

- ansible 1.9.6
- Mac OS X
- Docker version 17.09.0-ce, build afdb6d4








<!-- Update From Qiita API -->

# チャットメンバー募集


何か質問、悩み事、相談などあればLINEオープンチャットもご利用ください。

https://line.me/ti/g2/eEPltQ6Tzh3pYAZV8JXKZqc7PJ6L0rpm573dcQ





# Twitter


https://twitter.com/YumaInaura


<!-- Update From Qiita API -->
ruby 自作メソッドを作って使ってみた。

rubyで、自作メソッドを作って
そのメソッドにキーボード入力で値を入れて
戻り値を取得してみます。

```ruby:test.rb
def test(num1, num2)
  puts "合計：#{ num1 + num2 }"
end

input1 = gets.chomp.to_i
input2 = gets.chomp.to_i
test(input1, input2)
```
test.rbをターミナルで実行して
戻り値が返ってくるか確かめてみます。

```ruby:test.rb
$ ruby test.rb
#=> 111 # 入力値をinputに代入
#=> 444 # 入力値をinput1に代入
#=> 合計：555 メソッドの戻り値
```

こんな感じでメソッドを作って実行してみました。
これは初心者の初歩的なものです。
Perl(メモ) コンテキスト リファレンス デリファレンス

>[参考](https://github.com/hatena/Hatena-Textbook/blob/master/foundation-of-programming-perl.md)

```perl


use strict;
use warnings;

# コンテキスト(代表的ハマりポイント!!!!)
my @hoge = (3, 0, 1, 2);

my ($ans) = @hoge;
print $ans."\n"; #3 配列へ代入すると0番目のみ代入される

my $ans2 = @hoge;
print $ans2."\n"; #4 配列はスカラコンテキストでで評価すると長さが返される。

print $#hoge."\n"; #4 末尾の添字が表示されます 

## 配列の操作
#my @array = ('a', 'b', 'c', 'd');


#### 記号の使い方!!!!!


### リファレンスの取得作成（配列）
my @x = (1, 2, 3);
my $ref_x1 = \@x;

# 略記
my @ref_x2 = [1, 2, 3];
my $ref_x3 = [@x];



### デリファレンス(配列)
my $ref_x = [1, 2, 3];
print $ref_x->[0]."\n";
my @new_x = @$ref_x; # 記号に注意!!!
#print @new_x->[0]."\n"; Can't use an array as a reference at main.pl
print $new_x[0]."\n";

### リファレンスの取得/作成 (ハッシュ)

my %y = (
	perl => 'larry',
	ruby => 'matz',
	);
my $ref_y1 = \%y;

# 略記
my $ref_y2 = {
	perl => 'larry',
	ruby => 'matz',
};

### デリファレンス(ハッシュ)
my $ref_y = {
	perl => 'larry',
	ruby => 'matz',
};

print $ref_y->{perl}."\n"; # larry

my %new_f = %$ref_y;

print $new_f{perl}."\n"; #larry


## リファレンス/デリファレンスを扱う上で...

# 悪い例
my @foo = (1, 2, 3);
my %foo = (a => 1, b => 2, c => 3);
# $foo[1], $foo{a}
# 同じ変数を参照しているように見えるが、実際は違う変数です
## なので!! 基本的にリファrンス以外使わない(ハマりにくい)


# 必要な時だけデリファレンスする
my $list = [1, 2, 3];
push @$list, 10;

print $list->[3]."\n"; # 10
```
twig2系で再帰処理

twigで再帰処理を使う場合は`macro`を使うと楽だと思います。
twig1系では[twig で再帰処理](https://qiita.com/nanasess/items/5a1a6dbc1090e8ec0b36)の通りに実装すれば大丈夫です。

しかし、twig２系だと`_self`はテンプレート名を返してきてしまうため、`_self.foobar()`みたいな呼び出しができなくなってしまった・・・。

stackoverflowによると`import`文を使えばいいみたい。
[Twig Runtime Error: Impossible to invoke a method (“test”) on a string variable](https://stackoverflow.com/questions/42484037/twig-runtime-error-impossible-to-invoke-a-method-test-on-a-string-variable)

この記事を参考にして、twig2系での再起処理を実装してみた。
ポイントとしては`macros`を引数で渡すこと。
macroで定義した`recursiveCategories`の中ではimportした`macros`を参照できないため、仕方なく引数で渡すようにしている。
もっといい方法があれば良いのだが・・・。

```
{% import _self as macros %}

{% block body %}
        {% macro recursiveCategories(Category, macros) %}
            {% if Category.hasChildNodes() %}
                <ul>
                    {% for child in Category.childNodes() %}
                        <li>{{ child.name }}</li>
                        {{ macros.recursiveCategories(child) }}
                    {% endfor %}
                </ul>
            {% endif %}
        {% endmacro %}

        {% if Category.hasChildNodes() %}
        <ul>
            {% for ChildCategory in Category.childNodes() %}         
                <li>{{ ChildCategory.name }}</li>
                {{ macros.recursiveCategories(ChildCategory, macros) }}         
            {% endfor %}
        </ul>
        {% endif %}
{% endblock}
```



参考
https://github.com/symfony/demo/issues/322
umount時に「複数マウントされているようです」と表示されてマウント解除できない場合の対応

結果的には簡単なことでしたが、検索してもズバリの回答が見当たらなかったので記事にしてみます。

同じマウントポイントに複数回マウントをかけてしまいました。
例えば、下記のようにmountコマンドを2回実施したと思ってください。
mountは管理者でないとできないので、rootになっています。

*2019.9.8追記：マウントポイントは、普通 /mnt 配下ですよね... ということで、修正しました。（元は/home/user 配下でマウントする例になっていました。）*

`# mount -t cifs -o user=hoge,password=fuga //192.168.0.2/taeget_dir /mnt/mountpoint`
`# mount -t cifs -o user=hoge,password=fuga //192.168.0.2/taeget_dir /mnt/mountpoint`

後から気づいて**一般ユーザのままで**解除しようとしたところ、下記メッセージが表示されアンマウントできません。
（そもそも一般ユーザではアンマウントできないのですが、この時点では気づいておらず。）

`$ umount /mnt/mountpoint`
`umount: /mnt/mountpoint は複数マウントされているようです`

ここで一般ユーザのままであることに気づけばよかったのですが、しばらく検索するなど遠回りをしてしまいました。
結果的には、rootでumountすることでアンマウントできました。

`# umount /mnt/mountpoint`

1つずつアンマウントされるので、複数マウントされているのをすべて解除するには、複数回umountを実行する必要があります。


##ちなみに
複数マウントされた状態でなければ、一般ユーザでumountしようとすると次のメッセージが表示されます。これならミスに気づきやすいですね。

`$ umount /mnt/mountpoint`
`umount: /mnt/mountpoint は　fstab にありません (さらに、あなたは root ではありません)`
AtomでLangageパッケージの対象拡張子を増やしたい

# Langageパッケージの対象拡張子を増やしたい
対象パッケージは[language-vbdotnet](https://atom.io/packages/language-vbdotnet)
デフォルトだと対象拡張子はvbのみ。
ですがaspxも対象にしたい。
なので、パッケージのcsonファイルを修正します。

メニューバー[File]→[Settings]→[Open Config Folder]
.atom/package/langage-vbdotnet/grammers/vbdotnet.cson

fileTypesにaspxを追加します。
`'fileTypes': ['vb']`
↓
```'fileTypes': [
　'vb'
　'aspx'`
]
```

csonファイルを保存して完了です。
WSLでDockerを使う

# Windows10のWindows Subsystem for LinuxでDockerを使う

何かリンクされたみたいと思ったら、こんな時代になってるそうでした。

2018/07/06 [WSL上でDocker Engineが動くようになっていたっぽいという話](https://qiita.com/yanoshi/items/dcecbf117d9cbd14af87) - Qiita
元ネタ [docker is running natively on wsl](https://www.reddit.com/r/bashonubuntuonwindows/comments/8cvr27/docker_is_running_natively_on_wsl/) reddit

なんと、WSL から直接 docker 動いた！ でも、ちゃんと使おうとするとまだまだ制限がきついかな。（上記 reddit に書いてあるのと同じ現象で詰まった）やっぱり、まだまだ辛いですね。

##### 以下、元々の記事です。

Windows10のFall Creators Updateが一般提供開始され、Windows 10 Homeでも WSL (Windows Subsystem for Linux) で Ubuntu （他にもあるけど） を使えるようになりました。持っている Atom ベースの UMPC で、Ubuntu の Docker を動かしたいと思っていたのですが、VirtualBox に入れた Ubuntu では重くてどうしたものかと考えていました。

そこで、WSL があるのですが、docker入れてもdocker serverが動かない。Windows 10 Pro なら、Hyper-Vを有効化してDocker for Windows入れれば、WSLからも使えるのですが、ここは Home で何とかしたいです。

ということで、VirtualBoxに入れたUbuntuをDocker Serverとしてヘッドレスモードで動かして、WSLから使うことにしてみました。

#1. VirtualBoxのUbuntuにDockerをインストール

まずVirtualBoxにUbuntuをインストールする時点で、ネットワークアダプター#2に`ホストオンリーアダプター`を追加して使えるようにしておきます。IPアドレスを固定化しておくと良いかもです。

これには、[Docker公式の手順](https://docs.docker.com/engine/installation/linux/docker-ce/ubuntu/#set-up-the-repository)でリポジトリを設定して`docker-ce`をインストールします。

前提ソフトウェアのインストールができていれば。

```
$ curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
$ sudo add-apt-repository \
   "deb [arch=amd64] https://download.docker.com/linux/ubuntu \
   $(lsb_release -cs) \
   stable"
```

としてリポジトリを設定して、`docker-ce`をインストールします。

```
$ sudo apt update
$ sudo apt install -y docker-ce
```

#2. docker serverの待ち受け

docker serverがWSLからのリクエストを受け付けるように設定しておきます。

```
$ cd /etc/systemd/system/multi-user.target.wants
$ sudo vi docker.service
ExecStart=/usr/bin/docker -H fd:// -H　tcp://192.168.56.xxx:2375
$ sudo systemctl daemon-reload
$ sudo systemctl restart docker
```

ここでは、`ホストオンリーアダプター`のIPアドレスとポート番号を`2375`にしてみました。

# 3. WSLにdockerをインストール

VirtualBoxのUbuntuと同様にして`docker-ce`をインストールします。この時点では、`docker version`してもクライアント情報しか表示されません。

VirtualBoxのUbuntuで稼働している`docker server`に接続するために、`.bashrc`に環境変数を追加します。

```
$ vi .bashrc
export DOCKER_HOST='tcp://192.168.56.xxx:2375'
```

これで無事に使えるようになりました。

#4 docker server の起動/停止

VirtualBoxを使用していますから、スタートアップフォルダに`VBoxManage`コマンドでインスタンスを起動するショートカットを作成してみました。もちろん、ヘッドレスモードで起動しています。

Windowsのログインで無事に自動起動できるようになったのですが、シャットダウンする際に一々確認メッセージが出ています。もともと、非力な UMPC で動かすつもりですから使いたい時にだけ起動していれば十分です。

そこで、WSL側から`VBoxManage`コマンドを使って起動/停止することにしました。起動は、こうなります。

```
`/mnt/c/Program Files/Oracle/VirtualBox/VBoxManage.exe' startvm Ubuntu --type headless
```

ここでは`Ubuntu`としていますが、VirtualBoxに作成した仮想マシン名になります。

停止は、こんな感じです。

```
`/mnt/c/Program Files/Oracle/VirtualBox/VBoxManage.exe` controlvm Ubuntu acpipowerbutton
```

既に起動済みかどうかも確認できます。

```
`/mnt/c/Program Files/Oracle/VirtualBox/VBoxManage.exe` list runningvms
```

実際にはalias切って使うつもりですけど、とりあえずは、これで十分かな！
Apexでネスト(入れ子)のMapを使う時によくやる奴

入れ子のMapをよく使います。で、良くハマります。以下は備忘録。

##Mapに存在しないキーで呼び出すとエラーが出る
VisualforceでMapに存在しないキーで呼び出すとエラーがでるので注意しましょう。
呼び出す可能性があるキーはまずMapに突っ込んでおかないと駄目です。
よくやるのが、年月のテーブルです。

| 名前 | 4月 | 5月 | 6月 | 7月 | 8月 | 9月 | 10月 | 11月 | 12月 | 1月 | 2月 | 3月 |
|:------------:|:------------:|:------------:|:------------:|:------------:|:------------:|:------------:|:------------:|:------------:|:------------:|:------------:|:------------:|:------------:|
| C1| 100|200|300| 400| 500| 600| 700| 800| 900| 1000| 1100| 1200|
| C2| 1200|1100|1000| 900| 800| 700| 600| 500| 400| 300| 200| 100|

こういうテーブルを作りたい時に入れ子Mapを使うのですが、その場合は最初に全てのキーを突っ込んでおきます。

```Apex:Apexクラス
public Map<String,Map<Integer,Integer>> monthlyMap{get;set;}
LIST<String> keyName = new LIST<String>();
keyName.add('C1','C2'); //カテゴリ名みたいなモノ
LIST<Integer> intM = new LIST<Integer>();
intM.add(4,5,6,7,8,9,10,11,12,1,2,3);//月
for(String k : keyName){//カテゴリ名でループ
    Map<Integer,Integer> innerMap = new Map<Integer,Integer>();
    for(Integer i :intM){//内部Map用のデータを生成
        innerMap.put(i,null);
    }
    monthlyMap.put(k,innerMap);
}
```
こうして初期化しておけばVisualforce側でエラー出ないと思います。
その上で希望のデータを入れましょう

##入れ子のMapのデータにVisualforceからアクセスするには
上記のC1の4月のデータにアクセスしたい場合は

```Visualforce:Visualforce
<apex:outputtext value="{!monthlyMap['C1'][4]} />
```
という感じで指定します。

##年度の商談をSOQLで取得する場合

```apex:年度の商談をSOQLで取得
Integer thisYear = 2017;
LIST<Opportunity> thisYearOpps = LIST<Opportunity>();
thisYearOpps = [SELECT ID,CloseDate,categoryName__c FROM Opportunity WHERE FISCAL_YEAR(CloseDate) = :thisYear];
```
こんな感じでFISCAL_YEAR(CloseDate)を使う
categoryName__cは適当なカスタム項目です。

##商談のリストに絡めた形でMapのデータを取得するには
よくやるパターンですが、例えば商談の集計結果に付随したデータみたいなのを表示したいという場合です。
上記のthisYearOppsを表示して、それに引っ掛けてmonthlyMapのデータを使ってみます

```Visualforce:Visualforce
<apex:repeat value="{!thisYearOpps}" var="op">
<apex:outputtext value="{!monthlyMap[op.categoryName__c][month(op.CloseDate)]} />
</apex:repeat>
```
こんな風にします。Visualforce側で month()でDate型のデータを囲むとInteger型で月の数字を返してくれます。

一番上に書いたようなテーブルを作る場合は、LIST<LIST<Opportunity>>みたいな感じでリストのリストにしてapex:repeatを入れ子にすれば良いでしょう。
CakePHP コールバックのトランザクション確認

# save() 時のトランザクション状態確認

* CakePHP 3.5.4 で確認

beforeSave()、afterSave()、afterSaveCommit()で、トランザクションの状態を確認して見た。



# 結果

1 がトランザクション中、０はトランザクション外。

|コールバック    |begin()なし| beginあり |transactional()|
|----------------|----------|-----------|---------------|
|beforesave()    |1         |  1        |1              |
|aftersave()     |1         | 1         |1              |
|afteraveCommit()|0         |  -        |-              |
 

自前でトランザクションを開始するしないに関わらず、beforeSave(),afterSave()はsave()からのトランザクションになる。

afterSaveCommit()はドキュメントの通り、save()実行前にトランザクション開始されてたら呼ばれない。
Connection::commit() コミットしても呼ばれない。


# 参考：テストコード

```table.php
    public function beforeSave(\Cake\Event\Event $event, \Cake\Datasource\EntityInterface $entity, \ArrayObject $options)
    {
        debug('beforeSave():' . $this->getConnection()->inTransaction());
    }

    public function afterSave(\Cake\Event\Event $event, \Cake\Datasource\EntityInterface $entity, \ArrayObject $options)
    {
        debug('afterSave():' . $this->getConnection()->inTransaction());
    }

    public function afterSaveCommit(\Cake\Event\Event $event, \Cake\Datasource\EntityInterface $entity, \ArrayObject $options)
    {
        debug('afterSaveCommit():' . $this->getConnection()->inTransaction());
    }
```


```test.php
    public function testSave1()
    {
        echo '-------- save ---------' . PHP_EOL;

        $ad = $this->Users->newEntity();
        $ad->name = 'no-tran';

        $this->Users->save($ad);
    }

    public function testSave2()
    {
        echo '---------- save in Tran --------' . PHP_EOL;
        $ad = $this->Users->newEntity();
        $ad->name = 'in-tran';

        $this->Users->getConnection()->begin();
        $this->Users->save($ad);
        $this->Users->getConnection()->commit();
    }

    public function testSave3()
    {
        echo '----------- transactional() ---------' . PHP_EOL;

        $this->Users->getConnection()->transactional(function($conn) {
            $ad = $this->Users->newEntity();
            $ad->name = 'transactional()';
            $this->Users->save($ad);
        });
    }
```
Linux ゲストから見た VMWare の Bluetooth

VMware の BT が Linux からどのように見えるか整理します。VMware fusion 8.5.8 で動作確認。

VMware の設定画面 Virtual Machine > Settings > USB & Bluetooth には Share Bluetooth devices with Linux という項目があります。ここをチェックすると BT の振る舞いが変わります。

## Share Bluetooth devices with Linux が有効の時

```
# lsusb
...
Bus 002 Device 008: ID 0e0f:0008 VMware, Inc. 
Bus 002 Device 003: ID 0e0f:0002 VMware, Inc. Virtual USB Hub
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 002 Device 002: ID 0e0f:0003 VMware, Inc. Virtual Mouse
Bus 002 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub

# lsusb -s 2:8 -v | grep iProduct
...
  iProduct                2 Virtual Bluetooth Adapter

```

ID 0e0f:0008 の Virtual Bluetooth Adapter というデバイスが有効になります。BT のペアリングはホスト側で行い、ゲストからはペアリングが不要なデバイスが接続されているように見えるそうです。

## Share Bluetooth devices with Linux が無効の時

設定画面にホストの BT アダプタが現れるのでチェックをするとゲストから見えるようになります。

```
# lsusb
...
Bus 002 Device 009: ID 05ac:8289 Apple, Inc. 
Bus 002 Device 003: ID 0e0f:0002 VMware, Inc. Virtual USB Hub
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 002 Device 002: ID 0e0f:0003 VMware, Inc. Virtual Mouse
Bus 002 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub

# lsusb -s 2:9 -v | grep iProduct
...
  iProduct                2 Bluetooth USB Host Controller
```

ID 05ac:8289 の Bluetooth USB Host Controller というデバイスが有効になります。これはホストに接続された BT アダプタがそのまま現れた物です。ゲストからは BT の機能を全部使うことが出来ます。

## バグ

このように、Share Bluetooth devices with Linux が無効の時だけホストの BT アダプタが見えるというのが正常な動きだと思うのですが、リブート後チェックが無いのに VMware のアダプタが見えてしまう事がります。あれ? なんだこの USB デバイスは??? とびっくりしますが、気にしない事にします。
Node-REDのTwitter botでリプライ形式にする

Node-REDでtwitterボットを作る際に(正しく？)リプライ形式でツイートする方法のメモです。
単純なTweetやメンションによるメッセージ送付はサンプルがあちこちにあるのですが、受け付けたTweetに対するリプライを返す手順については見当たらなかったので、ここにまとめておきます。

ここでのリプライ形式とは、本家twittetサイトにて、当該ツイートをクリックした際にきちんと連結して表示されることをいいます。

<img alt="連結したツイート" src="https://qiita-image-store.s3.amazonaws.com/0/82999/a1ec2bd3-601b-cb81-a956-83195f5bffec.jpeg" width="40%">

twittet出力ノードの前にfunctionノードで下記のように、冒頭でのメンションと、msg.paramsを付けることでリプライになります。

<img width="545" alt="twitter-bot-nodes.png" src="https://qiita-image-store.s3.amazonaws.com/0/82999/e0edcf4f-b865-3d4b-4af2-fc8423076ae6.png">


```javascript:function：リプライ化
msg.payload = "@" + msg.tweet.user.screen_name + " " + msg.payload;
msg.params = {
    in_reply_to_status_id: msg.tweet.id_str
}
```

ポイントは、in_reply_to_status_id_strではなく、in_reply_to_status_idがパラメータになることと、そこに入れる値は逆にmsg.tweet.idではなくmsg.tweet.id_strであるということです。

なんか、気持ち悪い感じがしますが、msg.tweet.idには正しい値が入らず、丸め込まれて下二桁が0になってしまっているからです。また、ソースを追ったところ、この値はpostされるまで参照されることはなく、リクエストパラメータに渡されるので、本来整数が入るべきところに文字列として入っていても問題なく、エラーにもなりません。
apache access_logのファイル名を可変にする方法

access_logのファイル名を10分単位で任意のファイル名に変更したい場合どうすれば良いか調べた結果。

# 1. VirtualHost
```
<VirtualHost *:80>
  ServerName xxx.xxx
  SetEnvIf Request_URI \/favicon.ico$ no_log
  Logformat "%{%Y-%m-%d %T}t %A %{Client-Ip}i %{Referer}i %{User-Agent}i %D" common
  CustomLog "|/usr/local/bin/log.sh" common env=!no_log
</VirtualHost>
``` 

# 2. log.sh
```
#!/usr/bin/env bash
hostname=$(hostname)

while read line; do
  timestamp=$(date '+%s')
  prefix=$(($timestamp / 600))
  echo $line >> /var/log/access/${prefix}_foo_${hostname}
done
```

最初1つのログを処理してコマンドが終了する書き方をしていたら処理は動くけど以下のようなエラーが出るようになってしまったので上記のような継続的に標準入力を処理する方法に書き換える必要がありました。
apacheのログ出力は継続的にログを読み込むプロセスでなければいけないようですね。
```
AH00106: piped log program '/usr/local/bin/log.sh' failed unexpectedly
```
学生があまり聞く機会がないエンジニア用語まとめ2

[前回](https://qiita.com/kinzi0828/items/56e8881c2d908a2d0a93)の続きで、エンジニアが使う用語をまとめていきます
前回はおおまかな技術系でしたが、今回は言葉、ビジネス用語を。

気がついたら追加していきたいです。

#スニペット
プログラミングにおいて効率化するための手法です。
同じパターンや同じ処理は二度と書かない！過去のものを使う！
また、一度書いたコードはどこかに保存して使いやすいようにする！ようなことです。

例：スニペットを管理する。スニペットをつかう。など。

#サニタイズ
[参考1](http://www.phppro.jp/school/security/vol2/1)
入力された特別な意味のある記号をただの文字列として認識させるように変換処理すること。エスケープ。
しかし、全てを変換してしまうと窮屈なプログラムになるので、用途が肝心
例 `<`→`&lt;`　たとえば　`<script>`　が　`&lt;script>`　になり機能しなくなる
SQLインジェクション対策などで使われる。

#バリデーション
[参考1](http://wa3.i-3-i.info/word11610.html) : [参考2](http://www.atmarkit.co.jp/ait/articles/0903/02/news125.html)
フォーム文とかで文字のエラーチェックをするもの
サニタイズとの違いは、入力を許すか許さないか。バリデーションは許さない。
入力させないので、サニタイズする必要もなくなる。XSS対策などで使われる。

例えば、cakePHPはサニタイズよりもバリデーションが推奨されている。

#Excel方眼紙
[参考](http://trendy.nikkeibp.co.jp/article/pickup/20140327/1056189/?rt=nocnt)
Excelの１マスを小さくして体裁の整った図表を作りやすくしたもの。その見た目が方眼紙に見えることから。
セル結合が入ることで、表計算ができなくなったり、変更ができなくなったり不便な面がある。

#エビデンス
[参考1](https://mayonez.jp/topic/4167)
その結果になった証拠。文章だけでは説明できないものの証明など。
ログ、メールなどもそのうちの一つ

例えば、システム発注の際に言った・言ってないの水掛け論防止に役立つ？

#アジェンダ
[参考1](http://dictionary.sanseido-publ.co.jp/topic/10minnw/050agenda.html)
計画・予定表

#ブレスト
ブレーンストーミング

#エクスキューズ
言い訳